From e83fce3f50f646fa1d3daf6dabffa47045290a44 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 27 Mar 2009 10:20:34 +0100 Subject: Creating an instance of the QDesktopWidget breaks clipboard on X11. On X11 when user manually creates a QDesktopWidget object it breaks notifications from the root window since we have several QDesktopWidgets that have the same native window id and the wid->qwidget mapper (QWidgetPrivate::mapper) goes crazy. So whenever we get x11 event from the root window we cannot find a qwidget that corresponds to the window id and discard these events. Reviewed-by: Brad --- doc/src/qdesktopwidget.qdoc | 9 ++++++++- src/gui/kernel/qwidget.cpp | 11 +++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/doc/src/qdesktopwidget.qdoc b/doc/src/qdesktopwidget.qdoc index 0361aae..5a27fb4 100644 --- a/doc/src/qdesktopwidget.qdoc +++ b/doc/src/qdesktopwidget.qdoc @@ -48,6 +48,9 @@ \ingroup environment \mainclass + QApplication::desktop() function should be used to get an instance + of the QDesktopWidget. + Systems with more than one graphics card and monitor can manage the physical screen space available either as multiple desktops, or as a large virtual desktop, which usually has the size of the bounding @@ -86,12 +89,14 @@ screens. The correct width and height values are obtained using availableGeometry() or screenGeometry() for a particular screen. - \sa QApplication, QX11Info::appRootWindow() + \sa QApplication, QApplication::desktop(), QX11Info::appRootWindow() */ /*! \fn QDesktopWidget::QDesktopWidget() + \internal + Creates the desktop widget. If the system supports a virtual desktop, this widget will have @@ -104,6 +109,8 @@ /*! \fn QDesktopWidget::~QDesktopWidget() + \internal + Destroys the desktop widget and frees any allocated resources. */ diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 06810e0..dcb48cc 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -164,6 +164,7 @@ static inline bool bypassGraphicsProxyWidget(QWidget *p) #endif extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp +extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp QWidgetPrivate::QWidgetPrivate(int version) : QObjectPrivate(version), extra(0), focus_child(0) @@ -1400,7 +1401,13 @@ int QWidgetPrivate::maxInstances = 0; // Maximum number of widget instances void QWidgetPrivate::setWinId(WId id) // set widget identifier { Q_Q(QWidget); - if (mapper && data.winid) { + // the user might create a widget with Qt::Desktop window + // attribute (or create another QDesktopWidget instance), which + // will have the same windowid (the root window id) as the + // qt_desktopWidget. We should not add the second desktop widget + // to the mapper. + bool userDesktopWidget = qt_desktopWidget != 0 && qt_desktopWidget != q && q->windowType() == Qt::Desktop; + if (mapper && data.winid && !userDesktopWidget) { mapper->remove(data.winid); uncreatedWidgets->insert(q); } @@ -1409,7 +1416,7 @@ void QWidgetPrivate::setWinId(WId id) // set widget identifier #if defined(Q_WS_X11) hd = id; // X11: hd == ident #endif - if (mapper && id) { + if (mapper && id && !userDesktopWidget) { mapper->insert(data.winid, q); uncreatedWidgets->remove(q); } -- cgit v0.12 From 5d4c541cc308239e7f8d6e77d837cc1b2a1a7ebc Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 27 Mar 2009 11:36:16 +0100 Subject: Creating a native window handle doesn't reset input context on X11. When the current focus widget enforces the creation of the native window handle we should reset the input context. Task-number: 249578 Reviewed-by: Brad --- src/gui/kernel/qwidget.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index dcb48cc..09162ee 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -9793,12 +9793,21 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) } break; #endif - case Qt::WA_NativeWindow: + case Qt::WA_NativeWindow: { + QInputContext *ic = 0; + if (on && !internalWinId() && testAttribute(Qt::WA_InputMethodEnabled) && hasFocus()) { + ic = d->inputContext(); + ic->reset(); + ic->setFocusWidget(0); + } if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget()) parentWidget()->d_func()->enforceNativeChildren(); if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created)) d->createWinId(); + if (ic) + ic->setFocusWidget(this); break; + } case Qt::WA_PaintOnScreen: d->updateIsOpaque(); #if defined(Q_WS_WIN) || defined(Q_WS_X11) -- cgit v0.12 From b61933e6dfadd70655d1fad5344ba77da34587fc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 25 Mar 2009 20:19:57 +0100 Subject: whitespace --- tools/linguist/linguist/mainwindow.cpp | 2 +- tools/linguist/linguist/messageeditor.cpp | 2 +- tools/linguist/linguist/messagemodel.cpp | 12 ++++++------ tools/linguist/linguist/phraseview.cpp | 2 +- tools/linguist/linguist/translationsettingsdialog.h | 2 +- tools/linguist/lupdate/main.cpp | 2 +- tools/linguist/shared/cpp.cpp | 2 +- tools/linguist/shared/po.cpp | 2 +- tools/linguist/shared/profileevaluator.cpp | 4 ++-- tools/linguist/shared/qph.cpp | 2 +- tools/linguist/shared/qscript.cpp | 2 +- tools/linguist/shared/qscript.g | 2 +- tools/linguist/shared/translator.h | 2 +- tools/linguist/shared/translatortools.cpp | 4 ++-- tools/linguist/shared/ts.cpp | 8 ++++---- tools/linguist/shared/ui.cpp | 4 ++-- 16 files changed, 27 insertions(+), 27 deletions(-) diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp index e0a8a56..6ee0dd8 100644 --- a/tools/linguist/linguist/mainwindow.cpp +++ b/tools/linguist/linguist/mainwindow.cpp @@ -188,7 +188,7 @@ private: static const QVariant &pxObsolete() { - static const QVariant v = + static const QVariant v = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_obsolete.png"))); return v; } diff --git a/tools/linguist/linguist/messageeditor.cpp b/tools/linguist/linguist/messageeditor.cpp index f8c679c..16908bf 100644 --- a/tools/linguist/linguist/messageeditor.cpp +++ b/tools/linguist/linguist/messageeditor.cpp @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE // Allow translators to provide localized names for QLocale::languageToString // At least the own language should be translated ... This is a "hack" until // functionality is provided within Qt (see task 196275). -static const char * language_strings[] = +static const char * language_strings[] = { QT_TRANSLATE_NOOP("MessageEditor", "German"), QT_TRANSLATE_NOOP("MessageEditor", "Japanese"), diff --git a/tools/linguist/linguist/messagemodel.cpp b/tools/linguist/linguist/messagemodel.cpp index a7053cf..b049ab9 100644 --- a/tools/linguist/linguist/messagemodel.cpp +++ b/tools/linguist/linguist/messagemodel.cpp @@ -460,7 +460,7 @@ QString DataModel::prettifyFileName(const QString &fn) /****************************************************************************** * - * DataModelIterator + * DataModelIterator * *****************************************************************************/ @@ -1109,7 +1109,7 @@ void MultiDataModel::updateCountsOnRemove(int model, bool writable) /****************************************************************************** * - * MultiDataModelIterator + * MultiDataModelIterator * *****************************************************************************/ @@ -1214,17 +1214,17 @@ int MessageModel::columnCount(const QModelIndex &) const QVariant MessageModel::data(const QModelIndex &index, int role) const { - static QVariant pxOn = + static QVariant pxOn = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_on.png"))); - static QVariant pxOff = + static QVariant pxOff = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_off.png"))); - static QVariant pxObsolete = + static QVariant pxObsolete = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_obsolete.png"))); static QVariant pxDanger = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_danger.png"))); static QVariant pxWarning = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_warning.png"))); - static QVariant pxEmpty = + static QVariant pxEmpty = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_empty.png"))); int row = index.row(); diff --git a/tools/linguist/linguist/phraseview.cpp b/tools/linguist/linguist/phraseview.cpp index 78c9151..72c27dc 100644 --- a/tools/linguist/linguist/phraseview.cpp +++ b/tools/linguist/linguist/phraseview.cpp @@ -135,7 +135,7 @@ void PhraseView::contextMenuEvent(QContextMenuEvent *event) void PhraseView::mouseDoubleClickEvent(QMouseEvent *event) { QModelIndex index = indexAt(event->pos()); - if (!index.isValid()) + if (!index.isValid()) return; emit phraseSelected(m_modelIndex, m_phraseModel->phrase(index)->target()); diff --git a/tools/linguist/linguist/translationsettingsdialog.h b/tools/linguist/linguist/translationsettingsdialog.h index 8a633d9..a7ed1b4 100644 --- a/tools/linguist/linguist/translationsettingsdialog.h +++ b/tools/linguist/linguist/translationsettingsdialog.h @@ -76,4 +76,4 @@ private: QT_END_NAMESPACE -#endif // TRANSLATIONSETTINGSDIALOG_H +#endif // TRANSLATIONSETTINGSDIALOG_H diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index e7865d5..5869838 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -73,7 +73,7 @@ static void recursiveFileInfoList(const QDir &dir, if (fname != QLatin1String(".") && fname != QLatin1String("..")) { if (it->isDir()) recursiveFileInfoList(QDir(it->absoluteFilePath()), nameFilters, filter, recursive, fileinfolist); - else + else fileinfolist->append(*it); } } diff --git a/tools/linguist/shared/cpp.cpp b/tools/linguist/shared/cpp.cpp index 28616cc..333ffbf 100644 --- a/tools/linguist/shared/cpp.cpp +++ b/tools/linguist/shared/cpp.cpp @@ -784,7 +784,7 @@ static void parse(Translator *tor, const QString &initialContext, const QString if (yyTok == Tok_ColonColon) fullName.append(QString()); while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) { - if (yyTok == Tok_Ident) + if (yyTok == Tok_Ident) fullName.append(yyIdent); yyTok = getToken(); } diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index e9375e9..5842771 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -389,7 +389,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) for (; l != lines.size(); ++l) { QString line = lines.at(l); if (line.isEmpty()) - continue; + continue; if (isTranslationLine(line)) { bool isObsolete = line.startsWith(QLatin1String("#~ msgstr")); const QString prefix = QLatin1String(isObsolete ? "#~ " : ""); diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index 1e91f92..aa529c1 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -711,7 +711,7 @@ QStringList ProFileEvaluator::Private::qmakeFeaturePaths() // if (!specdir.cdUp() || specdir.isRoot()) // break; // if (QFile::exists(specdir.path() + QDir::separator() + "features")) { - // foreach (const QString &concat_it, concat) + // foreach (const QString &concat_it, concat) // feature_roots << (specdir.path() + concat_it); // break; // } @@ -1373,7 +1373,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct parents.append(proFile->fileName()); if (!parents.isEmpty()) parents.takeLast(); - if (parents.isEmpty()) + if (parents.isEmpty()) q->fileMessage(format("Project ERROR: %1").arg(msg)); else q->fileMessage(format("Project ERROR: %1. File was included from: '%2'") diff --git a/tools/linguist/shared/qph.cpp b/tools/linguist/shared/qph.cpp index 45d3a20..18f1634 100644 --- a/tools/linguist/shared/qph.cpp +++ b/tools/linguist/shared/qph.cpp @@ -101,7 +101,7 @@ bool QPHReader::read(Translator &translator) m_currentField = TargetField; else if (name() == QLatin1String("definition")) m_currentField = DefinitionField; - else + else m_currentField = NoField; } else if (isWhiteSpace()) { // ignore these diff --git a/tools/linguist/shared/qscript.cpp b/tools/linguist/shared/qscript.cpp index 9ab5e16..7377cba 100644 --- a/tools/linguist/shared/qscript.cpp +++ b/tools/linguist/shared/qscript.cpp @@ -2382,7 +2382,7 @@ bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd) return true; } -bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd) { Q_UNUSED(dev); Q_UNUSED(translator); diff --git a/tools/linguist/shared/qscript.g b/tools/linguist/shared/qscript.g index c7ee80d..8d33277 100644 --- a/tools/linguist/shared/qscript.g +++ b/tools/linguist/shared/qscript.g @@ -2012,7 +2012,7 @@ bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd) return true; } -bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd) { Q_UNUSED(dev); Q_UNUSED(translator); diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index f4279da..bbe7654 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -88,7 +88,7 @@ public: QString m_targetFileName; QDir m_sourceDir; QDir m_targetDir; // FIXME: TS spefic - QStringList m_dropTags; // tags to be dropped + QStringList m_dropTags; // tags to be dropped QStringList m_errors; bool m_verbose; bool m_ignoreUnfinished; diff --git a/tools/linguist/shared/translatortools.cpp b/tools/linguist/shared/translatortools.cpp index dcff546..96301d5 100644 --- a/tools/linguist/shared/translatortools.cpp +++ b/tools/linguist/shared/translatortools.cpp @@ -69,7 +69,7 @@ static int numberLength(const QString &s, int i) int pos = i; do { ++i; - } while (i < s.size() + } while (i < s.size() && (s.at(i).isDigit() || (isDigitFriendly(s[i]) && i + 1 < s.size() @@ -445,7 +445,7 @@ Translator merge(const Translator &tor, const Translator &virginTor, if (mv.sourceText().isEmpty()) { if (tor.contains(mv.context())) continue; - } else { + } else { if (tor.contains(mv.context(), mv.sourceText(), mv.comment())) continue; if (options & HeuristicSimilarText) { diff --git a/tools/linguist/shared/ts.cpp b/tools/linguist/shared/ts.cpp index 2e7d40f..d454e4e 100644 --- a/tools/linguist/shared/ts.cpp +++ b/tools/linguist/shared/ts.cpp @@ -373,7 +373,7 @@ bool TSReader::read(Translator &translator) } else if (elementStarts(strtranslation)) { // QXmlStreamAttributes atts = attributes(); - QStringRef type = atts.value(strtype); + QStringRef type = atts.value(strtype); if (type == strunfinished) msg.setType(TranslatorMessage::Unfinished); else if (type == strobsolete) @@ -440,7 +440,7 @@ static QString protect(const QString &str) QString result; result.reserve(str.length() * 12 / 10); for (int i = 0; i != str.size(); ++i) { - uint c = str.at(i).unicode(); + uint c = str.at(i).unicode(); switch (c) { case '\"': result += QLatin1String("""); @@ -708,12 +708,12 @@ bool loadTS(Translator &translator, QIODevice &dev, ConversionData &cd) return reader.read(translator); } -bool saveTS11(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveTS11(const Translator &translator, QIODevice &dev, ConversionData &cd) { return saveTS(translator, dev, cd, 11); } -bool saveTS20(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveTS20(const Translator &translator, QIODevice &dev, ConversionData &cd) { return saveTS(translator, dev, cd, 20); } diff --git a/tools/linguist/shared/ui.cpp b/tools/linguist/shared/ui.cpp index 4b86714..23a73e7 100644 --- a/tools/linguist/shared/ui.cpp +++ b/tools/linguist/shared/ui.cpp @@ -151,7 +151,7 @@ bool UiReader::fatalError(const QXmlParseException &exception) msg.sprintf("XML error: Parse error at line %d, column %d (%s).", exception.lineNumber(), exception.columnNumber(), exception.message().toLatin1().data()); - m_cd.appendError(msg); + m_cd.appendError(msg); return false; } @@ -188,7 +188,7 @@ bool loadUI(Translator &translator, QIODevice &dev, ConversionData &cd) return result; } -bool saveUI(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveUI(const Translator &translator, QIODevice &dev, ConversionData &cd) { Q_UNUSED(dev); Q_UNUSED(translator); -- cgit v0.12 From ddc1ff555604543cc2a3b1b797ff61b67abb0fe4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 25 Mar 2009 20:23:06 +0100 Subject: proper encoding and escaping --- tools/linguist/shared/qph.cpp | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/tools/linguist/shared/qph.cpp b/tools/linguist/shared/qph.cpp index 18f1634..799bf7d 100644 --- a/tools/linguist/shared/qph.cpp +++ b/tools/linguist/shared/qph.cpp @@ -133,14 +133,47 @@ static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &cd) return reader.read(translator); } -static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData &cd) +static QString protect(const QString &str) +{ + QString result; + result.reserve(str.length() * 12 / 10); + for (int i = 0; i != str.size(); ++i) { + uint c = str.at(i).unicode(); + switch (c) { + case '\"': + result += QLatin1String("""); + break; + case '&': + result += QLatin1String("&"); + break; + case '>': + result += QLatin1String(">"); + break; + case '<': + result += QLatin1String("<"); + break; + case '\'': + result += QLatin1String("'"); + break; + default: + if (c < 0x20 && c != '\r' && c != '\n' && c != '\t') + result += QString(QLatin1String("&#%1;")).arg(c); + else // this also covers surrogates + result += QChar(c); + } + } + return result; +} + +static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData &) { QTextStream t(&dev); - t << "\n"; + t.setCodec(QTextCodec::codecForName("UTF-8")); + t << "\n\n"; foreach (const TranslatorMessage &msg, translator.messages()) { t << "\n"; - t << " " << msg.sourceText() << "\n"; - t << " " << msg.translations().join(QLatin1String("@")) + t << " " << protect(msg.sourceText()) << "\n"; + t << " " << protect(msg.translations().join(QLatin1String("@"))) << "\n"; if (!msg.context().isEmpty() || !msg.comment().isEmpty()) t << " " << msg.context() << msg.comment() -- cgit v0.12 From 6ac130466400197b8977f60d14ed96abfb0d2172 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 25 Mar 2009 20:32:13 +0100 Subject: beautify / micro-optimize --- tools/linguist/shared/translator.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp index 3b5e8f3..6ae8059 100644 --- a/tools/linguist/shared/translator.cpp +++ b/tools/linguist/shared/translator.cpp @@ -105,13 +105,14 @@ void Translator::extend(const TranslatorMessage &msg) if (index == -1) { m_messages.append(msg); } else { - m_messages[index].addReferenceUniq(msg.fileName(), msg.lineNumber()); + TranslatorMessage &emsg = m_messages[index]; + emsg.addReferenceUniq(msg.fileName(), msg.lineNumber()); if (!msg.extraComment().isEmpty()) { - QString cmt = m_messages[index].extraComment(); + QString cmt = emsg.extraComment(); if (!cmt.isEmpty()) cmt.append(QLatin1String("\n----------\n")); cmt.append(msg.extraComment()); - m_messages[index].setExtraComment(cmt); + emsg.setExtraComment(cmt); } } } -- cgit v0.12 From 811eb47c3501479033ac3a484beeb896b6c0753f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 25 Mar 2009 20:33:07 +0100 Subject: avoid empty codec name --- tools/linguist/shared/translator.cpp | 2 +- tools/linguist/shared/ts.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp index 6ae8059..32404a5 100644 --- a/tools/linguist/shared/translator.cpp +++ b/tools/linguist/shared/translator.cpp @@ -545,7 +545,7 @@ void Translator::setCodecName(const QByteArray &name) if (!codec) { if (!name.isEmpty()) qWarning("No QTextCodec for %s available. Using Latin1\n", name.constData()); - m_codecName.clear(); + m_codecName = "ISO-8859-1"; } else { m_codecName = codec->name(); } diff --git a/tools/linguist/shared/ts.cpp b/tools/linguist/shared/ts.cpp index d454e4e..3af9e59 100644 --- a/tools/linguist/shared/ts.cpp +++ b/tools/linguist/shared/ts.cpp @@ -277,7 +277,9 @@ bool TSReader::read(Translator &translator) // ignore these, just whitespace } else if (elementStarts(strdefaultcodec)) { // - translator.setCodecName(readElementText().toLatin1()); + const QString &codec = readElementText(); + if (!codec.isEmpty()) + translator.setCodecName(codec.toLatin1()); // } else if (isStartElement() && name().toString().startsWith(strextrans)) { -- cgit v0.12 From 39c52d840cd1ba3bf988937f4f9c9a9cdba57bfc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 25 Mar 2009 21:04:48 +0100 Subject: actually ignore untranslated messages as it claims --- tools/linguist/shared/qm.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index c197e2b..1534e3f 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -646,10 +646,12 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData TranslatorMessage::Type typ = msg.type(); if (typ != TranslatorMessage::Obsolete) { if (typ == TranslatorMessage::Unfinished) { - if (msg.translation().isEmpty()) + if (msg.translation().isEmpty()) { ++untranslated; - else + continue; + } else { ++unfinished; + } } else { ++finished; } -- cgit v0.12 From 32798196d81439fa77b34425b95eb47556aebc8d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 25 Mar 2009 21:05:25 +0100 Subject: micro-optimization: don't evaluate same condition twice --- tools/linguist/shared/qm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index 1534e3f..4627b5d 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -650,6 +650,8 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData ++untranslated; continue; } else { + if (cd.ignoreUnfinished()) + continue; ++unfinished; } } else { @@ -660,7 +662,6 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData QString comment = msg.comment(); QStringList translations = msg.translations(); - if (!cd.ignoreUnfinished() || typ != TranslatorMessage::Unfinished) { /* Drop the comment in (context, sourceText, comment), unless the context is empty, @@ -680,7 +681,6 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData //filename and lineNumbers will be ignored from now. releaser.insert(tm); } - } } } -- cgit v0.12 From d3be9fa7c981430c48de0a65938f3a2bd636bfcc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Mar 2009 23:13:30 +0100 Subject: properly deal with messages which appear in multiple encodings in ts 1.1 and qm files, messages appear in their native encoding. that means that a message can appear multiple times - once in utf8 and once in the codecForTr. however, in ts 2.0 files, everything is utf8 and messages can have a utf8 flag for the later transformation into qm. unfortunately, there was no flag to mark that the message is needed in *both* encodings, and the respective case was completely ignored when reading ts 1.1 and qm files (causing error messages). Task-number: 249022 AutoTest: 322690 --- tools/linguist/shared/qm.cpp | 291 +++++++++++++++------------- tools/linguist/shared/translator.cpp | 26 +++ tools/linguist/shared/translator.h | 1 + tools/linguist/shared/translatormessage.cpp | 4 +- tools/linguist/shared/translatormessage.h | 3 + tools/linguist/shared/ts.cpp | 194 +++++++++++-------- 6 files changed, 299 insertions(+), 220 deletions(-) diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index 4627b5d..8a3658c 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -103,6 +103,43 @@ static uint elfHash(const QByteArray &ba) return h; } +class ByteTranslatorMessage +{ +public: + ByteTranslatorMessage( + const QByteArray &context, + const QByteArray &sourceText, + const QByteArray &comment, + const QStringList &translations) : + m_context(context), + m_sourcetext(sourceText), + m_comment(comment), + m_translations(translations) + {} + const QByteArray &context() const { return m_context; } + const QByteArray &sourceText() const { return m_sourcetext; } + const QByteArray &comment() const { return m_comment; } + const QStringList &translations() const { return m_translations; } + bool operator<(const ByteTranslatorMessage& m) const; + +private: + QByteArray m_context; + QByteArray m_sourcetext; + QByteArray m_comment; + QStringList m_translations; +}; + +Q_DECLARE_TYPEINFO(ByteTranslatorMessage, Q_MOVABLE_TYPE); + +bool ByteTranslatorMessage::operator<(const ByteTranslatorMessage& m) const +{ + if (m_context != m.m_context) + return m_context < m.m_context; + if (m_sourcetext != m.m_sourcetext) + return m_sourcetext < m.m_sourcetext; + return m_comment < m.m_comment; +} + class Releaser { public: @@ -133,27 +170,12 @@ public: m_codec = QTextCodec::codecForName(codecName); } - TranslatorMessage findMessage(const QString &context, - const QString &sourceText, const QString &comment, - const QString &fileName = QString(), int lineNumber = -1) const; - bool save(QIODevice *iod); - void insert(const TranslatorMessage &); - void remove(const TranslatorMessage &); - - bool contains(const QString &context, const QString &sourceText, - const QString & comment) const; - - bool contains(const QString &context, const QString &comment, - const QString &fileName, int lineNumber) const; + void insert(const TranslatorMessage &msg, bool forceComment); void squeeze(TranslatorSaveMode mode); - QList messages() const; - - bool isEmpty() const; - void setNumerusRules(const QByteArray &rules); private: @@ -163,18 +185,20 @@ private: // on turn should be the same as passed to the actual tr(...) calls QByteArray originalBytes(const QString &str, bool isUtf8) const; - Prefix commonPrefix(const TranslatorMessage &m1, const TranslatorMessage &m2) const; + void insertInternal(const TranslatorMessage &message, bool forceComment, bool isUtf8); - uint msgHash(const TranslatorMessage &msg) const; + Prefix commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2) const; - void writeMessage(const TranslatorMessage & msg, QDataStream & stream, + uint msgHash(const ByteTranslatorMessage &msg) const; + + void writeMessage(const ByteTranslatorMessage & msg, QDataStream & stream, TranslatorSaveMode strip, Prefix prefix) const; // for squeezed but non-file data, this is what needs to be deleted QByteArray m_messageArray; QByteArray m_offsetArray; QByteArray m_contextArray; - QMap m_messages; + QMap m_messages; QByteArray m_numerusRules; // Used to reproduce the original bytes @@ -193,12 +217,12 @@ QByteArray Releaser::originalBytes(const QString &str, bool isUtf8) const return m_codec ? m_codec->fromUnicode(str) : str.toLatin1(); } -uint Releaser::msgHash(const TranslatorMessage &msg) const +uint Releaser::msgHash(const ByteTranslatorMessage &msg) const { - return elfHash(originalBytes(msg.sourceText() + msg.comment(), msg.isUtf8())); + return elfHash(msg.sourceText() + msg.comment()); } -Prefix Releaser::commonPrefix(const TranslatorMessage &m1, const TranslatorMessage &m2) const +Prefix Releaser::commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2) const { if (msgHash(m1) != msgHash(m2)) return NoPrefix; @@ -211,7 +235,7 @@ Prefix Releaser::commonPrefix(const TranslatorMessage &m1, const TranslatorMessa return HashContextSourceTextComment; } -void Releaser::writeMessage(const TranslatorMessage & msg, QDataStream & stream, +void Releaser::writeMessage(const ByteTranslatorMessage &msg, QDataStream &stream, TranslatorSaveMode mode, Prefix prefix) const { for (int i = 0; i < msg.translations().count(); ++i) { @@ -228,14 +252,14 @@ void Releaser::writeMessage(const TranslatorMessage & msg, QDataStream & stream, switch (prefix) { default: case HashContextSourceTextComment: - stream << quint8(Tag_Comment) << originalBytes(msg.comment(), msg.isUtf8()); + stream << quint8(Tag_Comment) << msg.comment(); // fall through case HashContextSourceText: - stream << quint8(Tag_SourceText) << originalBytes(msg.sourceText(), msg.isUtf8()); + stream << quint8(Tag_SourceText) << msg.sourceText(); // fall through case HashContext: - stream << quint8(Tag_Context) << originalBytes(msg.context(), msg.isUtf8()); - ; + stream << quint8(Tag_Context) << msg.context(); + break; } stream << quint8(Tag_End); @@ -275,7 +299,7 @@ void Releaser::squeeze(TranslatorSaveMode mode) if (m_messages.isEmpty() && mode == SaveEverything) return; - QMap messages = m_messages; + QMap messages = m_messages; // re-build contents m_messageArray.clear(); @@ -286,7 +310,7 @@ void Releaser::squeeze(TranslatorSaveMode mode) QMap offsets; QDataStream ms(&m_messageArray, QIODevice::WriteOnly); - QMap::const_iterator it, next; + QMap::const_iterator it, next; int cpPrev = 0, cpNext = 0; for (it = messages.constBegin(); it != messages.constEnd(); ++it) { cpPrev = cpNext; @@ -310,7 +334,7 @@ void Releaser::squeeze(TranslatorSaveMode mode) } if (mode == SaveStripped) { - QMap contextSet; + QMap contextSet; for (it = messages.constBegin(); it != messages.constEnd(); ++it) ++contextSet[it.key().context()]; @@ -322,10 +346,10 @@ void Releaser::squeeze(TranslatorSaveMode mode) else hTableSize = (contextSet.size() < 10000) ? 15013 : 3 * contextSet.size() / 2; - QMultiMap hashMap; - QMap::const_iterator c; + QMultiMap hashMap; + QMap::const_iterator c; for (c = contextSet.constBegin(); c != contextSet.constEnd(); ++c) - hashMap.insert(elfHash(originalBytes(c.key(), false /*FIXME*/)) % hTableSize, c.key()); + hashMap.insert(elfHash(c.key()) % hTableSize, c.key()); /* The contexts found in this translator are stored in a hash @@ -360,16 +384,14 @@ void Releaser::squeeze(TranslatorSaveMode mode) t << quint16(0); // the entry at offset 0 cannot be used uint upto = 2; - QMap::const_iterator entry = hashMap.constBegin(); + QMap::const_iterator entry = hashMap.constBegin(); while (entry != hashMap.constEnd()) { int i = entry.key(); hTable[i] = quint16(upto >> 1); do { - QString context = entry.value(); - QByteArray ba = context.toUtf8(); - const char *con = ba.data(); - uint len = uint(qstrlen(con)); + const char *con = entry.value().constData(); + uint len = uint(entry.value().length()); len = qMin(len, 255u); t << quint8(len); t.writeRawData(con, len); @@ -394,68 +416,28 @@ void Releaser::squeeze(TranslatorSaveMode mode) } } -bool Releaser::contains(const QString &context, const QString &sourceText, - const QString &comment) const -{ - return !findMessage(context, sourceText, comment).translation().isNull(); -} - -bool Releaser::contains(const QString &context, const QString &comment, - const QString &fileName, int lineNumber) const -{ - return !findMessage(context, QString(), comment, fileName, lineNumber).isNull(); -} - -void Releaser::insert(const TranslatorMessage &message) -{ - m_messages.insert(message, 0); -} - -void Releaser::remove(const TranslatorMessage &message) -{ - m_messages.remove(message); -} - - -TranslatorMessage Releaser::findMessage(const QString &context, - const QString &sourceText, const QString &comment, - const QString &fileName, int lineNumber) const +void Releaser::insertInternal(const TranslatorMessage &message, bool forceComment, bool isUtf8) { - if (m_messages.isEmpty()) - return TranslatorMessage(); - - QMap::const_iterator it; - - // Either we want to find an item that matches context, sourcetext - // (and optionally comment) Or we want to find an item that - // matches context, filename, linenumber (and optionally comment) - TranslatorMessage msg(context, sourceText, comment, QString(), fileName, lineNumber); - it = m_messages.constFind(msg); - if (it != m_messages.constEnd()) - return it.key(); - - if (!comment.isEmpty()) { - it = m_messages.constFind(TranslatorMessage(context, sourceText, QString(), QString(), fileName, lineNumber)); - if (it != m_messages.constEnd()) - return it.key(); + ByteTranslatorMessage bmsg(originalBytes(message.context(), isUtf8), + originalBytes(message.sourceText(), isUtf8), + originalBytes(message.comment(), isUtf8), + message.translations()); + if (!forceComment) { + ByteTranslatorMessage bmsg2( + bmsg.context(), bmsg.sourceText(), QByteArray(""), bmsg.translations()); + if (!m_messages.contains(bmsg2)) { + m_messages.insert(bmsg2, 0); + return; + } } - - it = m_messages.constFind(TranslatorMessage(context, QString(), comment, QString(), fileName, lineNumber)); - if (it != m_messages.constEnd()) - return it.key(); - if (comment.isEmpty()) - return TranslatorMessage(); - - it = m_messages.constFind(TranslatorMessage(context, QString(), QString(), QString(), fileName, lineNumber)); - if (it != m_messages.constEnd()) - return it.key(); - return TranslatorMessage(); + m_messages.insert(bmsg, 0); } -bool Releaser::isEmpty() const +void Releaser::insert(const TranslatorMessage &message, bool forceComment) { - return m_messageArray.isEmpty() && m_offsetArray.isEmpty() - && m_contextArray.isEmpty() && m_messages.isEmpty(); + insertInternal(message, forceComment, message.isUtf8()); + if (message.isUtf8() && message.isNonUtf8()) + insertInternal(message, forceComment, false); } void Releaser::setNumerusRules(const QByteArray &rules) @@ -463,11 +445,6 @@ void Releaser::setNumerusRules(const QByteArray &rules) m_numerusRules = rules; } -QList Releaser::messages() const -{ - return m_messages.keys(); -} - static quint8 read8(const uchar *data) { return *data; @@ -478,6 +455,31 @@ static quint32 read32(const uchar *data) return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]); } +static void fromBytes(const char *str, int len, QTextCodec *codec, QTextCodec *utf8Codec, + QString *out, QString *utf8Out, + bool *isSystem, bool *isUtf8, bool *needs8Bit) +{ + for (int i = 0; i < len; ++i) + if (str[i] & 0x80) { + if (utf8Codec) { + QTextCodec::ConverterState cvtState; + *utf8Out = utf8Codec->toUnicode(str, len, &cvtState); + *isUtf8 = !cvtState.invalidChars; + } + QTextCodec::ConverterState cvtState; + *out = codec->toUnicode(str, len, &cvtState); + *isSystem = !cvtState.invalidChars; + *needs8Bit = true; + return; + } + *out = QString::fromLatin1(str, len); + *isSystem = true; + if (utf8Codec) { + *utf8Out = *out; + *isUtf8 = true; + } + *needs8Bit = false; +} bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) { @@ -543,10 +545,19 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) size_t numItems = offsetLength / (2 * sizeof(quint32)); //qDebug() << "NUMITEMS: " << numItems; - TranslatorMessage msg; - // FIXME: that's just a guess, the original locale data is lost... QTextCodec *codec = QTextCodec::codecForLocale(); + QTextCodec *utf8Codec = 0; + if (codec->name() != "UTF-8") + utf8Codec = QTextCodec::codecForName("UTF-8"); + + QString context, contextUtf8; + bool contextIsSystem, contextIsUtf8, contextNeeds8Bit; + QString sourcetext, sourcetextUtf8; + bool sourcetextIsSystem, sourcetextIsUtf8, sourcetextNeeds8Bit; + QString comment, commentUtf8; + bool commentIsSystem, commentIsUtf8, commentNeeds8Bit; + QStringList translations; for (const uchar *start = offsetArray; start != offsetArray + (numItems << 3); start += 8) { //quint32 hash = read32(start); @@ -575,7 +586,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) } str.replace(QChar(Translator::InternalVariantSeparator), QChar(Translator::DefaultVariantSeparator)); - msg.appendTranslation(str); + translations << str; m += len; break; } @@ -588,7 +599,9 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) m += 4; //qDebug() << "SOURCE LEN: " << len; //qDebug() << "SOURCE: " << QByteArray((const char*)m, len); - msg.setSourceText(codec->toUnicode(QByteArray((const char*)m, len))); + fromBytes((const char*)m, len, codec, utf8Codec, + &sourcetext, &sourcetextUtf8, + &sourcetextIsSystem, &sourcetextIsUtf8, &sourcetextNeeds8Bit); m += len; break; } @@ -597,7 +610,9 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) m += 4; //qDebug() << "CONTEXT LEN: " << len; //qDebug() << "CONTEXT: " << QByteArray((const char*)m, len); - msg.setContext(codec->toUnicode(QByteArray((const char*)m, len))); + fromBytes((const char*)m, len, codec, utf8Codec, + &context, &contextUtf8, + &contextIsSystem, &contextIsUtf8, &contextNeeds8Bit); m += len; break; } @@ -606,7 +621,9 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) m += 4; //qDebug() << "COMMENT LEN: " << len; //qDebug() << "COMMENT: " << QByteArray((const char*)m, len); - msg.setComment(codec->toUnicode(QByteArray((const char*)m, len))); + fromBytes((const char*)m, len, codec, utf8Codec, + &comment, &commentUtf8, + &commentIsSystem, &commentIsUtf8, &commentNeeds8Bit); m += len; break; } @@ -616,11 +633,33 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) } } end:; + TranslatorMessage msg; msg.setType(TranslatorMessage::Finished); + msg.setTranslations(translations); + translations.clear(); + if (contextNeeds8Bit || sourcetextNeeds8Bit || commentNeeds8Bit) { + if (utf8Codec && contextIsUtf8 && sourcetextIsUtf8 && commentIsUtf8) { + // The message is utf-8, but file is not. + msg.setUtf8(true); + msg.setContext(contextUtf8); + msg.setSourceText(sourcetextUtf8); + msg.setComment(commentUtf8); + translator.append(msg); + continue; + } + if (!(contextIsSystem && sourcetextIsSystem && commentIsSystem)) { + cd.appendError(QLatin1String( + "Cannot read file with current system character codec")); + return false; + } + // The message is 8-bit in the file's encoding (utf-8 or not). + } + msg.setContext(context); + msg.setSourceText(sourcetext); + msg.setComment(comment); translator.append(msg); - //qDebug() << "\nHASH:" << hash << msg.sourceText() << msg.context(); - msg.setTranslations(QStringList()); } + translator.resolveDualEncoded(); return ok; } @@ -657,30 +696,16 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData } else { ++finished; } - QString context = msg.context(); - QString sourceText = msg.sourceText(); - QString comment = msg.comment(); - QStringList translations = msg.translations(); - - /* - Drop the comment in (context, sourceText, comment), - unless the context is empty, - unless (context, sourceText, "") already exists or - unless we already dropped the comment of (context, - sourceText, comment0). - */ - if (comment.isEmpty() - || context.isEmpty() - || translator.contains(context, sourceText, QString()) - || !releaser.findMessage(context, sourceText, QString()).translation() - .isNull() ) { - releaser.insert(msg); - } else { - TranslatorMessage tm(context, sourceText, QString(), - QString(), QString(), -1, translations); - //filename and lineNumbers will be ignored from now. - releaser.insert(tm); - } + // Drop the comment in (context, sourceText, comment), + // unless the context is empty, + // unless (context, sourceText, "") already exists or + // unless we already dropped the comment of (context, + // sourceText, comment0). + bool forceComment = + msg.comment().isEmpty() + || msg.context().isEmpty() + || translator.contains(msg.context(), msg.sourceText(), QString()); + releaser.insert(msg, forceComment); } } diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp index 32404a5..3721204 100644 --- a/tools/linguist/shared/translator.cpp +++ b/tools/linguist/shared/translator.cpp @@ -114,6 +114,10 @@ void Translator::extend(const TranslatorMessage &msg) cmt.append(msg.extraComment()); emsg.setExtraComment(cmt); } + if (msg.isUtf8() != emsg.isUtf8()) { + emsg.setUtf8(true); + emsg.setNonUtf8(true); + } } } @@ -425,6 +429,28 @@ QList Translator::findDuplicates() const return ret; } +void Translator::resolveDualEncoded() +{ + QHash dups; + for (int i = 0; i < m_messages.count();) { + const TranslatorMessage &msg = m_messages.at(i); + QHash::ConstIterator it = dups.constFind(msg); + if (it != dups.constEnd()) { + TranslatorMessage &omsg = m_messages[*it]; + if (omsg.isUtf8() != msg.isUtf8() && !omsg.isNonUtf8()) { + omsg.setUtf8(true); + omsg.setNonUtf8(true); + m_messages.removeAt(i); + continue; + } + // Regular dupe; will complain later + } else { + dups[msg] = i; + } + ++i; + } +} + // Used by lupdate to be able to search using absolute paths during merging void Translator::makeFileNamesAbsolute(const QDir &originalPath) { diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index bbe7654..ba719ec 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -130,6 +130,7 @@ public: void stripIdenticalSourceTranslations(); void dropTranslations(); QList findDuplicates() const; + void resolveDualEncoded(); void makeFileNamesAbsolute(const QDir &originalPath); void setCodecName(const QByteArray &name); diff --git a/tools/linguist/shared/translatormessage.cpp b/tools/linguist/shared/translatormessage.cpp index ab4301f..afe66fe 100644 --- a/tools/linguist/shared/translatormessage.cpp +++ b/tools/linguist/shared/translatormessage.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE TranslatorMessage::TranslatorMessage() - : m_lineNumber(-1), m_type(Unfinished), m_utf8(false), m_plural(false) + : m_lineNumber(-1), m_type(Unfinished), m_utf8(false), m_nonUtf8(false), m_plural(false) { } @@ -66,7 +66,7 @@ TranslatorMessage::TranslatorMessage(const QString &context, : m_context(context), m_sourcetext(sourceText), m_comment(comment), m_userData(userData), m_translations(translations), m_fileName(fileName), m_lineNumber(lineNumber), - m_type(type), m_utf8(false), m_plural(plural) + m_type(type), m_utf8(false), m_nonUtf8(false), m_plural(plural) { } diff --git a/tools/linguist/shared/translatormessage.h b/tools/linguist/shared/translatormessage.h index fa37ff5..2818e28 100644 --- a/tools/linguist/shared/translatormessage.h +++ b/tools/linguist/shared/translatormessage.h @@ -136,6 +136,8 @@ public: void setType(Type t) { m_type = t; } bool isUtf8() const { return m_utf8; } // codecForTr override void setUtf8(bool on) { m_utf8 = on; } + bool isNonUtf8() const { return m_nonUtf8; } // codecForTr override + void setNonUtf8(bool on) { m_nonUtf8 = on; } bool isPlural() const { return m_plural; } void setPlural(bool isplural) { m_plural = isplural; } @@ -169,6 +171,7 @@ private: Type m_type; bool m_utf8; + bool m_nonUtf8; bool m_plural; }; diff --git a/tools/linguist/shared/ts.cpp b/tools/linguist/shared/ts.cpp index 3af9e59..8a6d365 100644 --- a/tools/linguist/shared/ts.cpp +++ b/tools/linguist/shared/ts.cpp @@ -212,6 +212,7 @@ QString TSReader::readTransContents() bool TSReader::read(Translator &translator) { + STRING(both); STRING(byte); STRING(comment); STRING(context); @@ -265,13 +266,15 @@ bool TSReader::read(Translator &translator) QString currentFile; QXmlStreamAttributes atts = attributes(); - //QString version = atts.value(strversion).toString(); + QString version = atts.value(strversion).toString(); translator.setLanguageCode(atts.value(strlanguage).toString()); translator.setSourceLanguageCode(atts.value(strsourcelanguage).toString()); while (!atEnd()) { readNext(); if (isEndElement()) { // found, finish local loop + if (version == QLatin1String("1.1")) + translator.resolveDualEncoded(); break; } else if (isWhiteSpace()) { // ignore these, just whitespace @@ -311,7 +314,9 @@ bool TSReader::read(Translator &translator) msg.setContext(context); msg.setType(TranslatorMessage::Finished); msg.setPlural(attributes().value(strnumerus) == stryes); - msg.setUtf8(attributes().value(strutf8) == strtrue + const QStringRef &utf8Attr = attributes().value(strutf8); + msg.setNonUtf8(utf8Attr == strboth); + msg.setUtf8(msg.isNonUtf8() || utf8Attr == strtrue || attributes().value(strencoding) == strUtf8); while (!atEnd()) { readNext(); @@ -594,107 +599,126 @@ bool saveTS(const Translator &translator, QIODevice &dev, ConversionData &cd, in foreach (const TranslatorMessage &msg, messageOrder[context]) { //msg.dump(); - t << " \n"; - if (translator.locationsType() != Translator::NoLocations) { - QString cfile = currentFile; - bool first = true; - foreach (const TranslatorMessage::Reference &ref, msg.allReferences()) { - QString fn = cd.m_targetDir.relativeFilePath(ref.fileName()) - .replace(QLatin1Char('\\'),QLatin1Char('/')); - int ln = ref.lineNumber(); - QString ld; - if (translator.locationsType() == Translator::RelativeLocations) { - if (ln != -1) { - int dlt = ln - currentLine[fn]; - if (dlt >= 0) - ld.append(QLatin1Char('+')); - ld.append(QString::number(dlt)); - currentLine[fn] = ln; + bool isUtf8 = msg.isUtf8(); + bool second = false; + forever { + + t << " \n"; + if (translator.locationsType() != Translator::NoLocations) { + QString cfile = currentFile; + bool first = true; + foreach (const TranslatorMessage::Reference &ref, msg.allReferences()) { + QString fn = cd.m_targetDir.relativeFilePath(ref.fileName()) + .replace(QLatin1Char('\\'),QLatin1Char('/')); + int ln = ref.lineNumber(); + QString ld; + if (translator.locationsType() == Translator::RelativeLocations) { + if (ln != -1) { + int dlt = ln - currentLine[fn]; + if (dlt >= 0) + ld.append(QLatin1Char('+')); + ld.append(QString::number(dlt)); + currentLine[fn] = ln; + } - if (fn != cfile) { - if (first) - currentFile = fn; - cfile = fn; + if (fn != cfile) { + if (first) + currentFile = fn; + cfile = fn; + } else { + fn.clear(); + } + first = false; } else { - fn.clear(); + if (ln != -1) + ld = QString::number(ln); } - first = false; - } else { - if (ln != -1) - ld = QString::number(ln); + t << " \n"; } - t << " \n"; } - } - t << " " - << evilBytes(msg.sourceText(), msg.isUtf8(), format, codecName) - << "\n"; + t << " " + << evilBytes(msg.sourceText(), isUtf8, format, codecName) + << "\n"; - if (format != 11 && !msg.oldSourceText().isEmpty()) - t << " " << protect(msg.oldSourceText()) << "\n"; + if (format != 11 && !msg.oldSourceText().isEmpty()) + t << " " << protect(msg.oldSourceText()) << "\n"; - if (!msg.comment().isEmpty()) { - t << " " - << evilBytes(msg.comment(), msg.isUtf8(), format, codecName) - << "\n"; - } + if (!msg.comment().isEmpty()) { + t << " " + << evilBytes(msg.comment(), isUtf8, format, codecName) + << "\n"; + } - if (format != 11) { + if (format != 11) { - if (!msg.oldComment().isEmpty()) - t << " " << protect(msg.oldComment()) << "\n"; + if (!msg.oldComment().isEmpty()) + t << " " << protect(msg.oldComment()) << "\n"; - if (!msg.extraComment().isEmpty()) - t << " " << protect(msg.extraComment()) - << "\n"; + if (!msg.extraComment().isEmpty()) + t << " " << protect(msg.extraComment()) + << "\n"; - if (!msg.translatorComment().isEmpty()) - t << " " << protect(msg.translatorComment()) - << "\n"; + if (!msg.translatorComment().isEmpty()) + t << " " << protect(msg.translatorComment()) + << "\n"; - } + } - t << " "; - QStringList translns = translator.normalizedTranslations(msg, cd, &result); - for (int j = 0; j < qMax(1, translns.count()); ++j) { - t << "\n "; + t << " "; + QStringList translns = translator.normalizedTranslations(msg, cd, &result); + for (int j = 0; j < qMax(1, translns.count()); ++j) { + t << "\n "; + } + t << "\n "; + } else { + writeVariants(t, " ", msg.translation()); } - t << "\n "; - } else { - writeVariants(t, " ", msg.translation()); - } - t << "\n"; + t << "\n"; + + if (format != 11) + writeExtras(t, " ", msg.extras(), drops); - if (format != 11) - writeExtras(t, " ", msg.extras(), drops); + if (!msg.userData().isEmpty()) + t << " " << msg.userData() << "\n"; + t << " \n"; - if (!msg.userData().isEmpty()) - t << " " << msg.userData() << "\n"; - t << " \n"; + if (format != 11 || second || !msg.isUtf8() || !msg.isNonUtf8()) + break; + isUtf8 = false; + second = true; + } } t << "\n"; } -- cgit v0.12 From f3ec88cb128ee912457e273c420839d4bd295572 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Mar 2009 19:02:25 +0100 Subject: declare type info next to the type, not "somewhere" --- tools/linguist/shared/translator.h | 2 -- tools/linguist/shared/translatormessage.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index ba719ec..8908305 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -52,8 +52,6 @@ QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(TranslatorMessage, Q_MOVABLE_TYPE); - class QIODevice; // A struct of "interesting" data passed to and from the load and save routines diff --git a/tools/linguist/shared/translatormessage.h b/tools/linguist/shared/translatormessage.h index 2818e28..363019e 100644 --- a/tools/linguist/shared/translatormessage.h +++ b/tools/linguist/shared/translatormessage.h @@ -175,6 +175,8 @@ private: bool m_plural; }; +Q_DECLARE_TYPEINFO(TranslatorMessage, Q_MOVABLE_TYPE); + int qHash(const TranslatorMessage &msg); QT_END_NAMESPACE -- cgit v0.12 From 65aadc316caca9c31a9aaf4011e4e02b3f8af19f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Mar 2009 19:58:57 +0100 Subject: static is even better than const --- tools/linguist/shared/qm.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index 8a3658c..d19b519 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -187,9 +187,9 @@ private: void insertInternal(const TranslatorMessage &message, bool forceComment, bool isUtf8); - Prefix commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2) const; + static Prefix commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2); - uint msgHash(const ByteTranslatorMessage &msg) const; + static uint msgHash(const ByteTranslatorMessage &msg); void writeMessage(const ByteTranslatorMessage & msg, QDataStream & stream, TranslatorSaveMode strip, Prefix prefix) const; @@ -217,12 +217,12 @@ QByteArray Releaser::originalBytes(const QString &str, bool isUtf8) const return m_codec ? m_codec->fromUnicode(str) : str.toLatin1(); } -uint Releaser::msgHash(const ByteTranslatorMessage &msg) const +uint Releaser::msgHash(const ByteTranslatorMessage &msg) { return elfHash(msg.sourceText() + msg.comment()); } -Prefix Releaser::commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2) const +Prefix Releaser::commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2) { if (msgHash(m1) != msgHash(m2)) return NoPrefix; -- cgit v0.12 From c211bfceadc4a83163e983d4a388becb7ee0aca5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Mar 2009 16:24:41 +0100 Subject: most definitely NOT \since 4.5 --- src/corelib/kernel/qtranslator.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index cdddf36..f97a319 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -765,8 +765,6 @@ void QTranslatorPrivate::clear() } /*! - \since 4.5 - Returns the translation for the key (\a context, \a sourceText, \a disambiguation). If none is found, also tries (\a context, \a sourceText, ""). If that still fails, returns an empty string. -- cgit v0.12 From 97a3b2d04dbfd9c56f1181b5f45864bcb1472099 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Mar 2009 16:33:25 +0100 Subject: remove pointless check this function is always called with found != 0 nowadays --- src/corelib/kernel/qtranslator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index f97a319..1eca817 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -95,8 +95,7 @@ static bool match(const uchar* found, const char* target, uint len) // (normalize it to be without the zero-terminating symbol) if (len > 0 && found[len-1] == '\0') --len; - // 0 means anything, "" means empty - return !found || (qstrncmp((const char *)found, target, len) == 0 && target[len] == '\0'); + return (qstrncmp((const char *)found, target, len) == 0 && target[len] == '\0'); } static uint elfHash(const char *name) -- cgit v0.12 From aeb5fd46c7a4427ba13d9d75947006dee5fb0a20 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Mar 2009 16:35:00 +0100 Subject: optimize the exact length of the template is known, so there is no point in using the more complex (and thus potentially slower) strncmp instead of memcmp. --- src/corelib/kernel/qtranslator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 1eca817..77d6599 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -95,7 +95,7 @@ static bool match(const uchar* found, const char* target, uint len) // (normalize it to be without the zero-terminating symbol) if (len > 0 && found[len-1] == '\0') --len; - return (qstrncmp((const char *)found, target, len) == 0 && target[len] == '\0'); + return (memcmp(found, target, len) == 0 && target[len] == '\0'); } static uint elfHash(const char *name) -- cgit v0.12 From 3aff9113a9702ea6f7e099a73136a718ae1b992f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Mar 2009 20:06:22 +0100 Subject: make shadow builds work even if a non-shadow build is present --- mkspecs/features/moc.prf | 2 +- mkspecs/features/uic.prf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index faa9871..5e09455 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -61,7 +61,7 @@ QMAKE_EXTRA_COMPILERS += moc_source INCREDIBUILD_XGE += moc_source #make sure we can include these files -INCLUDEPATH += $$MOC_DIR +INCLUDEPATH += $$OUT_PWD/$$MOC_DIR #auto depend on moc unix:!no_mocdepend { diff --git a/mkspecs/features/uic.prf b/mkspecs/features/uic.prf index 885fad7..8077954 100644 --- a/mkspecs/features/uic.prf +++ b/mkspecs/features/uic.prf @@ -34,7 +34,7 @@ isEmpty(QMAKE_MOD_UIC):QMAKE_MOD_UIC = ui_ INCREDIBUILD_XGE += uic } -INCLUDEPATH += $$UI_HEADERS_DIR +INCLUDEPATH += $$OUT_PWD/$$UI_HEADERS_DIR uic3 { isEmpty(FORMS3) { -- cgit v0.12 From 763f816a73feb29d235bf146db1aa18b46ba996e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Mar 2009 23:06:03 +0100 Subject: even more verbose debug output --- qmake/generators/makefile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 24e030e..d0fbcbe 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2806,7 +2806,7 @@ MakefileGenerator::fileFixify(const QString& file, const QString &out_d, const Q } if(ret.isEmpty()) ret = "."; - debug_msg(3, "Fixed[%d] %s :: to :: %s [%s::%s] [%s::%s]", fix, orig_file.toLatin1().constData(), + debug_msg(3, "Fixed[%d,%d] %s :: to :: %s [%s::%s] [%s::%s]", fix, canon, orig_file.toLatin1().constData(), ret.toLatin1().constData(), in_d.toLatin1().constData(), out_d.toLatin1().constData(), pwd.toLatin1().constData(), Option::output_dir.toLatin1().constData()); cache->insert(cacheKey, ret); -- cgit v0.12 From 7d2c8eb99c563b4fb236fe538123255f52f293a2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Mar 2009 23:06:27 +0100 Subject: don't include uic in non-gui configurations uic is set in default_pre. this leads to useless -I compiler flags when no ui files are used in fact, so it would be nice to get rid of it in cases where it is not used. for backwards compat, don't remove it from the _pre, but add some magic to _post to remove it again if QT does not contain gui. of course, we need a force_uic CONFIG to enable an exception for QtGui itself ... --- mkspecs/features/default_post.prf | 3 +++ src/gui/gui.pro | 1 + 2 files changed, 4 insertions(+) diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index 01074f4..424609e 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -6,5 +6,8 @@ incredibuild_xge { CONFIG = incredibuild_xge $$CONFIG } +# It's in the default config. Get rid of it now if unused. +!contains(QT, [Gg][Uu][Ii]):!CONFIG(force_uic):CONFIG -= uic + QMAKE_INCDIR += $$QMAKE_INCDIR_POST QMAKE_LIBDIR += $$QMAKE_LIBDIR_POST diff --git a/src/gui/gui.pro b/src/gui/gui.pro index f224e67..0d3bbc6 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -1,6 +1,7 @@ TARGET = QtGui QPRO_PWD = $$PWD QT = core +CONFIG += force_uic DEFINES += QT_BUILD_GUI_LIB QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000 -- cgit v0.12 From b3f88e8629390a49d12fd7684e711280b7b2c7c2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 27 Mar 2009 13:08:00 +0100 Subject: properly process backslash line continuations this is a backport of be5a9587865f9f042cac8feb5296b71b11a1a80f Task-number: 249633 --- tools/linguist/shared/cpp.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tools/linguist/shared/cpp.cpp b/tools/linguist/shared/cpp.cpp index 333ffbf..2e137cf 100644 --- a/tools/linguist/shared/cpp.cpp +++ b/tools/linguist/shared/cpp.cpp @@ -130,12 +130,19 @@ static int yyInPos; static uint getChar() { - if (yyInPos >= yyInStr.size()) - return EOF; - QChar c = yyInStr[yyInPos++]; - if (c.unicode() == '\n') - ++yyCurLineNo; - return c.unicode(); + forever { + if (yyInPos >= yyInStr.size()) + return EOF; + uint c = yyInStr[yyInPos++].unicode(); + if (c == '\\' && yyInPos < yyInStr.size() && yyInStr[yyInPos].unicode() == '\n') { + ++yyCurLineNo; + ++yyInPos; + continue; + } + if (c == '\n') + ++yyCurLineNo; + return c; + } } static uint getToken() -- cgit v0.12 From 4833b02f80bc5bcd7b0946453f3e6c7bc09b01f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 20 Mar 2009 13:47:28 +0100 Subject: Fix QPixmap::fromImage() bug for monochrome images on Mac. Monochrome images should be converted to black and white, not transparent and white. Reported on qt-interest. Task-number: 249175 Reviewed-by: Trond --- src/gui/image/qpixmap_mac.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp index bfc605b..26d9618 100644 --- a/src/gui/image/qpixmap_mac.cpp +++ b/src/gui/image/qpixmap_mac.cpp @@ -303,7 +303,7 @@ void QMacPixmapData::fromImage(const QImage &img, else one_bit = one_bit >> (x % 8); if ((one_bit & 0x01)) - *(drow+x) = 0x00000000; + *(drow+x) = 0xFF000000; else *(drow+x) = 0xFFFFFFFF; } -- cgit v0.12 From 95d189ee0df74497d70449f3967a38c67f5860ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 27 Mar 2009 08:45:09 +0100 Subject: Fix mismatch between stroke and fill of ellipses on X11. When drawing ellipse without stroke we need to use the same width/height for the fill as we would use for the stroke for the stroke and fill to match. Filling first and then stroking should produce the same result as filling and stroking in one go. Task-number: 249490 Reviewed-by: Trond --- src/gui/painting/qpaintengine_x11.cpp | 10 +++------- tests/arthur/data/qps/primitives.qps | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index e9f1bb3..32cb63d 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1479,14 +1479,10 @@ void QX11PaintEngine::drawEllipse(const QRect &rect) return; } d->setupAdaptedOrigin(rect.topLeft()); - if (d->has_brush) { // draw filled ellipse - if (!d->has_pen) { - XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64); + if (d->has_brush) { // draw filled ellipse + XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64); + if (!d->has_pen) // make smoother outline XDrawArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64); - return; - } else{ - XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64); - } } if (d->has_pen) // draw outline XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64); diff --git a/tests/arthur/data/qps/primitives.qps b/tests/arthur/data/qps/primitives.qps index dcb6516..c4cc92c 100644 --- a/tests/arthur/data/qps/primitives.qps +++ b/tests/arthur/data/qps/primitives.qps @@ -177,3 +177,22 @@ repeat_block drawShapes setPen black 4 translate 75 0 repeat_block drawShapes + +resetMatrix +setRenderHint Antialiasing off +setPen nopen +translate 550 100 +setBrush #7f7f7fff +drawRect -0.5 -0.5 21 21 +setBrush red +drawEllipse 0 0 20 20 +setBrush nobrush +setPen black +drawEllipse 0 0 20 20 + +translate 25 0 +setPen nopen +setBrush #7f7f7fff +drawRect 0 0 20 20 +setBrush red +drawEllipse 0 0 20 20 -- cgit v0.12 From e48709416ad314f30d8ea35fc386cb177bb4b32d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 27 Mar 2009 14:58:14 +0100 Subject: Fix very slow stroking of paths in X11 paint engine. Use QStroker::setRect() to avoid dashing parts of the path that are outside the device rect. Task-number: 246573 Reviewed-by: Trond --- src/gui/painting/qpaintengine_x11.cpp | 4 ++++ src/gui/painting/qpainterpath.cpp | 21 +++++++-------------- src/gui/painting/qpainterpath.h | 2 ++ src/gui/painting/qpainterpath_p.h | 11 +++++++++++ 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 32cb63d..d931f55 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -62,6 +62,7 @@ #include #include #include +#include #include "qpen.h" #include "qcolor.h" @@ -1756,9 +1757,11 @@ void QX11PaintEngine::drawPath(const QPainterPath &path) QPainterPath stroke; qreal width = d->cpen.widthF(); QPolygonF poly; + QRectF deviceRect(0, 0, d->pdev->width(), d->pdev->height()); // necessary to get aliased alphablended primitives to be drawn correctly if (d->cpen.isCosmetic() || d->has_scaling_xform) { stroker.setWidth(width == 0 ? 1 : width * d->xform_scale); + stroker.d_ptr->stroker.setClipRect(deviceRect); stroke = stroker.createStroke(path * d->matrix); if (stroke.isEmpty()) return; @@ -1766,6 +1769,7 @@ void QX11PaintEngine::drawPath(const QPainterPath &path) d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, false); } else { stroker.setWidth(width); + stroker.d_ptr->stroker.setClipRect(d->matrix.inverted().mapRect(deviceRect)); stroke = stroker.createStroke(path); if (stroke.isEmpty()) return; diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index bb07f81..70036e1 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -2387,21 +2387,13 @@ void qt_path_stroke_cubic_to(qfixed c1x, qfixed c1y, \sa QPen, QBrush */ -class QPainterPathStrokerPrivate +QPainterPathStrokerPrivate::QPainterPathStrokerPrivate() + : dashOffset(0) { -public: - QPainterPathStrokerPrivate() - : dashOffset(0) - { - stroker.setMoveToHook(qt_path_stroke_move_to); - stroker.setLineToHook(qt_path_stroke_line_to); - stroker.setCubicToHook(qt_path_stroke_cubic_to); - } - - QStroker stroker; - QVector dashPattern; - qreal dashOffset; -}; + stroker.setMoveToHook(qt_path_stroke_move_to); + stroker.setLineToHook(qt_path_stroke_line_to); + stroker.setCubicToHook(qt_path_stroke_cubic_to); +} /*! Creates a new stroker. @@ -2445,6 +2437,7 @@ QPainterPath QPainterPathStroker::createStroke(const QPainterPath &path) const QDashStroker dashStroker(&d->stroker); dashStroker.setDashPattern(d->dashPattern); dashStroker.setDashOffset(d->dashOffset); + dashStroker.setClipRect(d->stroker.clipRect()); dashStroker.strokePath(path, &stroke, QTransform()); } stroke.setFillRule(Qt::WindingFill); diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h index 88fb19d..6cd2af8 100644 --- a/src/gui/painting/qpainterpath.h +++ b/src/gui/painting/qpainterpath.h @@ -277,6 +277,8 @@ public: QPainterPath createStroke(const QPainterPath &path) const; private: + friend class QX11PaintEngine; + QPainterPathStrokerPrivate *d_ptr; }; diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h index 93f9704..29c48df 100644 --- a/src/gui/painting/qpainterpath_p.h +++ b/src/gui/painting/qpainterpath_p.h @@ -61,9 +61,20 @@ #include #include +#include QT_BEGIN_NAMESPACE +class QPainterPathStrokerPrivate +{ +public: + QPainterPathStrokerPrivate(); + + QStroker stroker; + QVector dashPattern; + qreal dashOffset; +}; + class QPolygonF; class QVectorPathConverter; -- cgit v0.12 From 062c476d378022a49307aca136cb9aab381e0814 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 27 Mar 2009 15:20:14 +0100 Subject: Fix background of QAbstractScrollArea when styled only with pseudo-class This may happen if you only have something like QAbstractScrollArea:focus { background: foo; } and you do not have a background set for the general case and the viewport has a different background role (such as QTextEdit, QAbstractItemView, ....) This is a regression from 4.4 since in 4.4 the :focus has no effect if you didn't have a background for the general case. Reviewed-by: bnilsen Task-number: 188195 --- src/gui/styles/qstylesheetstyle.cpp | 14 ++++++++++++- .../auto/qstylesheetstyle/tst_qstylesheetstyle.cpp | 23 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index f22cd56..a39eeb7 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -2916,6 +2916,10 @@ void QStyleSheetStyle::polish(QWidget *w) if (ew->autoFillBackground()) { ew->setAutoFillBackground(false); autoFillDisabledWidgets->insert(w); + if (ew != w) { //eg. viewport of a scrollarea + //(in order to draw the background anyway in case we don't.) + ew->setAttribute(Qt::WA_StyledBackground, true); + } } if (!rule.hasBackground() || rule.background()->isTransparent() || rule.hasBox() || (!rule.hasNativeBorder() && !rule.border()->isOpaque())) @@ -4345,8 +4349,16 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op return; case PE_Widget: - if (!rule.hasBackground()) + if (!rule.hasBackground()) { + QWidget *container = containerWidget(w); + if (autoFillDisabledWidgets->contains(container) + && (container == w || !renderRule(container, opt).hasBackground())) { + //we do not have a background, but we disabled the autofillbackground anyway. so fill the background now. + // (this may happen if we have rules like :focus) + p->fillRect(opt->rect, opt->palette.brush(w->backgroundRole())); + } break; + } #ifndef QT_NO_SCROLLAREA if (const QAbstractScrollArea *sa = qobject_cast(w)) { diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index 7954d00..aa63753 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -94,6 +94,7 @@ private slots: void embeddedFonts(); void opaquePaintEvent_data(); void opaquePaintEvent(); + void task188195_baseBackground(); //at the end because it mess with the style. void widgetStyle(); @@ -1354,6 +1355,28 @@ void tst_QStyleSheetStyle::opaquePaintEvent() QCOMPARE(cl.autoFillBackground(), !styled ); } +void tst_QStyleSheetStyle::task188195_baseBackground() +{ + QTreeView tree; + tree.setStyleSheet( "QTreeView:disabled { background-color:#ab1251; }" ); + tree.show(); + QTest::qWait(20); + QImage image(tree.width(), tree.height(), QImage::Format_ARGB32); + + tree.render(&image); + QVERIFY(testForColors(image, tree.palette().base().color())); + QVERIFY(!testForColors(image, QColor(0xab, 0x12, 0x51))); + + tree.setEnabled(false); + tree.render(&image); + QVERIFY(testForColors(image, QColor(0xab, 0x12, 0x51))); + + tree.setEnabled(true); + tree.render(&image); + QVERIFY(testForColors(image, tree.palette().base().color())); + QVERIFY(!testForColors(image, QColor(0xab, 0x12, 0x51))); +} + QTEST_MAIN(tst_QStyleSheetStyle) -- cgit v0.12 From 43c5656d834739e86f2895cfbf3d539bb8c7c498 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 25 Mar 2009 23:09:15 -0700 Subject: Major surface related fix Make sure all QDirectFBPaintDevice surfaces always are created with a format that is either QScreen::pixelFormat() or QDirectFBScreen::alphaPixmapFormat(). Also, clean up surface creation by providing more high level functions. Fix a bug where we would assume that ARGB means Format_ARGB32_Premultiplied and not Format_ARGB32. Reviewed-by: Tom Cooksey --- .../gfxdrivers/directfb/qdirectfbpaintdevice.cpp | 10 +- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 30 +- .../gfxdrivers/directfb/qdirectfbpixmap.cpp | 171 +++--------- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 301 +++++++++++++++++---- src/plugins/gfxdrivers/directfb/qdirectfbscreen.h | 28 +- .../gfxdrivers/directfb/qdirectfbsurface.cpp | 4 +- 6 files changed, 327 insertions(+), 217 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index 8a30ad4..8dbad53 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -64,8 +64,6 @@ void QDirectFBPaintDevice::lockDirectFB() { void *mem; int w, h; - DFBSurfacePixelFormat format; - DFBResult result = dfbSurface->Lock(dfbSurface, DSLF_WRITE, &mem, &bpl); if (result != DFB_OK || !mem) { DirectFBError("QDirectFBPixmapData::buffer()", result); @@ -73,10 +71,8 @@ void QDirectFBPaintDevice::lockDirectFB() { } dfbSurface->GetSize(dfbSurface, &w, &h); - dfbSurface->GetPixelFormat(dfbSurface, &format); - lockedImage = new QImage(static_cast(mem), w, h, bpl, - QDirectFBScreen::getImageFormat(format)); + QDirectFBScreen::getImageFormat(dfbSurface)); } @@ -102,9 +98,7 @@ void* QDirectFBPaintDevice::memory() const QImage::Format QDirectFBPaintDevice::format() const { - DFBSurfacePixelFormat dfbFormat; - dfbSurface->GetPixelFormat(dfbSurface, &dfbFormat); - return QDirectFBScreen::getImageFormat(dfbFormat); + return QDirectFBScreen::getImageFormat(dfbSurface); } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 86357e6..84a92d8 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -112,7 +112,7 @@ CachedImage::CachedImage(const QImage &image) description = QDirectFBScreen::getSurfaceDescription(image); QDirectFBScreen* screen = QDirectFBScreen::instance(); - tmpSurface = screen->createDFBSurface(&description); + tmpSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); if (!tmpSurface) { qWarning("CachedImage CreateSurface failed!"); return; @@ -124,7 +124,7 @@ CachedImage::CachedImage(const QImage &image) description.flags = DFBSurfaceDescriptionFlags(description.flags & ~DSDESC_PREALLOCATED); - s = screen->createDFBSurface(&description); + s = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); if (!s) qWarning("QDirectFBPaintEngine failed caching image"); @@ -159,7 +159,7 @@ IDirectFBSurface* SurfaceCache::getSurface(const uint *buf, int size) DFBSurfaceDescription description; description = QDirectFBScreen::getSurfaceDescription(buf, size); - surface = QDirectFBScreen::instance()->createDFBSurface(&description); + surface = QDirectFBScreen::instance()->createDFBSurface(&description, QDirectFBScreen::TrackSurface); if (!surface) qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface"); @@ -724,13 +724,10 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, const QRectF &src) { QImage image = srcImage; - if (QDirectFBScreen::getSurfacePixelFormat(image) == DSPF_UNKNOWN) { - QImage::Format format; - if (image.hasAlphaChannel()) - format = QImage::Format_ARGB32_Premultiplied; - else - format = QImage::Format_RGB32; - image = image.convertToFormat(format); + if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) { + image = image.convertToFormat(image.hasAlphaChannel() + ? QDirectFBScreen::instance()->alphaPixmapFormat() + : QDirectFBScreen::instance()->pixelFormat()); } CachedImage *img = imageCache[image.cacheKey()]; @@ -756,7 +753,8 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, DFBSurfaceDescription description; description = QDirectFBScreen::getSurfaceDescription(image); - imgSurface = QDirectFBScreen::instance()->createDFBSurface(&description); + imgSurface = QDirectFBScreen::instance()->createDFBSurface(&description, + QDirectFBScreen::DontTrackSurface); if (!imgSurface) { qWarning("QDirectFBPaintEnginePrivate::drawImage"); return; @@ -790,8 +788,10 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, } if (changeFlags) surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); - if (doRelease) - QDirectFBScreen::instance()->releaseDFBSurface(imgSurface); + if (doRelease) { + surface->ReleaseSource(surface); + imgSurface->Release(imgSurface); + } } void QDirectFBPaintEnginePrivate::updateClip() @@ -1092,11 +1092,11 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp); } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) { - QImage* img = static_cast(pixmap.pixmapData())->buffer(); + const QImage *img = static_cast(pixmap.pixmapData())->buffer(); + d->lock(); QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType); data->fromImage(*img, Qt::AutoColor); const QPixmap pix(data); - d->lock(); QRasterPaintEngine::drawTiledPixmap(r, pix, sp); } else { diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 6352652..6d942a4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -72,14 +72,19 @@ void QDirectFBPixmapData::resize(int width, int height) } DFBSurfaceDescription description; - description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | - DSDESC_HEIGHT); + description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH + | DSDESC_HEIGHT + | DSDESC_PIXELFORMAT); + QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, screen->pixelFormat()); description.width = width; description.height = height; - dfbSurface = screen->createDFBSurface(&description); - if (!dfbSurface) - qCritical("QDirectFBPixmapData::resize(): Unable to allocate surface"); + dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); + if (!dfbSurface) { + setSerialNumber(0); + qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface"); + return; + } setSerialNumber(++global_ser_no); } @@ -87,61 +92,15 @@ void QDirectFBPixmapData::resize(int width, int height) void QDirectFBPixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags) { - QImage image; - if (QDirectFBScreen::getSurfacePixelFormat(img) == DSPF_UNKNOWN) - image = img.convertToFormat(QImage::Format_ARGB32_Premultiplied); - else - image = img; - - DFBSurfaceDescription description; - description = QDirectFBScreen::getSurfaceDescription(image); - -#ifndef QT_NO_DIRECTFB_PREALLOCATED - IDirectFBSurface *imgSurface; - imgSurface = screen->createDFBSurface(&description); - if (!imgSurface) { - qWarning("QDirectFBPixmapData::fromImage()"); - setSerialNumber(0); - return; - } -#ifndef QT_NO_DIRECTFB_PALETTE - QDirectFBScreen::setSurfaceColorTable(imgSurface, image); -#endif -#endif // QT_NO_DIRECTFB_PREALLOCATED - - description.flags = DFBSurfaceDescriptionFlags(description.flags - & ~DSDESC_PREALLOCATED); - dfbSurface = screen->createDFBSurface(&description); + dfbSurface = screen->copyToDFBSurface(img, + img.hasAlphaChannel() ? screen->alphaPixmapFormat() + : screen->pixelFormat(), + QDirectFBScreen::TrackSurface); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fromImage()"); setSerialNumber(0); return; } - -#ifndef QT_NO_DIRECTFB_PALETTE - QDirectFBScreen::setSurfaceColorTable(dfbSurface, image); -#endif - -#ifdef QT_NO_DIRECTFB_PREALLOCATED - char *mem; - surface->Lock(surface, DSLF_WRITE, (void**)&mem, &bpl); - const int w = image.width() * image.depth() / 8; - for (int i = 0; i < image.height(); ++i) { - memcpy(mem, image.scanLine(i), w); - mem += bpl; - } - surface->Unlock(surface); -#else - DFBResult result; - dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); - result = dfbSurface->Blit(dfbSurface, imgSurface, 0, 0, 0); - if (result != DFB_OK) - DirectFBError("QDirectFBPixmapData::fromImage()", result); - dfbSurface->Flip(dfbSurface, 0, DSFLIP_NONE); - dfbSurface->ReleaseSource(dfbSurface); - screen->releaseDFBSurface(imgSurface); -#endif // QT_NO_DIRECTFB_PREALLOCATED - setSerialNumber(++global_ser_no); } @@ -161,30 +120,24 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) description.width = rect.width(); description.height = rect.height(); src->GetPixelFormat(src, &description.pixelformat); + src->GetCapabilities(src, &description.caps); - dfbSurface = screen->createDFBSurface(&description); + dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); if (!dfbSurface) { qWarning("QDirectFBPixmapData::copy()"); setSerialNumber(0); return; } - DFBResult result; -#ifndef QT_NO_DIRECTFB_PALETTE - IDirectFBPalette *palette; - result = src->GetPalette(src, &palette); - if (result == DFB_OK) { - dfbSurface->SetPalette(dfbSurface, palette); - palette->Release(palette); - } -#endif - dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); const DFBRectangle blitRect = { rect.x(), rect.y(), rect.width(), rect.height() }; - result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0); - if (result != DFB_OK) + DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0); + if (result != DFB_OK) { DirectFBError("QDirectFBPixmapData::copy()", result); + setSerialNumber(0); + return; + } setSerialNumber(++global_ser_no); } @@ -198,37 +151,16 @@ void QDirectFBPixmapData::fill(const QColor &color) Q_ASSERT(dfbSurface); if (color.alpha() < 255 && !hasAlphaChannel()) { - // convert to surface supporting alpha channel - DFBSurfacePixelFormat format; - dfbSurface->GetPixelFormat(dfbSurface, &format); - switch (format) { - case DSPF_YUY2: - case DSPF_UYVY: - format = DSPF_AYUV; - break; -#if (Q_DIRECTFB_VERSION >= 0x010100) - case DSPF_RGB444: - format = DSPF_ARGB4444; - break; - case DSPF_RGB555: -#endif - case DSPF_RGB18: - format = DSPF_ARGB6666; - break; - default: - format = DSPF_ARGB; - break; - } - DFBSurfaceDescription description; description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT); dfbSurface->GetSize(dfbSurface, &description.width, &description.height); - description.pixelformat = format; + QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, screen->alphaPixmapFormat()); screen->releaseDFBSurface(dfbSurface); // release old surface - dfbSurface = screen->createDFBSurface(&description); + dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); + setSerialNumber(++global_ser_no); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fill()"); setSerialNumber(0); @@ -245,6 +177,10 @@ bool QDirectFBPixmapData::hasAlphaChannel() const if (!serialNumber()) return false; + // We don't need to ask DFB for this really. Can just keep track + // of what image format this has. It should always have either + // QDirectFBScreen::alphaPixmapFormat() or QScreen::pixelFormat() + DFBSurfacePixelFormat format; dfbSurface->GetPixelFormat(dfbSurface, &format); switch (format) { @@ -274,14 +210,12 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, { QDirectFBPixmapData *that = const_cast(this); const QImage *image = that->buffer(); - if (image) { // avoid deep copy - const QImage transformed = image->transformed(transform, mode); - that->unlockDirectFB(); - QDirectFBPixmapData *data = new QDirectFBPixmapData(pixelType()); - data->fromImage(transformed, Qt::AutoColor); - return QPixmap(data); - } - return QPixmapData::transformed(transform, mode); + Q_ASSERT(image); + const QImage transformed = image->transformed(transform, mode); + that->unlockDirectFB(); + QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType); + data->fromImage(transformed, Qt::AutoColor); + return QPixmap(data); } int w, h; @@ -291,15 +225,14 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, if (size.isEmpty()) return QPixmap(); - QDirectFBPixmapData *data = new QDirectFBPixmapData(pixelType()); + QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType); data->resize(size.width(), size.height()); IDirectFBSurface *dest = data->dfbSurface; dest->SetBlittingFlags(dest, DSBLIT_NOFX); - const DFBRectangle srcRect = { 0, 0, w, h }; const DFBRectangle destRect = { 0, 0, size.width(), size.height() }; - dest->StretchBlit(dest, dfbSurface, &srcRect, &destRect); + dest->StretchBlit(dest, dfbSurface, 0, &destRect); return QPixmap(data); } @@ -309,39 +242,9 @@ QImage QDirectFBPixmapData::toImage() const if (!dfbSurface) return QImage(); -#ifdef QT_NO_DIRECTFB_PREALLOCATED QDirectFBPixmapData *that = const_cast(this); const QImage *img = that->buffer(); - const QImage copied = img->copy(); - that->unlockDirectFB(); - return copied; -#else - - int w, h; - dfbSurface->GetSize(dfbSurface, &w, &h); - - // Always convert to ARGB32: - QImage image(w, h, QImage::Format_ARGB32); - - DFBSurfaceDescription description; - description = QDirectFBScreen::getSurfaceDescription(image); - - IDirectFBSurface *imgSurface = screen->createDFBSurface(&description); - if (!imgSurface) { - qWarning("QDirectFBPixmapData::toImage()"); - return QImage(); - } - - imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX); - DFBResult result = imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0); - if (result != DFB_OK) { - DirectFBError("QDirectFBPixmapData::toImage() blit failed", result); - return QImage(); - } - screen->releaseDFBSurface(imgSurface); - - return image; -#endif // QT_NO_DIRECTFB_PREALLOCATED + return img->copy(); } QPaintEngine* QDirectFBPixmapData::paintEngine() const diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 26c023f..db9672a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -81,6 +81,7 @@ public: QDirectFBKeyboardHandler *keyboard; #endif bool videoonly; + QImage::Format alphaPixmapFormat; }; QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen* screen) @@ -96,6 +97,7 @@ QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen* screen) , keyboard(0) #endif , videoonly(false) + , alphaPixmapFormat(QImage::Format_Invalid) { #ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addObject(this); @@ -130,7 +132,80 @@ QDirectFBScreenPrivate::~QDirectFBScreenPrivate() dfb->Release(dfb); } -IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription* desc, bool track) + + +// creates a preallocated surface with the same format as the image if +// possible. + +IDirectFBSurface* QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCreationOptions options) +{ + if (img.isNull()) // assert? + return 0; + if (QDirectFBScreen::getSurfacePixelFormat(img.format()) == DSPF_UNKNOWN) { + QImage image = img.convertToFormat(img.hasAlphaChannel() + ? d_ptr->alphaPixmapFormat + : pixelFormat()); + IDirectFBSurface *tmp = createDFBSurface(image, false); + if (!tmp) { + qWarning("Couldn't create surface createDFBSurface(QImage, bool)"); + return 0; + } + IDirectFBSurface *surface = copyDFBSurface(tmp, image.format(), options); + tmp->Release(tmp); + return surface; + } + + DFBSurfaceDescription desc = QDirectFBScreen::getSurfaceDescription(img); + IDirectFBSurface *surface = createDFBSurface(&desc, options); +#ifdef QT_NO_DIRECTFB_PREALLOCATED + if (surface) { + char *mem; + int bpl; + surface->Lock(dfbSurface, DSLF_WRITE, (void**)&mem, &bpl); + const int h = img.height(); + for (int i = 0; i < h; ++i) { + memcpy(mem, img.scanLine(i), bpl); + mem += bpl; + } + surface->Unlock(ret); + } +#endif +#ifndef QT_NO_DIRECTFB_PALETTE + if (img.numColors() != 0) + QDirectFBScreen::setSurfaceColorTable(surface, img); +#endif + return surface; +} + +IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src, + QImage::Format format, + SurfaceCreationOptions options) +{ + Q_ASSERT(src); + QSize size; + src->GetSize(src, &size.rwidth(), &size.rheight()); + IDirectFBSurface *surface = createDFBSurface(size, format, options); + surface->SetBlittingFlags(surface, DSBLIT_NOFX); + surface->Blit(surface, src, 0, 0, 0); + surface->ReleaseSource(surface); // ??? Is this always right? + return surface; +} + +IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size, + QImage::Format format, + SurfaceCreationOptions options) +{ + DFBSurfaceDescription desc; + desc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH|DSDESC_HEIGHT); + if (!QDirectFBScreen::initSurfaceDescriptionPixelFormat(&desc, format)) + return 0; + desc.width = size.width(); + desc.height = size.height(); + return createDFBSurface(&desc, options); +} + + +IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription *desc, SurfaceCreationOptions options) { DFBResult result; IDirectFBSurface* newSurface = 0; @@ -152,13 +227,18 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription* result = d_ptr->dfb->CreateSurface(d_ptr->dfb, desc, &newSurface); if (result != DFB_OK) { - DirectFBError("QDirectFBScreen::createDFBSurface", result); + qWarning("QDirectFBScreen::createDFBSurface() Failed!\n" + " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s", + desc->flags, desc->caps, desc->width, desc->height, + desc->pixelformat, DFB_PIXELFORMAT_INDEX(desc->pixelformat), + desc->preallocated[0].data, desc->preallocated[0].pitch, + DirectFBErrorString(result)); return 0; } Q_ASSERT(newSurface); - if (track) { + if (options & TrackSurface) { d_ptr->allocatedSurfaces.insert(newSurface); //qDebug("Created a new DirectFB surface at %p. New count = %d", @@ -168,8 +248,63 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription* return newSurface; } -void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface* surface) +IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img, + QImage::Format format, + SurfaceCreationOptions options) { + QImage image = img; + const QImage::Format pixmapFormat = image.hasAlphaChannel() + ? QDirectFBScreen::alphaPixmapFormat() + : QDirectFBScreen::pixelFormat(); + + if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN +#ifdef QT_NO_DIRECTFB_PREALLOCATED + || image.format() != pixmapFormat +#endif + ) { + image = image.convertToFormat(pixmapFormat); + } + + + IDirectFBSurface *dfbSurface = createDFBSurface(img.size(), format, options); + if (!dfbSurface) { + qWarning("QDirectFBPixmapData::fromImage() Couldn't create surface"); + return 0; + } + +#ifndef QT_NO_DIRECTFB_PREALLOCATED + IDirectFBSurface *imgSurface = createDFBSurface(img, DontTrackSurface); + if (!imgSurface) { + qWarning("QDirectFBPixmapData::fromImage()"); + QDirectFBScreen::releaseDFBSurface(dfbSurface); + return 0; + } + Q_ASSERT(imgSurface); + DFBResult result; + dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); + result = dfbSurface->Blit(dfbSurface, imgSurface, 0, 0, 0); + if (result != DFB_OK) + DirectFBError("QDirectFBPixmapData::fromImage()", result); + dfbSurface->ReleaseSource(dfbSurface); + imgSurface->Release(imgSurface); +#else // QT_NO_DIRECTFB_PREALLOCATED + Q_ASSERT(image.format() == pixmapFormat); + char *mem; + int bpl; + dfbSurface->Lock(dfbSurface, DSLF_WRITE, (void**)&mem, &bpl); + const int w = image.width() * image.depth() / 8; + for (int i = 0; i < image.height(); ++i) { + memcpy(mem, image.scanLine(i), w); + mem += bpl; + } + dfbSurface->Unlock(dfbSurface); +#endif + return dfbSurface; +} + +void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface *surface) +{ + Q_ASSERT(QDirectFBScreen::instance()); Q_ASSERT(surface); surface->Release(surface); if (!d_ptr->allocatedSurfaces.remove(surface)) @@ -200,9 +335,9 @@ IDirectFBDisplayLayer* QDirectFBScreen::dfbDisplayLayer() } #endif -DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(const QImage &image) +DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(QImage::Format format) { - switch (image.format()) { + switch (format) { #ifndef QT_NO_DIRECTFB_PALETTE case QImage::Format_Indexed8: return DSPF_LUT8; @@ -233,8 +368,21 @@ DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(const QImage &image }; } -QImage::Format QDirectFBScreen::getImageFormat(DFBSurfacePixelFormat format) +static inline bool isPremultiplied(IDirectFBSurface *surface) +{ + Q_ASSERT(surface); + DFBSurfaceCapabilities caps; + const DFBResult result = surface->GetCapabilities(surface, &caps); + Q_ASSERT(result == DFB_OK); + Q_UNUSED(result); + return caps & DSCAPS_PREMULTIPLIED; +} + +QImage::Format QDirectFBScreen::getImageFormat(IDirectFBSurface *surface) { + DFBSurfacePixelFormat format; + surface->GetPixelFormat(surface, &format); + switch (format) { case DSPF_LUT8: return QImage::Format_Indexed8; @@ -257,8 +405,14 @@ QImage::Format QDirectFBScreen::getImageFormat(DFBSurfacePixelFormat format) return QImage::Format_RGB666; case DSPF_RGB32: return QImage::Format_RGB32; - case DSPF_ARGB: - return QImage::Format_ARGB32_Premultiplied; + case DSPF_ARGB: { + DFBSurfaceCapabilities caps; + const DFBResult result = surface->GetCapabilities(surface, &caps); + Q_ASSERT(result == DFB_OK); + Q_UNUSED(result); + return (caps & DSCAPS_PREMULTIPLIED + ? QImage::Format_ARGB32_Premultiplied + : QImage::Format_ARGB32); } default: break; } @@ -268,38 +422,32 @@ QImage::Format QDirectFBScreen::getImageFormat(DFBSurfacePixelFormat format) DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const QImage &image) { DFBSurfaceDescription description; - DFBSurfacePixelFormat format = getSurfacePixelFormat(image); + + const DFBSurfacePixelFormat format = getSurfacePixelFormat(image.format()); if (format == DSPF_UNKNOWN || image.isNull()) { description.flags = DFBSurfaceDescriptionFlags(0); return description; } - description.flags = DFBSurfaceDescriptionFlags(DSDESC_CAPS - | DSDESC_WIDTH + description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT - | DSDESC_PIXELFORMAT - | DSDESC_PREALLOCATED); - - description.caps = DSCAPS_NONE; +#ifndef QT_NO_DIRECTFB_PREALLOCATED + | DSDESC_PREALLOCATED +#endif + | DSDESC_PIXELFORMAT); + QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, image.format()); description.width = image.width(); description.height = image.height(); - description.pixelformat = format; +#ifndef QT_NO_DIRECTFB_PREALLOCATED description.preallocated[0].data = (void*)(image.bits()); description.preallocated[0].pitch = image.bytesPerLine(); description.preallocated[1].data = 0; description.preallocated[1].pitch = 0; +#endif - switch (image.format()) { - case QImage::Format_ARGB32_Premultiplied: - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_ARGB6666_Premultiplied: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_ARGB4444_Premultiplied: + if (QDirectFBScreen::isPremultiplied(image.format())) description.caps = DSCAPS_PREMULTIPLIED; - default: - break; - } return description; } @@ -337,7 +485,7 @@ void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface, if (numColors == 0) return; - QVarLengthArray colors(numColors); + QVarLengthArray colors(numColors); for (int i = 0; i < numColors; ++i) { QRgb c = image.color(i); colors[i].a = qAlpha(c); @@ -461,18 +609,10 @@ void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty) } else if (!image.isNull() && implicitHide) { show(); } + cursor = image.convertToFormat(QDirectFBScreen::instance()->alphaPixmapFormat()); if (!image.isNull()) { -#ifdef QT_NO_DIRECTFB_PALETTE - if (image.numColors() > 0) - cursor = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); - else -#endif - if (image.format() == QImage::Format_Indexed8) { - cursor = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); - } else { - cursor = image; - } + Q_ASSERT(cursor.numColors() == 0); size = cursor.size(); hotspot = QPoint(hotx, hoty); @@ -480,15 +620,12 @@ void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty) description = QDirectFBScreen::getSurfaceDescription(cursor); IDirectFBSurface *surface; - surface = QDirectFBScreen::instance()->createDFBSurface(&description); + surface = QDirectFBScreen::instance()->createDFBSurface(&description, + QDirectFBScreen::TrackSurface); if (!surface) { qWarning("QDirectFBScreenCursor::set: Unable to create surface"); return; } -#ifndef QT_NO_DIRECTFB_PALETTE - QDirectFBScreen::setSurfaceColorTable(surface, cursor); -#endif - DFBResult result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE); if (result != DFB_OK) { DirectFBError("QDirectFBScreenCursor::set: " @@ -636,7 +773,7 @@ bool QDirectFBScreen::connect(const QString &displaySpec) } const QStringList displayArgs = displaySpec.split(QLatin1Char(':'), - QString::SkipEmptyParts); + QString::SkipEmptyParts); d_ptr->setFlipFlags(displayArgs); @@ -663,6 +800,12 @@ bool QDirectFBScreen::connect(const QString &displaySpec) description.caps = DFBSurfaceCapabilities(DSCAPS_PRIMARY | DSCAPS_DOUBLE | DSCAPS_STATIC_ALLOC); + if (displayArgs.contains(QLatin1String("forcepremultiplied"), + Qt::CaseInsensitive)) { + description.caps = DFBSurfaceCapabilities(description.caps + | DSCAPS_PREMULTIPLIED); + } + if (!(d_ptr->flipFlags & DSFLIP_BLIT)) { description.caps = DFBSurfaceCapabilities(description.caps | DSCAPS_DOUBLE @@ -671,12 +814,43 @@ bool QDirectFBScreen::connect(const QString &displaySpec) // We don't track the primary surface as it's released in disconnect - d_ptr->dfbSurface = createDFBSurface(&description, false); + d_ptr->dfbSurface = createDFBSurface(&description, DontTrackSurface); if (!d_ptr->dfbSurface) { DirectFBError("QDirectFBScreen: error creating primary surface", result); return false; } + + // Work out what format we're going to use for surfaces with an alpha channel + d_ptr->alphaPixmapFormat = QDirectFBScreen::getImageFormat(d_ptr->dfbSurface); + setPixelFormat(d_ptr->alphaPixmapFormat); + switch (d_ptr->alphaPixmapFormat) { + case QImage::Format_RGB666: + d_ptr->alphaPixmapFormat = QImage::Format_ARGB6666_Premultiplied; + break; + case QImage::Format_RGB444: + d_ptr->alphaPixmapFormat = QImage::Format_ARGB4444_Premultiplied; + break; + case QImage::NImageFormats: + case QImage::Format_Invalid: + case QImage::Format_Mono: + case QImage::Format_MonoLSB: + case QImage::Format_Indexed8: + case QImage::Format_RGB32: + case QImage::Format_RGB888: + case QImage::Format_RGB16: + case QImage::Format_RGB555: + d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied; + break; + case QImage::Format_ARGB32: + case QImage::Format_ARGB32_Premultiplied: + case QImage::Format_ARGB4444_Premultiplied: + case QImage::Format_ARGB8555_Premultiplied: + case QImage::Format_ARGB8565_Premultiplied: + case QImage::Format_ARGB6666_Premultiplied: + // works already + break; + } d_ptr->dfbSurface->GetSize(d_ptr->dfbSurface, &w, &h); data = 0; @@ -692,7 +866,7 @@ bool QDirectFBScreen::connect(const QString &displaySpec) else DirectFBError("QDirectFBScreen: error getting surface format", result); - setPixelFormat(getImageFormat(format)); + setPixelFormat(getImageFormat(d_ptr->dfbSurface)); physWidth = physHeight = -1; QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)")); @@ -954,21 +1128,14 @@ void QDirectFBScreen::exposeRegion(QRegion r, int changing) void QDirectFBScreen::blit(const QImage &img, const QPoint &topLeft, const QRegion ®) { - IDirectFBSurface *src = 0; - DFBSurfaceDescription description = getSurfaceDescription(img); - - src = createDFBSurface(&description); + IDirectFBSurface *src = createDFBSurface(img, QDirectFBScreen::DontTrackSurface); if (!src) { qWarning("QDirectFBScreen::blit(): Error creating surface"); return; } -#ifndef QT_NO_DIRECTFB_PALETTE - setSurfaceColorTable(d_ptr->dfbSurface, img); -#endif - blit(src, topLeft, reg); - - releaseDFBSurface(src); + d_ptr->dfbSurface->ReleaseSource(d_ptr->dfbSurface); + src->Release(src); } void QDirectFBScreen::blit(IDirectFBSurface *src, const QPoint &topLeft, @@ -1021,3 +1188,27 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion) dfbRects.size()); } +QImage::Format QDirectFBScreen::alphaPixmapFormat() const +{ + return d_ptr->alphaPixmapFormat; +} + + +bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, + QImage::Format format) +{ + const DFBSurfacePixelFormat pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); + if (pixelformat == DSPF_UNKNOWN) + return false; + description->flags = DFBSurfaceDescriptionFlags(description->flags | DSDESC_PIXELFORMAT); + description->pixelformat = pixelformat; + if (QDirectFBScreen::isPremultiplied(format)) { + if (!(description->flags & DSDESC_CAPS)) { + description->caps = DSCAPS_PREMULTIPLIED; + description->flags = DFBSurfaceDescriptionFlags(description->flags | DSDESC_CAPS); + } else { + description->caps = DFBSurfaceCapabilities(description->caps | DSCAPS_PREMULTIPLIED); + } + } + return true; +} diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 35dea0d..a1e93c6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -88,18 +88,38 @@ public: #endif // Track surface creation/release so we can release all on exit - IDirectFBSurface* createDFBSurface(const DFBSurfaceDescription* desc, bool track = true); + enum SurfaceCreationOption { + DontTrackSurface = 0, + TrackSurface = 1 + }; + Q_DECLARE_FLAGS(SurfaceCreationOptions, SurfaceCreationOption); + IDirectFBSurface *createDFBSurface(const DFBSurfaceDescription *desc, + SurfaceCreationOptions options); + IDirectFBSurface *createDFBSurface(const QImage &image, + SurfaceCreationOptions options); + IDirectFBSurface *createDFBSurface(const QSize &size, + QImage::Format format, + SurfaceCreationOptions options); + IDirectFBSurface *copyDFBSurface(IDirectFBSurface *src, + QImage::Format format, + SurfaceCreationOptions options); + IDirectFBSurface *copyToDFBSurface(const QImage &image, + QImage::Format format, + SurfaceCreationOptions options); void releaseDFBSurface(IDirectFBSurface* surface); + bool preferVideoOnly() const; static int depth(DFBSurfacePixelFormat format); - static DFBSurfacePixelFormat getSurfacePixelFormat(const QImage &image); + static DFBSurfacePixelFormat getSurfacePixelFormat(QImage::Format format); static DFBSurfaceDescription getSurfaceDescription(const QImage &image); static DFBSurfaceDescription getSurfaceDescription(const uint *buffer, int length); - static QImage::Format getImageFormat(DFBSurfacePixelFormat format); + static QImage::Format getImageFormat(IDirectFBSurface *surface); + static bool initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, QImage::Format format); static inline bool isPremultiplied(QImage::Format format); + QImage::Format alphaPixmapFormat() const; #ifndef QT_NO_DIRECTFB_PALETTE static void setSurfaceColorTable(IDirectFBSurface *surface, @@ -114,6 +134,8 @@ private: QDirectFBScreenPrivate *d_ptr; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QDirectFBScreen::SurfaceCreationOptions); + inline bool QDirectFBScreen::isPremultiplied(QImage::Format format) { switch (format) { diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index ce026ea..00d1781 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -153,8 +153,8 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) DSDESC_PIXELFORMAT); description.width = rect.width(); description.height = rect.height(); - description.pixelformat = DSPF_ARGB; - + QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, + QDirectFBSurface::instance()->pixelFormat()); dfbSurface = QDirectFBScreen::instance()->createDFBSurface(&description, false); } else { Q_ASSERT(dfbSurface); -- cgit v0.12 From a3bb85673a4bf9aa7c629ab74b483a2faaa30369 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 27 Mar 2009 15:19:36 +0100 Subject: Make QMutexPool actually be thread-safe (double-checked locking doesn't work) This code was apparently mostly unchanged since 2005. Update it to match the atomics code. Reviewed-by: Bradley T. Hughes --- src/corelib/thread/qmutexpool.cpp | 15 ++++----------- src/corelib/thread/qmutexpool_p.h | 4 ++-- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp index 71ecab5..96a9940 100644 --- a/src/corelib/thread/qmutexpool.cpp +++ b/src/corelib/thread/qmutexpool.cpp @@ -96,9 +96,8 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (true)) QMutexPool is destructed. */ QMutexPool::QMutexPool(bool recursive, int size) - : count(size), recurs(recursive) + : mutexes(size), count(size), recurs(recursive) { - mutexes = new QMutex*[count]; for (int index = 0; index < count; ++index) { mutexes[index] = 0; } @@ -110,13 +109,10 @@ QMutexPool::QMutexPool(bool recursive, int size) */ QMutexPool::~QMutexPool() { - QMutexLocker locker(&mutex); for (int index = 0; index < count; ++index) { delete mutexes[index]; mutexes[index] = 0; } - delete [] mutexes; - mutexes = 0; } /*! @@ -138,12 +134,9 @@ QMutex *QMutexPool::get(const void *address) if (!mutexes[index]) { // mutex not created, create one - - QMutexLocker locker(&mutex); - // we need to check once again that the mutex hasn't been created, since - // 2 threads could be trying to create a mutex at the same index... - if (!mutexes[index]) - mutexes[index] = new QMutex(recurs ? QMutex::Recursive : QMutex::NonRecursive); + QMutex *newMutex = new QMutex(recurs ? QMutex::Recursive : QMutex::NonRecursive); + if (!mutexes[index].testAndSetOrdered(0, newMutex)) + delete newMutex; } return mutexes[index]; diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h index 65a3b54..4b91e5b 100644 --- a/src/corelib/thread/qmutexpool_p.h +++ b/src/corelib/thread/qmutexpool_p.h @@ -54,6 +54,7 @@ // #include "QtCore/qmutex.h" +#include "QtCore/qvarlengtharray.h" #ifndef QT_NO_THREAD @@ -70,8 +71,7 @@ public: static QMutex *globalInstanceGet(const void *address); private: - QMutex mutex; - QMutex **mutexes; + QVarLengthArray, 128> mutexes; int count; bool recurs; }; -- cgit v0.12 From c9db617cc2962ffbf76e6e6eb60a0c8a14843e52 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 27 Mar 2009 15:24:24 +0100 Subject: Small fix: initialise the global static isDebugging variable within the acquire guard of the local static. This only buys us one warning less by helgrind. Reviewed-by: Trust Me --- src/dbus/qdbusintegrator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 91b9cb1..7ed0cd5 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -921,10 +921,9 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) rootNode(QString(QLatin1Char('/'))) { static const bool threads = qDBusInitThreads(); - static const int debugging = qgetenv("QDBUS_DEBUG").toInt(); + static const int debugging = ::isDebugging = qgetenv("QDBUS_DEBUG").toInt(); Q_UNUSED(threads) - ::isDebugging = debugging; #ifdef QDBUS_THREAD_DEBUG if (debugging > 1) qdbusThreadDebug = qdbusDefaultThreadDebug; -- cgit v0.12 From 136f9766f6629a3e82609cf51346e4811bcc47ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 27 Mar 2009 16:53:22 +0100 Subject: Crash in OpenGL paint engine when brush style is Qt::NoBrush. Check for Qt::NoBrush and return early in the composite() function. Task-number: 249628 Reviewed-by: Trond --- src/opengl/qpaintengine_opengl.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index f332a50..976a021 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -5328,6 +5328,9 @@ void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const q_vertexType * Q_Q(QOpenGLPaintEngine); QGL_FUNC_CONTEXT; + if (current_style == Qt::NoBrush) + return; + DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Using compositing program: fragment_brush =" << fragment_brush << ", fragment_composition_mode =" << fragment_composition_mode; -- cgit v0.12 From 00644eefacdd5bbf61efc4a1d2d3b29c686b11e7 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 27 Mar 2009 16:22:29 +0100 Subject: QDesktopWidget::resized wasn't emitted properly on X11. When the size of one of the screen changes but the geometry of the whole desktop hasn't been changed the resized() signal wasn't emitted. The patch by Lubos Lunak also adds emitting of a signal whenever the screen is turned on or off. Task-number: 226048 Reviewed-by: Brad --- src/gui/kernel/qapplication_x11.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 1df442f..6babda9 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -3351,15 +3351,24 @@ int QApplication::x11ProcessEvent(XEvent* event) // update the size for desktop widget int scr = X11->ptrXRRRootToScreen(X11->display, event->xany.window); - QWidget *w = desktop()->screen(scr); + QDesktopWidget *desktop = QApplication::desktop(); + QWidget *w = desktop->screen(scr); QSize oldSize(w->size()); w->data->crect.setWidth(DisplayWidth(X11->display, scr)); w->data->crect.setHeight(DisplayHeight(X11->display, scr)); - if (w->size() != oldSize) { - QResizeEvent e(w->size(), oldSize); - QApplication::sendEvent(w, &e); - emit desktop()->resized(scr); - } + QVarLengthArray oldSizes(desktop->numScreens()); + for (int i = 0; i < desktop->numScreens(); ++i) + oldSizes[i] = desktop->screenGeometry(i); + QResizeEvent e(w->size(), oldSize); + QApplication::sendEvent(w, &e); + for (int i = 0; i < qMin(oldSizes.count(), desktop->numScreens()); ++i) { + if (oldSizes[i] != desktop->screenGeometry(i)) + emit desktop->resized(i); + } + for (int i = oldSizes.count(); i < desktop->numScreens(); ++i) + emit desktop->resized(i); // added + for (int i = desktop->numScreens(); i < oldSizes.count(); ++i) + emit desktop->resized(i); // removed } #endif // QT_NO_XRANDR -- cgit v0.12 From 459debfb42e22e88e061888a8a9202f746006dfb Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 27 Mar 2009 17:00:17 +0100 Subject: Documented the -xinput configure option in the doc. Reviewed-by: TrustMe --- doc/src/installation.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/installation.qdoc b/doc/src/installation.qdoc index 6d02801..925a195 100644 --- a/doc/src/installation.qdoc +++ b/doc/src/installation.qdoc @@ -614,7 +614,7 @@ in the \l{Qt for Windows CE Requirements} document. -xinerama or auto-detected1.1.0 Xi libXi X11 Input Extensions - auto-detected1.3.0 + -xinput or auto-detected1.3.0 Xt libXt Xt Intrinsics0.99 -- cgit v0.12 From 749745e0a1b099cf08b085da0ec063485724df11 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 27 Mar 2009 18:31:07 +0100 Subject: Fix Qt3Support compile Reviewed-by: thiago --- src/corelib/thread/qmutexpool_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h index 4b91e5b..1009ebb 100644 --- a/src/corelib/thread/qmutexpool_p.h +++ b/src/corelib/thread/qmutexpool_p.h @@ -53,6 +53,7 @@ // We mean it. // +#include "QtCore/qatomic.h" #include "QtCore/qmutex.h" #include "QtCore/qvarlengtharray.h" -- cgit v0.12 From 0ebf7aad380ad09475f3d19264f031d0f2ec2d55 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 27 Mar 2009 18:50:33 +0100 Subject: Revert "make shadow builds work even if a non-shadow build is present" This reverts commit 3aff9113a9702ea6f7e099a73136a718ae1b992f. --- mkspecs/features/moc.prf | 2 +- mkspecs/features/uic.prf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 5e09455..faa9871 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -61,7 +61,7 @@ QMAKE_EXTRA_COMPILERS += moc_source INCREDIBUILD_XGE += moc_source #make sure we can include these files -INCLUDEPATH += $$OUT_PWD/$$MOC_DIR +INCLUDEPATH += $$MOC_DIR #auto depend on moc unix:!no_mocdepend { diff --git a/mkspecs/features/uic.prf b/mkspecs/features/uic.prf index 8077954..885fad7 100644 --- a/mkspecs/features/uic.prf +++ b/mkspecs/features/uic.prf @@ -34,7 +34,7 @@ isEmpty(QMAKE_MOD_UIC):QMAKE_MOD_UIC = ui_ INCREDIBUILD_XGE += uic } -INCLUDEPATH += $$OUT_PWD/$$UI_HEADERS_DIR +INCLUDEPATH += $$UI_HEADERS_DIR uic3 { isEmpty(FORMS3) { -- cgit v0.12 From ec24cf81e231974fde2bb4903a00e63abce6465b Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 27 Mar 2009 18:51:20 +0100 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to origin/qtwebkit-4.5 ( 1beae2b64b5b1e9b97e82dc94de18ebac1c19efc ) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes in WebKit since the last update: ++ b/WebCore/ChangeLog 2009-03-27 Zack Rusin Reviewed by Simon Hausmann. https://bugs.webkit.org/show_bug.cgi?id=24280 Fix propagation of fill rules when rendering paths in the Qt build. * platform/graphics/qt/GraphicsContextQt.cpp: (WebCore::toQtFillRule): (WebCore::GraphicsContext::fillPath): (WebCore::GraphicsContext::strokePath): 2009-03-27 Zack Rusin Reviewed by Tor Arne Vestbø. https://bugs.webkit.org/show_bug.cgi?id=24275 Fix text field theming in the Qt build with the KDE 4 Oxygen style by adjusting the size vertically and horizontally to set padding on the element equal to the width of the style painted border. * platform/qt/RenderThemeQt.cpp: (WebCore::RenderThemeQt::RenderThemeQt): (WebCore::RenderThemeQt::computeSizeBasedOnStyle): (WebCore::RenderThemeQt::adjustTextFieldStyle): (WebCore::RenderThemeQt::paintTextField): * platform/qt/RenderThemeQt.h: --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 30 ++++++++++++++++++++++ .../platform/graphics/qt/GraphicsContextQt.cpp | 14 ++++++++++ .../webkit/WebCore/platform/qt/RenderThemeQt.cpp | 26 ++++++++++++++----- .../webkit/WebCore/platform/qt/RenderThemeQt.h | 3 +++ 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index da530c8..96840d0 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - 0b6fc217c2b853827926313c09bb3c32f66ffe43 + 1beae2b64b5b1e9b97e82dc94de18ebac1c19efc diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 3b20751..e8850f3 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,33 @@ +2009-03-27 Zack Rusin + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=24280 + + Fix propagation of fill rules when rendering paths in the Qt build. + + * platform/graphics/qt/GraphicsContextQt.cpp: + (WebCore::toQtFillRule): + (WebCore::GraphicsContext::fillPath): + (WebCore::GraphicsContext::strokePath): + +2009-03-27 Zack Rusin + + Reviewed by Tor Arne Vestbø. + + https://bugs.webkit.org/show_bug.cgi?id=24275 + + Fix text field theming in the Qt build with the KDE 4 Oxygen + style by adjusting the size vertically and horizontally to + set padding on the element equal to the width of the style painted border. + + * platform/qt/RenderThemeQt.cpp: + (WebCore::RenderThemeQt::RenderThemeQt): + (WebCore::RenderThemeQt::computeSizeBasedOnStyle): + (WebCore::RenderThemeQt::adjustTextFieldStyle): + (WebCore::RenderThemeQt::paintTextField): + * platform/qt/RenderThemeQt.h: + 2009-02-06 Dirk Schulze Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index 1830566..936c1ea 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -168,6 +168,18 @@ static inline QGradient applySpreadMethod(QGradient gradient, GradientSpreadMeth return gradient; } +static inline Qt::FillRule toQtFillRule(WindRule rule) +{ + switch(rule) { + case RULE_EVENODD: + return Qt::OddEvenFill; + case RULE_NONZERO: + return Qt::WindingFill; + } + qDebug("Qt: unrecognized wind rule!"); + return Qt::OddEvenFill; +} + struct TransparencyLayer { TransparencyLayer(const QPainter* p, const QRect &rect) @@ -541,6 +553,7 @@ void GraphicsContext::fillPath() QPainter *p = m_data->p(); QPainterPath path = m_data->currentPath; + path.setFillRule(toQtFillRule(fillRule())); switch (m_common->state.fillColorSpace) { case SolidColorSpace: @@ -569,6 +582,7 @@ void GraphicsContext::strokePath() QPainter *p = m_data->p(); QPen pen = p->pen(); QPainterPath path = m_data->currentPath; + path.setFillRule(toQtFillRule(fillRule())); switch (m_common->state.strokeColorSpace) { case SolidColorSpace: diff --git a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp index cc9d314..a9da76b 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -123,6 +124,12 @@ RenderThemeQt::RenderThemeQt() #endif m_fallbackStyle = 0; + + // this will need to be regenerated when the style changes + QLineEdit lineEdit; + QStyleOptionFrameV2 opt; + m_frameLineWidth = QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth, + &opt, &lineEdit); } RenderThemeQt::~RenderThemeQt() @@ -268,7 +275,7 @@ int RenderThemeQt::minimumMenuListSize(RenderStyle*) const return 7 * fm.width(QLatin1Char('x')); } -static void computeSizeBasedOnStyle(RenderStyle* renderStyle) +void RenderThemeQt::computeSizeBasedOnStyle(RenderStyle* renderStyle) const { // If the width and height are both specified, then we have nothing to do. if (!renderStyle->width().isIntrinsicOrAuto() && !renderStyle->height().isAuto()) @@ -335,13 +342,15 @@ static void computeSizeBasedOnStyle(RenderStyle* renderStyle) int h = qMax(fm.lineSpacing(), 14) + 2*verticalMargin; int w = fm.width(QLatin1Char('x')) * 17 + 2*horizontalMargin; QStyleOptionFrameV2 opt; - opt.lineWidth = applicationStyle->pixelMetric(QStyle::PM_DefaultFrameWidth, - &opt, 0); + opt.lineWidth = m_frameLineWidth; QSize sz = applicationStyle->sizeFromContents(QStyle::CT_LineEdit, - &opt, - QSize(w, h).expandedTo(QApplication::globalStrut()), - 0); + &opt, + QSize(w, h).expandedTo(QApplication::globalStrut()), + 0); size.setHeight(sz.height()); + + renderStyle->setPaddingLeft(Length(opt.lineWidth, Fixed)); + renderStyle->setPaddingRight(Length(opt.lineWidth, Fixed)); break; } default: @@ -482,6 +491,9 @@ void RenderThemeQt::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style, { style->setBackgroundColor(Color::transparent); style->setColor(QApplication::palette().text().color()); + style->resetBorder(); + style->resetPadding(); + computeSizeBasedOnStyle(style); } bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) @@ -495,7 +507,7 @@ bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInf panel.initFrom(p.widget); panel.rect = r; - panel.lineWidth = p.style->pixelMetric(QStyle::PM_DefaultFrameWidth, &panel, p.widget); + panel.lineWidth = m_frameLineWidth; panel.state |= QStyle::State_Sunken; panel.features = QStyleOptionFrameV2::None; diff --git a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h index b4a5064..5c78a72 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h +++ b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h @@ -128,6 +128,7 @@ private: void paintMediaBackground(QPainter* painter, const IntRect& r) const; QColor getMediaControlForegroundColor(RenderObject* o = 0) const; #endif + void computeSizeBasedOnStyle(RenderStyle* renderStyle) const; private: bool supportsFocus(ControlPart) const; @@ -144,6 +145,8 @@ private: QStyle* m_fallbackStyle; QStyle* fallbackStyle(); + + int m_frameLineWidth; }; class StylePainter -- cgit v0.12 From b410a39fad176593ed75b742a486f8710c6ef60f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 27 Mar 2009 18:10:36 +0100 Subject: Fix crashes in D-Bus due to race conditions. This happens in heavily threaded applications: libdbus-1 asks us to add and remove timers (and watches, but those less often) from any thread. Since QObject's model requires that timers and QSocketDescriptors be added only in the object's own thread, we have to sync back to the main thread. However, since D-Bus keeps adding and removing the timers, we have to keep a queue of timers to be added and that list is accessed by any thread. Make sure that list is only accessed in locked conditions. Reviewed-by: Bradley T. Hughes --- src/dbus/qdbusintegrator.cpp | 6 ++++-- src/dbus/qdbusthreaddebug_p.h | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 7ed0cd5..674426b 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -137,6 +137,7 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data) if (!q_dbus_timeout_get_enabled(timeout)) return true; + QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d); if (QCoreApplication::instance() && QThread::currentThread() == d->thread()) { // correct thread return qDBusRealAddTimeout(d, timeout, q_dbus_timeout_get_interval(timeout)); @@ -152,7 +153,6 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data) static bool qDBusRealAddTimeout(QDBusConnectionPrivate *d, DBusTimeout *timeout, int ms) { - QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d); Q_ASSERT(d->timeouts.keys(timeout).isEmpty()); int timerId = d->startTimer(ms); @@ -1035,12 +1035,14 @@ void QDBusConnectionPrivate::customEvent(QEvent *e) QDBusLockerBase::BeforeDeliver, this); switch (ev->subtype) { - case QDBusConnectionCallbackEvent::AddTimeout: + case QDBusConnectionCallbackEvent::AddTimeout: { + QDBusWatchAndTimeoutLocker locker(RealAddTimeoutAction, this); while (!timeoutsPendingAdd.isEmpty()) { QPair entry = timeoutsPendingAdd.takeFirst(); qDBusRealAddTimeout(this, entry.first, entry.second); } break; + } case QDBusConnectionCallbackEvent::KillTimer: qDebug() << QThread::currentThread() << "RemoveTimeout: killing timer" << (ev->timerId & 0xffffff); diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h index 715bd6f..20d819f 100644 --- a/src/dbus/qdbusthreaddebug_p.h +++ b/src/dbus/qdbusthreaddebug_p.h @@ -92,9 +92,10 @@ enum ThreadAction { PendingCallBlockAction = 28, AddTimeoutAction = 50, - RemoveTimeoutAction = 51, - KillTimerAction = 52, - TimerEventAction = 53, + RealAddTimeoutAction = 51, + RemoveTimeoutAction = 52, + KillTimerAction = 58, + TimerEventAction = 59, AddWatchAction = 60, RemoveWatchAction = 61, ToggleWatchAction = 62, -- cgit v0.12 From a4e8538e396efccf3f8193c7a5ba751d961f206d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 27 Mar 2009 18:32:20 +0100 Subject: Remove unnecessary debug message. Reviewed-by: Trust Me --- src/dbus/qdbusintegrator.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 674426b..8c701f5 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1045,7 +1045,6 @@ void QDBusConnectionPrivate::customEvent(QEvent *e) } case QDBusConnectionCallbackEvent::KillTimer: - qDebug() << QThread::currentThread() << "RemoveTimeout: killing timer" << (ev->timerId & 0xffffff); killTimer(ev->timerId); break; -- cgit v0.12 From ff30a91eedd30c0e2e0b62ad50ade3d7d27651a8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 27 Mar 2009 21:50:41 +0100 Subject: Add the parameter to the function call. Apparently we have a problem with these default parameters. We have basically: template void func(T * = 0); template<> void func(Something *); Now, according to GCC, I can't add "= 0" to the template specialisation. However, MSVC 2008 isn't able to call the specialisation without my extra 0 here. I've seen a similar issue before in QSharedPointer. I don't think this is a big deal because the error message output by MSVC 2008 indicates this is likely a compiler bug: qdbuspendingreply.h(98) : error C2440: 'default argument': cannot convert from 'T1 *' to 'QVariant *' where [ T1=QVariant ] --- src/dbus/qdbuspendingreply.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dbus/qdbuspendingreply.h b/src/dbus/qdbuspendingreply.h index 3880a7f..5ec9800 100644 --- a/src/dbus/qdbuspendingreply.h +++ b/src/dbus/qdbuspendingreply.h @@ -95,7 +95,7 @@ namespace QDBusPendingReplyTypes { enum { Total = Next::Total + 1 }; static inline void fillMetaTypes(int *p) { - *p = metaTypeFor(); + *p = metaTypeFor(0); Next::fillMetaTypes(++p); } }; @@ -171,7 +171,7 @@ public: Q_ASSERT_X(Index < count() && Index >= 0, "QDBusPendingReply::argumentAt", "Index out of bounds"); typedef typename Select::Type ResultType; - return qdbus_cast(argumentAt(Index)); + return qdbus_cast(argumentAt(Index), 0); } inline typename Select<0>::Type value() const -- cgit v0.12 From ba25c4a832516124bcd97758de9eede32797c5a0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 27 Mar 2009 14:55:13 +0100 Subject: Make use of a thread-specific variable in qFlagLocation. We're a bit too deep in the stack here for QThreadStorage. So just use the system support, provided it works. --- src/corelib/kernel/qobject.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 05015c0..0e632db 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2179,13 +2179,29 @@ void QObject::deleteLater() Signals and slots *****************************************************************************/ +// list taken from http://en.wikipedia.org/wiki/Thread-Specific_Storage +#if defined(Q_OS_WIN) +// Some people like to dynamically load Qt (LoadLibrary), so we can't use this +#elif defined(Q_CC_GNU) && !defined(Q_WS_QWS) +// GCC has warnings about this not being ported to all archs +// So we only enable what we know to work. More archs can be added later, like Mac +# if defined(Q_OS_LINUX) && (defined(QT_ARCH_I386) || defined(QT_ARCH_X86_64) || defined(QT_ARCH_IA64)) +# define THRSPECIFIC __thread __attribute__((tls_model("local-dynamic"))) +# endif +#elif defined(Q_CC_SUN) || defined(Q_CC_INTEL) || defined(Q_CC_XLC) +# define THRSPECIFIC __thread +#endif + +#ifndef THRSPECIFIC +# define THRSPECIFIC +#endif const int flagged_locations_count = 2; -static const char* flagged_locations[flagged_locations_count] = {0}; +static THRSPECIFIC const char* flagged_locations[flagged_locations_count] = {0}; const char *qFlagLocation(const char *method) { - static int idx = 0; + static THRSPECIFIC int idx = 0; flagged_locations[idx] = method; idx = (idx+1) % flagged_locations_count; return method; -- cgit v0.12