From 93e3a72f56d4b9ab020c58a2a3fac79be5fe49eb Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 25 Jun 2009 16:15:01 +0200 Subject: Doc: Indicated that QCompleter::completionModel() returns a proxy model. Task-number: 256138 Reviewed-by: jasplin --- src/gui/util/qcompleter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index 3d25f13..f4adcea 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -1582,6 +1582,10 @@ QString QCompleter::currentCompletion() const that contains all the possible matches for the current completion prefix. The completion model is auto-updated to reflect the current completions. + \note The return value of this function is defined to be an QAbstractItemModel + purely for generality. This actual kind of model returned is an instance of an + QAbstractProxyModel subclass. + \sa completionPrefix, model() */ QAbstractItemModel *QCompleter::completionModel() const -- cgit v0.12 From b2d61c982e860a532f931dfaea143749927784a6 Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 1 Jul 2009 08:49:22 +1000 Subject: Don assume QVariant::String data is going to always be unicode in QODBC - as was not the case for the psqlODBC driver Reviewed-by: Bill King --- src/sql/drivers/odbc/qsql_odbc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 2bedf7f..e18a9eb 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -1006,7 +1006,7 @@ QVariant QODBCResult::data(int field) d->fieldCache[i] = qGetBinaryData(d->hStmt, i); break; case QVariant::String: - d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), true); + d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), d->unicode); break; case QVariant::Double: { -- cgit v0.12 From 70137e0601549af1056082cdfbb4f141c70befab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chusslove=20Illich=20=28=D0=A7=D0=B0=D1=81=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=20=D0=98=D0=BB=D0=B8=D1=9B=29?= Date: Tue, 30 Jun 2009 23:29:02 +0200 Subject: operator==() for Unicode properties was omitting one property, which resulted in wrong choice of unique properties for characters 451-45f. Reviewed-By: Thiago Macieira Reviewed-By: Denis Dzyubenko --- util/unicode/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index cab6570..f1b4641 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -293,6 +293,7 @@ struct PropertyFlags { && lowerCaseDiff == o.lowerCaseDiff && upperCaseDiff == o.upperCaseDiff && titleCaseDiff == o.titleCaseDiff + && caseFoldDiff == o.caseFoldDiff && lowerCaseSpecial == o.lowerCaseSpecial && upperCaseSpecial == o.upperCaseSpecial && titleCaseSpecial == o.titleCaseSpecial -- cgit v0.12 From 5057276344a061b7f5553ef3ac12c513ccd9c694 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 30 Jun 2009 17:30:58 +0200 Subject: Document unified toolbar change with regard to full screen change. --- src/gui/widgets/qmainwindow.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 0a0faa0..0c841eb 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1419,9 +1419,10 @@ bool QMainWindow::event(QEvent *event) \i Toolbar breaks are not respected or preserved \i Any custom widgets in the toolbar will not be shown if the toolbar becomes too small (only actions will be shown) - \i If you call showFullScreen() on the main window, the QToolbar will - disappear since it is considered to be part of the title bar. You can - work around this by turning off the unified toolbar before you call + \i Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would + disappear since it is considered to be part of the title bar. Qt 4.5 and up will now work around this by pulling + the toolbars out and back into the regular toolbar and vice versa when you swap out. + However, a good practice would be that turning off the unified toolbar before you call showFullScreen() and restoring it after you call showNormal(). \endlist -- cgit v0.12 From f79955fc9b250f03d54be3c99b79062368b6273d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 1 Jul 2009 11:42:22 +0200 Subject: Improve QtHelp error reporting. Reviewed-by: kh --- tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp index b6e726b..c50f48d 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp @@ -639,7 +639,7 @@ void QHelpSearchIndexWriter::run() QFileInfo fInfo(indexPath); if (fInfo.exists() && !fInfo.isWritable()) { - qWarning("Full Text Search, could not create index (missing permissions)."); + qWarning("Full Text Search, could not create index (missing permissions for '%s').", qPrintable(indexPath)); return; } @@ -720,7 +720,7 @@ void QHelpSearchIndexWriter::run() } #if !defined(QT_NO_EXCEPTIONS) } catch (...) { - qWarning("Full Text Search, could not create index writer."); + qWarning("Full Text Search, could not create index writer in '%s'.", qPrintable(indexPath)); return; } #endif -- cgit v0.12 From 16e84b77571cb5dc97312ae613d96d7cd28ab4d2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 1 Jul 2009 10:52:28 +0200 Subject: Fixed the license header that the unicode table generated uses. Also made sure that the generated code will not have trailing whitespaces. Reviewed-by: Thiago Macieira --- util/unicode/main.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 8 deletions(-) diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index f1b4641..3c32e6d 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -1911,6 +1911,8 @@ static QByteArray createPropertyInfo() out += " // 0x" + QByteArray::number(BMP_END, 16); for (int i = 0; i < BMP_END/BMP_BLOCKSIZE; ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!((i*BMP_BLOCKSIZE) % 0x1000)) out += "\n"; out += "\n "; @@ -1918,9 +1920,13 @@ static QByteArray createPropertyInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n\n // 0x" + QByteArray::number(BMP_END, 16) + " - 0x" + QByteArray::number(SMP_END, 16) + "\n";; for (int i = BMP_END/BMP_BLOCKSIZE; i < blockMap.size(); ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!(i % (0x10000/SMP_BLOCKSIZE))) out += "\n"; out += "\n "; @@ -1928,14 +1934,21 @@ static QByteArray createPropertyInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n"; // write the data for (int i = 0; i < blocks.size(); ++i) { + if (out.endsWith(' ')) + out.chop(1); out += "\n"; const PropertyBlock &b = blocks.at(i); for (int j = 0; j < b.properties.size(); ++j) { - if (!(j % 8)) + if (!(j % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; + } out += QByteArray::number(b.properties.at(j)); out += ", "; } @@ -1948,6 +1961,8 @@ static QByteArray createPropertyInfo() Q_ASSERT(maxTitleCaseDiff < (1<<14)); Q_ASSERT(maxCaseFoldDiff < (1<<14)); + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n" "#define GET_PROP_INDEX(ucs4) \\\n" @@ -2204,6 +2219,8 @@ static QByteArray createCompositionInfo() out += " // 0 - 0x" + QByteArray::number(BMP_END, 16); for (int i = 0; i < BMP_END/BMP_BLOCKSIZE; ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!((i*BMP_BLOCKSIZE) % 0x1000)) out += "\n"; out += "\n "; @@ -2211,9 +2228,13 @@ static QByteArray createCompositionInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n\n // 0x" + QByteArray::number(BMP_END, 16) + " - 0x" + QByteArray::number(SMP_END, 16) + "\n";; for (int i = BMP_END/BMP_BLOCKSIZE; i < blockMap.size(); ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!(i % (0x10000/SMP_BLOCKSIZE))) out += "\n"; out += "\n "; @@ -2221,19 +2242,28 @@ static QByteArray createCompositionInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n"; // write the data for (int i = 0; i < blocks.size(); ++i) { + if (out.endsWith(' ')) + out.chop(1); out += "\n"; const DecompositionBlock &b = blocks.at(i); for (int j = 0; j < b.decompositionPositions.size(); ++j) { - if (!(j % 8)) + if (!(j % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; + } out += "0x" + QByteArray::number(b.decompositionPositions.at(j), 16); out += ", "; } } + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n" "#define GET_DECOMPOSITION_INDEX(ucs4) \\\n" @@ -2250,12 +2280,16 @@ static QByteArray createCompositionInfo() for (int i = 0; i < decompositions.size(); ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; } out += "0x" + QByteArray::number(decompositions.at(i), 16); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n"; return out; @@ -2328,6 +2362,8 @@ static QByteArray createLigatureInfo() out += " // 0 - 0x" + QByteArray::number(BMP_END, 16); for (int i = 0; i < BMP_END/BMP_BLOCKSIZE; ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!((i*BMP_BLOCKSIZE) % 0x1000)) out += "\n"; out += "\n "; @@ -2335,18 +2371,27 @@ static QByteArray createLigatureInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n"; // write the data for (int i = 0; i < blocks.size(); ++i) { + if (out.endsWith(' ')) + out.chop(1); out += "\n"; const DecompositionBlock &b = blocks.at(i); for (int j = 0; j < b.decompositionPositions.size(); ++j) { - if (!(j % 8)) + if (!(j % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; + } out += "0x" + QByteArray::number(b.decompositionPositions.at(j), 16); out += ", "; } } + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n" "#define GET_LIGATURE_INDEX(u2) " @@ -2358,12 +2403,16 @@ static QByteArray createLigatureInfo() for (int i = 0; i < ligatures.size(); ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; } out += "0x" + QByteArray::number(ligatures.at(i), 16); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n"; return out; @@ -2420,18 +2469,46 @@ int main(int, char **) "/****************************************************************************\n" "**\n" "** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).\n" + "** Contact: Nokia Corporation (qt-info@nokia.com)\n" + "**\n" + "** This file is part of the QtCore module of the Qt Toolkit.\n" "**\n" - "** This file is part of the $MODULE$ of the Qt Toolkit.\n" + "** $QT_BEGIN_LICENSE:LGPL$\n" + "** No Commercial Usage\n" + "** This file contains pre-release code and may not be distributed.\n" + "** You may use this file in accordance with the terms and conditions\n" + "** contained in the either Technology Preview License Agreement or the\n" + "** Beta Release License Agreement.\n" "**\n" - "** $TROLLTECH_DUAL_LICENSE$\n" + "** GNU Lesser General Public License Usage\n" + "** Alternatively, this file may be used under the terms of the GNU Lesser\n" + "** General Public License version 2.1 as published by the Free Software\n" + "** Foundation and appearing in the file LICENSE.LGPL included in the\n" + "** packaging of this file. Please review the following information to\n" + "** ensure the GNU Lesser General Public License version 2.1 requirements\n" + "** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.\n" "**\n" - "** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE\n" - "** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.\n" + "** In addition, as a special exception, Nokia gives you certain\n" + "** additional rights. These rights are described in the Nokia Qt LGPL\n" + "** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this\n" + "** package.\n" + "**\n" + "** GNU General Public License Usage\n" + "** Alternatively, this file may be used under the terms of the GNU\n" + "** General Public License version 3.0 as published by the Free Software\n" + "** Foundation and appearing in the file LICENSE.GPL included in the\n" + "** packaging of this file. Please review the following information to\n" + "** ensure the GNU General Public License version 3.0 requirements will be\n" + "** met: http://www.gnu.org/copyleft/gpl.html.\n" + "**\n" + "** If you are unsure which license is appropriate for your use, please\n" + "** contact the sales department at http://www.qtsoftware.com/contact.\n" + "** $QT_END_LICENSE$\n" "**\n" "****************************************************************************/\n\n" "/* This file is autogenerated from the Unicode 5.0 database. Do not edit */\n\n"; - + QByteArray warning = "//\n" "// W A R N I N G\n" -- cgit v0.12 From 3b9f9c1abaee60e94031e0a46f46c67410dc3d2f Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 1 Jul 2009 10:55:01 +0200 Subject: Regenerated unicode tables after the fix in the generator. This is related to the following fix: 70137e0601549af1056082cdfbb4f141c70befab Reviewed-by: trustme --- src/corelib/tools/qunicodetables.cpp | 13383 +++++++++++++++++---------------- src/corelib/tools/qunicodetables_p.h | 4 +- 2 files changed, 6694 insertions(+), 6693 deletions(-) diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp index 11ae801..0387181 100644 --- a/src/corelib/tools/qunicodetables.cpp +++ b/src/corelib/tools/qunicodetables.cpp @@ -46,3374 +46,3374 @@ QT_BEGIN_NAMESPACE static const unsigned short uc_property_trie[] = { // 0x11000 - 6256, 6288, 6320, 6352, 6384, 6416, 6448, 6480, - 6512, 6544, 6576, 6608, 6640, 6672, 6704, 6736, - 6768, 6800, 6832, 6864, 6896, 6928, 6960, 6992, - 7024, 7056, 7088, 7120, 7152, 7184, 7216, 7248, - 7280, 7312, 7344, 6512, 7376, 6512, 7408, 7440, - 7472, 7504, 7536, 7568, 7600, 7632, 7664, 7696, - 7728, 7760, 7792, 7824, 7856, 7888, 7920, 7952, - 7984, 8016, 8048, 8080, 8112, 8144, 8176, 8208, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8272, 8304, 8336, 8368, 8400, 8432, 8464, 8496, - 8528, 8560, 8592, 8624, 8656, 8688, 8720, 8752, - 8400, 8784, 8816, 8848, 8880, 8912, 8944, 8976, - 9008, 9040, 9072, 9104, 9136, 9168, 9200, 9232, - 9136, 9264, 9296, 9104, 9328, 9360, 9392, 9424, - 9456, 9488, 9520, 9552, 9584, 9616, 9648, 9552, - 9680, 9712, 9744, 9776, 9808, 9840, 9872, 9552, - - 9904, 9936, 9968, 9552, 9552, 10000, 10032, 10064, - 10096, 10096, 10128, 10160, 10160, 10192, 10224, 10256, - 10288, 10320, 10352, 10320, 10384, 10416, 10448, 10480, - 10512, 10320, 10544, 10576, 10608, 10320, 10320, 10640, - 10672, 10320, 10320, 10320, 10320, 10320, 10320, 10320, - 10320, 10320, 10320, 10320, 10320, 10320, 10320, 10320, - 10320, 10320, 10320, 10704, 10736, 10320, 10320, 10768, - 10800, 10832, 10864, 10896, 9904, 10928, 10960, 10992, - 11024, 10320, 11056, 11088, 10320, 11120, 9552, 9552, - 11152, 11184, 11216, 11248, 11280, 11312, 11344, 11376, - 11408, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 11440, 11472, 11504, 11536, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 11568, 11600, 11632, 11664, 11696, 11728, 11760, 11792, - 6512, 6512, 6512, 6512, 11824, 6512, 6512, 11856, - 11888, 11920, 11952, 11984, 12016, 12048, 12080, 12112, - - 12144, 12176, 12208, 12240, 12272, 12304, 12336, 12368, - 12400, 12432, 12464, 12496, 12528, 12560, 12592, 12624, - 12656, 12688, 12720, 12752, 12784, 12816, 12848, 12880, - 12912, 12944, 12976, 13008, 13040, 13072, 13104, 13136, - 13168, 13200, 13232, 13264, 13296, 13328, 13360, 13392, - 13168, 13168, 13168, 13168, 13424, 13456, 13488, 13520, - 13552, 13168, 13168, 13584, 13616, 13648, 9552, 9552, - 13680, 13712, 13744, 13776, 13808, 13840, 13872, 13904, - 13936, 13936, 13936, 13936, 13936, 13936, 13936, 13936, - 13968, 13968, 13968, 13968, 14000, 14032, 14064, 14096, - 13968, 14128, 13968, 14160, 14192, 14224, 14256, 14288, - 14320, 14352, 9552, 9552, 9552, 9552, 9552, 9552, - 14384, 14416, 14448, 14480, 14512, 14512, 14512, 14544, - 14576, 14608, 14640, 14672, 14704, 14736, 14736, 9552, - 14768, 9552, 9552, 9552, 14800, 14832, 14832, 14864, - 14832, 14832, 14832, 14832, 14832, 14832, 14896, 14928, - - 14960, 14992, 15024, 15056, 15088, 15120, 15152, 15184, - 15216, 15248, 15280, 15280, 15312, 15344, 15376, 15408, - 15440, 15472, 15504, 15536, 15472, 15568, 15600, 15632, - 15664, 15664, 15664, 15696, 15664, 15664, 15728, 15760, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15824, 11376, 11376, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15888, 9552, 9552, - - 15920, 15952, 15952, 15952, 15952, 15952, 15952, 15952, - 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, - 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, - 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, - 15952, 15952, 15952, 15952, 15984, 16016, 16048, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 16080, 16112, 9552, 9552, 9552, 9552, 9552, 9552, - 16144, 16176, 16208, 16240, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16496, 9552, 9552, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 16592, 16624, 16656, 16688, 16688, 16720, 9552, - 16752, 16784, 16816, 16848, 16848, 16880, 16912, 16848, - 16848, 16848, 16848, 16848, 16848, 16848, 16848, 16848, - 16848, 16944, 16976, 16848, 17008, 16848, 17040, 17072, - 17104, 17136, 17168, 17200, 16848, 16848, 16848, 17232, - 17264, 17296, 17328, 17360, 17392, 17424, 17456, 17488, - - 17520, 17552, 17584, 9552, 17616, 17616, 17616, 17648, - 17680, 17712, 17744, 17776, 17808, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 17840, 17872, 17904, 9552, 17936, 14640, 17968, 9552, - 18000, 18032, 18064, 17616, 18096, 18128, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 18160, 18192, 8240, 8240, 8240, 8240, 8240, 8240, - 18224, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 18256, 18288, 18320, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 6256, 6288, 6320, 6352, 6384, 6416, 6448, 6480, + 6512, 6544, 6576, 6608, 6640, 6672, 6704, 6736, + 6768, 6800, 6832, 6864, 6896, 6928, 6960, 6992, + 7024, 7056, 7088, 7120, 7152, 7184, 7216, 7248, + 7280, 7312, 7344, 6512, 7376, 6512, 7408, 7440, + 7472, 7504, 7536, 7568, 7600, 7632, 7664, 7696, + 7728, 7760, 7792, 7824, 7856, 7888, 7920, 7952, + 7984, 8016, 8048, 8080, 8112, 8144, 8176, 8208, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8272, 8304, 8336, 8368, 8400, 8432, 8464, 8496, + 8528, 8560, 8592, 8624, 8656, 8688, 8720, 8752, + 8400, 8784, 8816, 8848, 8880, 8912, 8944, 8976, + 9008, 9040, 9072, 9104, 9136, 9168, 9200, 9232, + 9136, 9264, 9296, 9104, 9328, 9360, 9392, 9424, + 9456, 9488, 9520, 9552, 9584, 9616, 9648, 9552, + 9680, 9712, 9744, 9776, 9808, 9840, 9872, 9552, + + 9904, 9936, 9968, 9552, 9552, 10000, 10032, 10064, + 10096, 10096, 10128, 10160, 10160, 10192, 10224, 10256, + 10288, 10320, 10352, 10320, 10384, 10416, 10448, 10480, + 10512, 10320, 10544, 10576, 10608, 10320, 10320, 10640, + 10672, 10320, 10320, 10320, 10320, 10320, 10320, 10320, + 10320, 10320, 10320, 10320, 10320, 10320, 10320, 10320, + 10320, 10320, 10320, 10704, 10736, 10320, 10320, 10768, + 10800, 10832, 10864, 10896, 9904, 10928, 10960, 10992, + 11024, 10320, 11056, 11088, 10320, 11120, 9552, 9552, + 11152, 11184, 11216, 11248, 11280, 11312, 11344, 11376, + 11408, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 11440, 11472, 11504, 11536, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 11568, 11600, 11632, 11664, 11696, 11728, 11760, 11792, + 6512, 6512, 6512, 6512, 11824, 6512, 6512, 11856, + 11888, 11920, 11952, 11984, 12016, 12048, 12080, 12112, + + 12144, 12176, 12208, 12240, 12272, 12304, 12336, 12368, + 12400, 12432, 12464, 12496, 12528, 12560, 12592, 12624, + 12656, 12688, 12720, 12752, 12784, 12816, 12848, 12880, + 12912, 12944, 12976, 13008, 13040, 13072, 13104, 13136, + 13168, 13200, 13232, 13264, 13296, 13328, 13360, 13392, + 13168, 13168, 13168, 13168, 13424, 13456, 13488, 13520, + 13552, 13168, 13168, 13584, 13616, 13648, 9552, 9552, + 13680, 13712, 13744, 13776, 13808, 13840, 13872, 13904, + 13936, 13936, 13936, 13936, 13936, 13936, 13936, 13936, + 13968, 13968, 13968, 13968, 14000, 14032, 14064, 14096, + 13968, 14128, 13968, 14160, 14192, 14224, 14256, 14288, + 14320, 14352, 9552, 9552, 9552, 9552, 9552, 9552, + 14384, 14416, 14448, 14480, 14512, 14512, 14512, 14544, + 14576, 14608, 14640, 14672, 14704, 14736, 14736, 9552, + 14768, 9552, 9552, 9552, 14800, 14832, 14832, 14864, + 14832, 14832, 14832, 14832, 14832, 14832, 14896, 14928, + + 14960, 14992, 15024, 15056, 15088, 15120, 15152, 15184, + 15216, 15248, 15280, 15280, 15312, 15344, 15376, 15408, + 15440, 15472, 15504, 15536, 15472, 15568, 15600, 15632, + 15664, 15664, 15664, 15696, 15664, 15664, 15728, 15760, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15824, 11376, 11376, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15888, 9552, 9552, + + 15920, 15952, 15952, 15952, 15952, 15952, 15952, 15952, + 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, + 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, + 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, + 15952, 15952, 15952, 15952, 15984, 16016, 16048, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 16080, 16112, 9552, 9552, 9552, 9552, 9552, 9552, + 16144, 16176, 16208, 16240, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16496, 9552, 9552, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 16592, 16624, 16656, 16688, 16688, 16720, 9552, + 16752, 16784, 16816, 16848, 16848, 16880, 16912, 16848, + 16848, 16848, 16848, 16848, 16848, 16848, 16848, 16848, + 16848, 16944, 16976, 16848, 17008, 16848, 17040, 17072, + 17104, 17136, 17168, 17200, 16848, 16848, 16848, 17232, + 17264, 17296, 17328, 17360, 17392, 17424, 17456, 17488, + + 17520, 17552, 17584, 9552, 17616, 17616, 17616, 17648, + 17680, 17712, 17744, 17776, 17808, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 17840, 17872, 17904, 9552, 17936, 14640, 17968, 9552, + 18000, 18032, 18064, 17616, 18096, 18128, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 18160, 18192, 8240, 8240, 8240, 8240, 8240, 8240, + 18224, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 18256, 18288, 18320, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, // 0x11000 - 0x110000 - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18608, 18608, 18608, 18864, 19120, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 19376, 19632, 19888, 20144, 20400, 20656, 20912, 21168, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21936, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 21680, 21680, 22192, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 22448, 22704, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216, - - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 6, 6, 7, - - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 14, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 9, - - 14, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 39, 40, 41, 42, 43, - - 42, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 39, 45, 41, 36, 0, - - 0, 0, 0, 0, 0, 46, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 47, 14, 48, 12, 12, 12, 49, 49, - 42, 49, 50, 51, 36, 52, 49, 42, - 53, 54, 55, 56, 57, 58, 49, 59, - 42, 60, 50, 61, 62, 62, 62, 14, - - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 36, - 38, 38, 38, 38, 38, 38, 38, 63, - - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 36, - 44, 44, 44, 44, 44, 44, 44, 64, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 67, 68, 65, 66, 65, 66, 65, 66, - 50, 65, 66, 65, 66, 65, 66, 65, - - 66, 65, 66, 65, 66, 65, 66, 65, - 66, 69, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 70, 65, 66, 65, 66, 65, 66, 71, - - 72, 73, 65, 66, 65, 66, 74, 65, - 66, 75, 75, 65, 66, 50, 76, 77, - 78, 65, 66, 75, 79, 80, 81, 82, - 65, 66, 83, 50, 81, 84, 85, 86, - - 65, 66, 65, 66, 65, 66, 87, 65, - 66, 87, 50, 50, 65, 66, 87, 65, - 66, 88, 88, 65, 66, 65, 66, 89, - 65, 66, 50, 90, 65, 66, 50, 91, - - 90, 90, 90, 90, 92, 93, 94, 92, - 93, 94, 92, 93, 94, 65, 66, 65, - 66, 65, 66, 65, 66, 65, 66, 65, - 66, 65, 66, 65, 66, 95, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 96, 92, 93, 94, 65, 66, 97, 98, - 99, 100, 65, 66, 65, 66, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 99, 100, 99, 100, 99, 100, 99, 100, - - 101, 102, 99, 100, 99, 100, 99, 100, - 99, 100, 99, 100, 99, 100, 99, 100, - 99, 100, 99, 100, 102, 102, 102, 103, - 103, 103, 104, 105, 106, 107, 108, 103, - - 103, 105, 109, 110, 111, 112, 113, 109, - 113, 109, 113, 109, 113, 109, 113, 109, - 50, 50, 50, 114, 115, 50, 116, 116, - 50, 117, 50, 118, 50, 50, 50, 50, - - 116, 50, 50, 119, 50, 50, 50, 50, - 120, 121, 50, 122, 50, 50, 50, 121, - 50, 50, 123, 50, 50, 124, 50, 50, - 50, 50, 50, 50, 50, 125, 50, 50, - - 126, 50, 50, 126, 50, 50, 50, 50, - 126, 127, 128, 128, 129, 50, 50, 50, - 50, 50, 130, 50, 90, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 131, 131, 131, 131, 131, 102, 102, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 133, 133, 134, 134, 134, 134, 134, - - 132, 132, 42, 42, 42, 42, 133, 133, - 135, 133, 133, 133, 135, 133, 133, 133, - 134, 134, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 136, - - 132, 132, 132, 132, 132, 42, 42, 42, - 42, 42, 136, 136, 136, 136, 137, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - - 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 140, 141, 141, - 141, 141, 140, 142, 141, 141, 141, 141, - - 141, 143, 143, 141, 141, 141, 141, 143, - 143, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 144, 144, 144, 144, - 144, 141, 141, 141, 141, 139, 139, 139, - - 139, 139, 139, 139, 139, 145, 146, 147, - 147, 147, 146, 146, 146, 147, 147, 148, - 149, 149, 149, 150, 150, 150, 150, 149, - 151, 152, 152, 153, 154, 155, 155, 156, - - 157, 157, 158, 159, 159, 159, 159, 159, - 159, 159, 159, 159, 159, 159, 159, 159, - 160, 160, 160, 160, 42, 42, 160, 160, - 160, 160, 132, 161, 161, 161, 34, 160, - - 160, 160, 160, 160, 42, 42, 162, 14, - 163, 163, 163, 160, 164, 160, 165, 165, - 166, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - - 38, 38, 160, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 167, 168, 168, 168, - 169, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - - 44, 44, 170, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 171, 172, 172, 160, - 173, 174, 175, 175, 175, 176, 177, 131, - 178, 179, 65, 100, 65, 100, 65, 100, - - 65, 100, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 180, 181, 182, 50, 183, 184, 185, 186, - 187, 188, 186, 187, 103, 189, 189, 189, - - 190, 191, 191, 191, 191, 191, 191, 191, - 191, 191, 191, 191, 191, 190, 191, 191, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 192, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 192, 181, 181, - - 65, 66, 193, 139, 139, 139, 139, 160, - 194, 194, 178, 179, 99, 100, 99, 100, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - - 195, 65, 66, 65, 66, 178, 179, 65, - 66, 178, 179, 65, 66, 178, 179, 196, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 99, 100, 65, 66, - 65, 66, 65, 66, 65, 66, 105, 106, - 65, 66, 113, 109, 113, 109, 113, 109, - - 178, 179, 178, 179, 178, 179, 178, 179, - 178, 179, 178, 179, 178, 179, 178, 179, - 113, 109, 113, 109, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, - - 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 160, - 160, 134, 198, 198, 199, 198, 199, 198, - - 160, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - - 200, 200, 200, 200, 200, 200, 200, 201, - 160, 202, 203, 160, 160, 160, 160, 160, - 204, 205, 206, 206, 206, 206, 205, 206, - 206, 206, 207, 205, 206, 206, 206, 206, - - 206, 206, 152, 205, 205, 205, 205, 205, - 206, 206, 205, 206, 206, 207, 208, 206, - 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, - - 225, 226, 227, 225, 206, 152, 228, 229, - 204, 204, 204, 204, 204, 204, 204, 204, - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 230, - - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 204, 204, 204, 204, 204, - 230, 230, 230, 231, 232, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - - 233, 233, 233, 233, 234, 234, 234, 234, - 234, 234, 234, 235, 236, 237, 238, 238, - 149, 149, 149, 149, 149, 149, 234, 234, - 234, 234, 234, 239, 234, 234, 240, 241, - - 234, 242, 243, 243, 243, 243, 244, 243, - 244, 243, 244, 244, 244, 244, 244, 243, - 243, 243, 243, 244, 244, 244, 244, 244, - 244, 244, 244, 234, 234, 234, 234, 234, - - 245, 244, 244, 244, 244, 244, 244, 244, - 243, 244, 244, 246, 247, 248, 249, 250, - 251, 252, 253, 146, 146, 147, 150, 149, - 149, 153, 153, 153, 152, 153, 153, 234, - - 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 265, 266, 267, 267, - 268, 243, 243, 243, 242, 243, 243, 243, - 244, 244, 244, 244, 244, 244, 244, 244, - - 244, 244, 244, 244, 244, 244, 244, 244, - 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 244, 244, 244, 244, 244, 244, - - 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, - 269, 269, 244, 244, 244, 244, 244, 269, - - 243, 244, 244, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 244, 243, 244, 270, - 244, 244, 243, 243, 241, 243, 139, 139, - 139, 139, 139, 139, 139, 271, 272, 139, - - 139, 139, 139, 141, 139, 273, 273, 139, - 139, 49, 141, 139, 139, 141, 274, 274, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 269, 269, 269, 275, 275, 276, - - 277, 277, 277, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 234, 279, - 270, 280, 269, 269, 269, 270, 270, 270, - 270, 270, 269, 269, 269, 269, 270, 269, - - 269, 269, 269, 269, 269, 269, 269, 269, - 270, 269, 270, 269, 270, 276, 276, 274, - 146, 147, 146, 146, 147, 146, 146, 147, - 147, 147, 146, 147, 147, 146, 147, 146, - - 146, 146, 147, 146, 147, 146, 147, 146, - 147, 146, 146, 234, 234, 274, 276, 276, - 281, 281, 281, 281, 281, 281, 281, 281, - 281, 282, 282, 282, 281, 281, 281, 281, - - 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 282, 282, 281, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - - 283, 283, 283, 283, 283, 283, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 285, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - - 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 297, 297, 297, 297, 297, - 297, 297, 298, 297, 299, 299, 300, 301, - 302, 303, 304, 204, 204, 204, 204, 204, - - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - - 160, 305, 305, 306, 307, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 160, 160, 308, 90, 306, 306, - - 306, 305, 305, 305, 305, 305, 305, 305, - 305, 306, 306, 306, 306, 309, 160, 160, - 90, 139, 141, 139, 139, 160, 160, 160, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 305, 305, 310, 310, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 198, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 321, 321, 322, 321, 321, - - 160, 305, 306, 306, 160, 90, 90, 90, - 90, 90, 90, 90, 90, 160, 160, 90, - 90, 160, 160, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 160, 160, 160, 90, 90, - 90, 90, 160, 160, 308, 307, 323, 306, - - 306, 305, 305, 305, 305, 160, 160, 306, - 306, 160, 160, 306, 306, 309, 322, 160, - 160, 160, 160, 160, 160, 160, 160, 323, - 160, 160, 160, 160, 90, 90, 160, 90, - - 90, 90, 305, 305, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 90, 90, 12, 12, 324, 324, 324, 324, - 324, 324, 193, 160, 160, 160, 160, 160, - - 160, 325, 305, 326, 160, 90, 90, 90, - 90, 90, 90, 160, 160, 160, 160, 90, - 90, 160, 160, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 160, 90, 90, 160, - 90, 90, 160, 160, 308, 160, 306, 306, - - 306, 305, 305, 160, 160, 160, 160, 305, - 305, 160, 160, 305, 305, 309, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 90, 90, 90, 90, 160, 90, 160, - - 160, 160, 160, 160, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 305, 305, 90, 90, 90, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 305, 305, 306, 160, 90, 90, 90, - 90, 90, 90, 90, 307, 90, 160, 90, - 90, 90, 160, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 160, 90, 90, 90, - 90, 90, 160, 160, 308, 90, 306, 306, - - 306, 305, 305, 305, 305, 305, 160, 305, - 305, 306, 160, 306, 306, 309, 160, 160, - 90, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 90, 307, 325, 325, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 160, 327, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 160, 307, 90, 90, - 90, 90, 160, 160, 308, 90, 323, 305, - - 306, 305, 305, 305, 160, 160, 160, 306, - 306, 160, 160, 306, 306, 309, 160, 160, - 160, 160, 160, 160, 160, 160, 305, 323, - 160, 160, 160, 160, 90, 90, 160, 90, - - 90, 90, 160, 160, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 193, 307, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 305, 90, 160, 90, 90, 90, - 90, 90, 90, 160, 160, 160, 90, 90, - 90, 160, 90, 90, 90, 90, 160, 160, - 160, 90, 90, 160, 90, 160, 90, 90, - - 160, 160, 160, 90, 90, 160, 160, 160, - 90, 90, 90, 160, 160, 160, 90, 90, - 90, 90, 90, 90, 90, 90, 322, 90, - 90, 90, 160, 160, 160, 160, 323, 306, - - 305, 306, 306, 160, 160, 160, 306, 306, - 306, 160, 306, 306, 306, 309, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 323, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 328, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 324, 324, 324, 238, 238, 238, 238, 238, - 238, 327, 238, 160, 160, 160, 160, 160, - - 160, 306, 306, 306, 160, 90, 90, 90, - 90, 90, 90, 90, 90, 160, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 160, 90, 90, 90, - 90, 90, 160, 160, 160, 160, 305, 305, - - 305, 306, 306, 306, 306, 160, 305, 305, - 305, 160, 305, 305, 305, 309, 160, 160, - 160, 160, 160, 160, 160, 329, 330, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 90, 90, 160, 160, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 306, 306, 160, 90, 90, 90, - 90, 90, 90, 90, 90, 160, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 160, 90, 90, 90, - 90, 90, 160, 160, 331, 307, 306, 332, - - 306, 306, 323, 306, 306, 160, 332, 306, - 306, 160, 306, 306, 305, 309, 160, 160, - 160, 160, 160, 160, 160, 323, 323, 160, - 160, 160, 160, 160, 160, 160, 90, 160, - - 90, 90, 333, 333, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 160, 300, 300, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 160, 160, 160, 160, 323, 306, - - 306, 305, 305, 305, 160, 160, 306, 306, - 306, 160, 306, 306, 306, 309, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 323, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 334, 334, 160, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 160, - 160, 160, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 160, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 160, 335, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 160, - 160, 160, 336, 160, 160, 160, 160, 337, - 334, 334, 284, 284, 284, 160, 284, 160, - 334, 334, 334, 334, 334, 334, 334, 337, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 334, 334, 338, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, - - 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, - 339, 340, 339, 339, 340, 340, 340, 340, - 341, 341, 342, 160, 160, 160, 160, 12, - - 339, 339, 339, 339, 339, 339, 343, 340, - 344, 344, 344, 344, 340, 340, 340, 198, - 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 345, 345, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 339, 339, 160, 339, 160, 160, 339, - 339, 160, 339, 160, 160, 339, 160, 160, - 160, 160, 160, 160, 339, 339, 339, 339, - 160, 339, 339, 339, 339, 339, 339, 339, - - 160, 339, 339, 339, 160, 339, 160, 339, - 160, 160, 339, 339, 160, 339, 339, 339, - 339, 340, 339, 339, 340, 340, 340, 340, - 346, 346, 160, 340, 340, 339, 160, 160, - - 339, 339, 339, 339, 339, 160, 343, 160, - 347, 347, 347, 347, 340, 340, 160, 160, - 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 160, 160, 339, 339, 160, 160, - - 348, 349, 349, 349, 350, 351, 350, 350, - 352, 350, 350, 353, 352, 354, 354, 354, - 354, 354, 352, 355, 356, 355, 355, 355, - 205, 205, 355, 355, 355, 355, 355, 355, - - 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 367, 367, 367, 367, 367, - 367, 367, 367, 367, 368, 205, 355, 205, - 355, 369, 370, 371, 370, 371, 372, 372, - - 348, 348, 348, 348, 348, 348, 348, 348, - 160, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 348, 348, 348, 348, 348, 348, - - 348, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 335, 160, 160, 160, 160, 160, - 160, 373, 374, 375, 376, 375, 375, 375, - 375, 375, 374, 374, 374, 374, 375, 377, - - 374, 375, 206, 206, 378, 353, 206, 206, - 348, 348, 348, 348, 160, 160, 160, 160, - 375, 375, 375, 375, 375, 375, 284, 375, - 160, 375, 375, 375, 375, 375, 375, 375, - - 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 375, 375, 284, 284, - 284, 375, 375, 375, 375, 375, 375, 375, - 284, 375, 284, 284, 284, 160, 379, 379, - - 380, 380, 380, 380, 380, 380, 147, 380, - 380, 380, 380, 380, 380, 160, 160, 380, - 381, 381, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 382, 382, - - 382, 382, 160, 382, 382, 382, 382, 382, - 160, 382, 382, 160, 383, 384, 384, 384, - 384, 383, 384, 160, 160, 160, 384, 385, - 383, 386, 160, 160, 160, 160, 160, 160, - - 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 397, 338, 338, 338, 338, - 382, 382, 382, 382, 382, 382, 383, 383, - 384, 384, 160, 160, 160, 160, 160, 160, - - 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, - - 398, 398, 398, 398, 398, 398, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 399, - 399, 322, 322, 198, 400, 160, 160, 160, - - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 160, 160, 160, 160, 160, 401, - - 402, 402, 402, 402, 402, 402, 402, 402, - 402, 402, 402, 402, 402, 402, 402, 402, - 402, 402, 402, 402, 402, 402, 402, 402, - 402, 402, 402, 402, 402, 402, 402, 402, - - 402, 402, 402, 160, 160, 160, 160, 160, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 160, 160, 160, 160, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 160, - 335, 160, 335, 335, 335, 335, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 160, - - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 335, 335, 335, 335, 335, 335, 160, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 322, - - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 160, 160, 160, 160, 153, - - 404, 405, 406, 338, 338, 338, 338, 406, - 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 416, 416, 416, 416, 416, - 416, 416, 416, 416, 416, 160, 160, 160, - - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 160, 160, 160, 160, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 338, 406, 335, - 335, 335, 335, 335, 335, 335, 335, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 418, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 419, 420, 160, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 405, 405, 405, 421, 421, - 421, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 399, 399, 399, 160, 399, 399, - 399, 399, 422, 422, 423, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 422, 422, 423, 424, 424, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 422, 422, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 399, 399, 399, 160, 399, 399, - 399, 160, 422, 422, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 425, 425, 383, 384, - 384, 384, 384, 384, 384, 384, 383, 383, - - 383, 383, 383, 383, 383, 383, 384, 383, - 383, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 386, 384, 405, 405, 426, 427, - 405, 338, 405, 428, 382, 429, 160, 160, - - 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 160, 160, 160, 160, 160, 160, - 430, 430, 430, 430, 430, 430, 430, 430, - 430, 430, 160, 160, 160, 160, 160, 160, - - 431, 431, 432, 433, 432, 432, 434, 431, - 432, 433, 431, 284, 284, 284, 435, 160, - 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 160, 160, 160, 160, 160, 160, - - 335, 335, 335, 137, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 160, 160, 160, 160, 160, 160, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 436, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 160, 160, 160, - - 325, 325, 325, 326, 326, 326, 326, 325, - 325, 437, 437, 437, 160, 160, 160, 160, - 326, 326, 325, 326, 326, 326, 326, 326, - 326, 438, 149, 150, 160, 160, 160, 160, - - 238, 160, 160, 160, 439, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, - 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 450, 450, 450, 450, 450, 450, - - 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 450, 450, 450, 450, 160, 160, - 450, 450, 450, 450, 450, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 451, 451, 451, 451, 451, 451, 451, 451, - 451, 451, 451, 451, 451, 451, 451, 451, - 451, 451, 451, 451, 451, 451, 451, 451, - 451, 451, 451, 451, 451, 451, 451, 451, - - 451, 451, 451, 451, 451, 451, 451, 451, - 451, 451, 160, 160, 160, 160, 160, 160, - 452, 452, 452, 452, 452, 452, 452, 452, - 452, 452, 452, 452, 452, 452, 452, 452, - - 452, 451, 451, 451, 451, 451, 451, 451, - 452, 452, 160, 160, 160, 160, 160, 160, - 328, 453, 454, 455, 456, 457, 458, 459, - 460, 461, 160, 160, 160, 160, 462, 462, - - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 153, - 152, 463, 463, 463, 160, 160, 464, 465, - - 333, 333, 333, 333, 466, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 467, 466, 333, 333, - 333, 333, 333, 466, 333, 466, 466, 466, - - 466, 466, 333, 466, 468, 321, 321, 321, - 321, 321, 321, 321, 160, 160, 160, 160, - 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 479, 480, 480, 479, 479, - - 480, 481, 481, 481, 481, 481, 481, 481, - 481, 481, 481, 297, 298, 297, 297, 297, - 297, 297, 297, 297, 481, 481, 481, 481, - 481, 481, 481, 481, 481, 160, 160, 160, - - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - - 482, 482, 482, 482, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - - 482, 482, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, - 483, 103, 103, 103, 103, 484, 103, 103, - - 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 483, 483, 483, 483, 483, - - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - - 153, 153, 152, 153, 297, 297, 297, 297, - 297, 297, 298, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 297, 298, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 485, 486, - 487, 488, 489, 490, 160, 160, 160, 160, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 160, 160, 160, 160, 160, 160, - - 491, 491, 491, 491, 491, 491, 491, 491, - 492, 492, 492, 492, 492, 492, 492, 492, - 491, 491, 491, 491, 491, 491, 160, 160, - 492, 492, 492, 492, 492, 492, 160, 160, - - 491, 491, 491, 491, 491, 491, 491, 491, - 492, 492, 492, 492, 492, 492, 492, 492, - 491, 491, 491, 491, 491, 491, 491, 491, - 492, 492, 492, 492, 492, 492, 492, 492, - - 491, 491, 491, 491, 491, 491, 160, 160, - 492, 492, 492, 492, 492, 492, 160, 160, - 493, 491, 494, 491, 495, 491, 496, 491, - 160, 492, 160, 492, 160, 492, 160, 492, - - 491, 491, 491, 491, 491, 491, 491, 491, - 492, 492, 492, 492, 492, 492, 492, 492, - 497, 497, 498, 498, 498, 498, 499, 499, - 500, 500, 501, 501, 502, 502, 160, 160, - - 503, 504, 505, 506, 507, 508, 509, 510, - 511, 512, 513, 514, 515, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 529, 530, 531, 532, 533, 534, - - 535, 536, 537, 538, 539, 540, 541, 542, - 543, 544, 545, 546, 547, 548, 549, 550, - 491, 491, 551, 552, 553, 160, 554, 555, - 492, 492, 556, 556, 557, 42, 558, 42, - - 42, 42, 559, 560, 561, 160, 562, 563, - 564, 564, 564, 564, 565, 42, 42, 42, - 491, 491, 566, 567, 160, 160, 568, 569, - 492, 492, 570, 570, 160, 42, 42, 42, - - 491, 491, 571, 572, 573, 182, 574, 575, - 492, 492, 576, 576, 577, 42, 42, 42, - 160, 160, 578, 579, 580, 160, 581, 582, - 583, 583, 584, 584, 585, 42, 42, 160, - - 586, 586, 586, 586, 586, 586, 586, 587, - 586, 586, 586, 588, 589, 590, 591, 592, - 593, 594, 593, 593, 595, 596, 14, 14, - 597, 598, 599, 600, 597, 601, 599, 600, - - 14, 14, 14, 14, 602, 602, 602, 603, - 604, 605, 606, 607, 608, 609, 610, 611, - 13, 13, 13, 13, 13, 612, 612, 612, - 14, 597, 601, 14, 613, 613, 14, 43, - - 43, 14, 14, 14, 614, 16, 17, 615, - 616, 616, 431, 431, 431, 431, 617, 617, - 617, 617, 185, 618, 619, 620, 621, 617, - 621, 621, 621, 621, 620, 621, 621, 622, - - 623, 624, 624, 624, 160, 160, 160, 160, - 160, 160, 625, 625, 625, 625, 625, 625, - 626, 627, 160, 160, 628, 629, 630, 631, - 632, 633, 634, 634, 36, 16, 17, 50, - - 626, 60, 55, 56, 628, 629, 630, 631, - 632, 633, 634, 634, 36, 16, 17, 160, - 483, 483, 483, 483, 483, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 12, 12, 12, 12, 12, 12, 12, 48, - 12, 12, 12, 635, 636, 428, 428, 428, - 637, 637, 638, 638, 638, 638, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 139, 139, 144, 144, 139, 139, 139, 139, - 144, 144, 144, 139, 139, 272, 272, 272, - - 272, 139, 194, 194, 639, 640, 640, 159, - 641, 159, 640, 642, 298, 298, 298, 298, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 49, 49, 175, 643, 49, 49, 49, 175, - 49, 643, 50, 175, 175, 175, 50, 50, - 175, 175, 175, 50, 49, 175, 644, 49, - 49, 175, 175, 175, 175, 175, 49, 49, - - 49, 49, 49, 49, 175, 49, 645, 49, - 175, 49, 646, 647, 175, 175, 648, 50, - 175, 175, 649, 175, 50, 90, 90, 90, - 90, 131, 650, 238, 103, 627, 651, 651, - - 185, 185, 185, 185, 185, 651, 627, 627, - 627, 627, 652, 185, 417, 300, 653, 160, - 160, 160, 160, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - - 654, 654, 654, 654, 654, 654, 654, 654, - 654, 654, 654, 654, 654, 654, 654, 654, - 655, 655, 655, 655, 655, 655, 655, 655, - 655, 655, 655, 655, 655, 655, 655, 655, - - 656, 656, 656, 99, 109, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 36, 36, 36, 36, 36, 49, 49, 49, - 49, 49, 36, 36, 49, 49, 49, 49, - - 36, 49, 49, 36, 49, 49, 36, 49, - 49, 49, 49, 49, 49, 49, 36, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 36, 36, - 49, 49, 36, 49, 36, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - - 36, 36, 36, 36, 36, 36, 36, 36, - 657, 657, 657, 658, 658, 658, 36, 36, - 36, 36, 18, 54, 36, 659, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 660, 661, 36, 36, - - 36, 36, 36, 662, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 660, 661, 660, 661, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - - 36, 36, 36, 36, 660, 661, 660, 661, - 660, 661, 660, 661, 36, 36, 660, 661, - 660, 661, 660, 661, 660, 661, 660, 661, - 660, 661, 660, 661, 660, 661, 660, 661, - - 660, 661, 660, 661, 660, 661, 660, 661, - 660, 661, 660, 661, 36, 36, 36, 660, - 661, 660, 661, 36, 36, 36, 36, 36, - 663, 36, 36, 36, 36, 36, 36, 36, - - 36, 36, 660, 661, 36, 36, 664, 36, - 665, 666, 36, 666, 36, 36, 36, 36, - 660, 661, 660, 661, 660, 661, 660, 661, - 36, 36, 36, 36, 36, 36, 36, 36, - - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 660, 661, 660, 661, 667, 36, 36, - 660, 661, 36, 36, 36, 36, 660, 661, - 660, 661, 660, 661, 660, 661, 660, 661, - - 660, 661, 660, 661, 660, 661, 660, 661, - 660, 661, 660, 661, 660, 661, 36, 36, - 660, 661, 668, 668, 668, 185, 669, 669, - 185, 185, 670, 670, 670, 671, 671, 185, - - 49, 650, 49, 49, 49, 49, 49, 49, - 660, 661, 660, 661, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 36, 36, 49, 49, 49, 49, 49, 49, - 49, 16, 17, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 650, 185, 650, 650, 650, - - 650, 650, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 380, 650, 650, - 650, 650, 650, 185, 185, 185, 185, 185, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 652, 652, 652, 652, - 652, 652, 652, 652, 652, 652, 652, 652, - - 652, 652, 652, 652, 652, 652, 652, 652, - 652, 652, 652, 652, 652, 652, 652, 238, - 238, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 672, 672, 672, 672, - - 672, 672, 300, 300, 300, 300, 300, 300, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 650, 650, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 673, 674, 675, 676, 677, 678, 679, 680, - 681, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 673, 674, 675, 676, - 677, 678, 679, 680, 681, 62, 62, 62, - - 62, 62, 62, 62, 62, 62, 62, 62, - 60, 55, 56, 628, 629, 630, 631, 632, - 633, 682, 682, 682, 682, 682, 682, 682, - 682, 682, 682, 682, 193, 193, 193, 193, - - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 683, 683, - 683, 683, 683, 683, 683, 683, 683, 683, - - 683, 683, 683, 683, 683, 683, 683, 683, - 683, 683, 683, 683, 683, 683, 683, 683, - 684, 684, 684, 684, 684, 684, 684, 684, - 684, 684, 684, 684, 684, 684, 684, 684, - - 684, 684, 684, 684, 684, 684, 684, 684, - 684, 684, 685, 686, 686, 686, 686, 686, - 686, 686, 686, 686, 686, 687, 688, 689, - 690, 691, 692, 693, 694, 695, 686, 696, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 652, 652, - 652, 652, 652, 652, 652, 652, 652, 652, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 36, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 36, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 650, 650, 650, 650, 650, 650, 650, 650, - 185, 185, 185, 185, 185, 185, 185, 185, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 238, 238, 652, 652, - 417, 650, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 36, - 650, 650, 652, 652, 652, 652, 652, 652, - 652, 652, 652, 652, 652, 652, 417, 417, - - 652, 652, 652, 652, 652, 652, 652, 652, - 652, 652, 238, 238, 238, 238, 238, 238, - 238, 238, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 160, 160, 160, - - 238, 238, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 404, 417, 417, 417, - 417, 417, 300, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 49, 49, 49, 49, 160, 49, 49, - 49, 49, 160, 160, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 160, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 160, 49, 160, 49, - 49, 49, 49, 160, 160, 160, 49, 160, - 49, 49, 49, 697, 697, 697, 697, 160, - - 160, 49, 698, 698, 49, 49, 49, 49, - 699, 700, 699, 700, 699, 700, 699, 700, - 699, 700, 699, 700, 699, 700, 673, 674, - 675, 676, 677, 678, 679, 680, 681, 62, - - 673, 674, 675, 676, 677, 678, 679, 680, - 681, 62, 673, 674, 675, 676, 677, 678, - 679, 680, 681, 62, 49, 160, 160, 160, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 160, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 160, - - 701, 701, 701, 702, 703, 704, 705, 672, - 672, 672, 672, 160, 160, 160, 160, 160, - 185, 185, 185, 185, 185, 706, 707, 185, - 185, 185, 185, 185, 185, 706, 707, 185, - - 185, 185, 706, 707, 706, 707, 699, 700, - 699, 700, 699, 700, 160, 160, 160, 160, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - - 185, 185, 185, 699, 700, 699, 700, 699, - 700, 699, 700, 699, 700, 708, 709, 710, - 711, 699, 700, 699, 700, 699, 700, 699, - 700, 185, 185, 185, 185, 185, 185, 185, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 712, 185, 185, 185, 185, 185, 185, 185, - - 706, 707, 185, 185, 706, 707, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 706, - 707, 706, 707, 185, 706, 707, 185, 185, - 699, 700, 699, 700, 185, 185, 185, 185, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 713, 185, 185, - 706, 707, 185, 185, 699, 700, 185, 185, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 706, 707, 706, 707, 185, - 185, 185, 185, 185, 706, 707, 185, 185, - 185, 185, 185, 185, 706, 707, 185, 185, - - 185, 185, 185, 185, 706, 707, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 706, 707, 185, 185, 706, 707, 706, - - 707, 706, 707, 706, 707, 185, 185, 185, - 185, 185, 185, 706, 707, 185, 185, 185, - 185, 706, 707, 706, 707, 706, 707, 706, - 707, 706, 707, 706, 707, 185, 185, 185, - - 185, 706, 707, 185, 185, 185, 706, 707, - 706, 707, 706, 707, 706, 707, 185, 706, - 707, 185, 185, 706, 707, 185, 185, 185, - 185, 185, 185, 706, 707, 706, 707, 706, - - 707, 706, 707, 706, 707, 706, 707, 185, - 185, 185, 185, 185, 185, 706, 707, 706, - 707, 706, 707, 706, 707, 706, 707, 185, - 185, 185, 185, 185, 185, 185, 714, 185, - - 185, 185, 185, 715, 716, 715, 185, 185, - 185, 185, 185, 185, 706, 707, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 706, - 707, 706, 707, 185, 185, 185, 185, 185, - - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 417, 417, - 417, 417, 417, 417, 300, 300, 300, 300, - 300, 300, 300, 160, 160, 160, 160, 160, - - 300, 300, 300, 300, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 717, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 717, 717, 717, 717, 717, - - 717, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 717, 717, 717, 717, 160, - 718, 718, 718, 718, 718, 718, 718, 718, - 718, 718, 718, 718, 718, 718, 718, 718, - - 718, 718, 718, 718, 718, 718, 718, 718, - 718, 718, 718, 718, 718, 718, 718, 718, - 718, 718, 718, 718, 718, 718, 718, 718, - 718, 718, 718, 718, 718, 718, 718, 160, - - 113, 109, 719, 720, 721, 722, 723, 113, - 109, 113, 109, 113, 109, 160, 160, 160, - 160, 160, 160, 160, 724, 113, 109, 724, - 160, 160, 160, 160, 160, 160, 160, 160, - - 105, 106, 105, 106, 105, 106, 105, 106, - 105, 106, 105, 106, 105, 106, 105, 106, - 105, 106, 105, 106, 105, 106, 105, 106, - 105, 106, 105, 106, 105, 106, 105, 106, - - 105, 106, 105, 106, 103, 417, 417, 417, - 417, 417, 417, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 621, 621, 621, 621, 725, 621, 621, - - 726, 726, 726, 726, 726, 726, 726, 726, - 726, 726, 726, 726, 726, 726, 726, 726, - 726, 726, 726, 726, 726, 726, 726, 726, - 726, 726, 726, 726, 726, 726, 726, 726, - - 726, 726, 726, 726, 726, 726, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - - 322, 322, 322, 322, 322, 322, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 400, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 322, 322, 322, 322, 322, 322, 322, 160, - 322, 322, 322, 322, 322, 322, 322, 160, - 322, 322, 322, 322, 322, 322, 322, 160, - 322, 322, 322, 322, 322, 322, 322, 160, - - 727, 727, 728, 729, 728, 729, 727, 727, - 727, 728, 729, 727, 728, 729, 621, 621, - 621, 621, 621, 621, 621, 621, 620, 730, - 160, 160, 160, 160, 728, 729, 160, 160, - - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 160, 731, 731, 731, 731, 731, - - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 160, 160, 160, 160, - - 732, 733, 734, 735, 736, 737, 738, 739, - 16, 17, 16, 17, 16, 17, 16, 17, - 16, 17, 736, 736, 16, 17, 16, 17, - 16, 17, 16, 17, 740, 16, 17, 741, - - 736, 739, 739, 739, 739, 739, 739, 739, - 739, 739, 742, 743, 140, 744, 745, 745, - 746, 747, 747, 747, 747, 747, 736, 736, - 748, 748, 748, 749, 750, 751, 731, 736, - - 160, 752, 738, 752, 738, 752, 738, 752, - 738, 752, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - - 738, 738, 738, 752, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - - 738, 738, 738, 752, 738, 752, 738, 752, - 738, 738, 738, 738, 738, 738, 752, 738, - 738, 738, 738, 738, 738, 753, 753, 160, - 160, 754, 754, 755, 755, 756, 756, 757, - - 758, 759, 760, 759, 760, 759, 760, 759, - 760, 759, 760, 760, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - - 760, 760, 760, 759, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - - 760, 760, 760, 759, 760, 759, 760, 759, - 760, 760, 760, 760, 760, 760, 759, 760, - 760, 760, 760, 760, 760, 759, 759, 760, - 760, 760, 760, 761, 762, 762, 762, 763, - - 160, 160, 160, 160, 160, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 160, 160, 160, - 160, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 160, - 765, 765, 766, 766, 766, 766, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 160, 160, 160, 160, 160, 160, 160, 160, - - 768, 768, 768, 768, 768, 768, 768, 768, - 768, 768, 768, 768, 768, 768, 768, 768, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 769, 769, 769, 769, 769, 769, 769, 769, - 769, 769, 769, 769, 769, 769, 769, 769, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 770, 770, 160, - - 766, 766, 766, 766, 766, 766, 766, 766, - 766, 766, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - - 765, 765, 765, 765, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 770, 771, 771, 771, 771, 771, 771, 771, - 771, 771, 771, 771, 771, 771, 771, 771, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 770, 770, 768, 765, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 771, 771, 771, 771, 771, 771, 771, - 771, 771, 771, 771, 771, 771, 771, 771, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 770, 770, 770, 770, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 160, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 770, - 770, 770, 770, 765, 765, 765, 765, 765, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 770, 770, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 770, - - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - - 738, 738, 738, 738, 738, 738, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 160, 160, 160, 160, - - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 774, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 160, 160, 160, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - - 731, 731, 775, 775, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 775, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - - 731, 775, 731, 731, 731, 775, 731, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 776, 776, 776, 776, 776, 776, 776, 776, - 776, 776, 776, 776, 776, 776, 776, 776, - 776, 776, 776, 776, 776, 776, 776, 777, - 777, 777, 777, 160, 160, 160, 160, 160, - - 778, 778, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 322, 322, 779, 322, 322, 322, 780, 322, - 322, 322, 322, 781, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - - 322, 322, 322, 463, 463, 781, 781, 463, - 417, 417, 417, 417, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 782, 782, 303, 303, - 160, 160, 160, 160, 160, 160, 160, 160, - - 783, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 783, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 783, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 783, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 783, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 783, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 783, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 783, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 785, 785, 785, 785, 785, 785, 785, 785, - 785, 785, 785, 785, 785, 785, 785, 785, - 785, 785, 785, 785, 785, 785, 785, 785, - 785, 785, 785, 785, 785, 785, 785, 785, - - 786, 786, 786, 786, 786, 786, 786, 786, - 786, 786, 786, 786, 786, 786, 786, 786, - 786, 786, 786, 786, 786, 786, 786, 786, - 786, 786, 786, 786, 786, 786, 786, 786, - - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 160, 160, - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 787, 787, 787, - - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 787, 787, 787, - - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 160, 160, 160, 160, 160, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 160, 160, 160, 160, 160, 160, - - 788, 789, 790, 791, 792, 793, 794, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 795, 796, 797, 798, 799, - 160, 160, 160, 160, 160, 800, 801, 230, - - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 634, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 204, - 230, 230, 230, 230, 230, 204, 230, 204, - - 230, 230, 204, 230, 230, 204, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 230, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 599, 741, - - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 234, 234, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 234, 234, 234, 234, 234, 234, 234, 234, - 802, 802, 802, 802, 802, 802, 802, 802, - 802, 802, 802, 802, 802, 802, 802, 802, - - 802, 802, 802, 802, 802, 802, 802, 802, - 802, 802, 802, 802, 802, 802, 802, 802, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 803, 238, 234, 234, - - 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, - 804, 805, 805, 804, 804, 806, 806, 807, - 808, 809, 160, 160, 160, 160, 160, 160, - - 139, 139, 139, 139, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 735, 746, 746, 810, 810, 599, 741, 599, - 741, 599, 741, 599, 741, 599, 741, 599, - - 741, 599, 741, 599, 741, 751, 751, 811, - 812, 735, 735, 735, 735, 810, 810, 810, - 813, 735, 814, 160, 761, 815, 9, 9, - 746, 16, 17, 16, 17, 16, 17, 816, - - 735, 735, 817, 818, 819, 820, 821, 160, - 735, 12, 13, 735, 160, 160, 160, 160, - 242, 242, 242, 285, 242, 234, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 234, 234, 822, - - 160, 9, 735, 816, 12, 13, 735, 735, - 16, 17, 735, 817, 813, 818, 814, 823, - 824, 825, 826, 827, 828, 829, 830, 831, - 832, 833, 815, 761, 834, 821, 835, 9, - - 735, 836, 836, 836, 836, 836, 836, 836, - 836, 836, 836, 836, 836, 836, 836, 836, - 836, 836, 836, 836, 836, 836, 836, 836, - 836, 836, 836, 39, 735, 41, 837, 810, - - 837, 838, 838, 838, 838, 838, 838, 838, - 838, 838, 838, 838, 838, 838, 838, 838, - 838, 838, 838, 838, 838, 838, 838, 838, - 838, 838, 838, 39, 821, 41, 821, 699, - - 700, 734, 16, 17, 733, 761, 839, 759, - 759, 759, 759, 759, 759, 759, 759, 759, - 762, 839, 839, 839, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 839, 839, - - 839, 839, 839, 839, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 762, 762, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 160, - - 160, 160, 90, 90, 90, 90, 90, 90, - 160, 160, 90, 90, 90, 90, 90, 90, - 160, 160, 90, 90, 90, 90, 90, 90, - 160, 160, 90, 90, 90, 160, 160, 160, - - 48, 12, 821, 837, 736, 12, 12, 160, - 49, 36, 36, 36, 36, 49, 49, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 840, 840, 840, 841, 49, 842, 842, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 160, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - - 307, 307, 307, 307, 307, 307, 307, 160, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 160, 307, 307, 160, 307, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 160, 160, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 160, 160, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 160, 160, 160, 160, 160, - - 843, 844, 845, 160, 160, 160, 160, 846, - 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, - - 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 160, 160, 160, 847, - 847, 847, 847, 847, 847, 847, 847, 847, - - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 848, 848, 848, - - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 725, 725, 725, - 725, 417, 417, 417, 417, 417, 417, 417, - - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 725, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 160, - - 850, 850, 850, 850, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, - - 849, 851, 849, 849, 849, 849, 849, 849, - 849, 849, 851, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 160, 843, - - 322, 322, 322, 322, 160, 160, 160, 160, - 322, 322, 322, 322, 322, 322, 322, 322, - 464, 852, 852, 852, 852, 852, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 853, 853, 853, 853, 853, 853, 853, 853, - 853, 853, 853, 853, 853, 853, 853, 853, - 853, 853, 853, 853, 853, 853, 853, 853, - 853, 853, 853, 853, 853, 853, 853, 853, - - 853, 853, 853, 853, 853, 853, 854, 854, - 855, 855, 855, 855, 855, 855, 855, 855, - 855, 855, 855, 855, 855, 855, 855, 855, - 855, 855, 855, 855, 855, 855, 855, 855, - - 855, 855, 855, 855, 855, 855, 855, 855, - 855, 855, 855, 855, 855, 855, 856, 856, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 160, 160, - - 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 857, 857, 857, 857, 857, 857, 204, 204, - 857, 204, 857, 857, 857, 857, 857, 857, - 857, 857, 857, 857, 857, 857, 857, 857, - 857, 857, 857, 857, 857, 857, 857, 857, - - 857, 857, 857, 857, 857, 857, 857, 857, - 857, 857, 857, 857, 857, 857, 857, 857, - 857, 857, 857, 857, 857, 857, 204, 857, - 857, 204, 204, 204, 857, 204, 204, 857, - - 858, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 858, 858, 859, 859, - 859, 859, 204, 204, 204, 204, 204, 860, - - 861, 781, 781, 781, 204, 781, 781, 204, - 204, 204, 204, 204, 781, 152, 781, 153, - 861, 861, 861, 861, 204, 861, 861, 861, - 204, 861, 861, 861, 861, 861, 861, 861, - - 861, 861, 861, 861, 861, 861, 861, 861, - 861, 861, 861, 861, 861, 861, 861, 861, - 861, 861, 861, 861, 204, 204, 204, 204, - 153, 642, 152, 204, 204, 204, 204, 780, - - 862, 863, 864, 865, 866, 866, 866, 866, - 204, 204, 204, 204, 204, 204, 204, 204, - 867, 867, 867, 867, 867, 867, 867, 867, - 868, 204, 204, 204, 204, 204, 204, 204, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 480, 480, 480, 480, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 160, - 160, 160, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 871, 872, 873, - 873, 873, 870, 870, 870, 874, 871, 871, - 871, 871, 871, 875, 875, 875, 875, 875, - 875, 875, 875, 876, 876, 876, 876, 876, - 876, 876, 876, 870, 870, 877, 877, 877, - 877, 877, 876, 876, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 877, 877, 877, 877, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 153, 153, 153, 417, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 878, 878, 878, 878, 878, 878, 878, 878, - 878, 878, 878, 878, 878, 878, 878, 878, - 878, 878, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 880, 880, 880, 160, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 160, 879, 879, - 160, 160, 879, 160, 160, 879, 879, 160, - 160, 879, 879, 879, 879, 160, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 160, 880, 160, 880, 880, 880, - 880, 102, 880, 880, 160, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - - 880, 880, 880, 880, 879, 879, 160, 879, - 879, 879, 879, 160, 160, 879, 879, 879, - 879, 879, 879, 879, 879, 160, 879, 879, - 879, 879, 879, 879, 879, 160, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 160, 879, 879, 879, 879, 160, - 879, 879, 879, 879, 879, 160, 879, 160, - 160, 160, 879, 879, 879, 879, 879, 879, - 879, 160, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 103, 103, 160, 160, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 881, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 881, 880, 880, 880, 880, - 880, 880, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 881, 880, 880, 880, 880, - - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 881, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 881, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 881, - 880, 880, 880, 880, 880, 880, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 881, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 881, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 881, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 881, 880, 880, 880, 880, - 880, 880, 882, 724, 160, 160, 883, 884, - 885, 886, 887, 888, 889, 890, 891, 892, - 883, 884, 885, 886, 887, 888, 889, 890, - 891, 892, 883, 884, 885, 886, 887, 888, - 889, 890, 891, 892, 883, 884, 885, 886, - 887, 888, 889, 890, 891, 892, 883, 884, - 885, 886, 887, 888, 889, 890, 891, 892, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 893, 893, - - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 875, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 893, 893, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18608, 18608, 18608, 18864, 19120, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 19376, 19632, 19888, 20144, 20400, 20656, 20912, 21168, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21936, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 21680, 21680, 22192, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 22448, 22704, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216, + + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 7, + + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 14, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 9, + + 14, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 39, 40, 41, 42, 43, + + 42, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 39, 45, 41, 36, 0, + + 0, 0, 0, 0, 0, 46, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 47, 14, 48, 12, 12, 12, 49, 49, + 42, 49, 50, 51, 36, 52, 49, 42, + 53, 54, 55, 56, 57, 58, 49, 59, + 42, 60, 50, 61, 62, 62, 62, 14, + + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 36, + 38, 38, 38, 38, 38, 38, 38, 63, + + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 36, + 44, 44, 44, 44, 44, 44, 44, 64, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 67, 68, 65, 66, 65, 66, 65, 66, + 50, 65, 66, 65, 66, 65, 66, 65, + + 66, 65, 66, 65, 66, 65, 66, 65, + 66, 69, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 70, 65, 66, 65, 66, 65, 66, 71, + + 72, 73, 65, 66, 65, 66, 74, 65, + 66, 75, 75, 65, 66, 50, 76, 77, + 78, 65, 66, 75, 79, 80, 81, 82, + 65, 66, 83, 50, 81, 84, 85, 86, + + 65, 66, 65, 66, 65, 66, 87, 65, + 66, 87, 50, 50, 65, 66, 87, 65, + 66, 88, 88, 65, 66, 65, 66, 89, + 65, 66, 50, 90, 65, 66, 50, 91, + + 90, 90, 90, 90, 92, 93, 94, 92, + 93, 94, 92, 93, 94, 65, 66, 65, + 66, 65, 66, 65, 66, 65, 66, 65, + 66, 65, 66, 65, 66, 95, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 96, 92, 93, 94, 65, 66, 97, 98, + 99, 100, 65, 66, 65, 66, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 99, 100, 99, 100, 99, 100, 99, 100, + + 101, 102, 99, 100, 99, 100, 99, 100, + 99, 100, 99, 100, 99, 100, 99, 100, + 99, 100, 99, 100, 102, 102, 102, 103, + 103, 103, 104, 105, 106, 107, 108, 103, + + 103, 105, 109, 110, 111, 112, 113, 109, + 113, 109, 113, 109, 113, 109, 113, 109, + 50, 50, 50, 114, 115, 50, 116, 116, + 50, 117, 50, 118, 50, 50, 50, 50, + + 116, 50, 50, 119, 50, 50, 50, 50, + 120, 121, 50, 122, 50, 50, 50, 121, + 50, 50, 123, 50, 50, 124, 50, 50, + 50, 50, 50, 50, 50, 125, 50, 50, + + 126, 50, 50, 126, 50, 50, 50, 50, + 126, 127, 128, 128, 129, 50, 50, 50, + 50, 50, 130, 50, 90, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 131, 131, 131, 131, 131, 102, 102, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 133, 133, 134, 134, 134, 134, 134, + + 132, 132, 42, 42, 42, 42, 133, 133, + 135, 133, 133, 133, 135, 133, 133, 133, + 134, 134, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 136, + + 132, 132, 132, 132, 132, 42, 42, 42, + 42, 42, 136, 136, 136, 136, 137, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + + 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 140, 141, 141, + 141, 141, 140, 142, 141, 141, 141, 141, + + 141, 143, 143, 141, 141, 141, 141, 143, + 143, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 144, 144, 144, 144, + 144, 141, 141, 141, 141, 139, 139, 139, + + 139, 139, 139, 139, 139, 145, 146, 147, + 147, 147, 146, 146, 146, 147, 147, 148, + 149, 149, 149, 150, 150, 150, 150, 149, + 151, 152, 152, 153, 154, 155, 155, 156, + + 157, 157, 158, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, + 160, 160, 160, 160, 42, 42, 160, 160, + 160, 160, 132, 161, 161, 161, 34, 160, + + 160, 160, 160, 160, 42, 42, 162, 14, + 163, 163, 163, 160, 164, 160, 165, 165, + 166, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + + 38, 38, 160, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 167, 168, 168, 168, + 169, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + + 44, 44, 170, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 171, 172, 172, 160, + 173, 174, 175, 175, 175, 176, 177, 131, + 178, 179, 65, 100, 65, 100, 65, 100, + + 65, 100, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 180, 181, 182, 50, 183, 184, 185, 186, + 187, 188, 186, 187, 103, 189, 189, 189, + + 190, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 190, 191, 191, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 192, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 192, 193, 193, + + 65, 66, 194, 139, 139, 139, 139, 160, + 195, 195, 178, 179, 99, 100, 99, 100, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + + 196, 65, 66, 65, 66, 178, 179, 65, + 66, 178, 179, 65, 66, 178, 179, 197, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 99, 100, 65, 66, + 65, 66, 65, 66, 65, 66, 105, 106, + 65, 66, 113, 109, 113, 109, 113, 109, + + 178, 179, 178, 179, 178, 179, 178, 179, + 178, 179, 178, 179, 178, 179, 178, 179, + 113, 109, 113, 109, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 160, + 160, 134, 199, 199, 200, 199, 200, 199, + + 160, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + + 201, 201, 201, 201, 201, 201, 201, 202, + 160, 203, 204, 160, 160, 160, 160, 160, + 205, 206, 207, 207, 207, 207, 206, 207, + 207, 207, 208, 206, 207, 207, 207, 207, + + 207, 207, 152, 206, 206, 206, 206, 206, + 207, 207, 206, 207, 207, 208, 209, 207, + 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, + + 226, 227, 228, 226, 207, 152, 229, 230, + 205, 205, 205, 205, 205, 205, 205, 205, + 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, + + 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 205, 205, 205, 205, 205, + 231, 231, 231, 232, 233, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, + + 234, 234, 234, 234, 235, 235, 235, 235, + 235, 235, 235, 236, 237, 238, 239, 239, + 149, 149, 149, 149, 149, 149, 235, 235, + 235, 235, 235, 240, 235, 235, 241, 242, + + 235, 243, 244, 244, 244, 244, 245, 244, + 245, 244, 245, 245, 245, 245, 245, 244, + 244, 244, 244, 245, 245, 245, 245, 245, + 245, 245, 245, 235, 235, 235, 235, 235, + + 246, 245, 245, 245, 245, 245, 245, 245, + 244, 245, 245, 247, 248, 249, 250, 251, + 252, 253, 254, 146, 146, 147, 150, 149, + 149, 153, 153, 153, 152, 153, 153, 235, + + 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 266, 267, 268, 268, + 269, 244, 244, 244, 243, 244, 244, 244, + 245, 245, 245, 245, 245, 245, 245, 245, + + 245, 245, 245, 245, 245, 245, 245, 245, + 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 245, 245, 245, 245, 245, 245, + + 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, + 270, 270, 245, 245, 245, 245, 245, 270, + + 244, 245, 245, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 245, 244, 245, 271, + 245, 245, 244, 244, 242, 244, 139, 139, + 139, 139, 139, 139, 139, 272, 273, 139, + + 139, 139, 139, 141, 139, 274, 274, 139, + 139, 49, 141, 139, 139, 141, 275, 275, + 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 270, 270, 270, 276, 276, 277, + + 278, 278, 278, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 235, 280, + 271, 281, 270, 270, 270, 271, 271, 271, + 271, 271, 270, 270, 270, 270, 271, 270, + + 270, 270, 270, 270, 270, 270, 270, 270, + 271, 270, 271, 270, 271, 277, 277, 275, + 146, 147, 146, 146, 147, 146, 146, 147, + 147, 147, 146, 147, 147, 146, 147, 146, + + 146, 146, 147, 146, 147, 146, 147, 146, + 147, 146, 146, 235, 235, 275, 277, 277, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 283, 283, 283, 282, 282, 282, 282, + + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 283, 283, 282, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + + 284, 284, 284, 284, 284, 284, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, + 285, 286, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + + 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 297, 297, 297, 297, 297, + 297, 297, 297, 297, 297, 297, 297, 297, + 297, 297, 297, 297, 297, 297, 297, 297, + + 297, 297, 297, 297, 297, 297, 297, 297, + 297, 297, 297, 298, 298, 298, 298, 298, + 298, 298, 299, 298, 300, 300, 301, 302, + 303, 304, 305, 205, 205, 205, 205, 205, + + 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, + + 160, 306, 306, 307, 308, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 160, 160, 309, 90, 307, 307, + + 307, 306, 306, 306, 306, 306, 306, 306, + 306, 307, 307, 307, 307, 310, 160, 160, + 90, 139, 141, 139, 139, 160, 160, 160, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 306, 306, 311, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 199, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 322, 322, 323, 322, 322, + + 160, 306, 307, 307, 160, 90, 90, 90, + 90, 90, 90, 90, 90, 160, 160, 90, + 90, 160, 160, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 160, 160, 160, 90, 90, + 90, 90, 160, 160, 309, 308, 324, 307, + + 307, 306, 306, 306, 306, 160, 160, 307, + 307, 160, 160, 307, 307, 310, 323, 160, + 160, 160, 160, 160, 160, 160, 160, 324, + 160, 160, 160, 160, 90, 90, 160, 90, + + 90, 90, 306, 306, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 90, 90, 12, 12, 325, 325, 325, 325, + 325, 325, 194, 160, 160, 160, 160, 160, + + 160, 326, 306, 327, 160, 90, 90, 90, + 90, 90, 90, 160, 160, 160, 160, 90, + 90, 160, 160, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 160, 90, 90, 160, + 90, 90, 160, 160, 309, 160, 307, 307, + + 307, 306, 306, 160, 160, 160, 160, 306, + 306, 160, 160, 306, 306, 310, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 90, 90, 90, 90, 160, 90, 160, + + 160, 160, 160, 160, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 306, 306, 90, 90, 90, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 306, 306, 307, 160, 90, 90, 90, + 90, 90, 90, 90, 308, 90, 160, 90, + 90, 90, 160, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 160, 90, 90, 90, + 90, 90, 160, 160, 309, 90, 307, 307, + + 307, 306, 306, 306, 306, 306, 160, 306, + 306, 307, 160, 307, 307, 310, 160, 160, + 90, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 90, 308, 326, 326, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 160, 328, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 160, 308, 90, 90, + 90, 90, 160, 160, 309, 90, 324, 306, + + 307, 306, 306, 306, 160, 160, 160, 307, + 307, 160, 160, 307, 307, 310, 160, 160, + 160, 160, 160, 160, 160, 160, 306, 324, + 160, 160, 160, 160, 90, 90, 160, 90, + + 90, 90, 160, 160, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 194, 308, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 306, 90, 160, 90, 90, 90, + 90, 90, 90, 160, 160, 160, 90, 90, + 90, 160, 90, 90, 90, 90, 160, 160, + 160, 90, 90, 160, 90, 160, 90, 90, + + 160, 160, 160, 90, 90, 160, 160, 160, + 90, 90, 90, 160, 160, 160, 90, 90, + 90, 90, 90, 90, 90, 90, 323, 90, + 90, 90, 160, 160, 160, 160, 324, 307, + + 306, 307, 307, 160, 160, 160, 307, 307, + 307, 160, 307, 307, 307, 310, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 324, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 329, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 325, 325, 325, 239, 239, 239, 239, 239, + 239, 328, 239, 160, 160, 160, 160, 160, + + 160, 307, 307, 307, 160, 90, 90, 90, + 90, 90, 90, 90, 90, 160, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 160, 90, 90, 90, + 90, 90, 160, 160, 160, 160, 306, 306, + + 306, 307, 307, 307, 307, 160, 306, 306, + 306, 160, 306, 306, 306, 310, 160, 160, + 160, 160, 160, 160, 160, 330, 331, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 90, 90, 160, 160, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 307, 307, 160, 90, 90, 90, + 90, 90, 90, 90, 90, 160, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 160, 90, 90, 90, + 90, 90, 160, 160, 332, 308, 307, 333, + + 307, 307, 324, 307, 307, 160, 333, 307, + 307, 160, 307, 307, 306, 310, 160, 160, + 160, 160, 160, 160, 160, 324, 324, 160, + 160, 160, 160, 160, 160, 160, 90, 160, + + 90, 90, 334, 334, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 160, 301, 301, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 160, 160, 160, 160, 324, 307, + + 307, 306, 306, 306, 160, 160, 307, 307, + 307, 160, 307, 307, 307, 310, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 324, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 335, 335, 160, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 160, + 160, 160, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 160, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 160, 336, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 160, + 160, 160, 337, 160, 160, 160, 160, 338, + 335, 335, 285, 285, 285, 160, 285, 160, + 335, 335, 335, 335, 335, 335, 335, 338, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 335, 335, 339, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 341, 340, 340, 341, 341, 341, 341, + 342, 342, 343, 160, 160, 160, 160, 12, + + 340, 340, 340, 340, 340, 340, 344, 341, + 345, 345, 345, 345, 341, 341, 341, 199, + 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 346, 346, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 340, 340, 160, 340, 160, 160, 340, + 340, 160, 340, 160, 160, 340, 160, 160, + 160, 160, 160, 160, 340, 340, 340, 340, + 160, 340, 340, 340, 340, 340, 340, 340, + + 160, 340, 340, 340, 160, 340, 160, 340, + 160, 160, 340, 340, 160, 340, 340, 340, + 340, 341, 340, 340, 341, 341, 341, 341, + 347, 347, 160, 341, 341, 340, 160, 160, + + 340, 340, 340, 340, 340, 160, 344, 160, + 348, 348, 348, 348, 341, 341, 160, 160, + 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 160, 160, 340, 340, 160, 160, + + 349, 350, 350, 350, 351, 352, 351, 351, + 353, 351, 351, 354, 353, 355, 355, 355, + 355, 355, 353, 356, 357, 356, 356, 356, + 206, 206, 356, 356, 356, 356, 356, 356, + + 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 369, 206, 356, 206, + 356, 370, 371, 372, 371, 372, 373, 373, + + 349, 349, 349, 349, 349, 349, 349, 349, + 160, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, + + 349, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 336, 160, 160, 160, 160, 160, + 160, 374, 375, 376, 377, 376, 376, 376, + 376, 376, 375, 375, 375, 375, 376, 378, + + 375, 376, 207, 207, 379, 354, 207, 207, + 349, 349, 349, 349, 160, 160, 160, 160, + 376, 376, 376, 376, 376, 376, 285, 376, + 160, 376, 376, 376, 376, 376, 376, 376, + + 376, 376, 376, 376, 376, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 285, 285, + 285, 376, 376, 376, 376, 376, 376, 376, + 285, 376, 285, 285, 285, 160, 380, 380, + + 381, 381, 381, 381, 381, 381, 147, 381, + 381, 381, 381, 381, 381, 160, 160, 381, + 382, 382, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, + + 383, 383, 160, 383, 383, 383, 383, 383, + 160, 383, 383, 160, 384, 385, 385, 385, + 385, 384, 385, 160, 160, 160, 385, 386, + 384, 387, 160, 160, 160, 160, 160, 160, + + 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 398, 339, 339, 339, 339, + 383, 383, 383, 383, 383, 383, 384, 384, + 385, 385, 160, 160, 160, 160, 160, 160, + + 399, 399, 399, 399, 399, 399, 399, 399, + 399, 399, 399, 399, 399, 399, 399, 399, + 399, 399, 399, 399, 399, 399, 399, 399, + 399, 399, 399, 399, 399, 399, 399, 399, + + 399, 399, 399, 399, 399, 399, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 400, + 400, 323, 323, 199, 401, 160, 160, 160, + + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 160, 160, 160, 160, 160, 402, + + 403, 403, 403, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, + + 403, 403, 403, 160, 160, 160, 160, 160, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 160, 160, 160, 160, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 160, + 336, 160, 336, 336, 336, 336, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 160, + + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 336, 336, 336, 336, 336, 336, 160, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 323, + + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 160, 160, 160, 160, 153, + + 405, 406, 407, 339, 339, 339, 339, 407, + 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 160, 160, 160, + + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 160, 160, 160, 160, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 339, 407, 336, + 336, 336, 336, 336, 336, 336, 336, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 419, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 420, 421, 160, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 406, 406, 406, 422, 422, + 422, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 160, 400, 400, + 400, 400, 423, 423, 424, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 423, 423, 424, 425, 425, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 423, 423, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 160, 400, 400, + 400, 160, 423, 423, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 426, 426, 384, 385, + 385, 385, 385, 385, 385, 385, 384, 384, + + 384, 384, 384, 384, 384, 384, 385, 384, + 384, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 387, 385, 406, 406, 427, 428, + 406, 339, 406, 429, 383, 430, 160, 160, + + 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 160, 160, 160, 160, 160, 160, + 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 160, 160, 160, 160, 160, 160, + + 432, 432, 433, 434, 433, 433, 435, 432, + 433, 434, 432, 285, 285, 285, 436, 160, + 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 160, 160, 160, 160, 160, 160, + + 336, 336, 336, 137, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 160, 160, 160, 160, 160, 160, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 437, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 160, 160, 160, + + 326, 326, 326, 327, 327, 327, 327, 326, + 326, 438, 438, 438, 160, 160, 160, 160, + 327, 327, 326, 327, 327, 327, 327, 327, + 327, 439, 149, 150, 160, 160, 160, 160, + + 239, 160, 160, 160, 440, 440, 441, 442, + 443, 444, 445, 446, 447, 448, 449, 450, + 451, 451, 451, 451, 451, 451, 451, 451, + 451, 451, 451, 451, 451, 451, 451, 451, + + 451, 451, 451, 451, 451, 451, 451, 451, + 451, 451, 451, 451, 451, 451, 160, 160, + 451, 451, 451, 451, 451, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 452, 452, 452, 452, 452, 452, 452, 452, + 452, 452, 452, 452, 452, 452, 452, 452, + 452, 452, 452, 452, 452, 452, 452, 452, + 452, 452, 452, 452, 452, 452, 452, 452, + + 452, 452, 452, 452, 452, 452, 452, 452, + 452, 452, 160, 160, 160, 160, 160, 160, + 453, 453, 453, 453, 453, 453, 453, 453, + 453, 453, 453, 453, 453, 453, 453, 453, + + 453, 452, 452, 452, 452, 452, 452, 452, + 453, 453, 160, 160, 160, 160, 160, 160, + 329, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 160, 160, 160, 160, 463, 463, + + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 153, + 152, 464, 464, 464, 160, 160, 465, 466, + + 334, 334, 334, 334, 467, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 468, 467, 334, 334, + 334, 334, 334, 467, 334, 467, 467, 467, + + 467, 467, 334, 467, 469, 322, 322, 322, + 322, 322, 322, 322, 160, 160, 160, 160, + 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 480, 481, 481, 480, 480, + + 481, 482, 482, 482, 482, 482, 482, 482, + 482, 482, 482, 298, 299, 298, 298, 298, + 298, 298, 298, 298, 482, 482, 482, 482, + 482, 482, 482, 482, 482, 160, 160, 160, + + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + + 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + + 483, 483, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 484, 103, 103, 103, 103, 485, 103, 103, + + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 484, 484, 484, 484, 484, + + 484, 484, 484, 484, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 484, + + 153, 153, 152, 153, 298, 298, 298, 298, + 298, 298, 299, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 298, 299, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 486, 487, + 488, 489, 490, 491, 160, 160, 160, 160, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 160, 160, 160, 160, 160, 160, + + 492, 492, 492, 492, 492, 492, 492, 492, + 493, 493, 493, 493, 493, 493, 493, 493, + 492, 492, 492, 492, 492, 492, 160, 160, + 493, 493, 493, 493, 493, 493, 160, 160, + + 492, 492, 492, 492, 492, 492, 492, 492, + 493, 493, 493, 493, 493, 493, 493, 493, + 492, 492, 492, 492, 492, 492, 492, 492, + 493, 493, 493, 493, 493, 493, 493, 493, + + 492, 492, 492, 492, 492, 492, 160, 160, + 493, 493, 493, 493, 493, 493, 160, 160, + 494, 492, 495, 492, 496, 492, 497, 492, + 160, 493, 160, 493, 160, 493, 160, 493, + + 492, 492, 492, 492, 492, 492, 492, 492, + 493, 493, 493, 493, 493, 493, 493, 493, + 498, 498, 499, 499, 499, 499, 500, 500, + 501, 501, 502, 502, 503, 503, 160, 160, + + 504, 505, 506, 507, 508, 509, 510, 511, + 512, 513, 514, 515, 516, 517, 518, 519, + 520, 521, 522, 523, 524, 525, 526, 527, + 528, 529, 530, 531, 532, 533, 534, 535, + + 536, 537, 538, 539, 540, 541, 542, 543, + 544, 545, 546, 547, 548, 549, 550, 551, + 492, 492, 552, 553, 554, 160, 555, 556, + 493, 493, 557, 557, 558, 42, 559, 42, + + 42, 42, 560, 561, 562, 160, 563, 564, + 565, 565, 565, 565, 566, 42, 42, 42, + 492, 492, 567, 568, 160, 160, 569, 570, + 493, 493, 571, 571, 160, 42, 42, 42, + + 492, 492, 572, 573, 574, 182, 575, 576, + 493, 493, 577, 577, 578, 42, 42, 42, + 160, 160, 579, 580, 581, 160, 582, 583, + 584, 584, 585, 585, 586, 42, 42, 160, + + 587, 587, 587, 587, 587, 587, 587, 588, + 587, 587, 587, 589, 590, 591, 592, 593, + 594, 595, 594, 594, 596, 597, 14, 14, + 598, 599, 600, 601, 598, 602, 600, 601, + + 14, 14, 14, 14, 603, 603, 603, 604, + 605, 606, 607, 608, 609, 610, 611, 612, + 13, 13, 13, 13, 13, 613, 613, 613, + 14, 598, 602, 14, 614, 614, 14, 43, + + 43, 14, 14, 14, 615, 16, 17, 616, + 617, 617, 432, 432, 432, 432, 618, 618, + 618, 618, 185, 619, 620, 621, 622, 618, + 622, 622, 622, 622, 621, 622, 622, 623, + + 624, 625, 625, 625, 160, 160, 160, 160, + 160, 160, 626, 626, 626, 626, 626, 626, + 627, 628, 160, 160, 629, 630, 631, 632, + 633, 634, 635, 635, 36, 16, 17, 50, + + 627, 60, 55, 56, 629, 630, 631, 632, + 633, 634, 635, 635, 36, 16, 17, 160, + 484, 484, 484, 484, 484, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 12, 12, 12, 12, 12, 12, 12, 48, + 12, 12, 12, 636, 637, 429, 429, 429, + 638, 638, 639, 639, 639, 639, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 139, 139, 144, 144, 139, 139, 139, 139, + 144, 144, 144, 139, 139, 273, 273, 273, + + 273, 139, 195, 195, 640, 641, 641, 159, + 642, 159, 641, 643, 299, 299, 299, 299, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 49, 49, 175, 644, 49, 49, 49, 175, + 49, 644, 50, 175, 175, 175, 50, 50, + 175, 175, 175, 50, 49, 175, 645, 49, + 49, 175, 175, 175, 175, 175, 49, 49, + + 49, 49, 49, 49, 175, 49, 646, 49, + 175, 49, 647, 648, 175, 175, 649, 50, + 175, 175, 650, 175, 50, 90, 90, 90, + 90, 131, 651, 239, 103, 628, 652, 652, + + 185, 185, 185, 185, 185, 652, 628, 628, + 628, 628, 653, 185, 418, 301, 654, 160, + 160, 160, 160, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, + + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 656, 656, 656, 656, 656, 656, 656, 656, + 656, 656, 656, 656, 656, 656, 656, 656, + + 657, 657, 657, 99, 109, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 36, 36, 36, 36, 36, 49, 49, 49, + 49, 49, 36, 36, 49, 49, 49, 49, + + 36, 49, 49, 36, 49, 49, 36, 49, + 49, 49, 49, 49, 49, 49, 36, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 36, 36, + 49, 49, 36, 49, 36, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + + 36, 36, 36, 36, 36, 36, 36, 36, + 658, 658, 658, 659, 659, 659, 36, 36, + 36, 36, 18, 54, 36, 660, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 661, 662, 36, 36, + + 36, 36, 36, 663, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 661, 662, 661, 662, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + + 36, 36, 36, 36, 661, 662, 661, 662, + 661, 662, 661, 662, 36, 36, 661, 662, + 661, 662, 661, 662, 661, 662, 661, 662, + 661, 662, 661, 662, 661, 662, 661, 662, + + 661, 662, 661, 662, 661, 662, 661, 662, + 661, 662, 661, 662, 36, 36, 36, 661, + 662, 661, 662, 36, 36, 36, 36, 36, + 664, 36, 36, 36, 36, 36, 36, 36, + + 36, 36, 661, 662, 36, 36, 665, 36, + 666, 667, 36, 667, 36, 36, 36, 36, + 661, 662, 661, 662, 661, 662, 661, 662, + 36, 36, 36, 36, 36, 36, 36, 36, + + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 661, 662, 661, 662, 668, 36, 36, + 661, 662, 36, 36, 36, 36, 661, 662, + 661, 662, 661, 662, 661, 662, 661, 662, + + 661, 662, 661, 662, 661, 662, 661, 662, + 661, 662, 661, 662, 661, 662, 36, 36, + 661, 662, 669, 669, 669, 185, 670, 670, + 185, 185, 671, 671, 671, 672, 672, 185, + + 49, 651, 49, 49, 49, 49, 49, 49, + 661, 662, 661, 662, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 36, 36, 49, 49, 49, 49, 49, 49, + 49, 16, 17, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 651, 185, 651, 651, 651, + + 651, 651, 651, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 381, 651, 651, + 651, 651, 651, 185, 185, 185, 185, 185, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, + + 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 239, + 239, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 673, 673, 673, 673, + + 673, 673, 301, 301, 301, 301, 301, 301, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 651, 651, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 674, 675, 676, 677, 678, 679, 680, 681, + 682, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 674, 675, 676, 677, + 678, 679, 680, 681, 682, 62, 62, 62, + + 62, 62, 62, 62, 62, 62, 62, 62, + 60, 55, 56, 629, 630, 631, 632, 633, + 634, 683, 683, 683, 683, 683, 683, 683, + 683, 683, 683, 683, 194, 194, 194, 194, + + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, + + 684, 684, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, + 685, 685, 685, 685, 685, 685, 685, 685, + 685, 685, 685, 685, 685, 685, 685, 685, + + 685, 685, 685, 685, 685, 685, 685, 685, + 685, 685, 686, 687, 687, 687, 687, 687, + 687, 687, 687, 687, 687, 688, 689, 690, + 691, 692, 693, 694, 695, 696, 687, 697, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 36, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 36, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 651, 651, 651, 651, 651, 651, 651, 651, + 185, 185, 185, 185, 185, 185, 185, 185, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 239, 239, 653, 653, + 418, 651, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 36, + 651, 651, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 418, 418, + + 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 239, 239, 239, 239, 239, 239, + 239, 239, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 160, 160, 160, + + 239, 239, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 405, 418, 418, 418, + 418, 418, 301, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 49, 49, 49, 49, 160, 49, 49, + 49, 49, 160, 160, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 160, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 160, 49, 160, 49, + 49, 49, 49, 160, 160, 160, 49, 160, + 49, 49, 49, 698, 698, 698, 698, 160, + + 160, 49, 699, 699, 49, 49, 49, 49, + 700, 701, 700, 701, 700, 701, 700, 701, + 700, 701, 700, 701, 700, 701, 674, 675, + 676, 677, 678, 679, 680, 681, 682, 62, + + 674, 675, 676, 677, 678, 679, 680, 681, + 682, 62, 674, 675, 676, 677, 678, 679, + 680, 681, 682, 62, 49, 160, 160, 160, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 160, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 160, + + 702, 702, 702, 703, 704, 705, 706, 673, + 673, 673, 673, 160, 160, 160, 160, 160, + 185, 185, 185, 185, 185, 707, 708, 185, + 185, 185, 185, 185, 185, 707, 708, 185, + + 185, 185, 707, 708, 707, 708, 700, 701, + 700, 701, 700, 701, 160, 160, 160, 160, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + + 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + + 185, 185, 185, 700, 701, 700, 701, 700, + 701, 700, 701, 700, 701, 709, 710, 711, + 712, 700, 701, 700, 701, 700, 701, 700, + 701, 185, 185, 185, 185, 185, 185, 185, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 713, 185, 185, 185, 185, 185, 185, 185, + + 707, 708, 185, 185, 707, 708, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 707, + 708, 707, 708, 185, 707, 708, 185, 185, + 700, 701, 700, 701, 185, 185, 185, 185, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 714, 185, 185, + 707, 708, 185, 185, 700, 701, 185, 185, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 707, 708, 707, 708, 185, + 185, 185, 185, 185, 707, 708, 185, 185, + 185, 185, 185, 185, 707, 708, 185, 185, + + 185, 185, 185, 185, 707, 708, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 707, 708, 185, 185, 707, 708, 707, + + 708, 707, 708, 707, 708, 185, 185, 185, + 185, 185, 185, 707, 708, 185, 185, 185, + 185, 707, 708, 707, 708, 707, 708, 707, + 708, 707, 708, 707, 708, 185, 185, 185, + + 185, 707, 708, 185, 185, 185, 707, 708, + 707, 708, 707, 708, 707, 708, 185, 707, + 708, 185, 185, 707, 708, 185, 185, 185, + 185, 185, 185, 707, 708, 707, 708, 707, + + 708, 707, 708, 707, 708, 707, 708, 185, + 185, 185, 185, 185, 185, 707, 708, 707, + 708, 707, 708, 707, 708, 707, 708, 185, + 185, 185, 185, 185, 185, 185, 715, 185, + + 185, 185, 185, 716, 717, 716, 185, 185, + 185, 185, 185, 185, 707, 708, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 707, + 708, 707, 708, 185, 185, 185, 185, 185, + + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 418, 418, + 418, 418, 418, 418, 301, 301, 301, 301, + 301, 301, 301, 160, 160, 160, 160, 160, + + 301, 301, 301, 301, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 718, + + 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 160, + 719, 719, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 719, + + 719, 719, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 160, + + 113, 109, 720, 721, 722, 723, 724, 113, + 109, 113, 109, 113, 109, 160, 160, 160, + 160, 160, 160, 160, 725, 113, 109, 725, + 160, 160, 160, 160, 160, 160, 160, 160, + + 105, 106, 105, 106, 105, 106, 105, 106, + 105, 106, 105, 106, 105, 106, 105, 106, + 105, 106, 105, 106, 105, 106, 105, 106, + 105, 106, 105, 106, 105, 106, 105, 106, + + 105, 106, 105, 106, 103, 418, 418, 418, + 418, 418, 418, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 622, 622, 622, 622, 726, 622, 622, + + 727, 727, 727, 727, 727, 727, 727, 727, + 727, 727, 727, 727, 727, 727, 727, 727, + 727, 727, 727, 727, 727, 727, 727, 727, + 727, 727, 727, 727, 727, 727, 727, 727, + + 727, 727, 727, 727, 727, 727, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + + 323, 323, 323, 323, 323, 323, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 401, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 323, 323, 323, 323, 323, 323, 323, 160, + 323, 323, 323, 323, 323, 323, 323, 160, + 323, 323, 323, 323, 323, 323, 323, 160, + 323, 323, 323, 323, 323, 323, 323, 160, + + 728, 728, 729, 730, 729, 730, 728, 728, + 728, 729, 730, 728, 729, 730, 622, 622, + 622, 622, 622, 622, 622, 622, 621, 731, + 160, 160, 160, 160, 729, 730, 160, 160, + + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 160, 732, 732, 732, 732, 732, + + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 160, 160, 160, 160, + + 733, 734, 735, 736, 737, 738, 739, 740, + 16, 17, 16, 17, 16, 17, 16, 17, + 16, 17, 737, 737, 16, 17, 16, 17, + 16, 17, 16, 17, 741, 16, 17, 742, + + 737, 740, 740, 740, 740, 740, 740, 740, + 740, 740, 743, 744, 140, 745, 746, 746, + 747, 748, 748, 748, 748, 748, 737, 737, + 749, 749, 749, 750, 751, 752, 732, 737, + + 160, 753, 739, 753, 739, 753, 739, 753, + 739, 753, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + + 739, 739, 739, 753, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + + 739, 739, 739, 753, 739, 753, 739, 753, + 739, 739, 739, 739, 739, 739, 753, 739, + 739, 739, 739, 739, 739, 754, 754, 160, + 160, 755, 755, 756, 756, 757, 757, 758, + + 759, 760, 761, 760, 761, 760, 761, 760, + 761, 760, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + + 761, 761, 761, 760, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + + 761, 761, 761, 760, 761, 760, 761, 760, + 761, 761, 761, 761, 761, 761, 760, 761, + 761, 761, 761, 761, 761, 760, 760, 761, + 761, 761, 761, 762, 763, 763, 763, 764, + + 160, 160, 160, 160, 160, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 160, 160, 160, + 160, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 160, + 766, 766, 767, 767, 767, 767, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 160, 160, 160, 160, 160, 160, 160, 160, + + 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 770, 770, 770, 770, 770, 770, 770, 770, + 770, 770, 770, 770, 770, 770, 770, 770, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 771, 771, 160, + + 767, 767, 767, 767, 767, 767, 767, 767, + 767, 767, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + + 766, 766, 766, 766, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 771, 772, 772, 772, 772, 772, 772, 772, + 772, 772, 772, 772, 772, 772, 772, 772, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 771, 771, 769, 766, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 772, 772, 772, 772, 772, 772, 772, + 772, 772, 772, 772, 772, 772, 772, 772, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 771, 771, 771, 771, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 160, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 771, + 771, 771, 771, 766, 766, 766, 766, 766, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 771, 771, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 771, + + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + + 739, 739, 739, 739, 739, 739, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 160, 160, 160, 160, + + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 775, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 160, 160, 160, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + + 732, 732, 776, 776, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 776, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + + 732, 776, 732, 732, 732, 776, 732, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 777, 777, 777, 777, 777, 777, 777, 777, + 777, 777, 777, 777, 777, 777, 777, 777, + 777, 777, 777, 777, 777, 777, 777, 778, + 778, 778, 778, 160, 160, 160, 160, 160, + + 779, 779, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 323, 323, 780, 323, 323, 323, 781, 323, + 323, 323, 323, 782, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + + 323, 323, 323, 464, 464, 782, 782, 464, + 418, 418, 418, 418, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 783, 783, 304, 304, + 160, 160, 160, 160, 160, 160, 160, 160, + + 784, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 784, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 784, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 784, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 784, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 784, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 784, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 784, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 786, 786, 786, 786, 786, 786, 786, 786, + 786, 786, 786, 786, 786, 786, 786, 786, + 786, 786, 786, 786, 786, 786, 786, 786, + 786, 786, 786, 786, 786, 786, 786, 786, + + 787, 787, 787, 787, 787, 787, 787, 787, + 787, 787, 787, 787, 787, 787, 787, 787, + 787, 787, 787, 787, 787, 787, 787, 787, + 787, 787, 787, 787, 787, 787, 787, 787, + + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 160, 160, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 160, 160, 160, 160, 160, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 160, 160, 160, 160, 160, 160, + + 789, 790, 791, 792, 793, 794, 795, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 796, 797, 798, 799, 800, + 160, 160, 160, 160, 160, 801, 802, 231, + + 231, 231, 231, 231, 231, 231, 231, 231, + 231, 635, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 205, + 231, 231, 231, 231, 231, 205, 231, 205, + + 231, 231, 205, 231, 231, 205, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 600, 742, + + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 235, 235, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 235, 235, 235, 235, 235, 235, 235, 235, + 803, 803, 803, 803, 803, 803, 803, 803, + 803, 803, 803, 803, 803, 803, 803, 803, + + 803, 803, 803, 803, 803, 803, 803, 803, + 803, 803, 803, 803, 803, 803, 803, 803, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 804, 239, 235, 235, + + 423, 423, 423, 423, 423, 423, 423, 423, + 423, 423, 423, 423, 423, 423, 423, 423, + 805, 806, 806, 805, 805, 807, 807, 808, + 809, 810, 160, 160, 160, 160, 160, 160, + + 139, 139, 139, 139, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 736, 747, 747, 811, 811, 600, 742, 600, + 742, 600, 742, 600, 742, 600, 742, 600, + + 742, 600, 742, 600, 742, 752, 752, 812, + 813, 736, 736, 736, 736, 811, 811, 811, + 814, 736, 815, 160, 762, 816, 9, 9, + 747, 16, 17, 16, 17, 16, 17, 817, + + 736, 736, 818, 819, 820, 821, 822, 160, + 736, 12, 13, 736, 160, 160, 160, 160, + 243, 243, 243, 286, 243, 235, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 235, 235, 823, + + 160, 9, 736, 817, 12, 13, 736, 736, + 16, 17, 736, 818, 814, 819, 815, 824, + 825, 826, 827, 828, 829, 830, 831, 832, + 833, 834, 816, 762, 835, 822, 836, 9, + + 736, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 39, 736, 41, 838, 811, + + 838, 839, 839, 839, 839, 839, 839, 839, + 839, 839, 839, 839, 839, 839, 839, 839, + 839, 839, 839, 839, 839, 839, 839, 839, + 839, 839, 839, 39, 822, 41, 822, 700, + + 701, 735, 16, 17, 734, 762, 840, 760, + 760, 760, 760, 760, 760, 760, 760, 760, + 763, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 840, 840, 840, 840, 840, 840, + + 840, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 840, 840, 840, 840, 763, 763, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 160, + + 160, 160, 90, 90, 90, 90, 90, 90, + 160, 160, 90, 90, 90, 90, 90, 90, + 160, 160, 90, 90, 90, 90, 90, 90, + 160, 160, 90, 90, 90, 160, 160, 160, + + 48, 12, 822, 838, 737, 12, 12, 160, + 49, 36, 36, 36, 36, 49, 49, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 841, 841, 841, 842, 49, 843, 843, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 160, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + + 308, 308, 308, 308, 308, 308, 308, 160, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 160, 308, 308, 160, 308, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 160, 160, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 160, 160, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 160, 160, 160, 160, 160, + + 844, 845, 846, 160, 160, 160, 160, 847, + 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 847, 847, 847, 847, + + 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 160, 160, 160, 848, + 848, 848, 848, 848, 848, 848, 848, 848, + + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 849, + + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 726, 726, 726, + 726, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 726, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 160, + + 851, 851, 851, 851, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, + + 850, 852, 850, 850, 850, 850, 850, 850, + 850, 850, 852, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 160, 844, + + 323, 323, 323, 323, 160, 160, 160, 160, + 323, 323, 323, 323, 323, 323, 323, 323, + 465, 853, 853, 853, 853, 853, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, + + 854, 854, 854, 854, 854, 854, 855, 855, + 856, 856, 856, 856, 856, 856, 856, 856, + 856, 856, 856, 856, 856, 856, 856, 856, + 856, 856, 856, 856, 856, 856, 856, 856, + + 856, 856, 856, 856, 856, 856, 856, 856, + 856, 856, 856, 856, 856, 856, 857, 857, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 160, 160, + + 441, 442, 443, 444, 445, 446, 447, 448, + 449, 450, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 858, 858, 858, 858, 858, 858, 205, 205, + 858, 205, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, + + 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 205, 858, + 858, 205, 205, 205, 858, 205, 205, 858, + + 859, 859, 859, 859, 859, 859, 859, 859, + 859, 859, 859, 859, 859, 859, 859, 859, + 859, 859, 859, 859, 859, 859, 860, 860, + 860, 860, 205, 205, 205, 205, 205, 861, + + 862, 782, 782, 782, 205, 782, 782, 205, + 205, 205, 205, 205, 782, 152, 782, 153, + 862, 862, 862, 862, 205, 862, 862, 862, + 205, 862, 862, 862, 862, 862, 862, 862, + + 862, 862, 862, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 205, 205, 205, 205, + 153, 643, 152, 205, 205, 205, 205, 781, + + 863, 864, 865, 866, 867, 867, 867, 867, + 205, 205, 205, 205, 205, 205, 205, 205, + 868, 868, 868, 868, 868, 868, 868, 868, + 869, 205, 205, 205, 205, 205, 205, 205, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 481, 481, 481, 481, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 160, + 160, 160, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 872, 873, 874, + 874, 874, 871, 871, 871, 875, 872, 872, + 872, 872, 872, 876, 876, 876, 876, 876, + 876, 876, 876, 877, 877, 877, 877, 877, + 877, 877, 877, 871, 871, 878, 878, 878, + 878, 878, 877, 877, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 878, 878, 878, 878, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 153, 153, 153, 418, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 879, 879, 879, 879, 879, 879, 879, 879, + 879, 879, 879, 879, 879, 879, 879, 879, + 879, 879, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 881, 881, 881, 160, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 160, 880, 880, + 160, 160, 880, 160, 160, 880, 880, 160, + 160, 880, 880, 880, 880, 160, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 160, 881, 160, 881, 881, 881, + 881, 102, 881, 881, 160, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + + 881, 881, 881, 881, 880, 880, 160, 880, + 880, 880, 880, 160, 160, 880, 880, 880, + 880, 880, 880, 880, 880, 160, 880, 880, + 880, 880, 880, 880, 880, 160, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 160, 880, 880, 880, 880, 160, + 880, 880, 880, 880, 880, 160, 880, 160, + 160, 160, 880, 880, 880, 880, 880, 880, + 880, 160, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 103, 103, 160, 160, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 882, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 882, 881, 881, 881, 881, + 881, 881, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 882, 881, 881, 881, 881, + + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 882, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 882, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 882, + 881, 881, 881, 881, 881, 881, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 882, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 882, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 882, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 882, 881, 881, 881, 881, + 881, 881, 883, 725, 160, 160, 884, 885, + 886, 887, 888, 889, 890, 891, 892, 893, + 884, 885, 886, 887, 888, 889, 890, 891, + 892, 893, 884, 885, 886, 887, 888, 889, + 890, 891, 892, 893, 884, 885, 886, 887, + 888, 889, 890, 891, 892, 893, 884, 885, + 886, 887, 888, 889, 890, 891, 892, 893, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 894, 894, + + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 876, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 894, 894, }; #define GET_PROP_INDEX(ucs4) \ @@ -3618,6 +3618,7 @@ static const QUnicodeTables::Properties uc_properties [] = { { 15, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 80, 0, 0, 80, 0, 3, 5}, { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 80, 0, 0, 80, 0, 3, 5}, { 16, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, -80, -80, 0, 0, 3, 4}, + { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -80, -80, 0, 0, 3, 4}, { 30, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, { 3, 19, 17, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0}, { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 15, 0, 0, 15, 0, 3, 5}, @@ -4335,13 +4336,13 @@ static inline const QUnicodeTables::Properties *qGetProp(ushort ucs2) return uc_properties + index; } -Q_CORE_EXPORT const QUnicodeTables::Properties* QT_FASTCALL QUnicodeTables::properties(uint ucs4) +Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(uint ucs4) { int index = GET_PROP_INDEX(ucs4); return uc_properties + index; } -Q_CORE_EXPORT const QUnicodeTables::Properties* QT_FASTCALL QUnicodeTables::properties(ushort ucs2) +Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(ushort ucs2) { int index = GET_PROP_INDEX_UCS2(ucs2); return uc_properties + index; @@ -4382,1446 +4383,1446 @@ static const ushort specialCaseMap [] = { static const unsigned short uc_decomposition_trie[] = { // 0 - 0x3400 - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1564, 1580, 1596, 1612, 1628, 1644, - 1660, 1676, 1692, 1708, 1724, 1740, 1756, 1772, - 1548, 1548, 1788, 1804, 1820, 1836, 1852, 1868, - 1884, 1900, 1916, 1932, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1948, 1548, 1964, 1980, 1548, - 1548, 1548, 1548, 1548, 1996, 1548, 1548, 2012, - 2028, 2044, 2060, 2076, 2092, 2108, 1548, 2124, - 2140, 2156, 1548, 2172, 1548, 2188, 1548, 2204, - 1548, 1548, 1548, 1548, 2220, 2236, 2252, 2268, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 2284, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 2300, 1548, 1548, 1548, 1548, 2316, - 1548, 1548, 1548, 1548, 2332, 2348, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 2364, 2380, 1548, 2396, 1548, 1548, - 1548, 1548, 1548, 1548, 2412, 2428, 1548, 1548, - 1548, 1548, 1548, 2444, 1548, 2460, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 2476, 2492, 1548, 1548, - 1548, 2508, 1548, 1548, 2524, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 2540, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 2556, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 2572, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 2588, 1548, 1548, - 1548, 1548, 1548, 2604, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 2620, 1548, 2636, 1548, 1548, - 2652, 1548, 1548, 1548, 2668, 2684, 2700, 2716, - 2732, 2748, 2764, 2780, 1548, 1548, 1548, 1548, - - 1548, 1548, 2796, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 2812, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 2828, 2844, 1548, 2860, 2876, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 2892, 2908, 2924, 2940, 2956, 2972, - 1548, 2988, 3004, 3020, 1548, 1548, 1548, 1548, - 3036, 3052, 3068, 3084, 3100, 3116, 3132, 3148, - 3164, 3180, 3196, 3212, 3228, 3244, 3260, 3276, - 3292, 3308, 3324, 3340, 3356, 3372, 3388, 3404, - 3420, 3436, 3452, 3468, 3484, 3500, 3516, 3532, - - 3548, 3564, 3580, 3596, 3612, 3628, 1548, 3644, - 3660, 3676, 3692, 1548, 1548, 1548, 1548, 1548, - 3708, 3724, 3740, 3756, 3772, 3788, 3804, 3820, - 1548, 3836, 3852, 1548, 3868, 1548, 1548, 1548, - 3884, 1548, 3900, 3916, 3932, 1548, 3948, 3964, - 3980, 1548, 3996, 1548, 1548, 1548, 4012, 1548, - 1548, 1548, 4028, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 4044, 4060, - 4076, 4092, 4108, 4124, 4140, 4156, 4172, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 4188, 1548, 1548, 1548, 1548, 1548, 1548, 4204, - 1548, 1548, 1548, 1548, 1548, 4220, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 4236, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 4252, 1548, 1548, 1548, 1548, 1548, 4268, - 4284, 4300, 4316, 4332, 4348, 4364, 4380, 4396, - 4412, 4428, 4444, 4460, 4476, 4492, 1548, 1548, - - 4508, 1548, 1548, 4524, 4540, 4556, 4572, 4588, - 1548, 4604, 4620, 4636, 4652, 4668, 1548, 4684, - 1548, 1548, 1548, 4700, 4716, 4732, 4748, 4764, - 4780, 4796, 1548, 1548, 1548, 1548, 1548, 1548, - 4812, 4828, 4844, 4860, 4876, 4892, 4908, 4924, - 4940, 4956, 4972, 4988, 5004, 5020, 5036, 5052, - 5068, 5084, 5100, 5116, 5132, 5148, 5164, 5180, - 5196, 5212, 5228, 5244, 5260, 5276, 5292, 5308, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1564, 1580, 1596, 1612, 1628, 1644, + 1660, 1676, 1692, 1708, 1724, 1740, 1756, 1772, + 1548, 1548, 1788, 1804, 1820, 1836, 1852, 1868, + 1884, 1900, 1916, 1932, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1948, 1548, 1964, 1980, 1548, + 1548, 1548, 1548, 1548, 1996, 1548, 1548, 2012, + 2028, 2044, 2060, 2076, 2092, 2108, 1548, 2124, + 2140, 2156, 1548, 2172, 1548, 2188, 1548, 2204, + 1548, 1548, 1548, 1548, 2220, 2236, 2252, 2268, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 2284, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 2300, 1548, 1548, 1548, 1548, 2316, + 1548, 1548, 1548, 1548, 2332, 2348, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 2364, 2380, 1548, 2396, 1548, 1548, + 1548, 1548, 1548, 1548, 2412, 2428, 1548, 1548, + 1548, 1548, 1548, 2444, 1548, 2460, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 2476, 2492, 1548, 1548, + 1548, 2508, 1548, 1548, 2524, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 2540, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 2556, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 2572, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 2588, 1548, 1548, + 1548, 1548, 1548, 2604, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 2620, 1548, 2636, 1548, 1548, + 2652, 1548, 1548, 1548, 2668, 2684, 2700, 2716, + 2732, 2748, 2764, 2780, 1548, 1548, 1548, 1548, + + 1548, 1548, 2796, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 2812, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 2828, 2844, 1548, 2860, 2876, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 2892, 2908, 2924, 2940, 2956, 2972, + 1548, 2988, 3004, 3020, 1548, 1548, 1548, 1548, + 3036, 3052, 3068, 3084, 3100, 3116, 3132, 3148, + 3164, 3180, 3196, 3212, 3228, 3244, 3260, 3276, + 3292, 3308, 3324, 3340, 3356, 3372, 3388, 3404, + 3420, 3436, 3452, 3468, 3484, 3500, 3516, 3532, + + 3548, 3564, 3580, 3596, 3612, 3628, 1548, 3644, + 3660, 3676, 3692, 1548, 1548, 1548, 1548, 1548, + 3708, 3724, 3740, 3756, 3772, 3788, 3804, 3820, + 1548, 3836, 3852, 1548, 3868, 1548, 1548, 1548, + 3884, 1548, 3900, 3916, 3932, 1548, 3948, 3964, + 3980, 1548, 3996, 1548, 1548, 1548, 4012, 1548, + 1548, 1548, 4028, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 4044, 4060, + 4076, 4092, 4108, 4124, 4140, 4156, 4172, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 4188, 1548, 1548, 1548, 1548, 1548, 1548, 4204, + 1548, 1548, 1548, 1548, 1548, 4220, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 4236, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 4252, 1548, 1548, 1548, 1548, 1548, 4268, + 4284, 4300, 4316, 4332, 4348, 4364, 4380, 4396, + 4412, 4428, 4444, 4460, 4476, 4492, 1548, 1548, + + 4508, 1548, 1548, 4524, 4540, 4556, 4572, 4588, + 1548, 4604, 4620, 4636, 4652, 4668, 1548, 4684, + 1548, 1548, 1548, 4700, 4716, 4732, 4748, 4764, + 4780, 4796, 1548, 1548, 1548, 1548, 1548, 1548, + 4812, 4828, 4844, 4860, 4876, 4892, 4908, 4924, + 4940, 4956, 4972, 4988, 5004, 5020, 5036, 5052, + 5068, 5084, 5100, 5116, 5132, 5148, 5164, 5180, + 5196, 5212, 5228, 5244, 5260, 5276, 5292, 5308, // 0x3400 - 0x30000 - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - - 5324, 5324, 5324, 5324, 5324, 5580, 5836, 6092, - 6348, 6604, 6860, 7116, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 7372, 5324, 5324, - 7628, 7884, 8140, 8396, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - - 5324, 5324, 5324, 5324, 8652, 8908, 9164, 5324, - 5324, 5324, 5324, 5324, - - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x2, 0xffff, 0x5, 0xffff, 0xffff, 0xffff, 0xffff, 0x7, - - 0xffff, 0xffff, 0xa, 0xc, 0xe, 0x11, 0xffff, 0xffff, - 0x13, 0x16, 0x18, 0xffff, 0x1a, 0x1e, 0x22, 0xffff, - - 0x26, 0x29, 0x2c, 0x2f, 0x32, 0x35, 0xffff, 0x38, - 0x3b, 0x3e, 0x41, 0x44, 0x47, 0x4a, 0x4d, 0x50, - - 0xffff, 0x53, 0x56, 0x59, 0x5c, 0x5f, 0x62, 0xffff, - 0xffff, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0xffff, 0xffff, - - 0x74, 0x77, 0x7a, 0x7d, 0x80, 0x83, 0xffff, 0x86, - 0x89, 0x8c, 0x8f, 0x92, 0x95, 0x98, 0x9b, 0x9e, - - 0xffff, 0xa1, 0xa4, 0xa7, 0xaa, 0xad, 0xb0, 0xffff, - 0xffff, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xffff, 0xc2, - - 0xc5, 0xc8, 0xcb, 0xce, 0xd1, 0xd4, 0xd7, 0xda, - 0xdd, 0xe0, 0xe3, 0xe6, 0xe9, 0xec, 0xef, 0xf2, - - 0xffff, 0xffff, 0xf5, 0xf8, 0xfb, 0xfe, 0x101, 0x104, - 0x107, 0x10a, 0x10d, 0x110, 0x113, 0x116, 0x119, 0x11c, - - 0x11f, 0x122, 0x125, 0x128, 0x12b, 0x12e, 0xffff, 0xffff, - 0x131, 0x134, 0x137, 0x13a, 0x13d, 0x140, 0x143, 0x146, - - 0x149, 0xffff, 0x14c, 0x14f, 0x152, 0x155, 0x158, 0x15b, - 0xffff, 0x15e, 0x161, 0x164, 0x167, 0x16a, 0x16d, 0x170, - - 0x173, 0xffff, 0xffff, 0x176, 0x179, 0x17c, 0x17f, 0x182, - 0x185, 0x188, 0xffff, 0xffff, 0x18b, 0x18e, 0x191, 0x194, - - 0x197, 0x19a, 0xffff, 0xffff, 0x19d, 0x1a0, 0x1a3, 0x1a6, - 0x1a9, 0x1ac, 0x1af, 0x1b2, 0x1b5, 0x1b8, 0x1bb, 0x1be, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + + 5324, 5324, 5324, 5324, 5324, 5580, 5836, 6092, + 6348, 6604, 6860, 7116, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 7372, 5324, 5324, + 7628, 7884, 8140, 8396, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + + 5324, 5324, 5324, 5324, 8652, 8908, 9164, 5324, + 5324, 5324, 5324, 5324, + + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x2, 0xffff, 0x5, 0xffff, 0xffff, 0xffff, 0xffff, 0x7, + + 0xffff, 0xffff, 0xa, 0xc, 0xe, 0x11, 0xffff, 0xffff, + 0x13, 0x16, 0x18, 0xffff, 0x1a, 0x1e, 0x22, 0xffff, + + 0x26, 0x29, 0x2c, 0x2f, 0x32, 0x35, 0xffff, 0x38, + 0x3b, 0x3e, 0x41, 0x44, 0x47, 0x4a, 0x4d, 0x50, + + 0xffff, 0x53, 0x56, 0x59, 0x5c, 0x5f, 0x62, 0xffff, + 0xffff, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0xffff, 0xffff, + + 0x74, 0x77, 0x7a, 0x7d, 0x80, 0x83, 0xffff, 0x86, + 0x89, 0x8c, 0x8f, 0x92, 0x95, 0x98, 0x9b, 0x9e, + + 0xffff, 0xa1, 0xa4, 0xa7, 0xaa, 0xad, 0xb0, 0xffff, + 0xffff, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xffff, 0xc2, + + 0xc5, 0xc8, 0xcb, 0xce, 0xd1, 0xd4, 0xd7, 0xda, + 0xdd, 0xe0, 0xe3, 0xe6, 0xe9, 0xec, 0xef, 0xf2, + + 0xffff, 0xffff, 0xf5, 0xf8, 0xfb, 0xfe, 0x101, 0x104, + 0x107, 0x10a, 0x10d, 0x110, 0x113, 0x116, 0x119, 0x11c, + + 0x11f, 0x122, 0x125, 0x128, 0x12b, 0x12e, 0xffff, 0xffff, + 0x131, 0x134, 0x137, 0x13a, 0x13d, 0x140, 0x143, 0x146, + + 0x149, 0xffff, 0x14c, 0x14f, 0x152, 0x155, 0x158, 0x15b, + 0xffff, 0x15e, 0x161, 0x164, 0x167, 0x16a, 0x16d, 0x170, + + 0x173, 0xffff, 0xffff, 0x176, 0x179, 0x17c, 0x17f, 0x182, + 0x185, 0x188, 0xffff, 0xffff, 0x18b, 0x18e, 0x191, 0x194, + + 0x197, 0x19a, 0xffff, 0xffff, 0x19d, 0x1a0, 0x1a3, 0x1a6, + 0x1a9, 0x1ac, 0x1af, 0x1b2, 0x1b5, 0x1b8, 0x1bb, 0x1be, - 0x1c1, 0x1c4, 0x1c7, 0x1ca, 0x1cd, 0x1d0, 0xffff, 0xffff, - 0x1d3, 0x1d6, 0x1d9, 0x1dc, 0x1df, 0x1e2, 0x1e5, 0x1e8, + 0x1c1, 0x1c4, 0x1c7, 0x1ca, 0x1cd, 0x1d0, 0xffff, 0xffff, + 0x1d3, 0x1d6, 0x1d9, 0x1dc, 0x1df, 0x1e2, 0x1e5, 0x1e8, - 0x1eb, 0x1ee, 0x1f1, 0x1f4, 0x1f7, 0x1fa, 0x1fd, 0x200, - 0x203, 0x206, 0x209, 0x20c, 0x20f, 0x212, 0x215, 0x218, + 0x1eb, 0x1ee, 0x1f1, 0x1f4, 0x1f7, 0x1fa, 0x1fd, 0x200, + 0x203, 0x206, 0x209, 0x20c, 0x20f, 0x212, 0x215, 0x218, - 0x21a, 0x21d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x220, + 0x21a, 0x21d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x220, - 0x223, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x223, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x226, 0x229, 0x22c, 0x22f, - 0x232, 0x235, 0x238, 0x23b, 0x23e, 0x241, 0x244, 0x247, + 0xffff, 0xffff, 0xffff, 0xffff, 0x226, 0x229, 0x22c, 0x22f, + 0x232, 0x235, 0x238, 0x23b, 0x23e, 0x241, 0x244, 0x247, - 0x24a, 0x24d, 0x250, 0x253, 0x256, 0x259, 0x25c, 0x25f, - 0x262, 0x265, 0x268, 0x26b, 0x26e, 0xffff, 0x271, 0x274, + 0x24a, 0x24d, 0x250, 0x253, 0x256, 0x259, 0x25c, 0x25f, + 0x262, 0x265, 0x268, 0x26b, 0x26e, 0xffff, 0x271, 0x274, - 0x277, 0x27a, 0x27d, 0x280, 0xffff, 0xffff, 0x283, 0x286, - 0x289, 0x28c, 0x28f, 0x292, 0x295, 0x298, 0x29b, 0x29e, + 0x277, 0x27a, 0x27d, 0x280, 0xffff, 0xffff, 0x283, 0x286, + 0x289, 0x28c, 0x28f, 0x292, 0x295, 0x298, 0x29b, 0x29e, - 0x2a1, 0x2a4, 0x2a7, 0x2aa, 0x2ad, 0x2b0, 0xffff, 0xffff, - 0x2b3, 0x2b6, 0x2b9, 0x2bc, 0x2bf, 0x2c2, 0x2c5, 0x2c8, + 0x2a1, 0x2a4, 0x2a7, 0x2aa, 0x2ad, 0x2b0, 0xffff, 0xffff, + 0x2b3, 0x2b6, 0x2b9, 0x2bc, 0x2bf, 0x2c2, 0x2c5, 0x2c8, - 0x2cb, 0x2ce, 0x2d1, 0x2d4, 0x2d7, 0x2da, 0x2dd, 0x2e0, - 0x2e3, 0x2e6, 0x2e9, 0x2ec, 0x2ef, 0x2f2, 0x2f5, 0x2f8, + 0x2cb, 0x2ce, 0x2d1, 0x2d4, 0x2d7, 0x2da, 0x2dd, 0x2e0, + 0x2e3, 0x2e6, 0x2e9, 0x2ec, 0x2ef, 0x2f2, 0x2f5, 0x2f8, - 0x2fb, 0x2fe, 0x301, 0x304, 0x307, 0x30a, 0x30d, 0x310, - 0x313, 0x316, 0x319, 0x31c, 0xffff, 0xffff, 0x31f, 0x322, + 0x2fb, 0x2fe, 0x301, 0x304, 0x307, 0x30a, 0x30d, 0x310, + 0x313, 0x316, 0x319, 0x31c, 0xffff, 0xffff, 0x31f, 0x322, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x325, 0x328, - 0x32b, 0x32e, 0x331, 0x334, 0x337, 0x33a, 0x33d, 0x340, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x325, 0x328, + 0x32b, 0x32e, 0x331, 0x334, 0x337, 0x33a, 0x33d, 0x340, - 0x343, 0x346, 0x349, 0x34c, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x343, 0x346, 0x349, 0x34c, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x34f, 0x351, 0x353, 0x355, 0x357, 0x359, 0x35b, 0x35d, - 0x35f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x34f, 0x351, 0x353, 0x355, 0x357, 0x359, 0x35b, 0x35d, + 0x35f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x361, 0x364, 0x367, 0x36a, 0x36d, 0x370, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x361, 0x364, 0x367, 0x36a, 0x36d, 0x370, 0xffff, 0xffff, - 0x373, 0x375, 0x377, 0x379, 0x37b, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x373, 0x375, 0x377, 0x379, 0x37b, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x37d, 0x37f, 0xffff, 0x381, 0x383, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x37d, 0x37f, 0xffff, 0x381, 0x383, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x386, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x388, 0xffff, 0xffff, 0xffff, 0x38b, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x386, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x388, 0xffff, 0xffff, 0xffff, 0x38b, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x38d, 0x390, 0x393, 0x396, - 0x398, 0x39b, 0x39e, 0xffff, 0x3a1, 0xffff, 0x3a4, 0x3a7, + 0xffff, 0xffff, 0xffff, 0xffff, 0x38d, 0x390, 0x393, 0x396, + 0x398, 0x39b, 0x39e, 0xffff, 0x3a1, 0xffff, 0x3a4, 0x3a7, - 0x3aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x3aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x3ad, 0x3b0, 0x3b3, 0x3b6, 0x3b9, 0x3bc, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x3ad, 0x3b0, 0x3b3, 0x3b6, 0x3b9, 0x3bc, - 0x3bf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x3bf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x3c2, 0x3c5, 0x3c8, 0x3cb, 0x3ce, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x3c2, 0x3c5, 0x3c8, 0x3cb, 0x3ce, 0xffff, - 0x3d1, 0x3d3, 0x3d5, 0x3d7, 0x3da, 0x3dd, 0x3df, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x3d1, 0x3d3, 0x3d5, 0x3d7, 0x3da, 0x3dd, 0x3df, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x3e1, 0x3e3, 0x3e5, 0xffff, 0x3e7, 0x3e9, 0xffff, 0xffff, - 0xffff, 0x3eb, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x3e1, 0x3e3, 0x3e5, 0xffff, 0x3e7, 0x3e9, 0xffff, 0xffff, + 0xffff, 0x3eb, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x3ed, 0x3f0, 0xffff, 0x3f3, 0xffff, 0xffff, 0xffff, 0x3f6, - 0xffff, 0xffff, 0xffff, 0xffff, 0x3f9, 0x3fc, 0x3ff, 0xffff, + 0x3ed, 0x3f0, 0xffff, 0x3f3, 0xffff, 0xffff, 0xffff, 0x3f6, + 0xffff, 0xffff, 0xffff, 0xffff, 0x3f9, 0x3fc, 0x3ff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x402, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x402, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x405, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x405, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x408, 0x40b, 0xffff, 0x40e, 0xffff, 0xffff, 0xffff, 0x411, - 0xffff, 0xffff, 0xffff, 0xffff, 0x414, 0x417, 0x41a, 0xffff, + 0x408, 0x40b, 0xffff, 0x40e, 0xffff, 0xffff, 0xffff, 0x411, + 0xffff, 0xffff, 0xffff, 0xffff, 0x414, 0x417, 0x41a, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x41d, 0x420, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x41d, 0x420, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x423, 0x426, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x423, 0x426, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x429, 0x42c, 0x42f, 0x432, 0xffff, 0xffff, 0x435, 0x438, - 0xffff, 0xffff, 0x43b, 0x43e, 0x441, 0x444, 0x447, 0x44a, + 0x429, 0x42c, 0x42f, 0x432, 0xffff, 0xffff, 0x435, 0x438, + 0xffff, 0xffff, 0x43b, 0x43e, 0x441, 0x444, 0x447, 0x44a, - 0xffff, 0xffff, 0x44d, 0x450, 0x453, 0x456, 0x459, 0x45c, - 0xffff, 0xffff, 0x45f, 0x462, 0x465, 0x468, 0x46b, 0x46e, + 0xffff, 0xffff, 0x44d, 0x450, 0x453, 0x456, 0x459, 0x45c, + 0xffff, 0xffff, 0x45f, 0x462, 0x465, 0x468, 0x46b, 0x46e, - 0x471, 0x474, 0x477, 0x47a, 0x47d, 0x480, 0xffff, 0xffff, - 0x483, 0x486, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x471, 0x474, 0x477, 0x47a, 0x47d, 0x480, 0xffff, 0xffff, + 0x483, 0x486, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x489, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x489, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x48c, 0x48f, 0x492, 0x495, 0x498, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x48c, 0x48f, 0x492, 0x495, 0x498, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x49b, 0x49e, 0x4a1, - 0x4a4, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x49b, 0x49e, 0x4a1, + 0x4a4, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x4a7, 0xffff, 0x4aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x4a7, 0xffff, 0x4aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x4ad, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x4ad, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x4b0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x4b0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x4b3, 0xffff, 0xffff, 0x4b6, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x4b3, 0xffff, 0xffff, 0x4b6, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x4b9, 0x4bc, 0x4bf, 0x4c2, 0x4c5, 0x4c8, 0x4cb, 0x4ce, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x4b9, 0x4bc, 0x4bf, 0x4c2, 0x4c5, 0x4c8, 0x4cb, 0x4ce, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x4d1, 0x4d4, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x4d1, 0x4d4, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x4d7, 0x4da, 0xffff, 0x4dd, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x4d7, 0x4da, 0xffff, 0x4dd, - 0xffff, 0xffff, 0xffff, 0x4e0, 0xffff, 0xffff, 0x4e3, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x4e0, 0xffff, 0xffff, 0x4e3, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x4e6, 0x4e9, 0x4ec, 0xffff, 0xffff, 0x4ef, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x4e6, 0x4e9, 0x4ec, 0xffff, 0xffff, 0x4ef, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x4f2, 0xffff, 0xffff, 0x4f5, 0x4f8, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x4f2, 0xffff, 0xffff, 0x4f5, 0x4f8, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x4fb, 0x4fe, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x4fb, 0x4fe, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x501, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x501, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x504, 0x507, 0x50a, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x504, 0x507, 0x50a, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x50d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x50d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x510, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x513, - 0x516, 0xffff, 0x519, 0x51c, 0xffff, 0xffff, 0xffff, 0xffff, + 0x510, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x513, + 0x516, 0xffff, 0x519, 0x51c, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x51f, 0x522, 0x525, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x51f, 0x522, 0x525, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x528, 0xffff, 0x52b, 0x52e, 0x531, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x528, 0xffff, 0x52b, 0x52e, 0x531, 0xffff, - 0xffff, 0xffff, 0xffff, 0x534, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x534, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x537, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x537, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x53a, 0x53d, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x53a, 0x53d, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x540, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x540, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x542, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x545, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x542, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x545, 0xffff, 0xffff, - 0xffff, 0xffff, 0x548, 0xffff, 0xffff, 0xffff, 0xffff, 0x54b, - 0xffff, 0xffff, 0xffff, 0xffff, 0x54e, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x548, 0xffff, 0xffff, 0xffff, 0xffff, 0x54b, + 0xffff, 0xffff, 0xffff, 0xffff, 0x54e, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x551, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x551, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x554, 0xffff, 0x557, 0x55a, 0x55d, - 0x560, 0x563, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x554, 0xffff, 0x557, 0x55a, 0x55d, + 0x560, 0x563, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x566, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x566, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x569, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x56c, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x569, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x56c, 0xffff, 0xffff, - 0xffff, 0xffff, 0x56f, 0xffff, 0xffff, 0xffff, 0xffff, 0x572, - 0xffff, 0xffff, 0xffff, 0xffff, 0x575, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x56f, 0xffff, 0xffff, 0xffff, 0xffff, 0x572, + 0xffff, 0xffff, 0xffff, 0xffff, 0x575, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x578, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x578, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x57b, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x57b, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x57e, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x57e, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x580, 0xffff, - 0x583, 0xffff, 0x586, 0xffff, 0x589, 0xffff, 0x58c, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x580, 0xffff, + 0x583, 0xffff, 0x586, 0xffff, 0x589, 0xffff, 0x58c, 0xffff, - 0xffff, 0xffff, 0x58f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x58f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x592, 0xffff, 0x595, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x592, 0xffff, 0x595, 0xffff, 0xffff, - 0x598, 0x59b, 0xffff, 0x59e, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x598, 0x59b, 0xffff, 0x59e, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x5a1, 0x5a3, 0x5a5, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x5a1, 0x5a3, 0x5a5, 0xffff, - 0x5a7, 0x5a9, 0x5ab, 0x5ad, 0x5af, 0x5b1, 0x5b3, 0x5b5, - 0x5b7, 0x5b9, 0x5bb, 0xffff, 0x5bd, 0x5bf, 0x5c1, 0x5c3, + 0x5a7, 0x5a9, 0x5ab, 0x5ad, 0x5af, 0x5b1, 0x5b3, 0x5b5, + 0x5b7, 0x5b9, 0x5bb, 0xffff, 0x5bd, 0x5bf, 0x5c1, 0x5c3, - 0x5c5, 0x5c7, 0x5c9, 0x5cb, 0x5cd, 0x5cf, 0x5d1, 0x5d3, - 0x5d5, 0x5d7, 0x5d9, 0x5db, 0x5dd, 0x5df, 0xffff, 0x5e1, + 0x5c5, 0x5c7, 0x5c9, 0x5cb, 0x5cd, 0x5cf, 0x5d1, 0x5d3, + 0x5d5, 0x5d7, 0x5d9, 0x5db, 0x5dd, 0x5df, 0xffff, 0x5e1, - 0x5e3, 0x5e5, 0x5e7, 0x5e9, 0x5eb, 0x5ed, 0x5ef, 0x5f1, - 0x5f3, 0x5f5, 0x5f7, 0x5f9, 0x5fb, 0x5fd, 0x5ff, 0x601, + 0x5e3, 0x5e5, 0x5e7, 0x5e9, 0x5eb, 0x5ed, 0x5ef, 0x5f1, + 0x5f3, 0x5f5, 0x5f7, 0x5f9, 0x5fb, 0x5fd, 0x5ff, 0x601, - 0x603, 0x605, 0x607, 0x609, 0x60b, 0x60d, 0x60f, 0x611, - 0x613, 0x615, 0x617, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x603, 0x605, 0x607, 0x609, 0x60b, 0x60d, 0x60f, 0x611, + 0x613, 0x615, 0x617, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x619, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x619, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x61b, 0x61d, 0x61f, 0x621, 0x623, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x61b, 0x61d, 0x61f, 0x621, 0x623, - 0x625, 0x627, 0x629, 0x62b, 0x62d, 0x62f, 0x631, 0x633, - 0x635, 0x637, 0x639, 0x63b, 0x63d, 0x63f, 0x641, 0x643, + 0x625, 0x627, 0x629, 0x62b, 0x62d, 0x62f, 0x631, 0x633, + 0x635, 0x637, 0x639, 0x63b, 0x63d, 0x63f, 0x641, 0x643, - 0x645, 0x647, 0x649, 0x64b, 0x64d, 0x64f, 0x651, 0x653, - 0x655, 0x657, 0x659, 0x65b, 0x65d, 0x65f, 0x661, 0x663, + 0x645, 0x647, 0x649, 0x64b, 0x64d, 0x64f, 0x651, 0x653, + 0x655, 0x657, 0x659, 0x65b, 0x65d, 0x65f, 0x661, 0x663, - 0x665, 0x668, 0x66b, 0x66e, 0x671, 0x674, 0x677, 0x67a, - 0x67d, 0x680, 0x683, 0x686, 0x689, 0x68c, 0x68f, 0x692, + 0x665, 0x668, 0x66b, 0x66e, 0x671, 0x674, 0x677, 0x67a, + 0x67d, 0x680, 0x683, 0x686, 0x689, 0x68c, 0x68f, 0x692, - 0x695, 0x698, 0x69b, 0x69e, 0x6a1, 0x6a4, 0x6a7, 0x6aa, - 0x6ad, 0x6b0, 0x6b3, 0x6b6, 0x6b9, 0x6bc, 0x6bf, 0x6c2, + 0x695, 0x698, 0x69b, 0x69e, 0x6a1, 0x6a4, 0x6a7, 0x6aa, + 0x6ad, 0x6b0, 0x6b3, 0x6b6, 0x6b9, 0x6bc, 0x6bf, 0x6c2, - 0x6c5, 0x6c8, 0x6cb, 0x6ce, 0x6d1, 0x6d4, 0x6d7, 0x6da, - 0x6dd, 0x6e0, 0x6e3, 0x6e6, 0x6e9, 0x6ec, 0x6ef, 0x6f2, + 0x6c5, 0x6c8, 0x6cb, 0x6ce, 0x6d1, 0x6d4, 0x6d7, 0x6da, + 0x6dd, 0x6e0, 0x6e3, 0x6e6, 0x6e9, 0x6ec, 0x6ef, 0x6f2, - 0x6f5, 0x6f8, 0x6fb, 0x6fe, 0x701, 0x704, 0x707, 0x70a, - 0x70d, 0x710, 0x713, 0x716, 0x719, 0x71c, 0x71f, 0x722, + 0x6f5, 0x6f8, 0x6fb, 0x6fe, 0x701, 0x704, 0x707, 0x70a, + 0x70d, 0x710, 0x713, 0x716, 0x719, 0x71c, 0x71f, 0x722, - 0x725, 0x728, 0x72b, 0x72e, 0x731, 0x734, 0x737, 0x73a, - 0x73d, 0x740, 0x743, 0x746, 0x749, 0x74c, 0x74f, 0x752, + 0x725, 0x728, 0x72b, 0x72e, 0x731, 0x734, 0x737, 0x73a, + 0x73d, 0x740, 0x743, 0x746, 0x749, 0x74c, 0x74f, 0x752, - 0x755, 0x758, 0x75b, 0x75e, 0x761, 0x764, 0x767, 0x76a, - 0x76d, 0x770, 0x773, 0x776, 0x779, 0x77c, 0x77f, 0x782, + 0x755, 0x758, 0x75b, 0x75e, 0x761, 0x764, 0x767, 0x76a, + 0x76d, 0x770, 0x773, 0x776, 0x779, 0x77c, 0x77f, 0x782, - 0x785, 0x788, 0x78b, 0x78e, 0x791, 0x794, 0x797, 0x79a, - 0x79d, 0x7a0, 0x7a3, 0x7a6, 0x7a9, 0x7ac, 0x7af, 0x7b2, + 0x785, 0x788, 0x78b, 0x78e, 0x791, 0x794, 0x797, 0x79a, + 0x79d, 0x7a0, 0x7a3, 0x7a6, 0x7a9, 0x7ac, 0x7af, 0x7b2, - 0x7b5, 0x7b8, 0x7bb, 0x7be, 0x7c1, 0x7c4, 0x7c7, 0x7ca, - 0x7cd, 0x7d0, 0x7d3, 0x7d6, 0x7d9, 0x7dc, 0x7df, 0x7e2, + 0x7b5, 0x7b8, 0x7bb, 0x7be, 0x7c1, 0x7c4, 0x7c7, 0x7ca, + 0x7cd, 0x7d0, 0x7d3, 0x7d6, 0x7d9, 0x7dc, 0x7df, 0x7e2, - 0x7e5, 0x7e8, 0x7eb, 0x7ee, 0x7f1, 0x7f4, 0x7f7, 0x7fa, - 0x7fd, 0x800, 0x803, 0x806, 0x809, 0x80c, 0x80f, 0x812, + 0x7e5, 0x7e8, 0x7eb, 0x7ee, 0x7f1, 0x7f4, 0x7f7, 0x7fa, + 0x7fd, 0x800, 0x803, 0x806, 0x809, 0x80c, 0x80f, 0x812, - 0x815, 0x818, 0x81b, 0x81e, 0x821, 0x824, 0x827, 0x82a, - 0x82d, 0x830, 0x833, 0x836, 0xffff, 0xffff, 0xffff, 0xffff, + 0x815, 0x818, 0x81b, 0x81e, 0x821, 0x824, 0x827, 0x82a, + 0x82d, 0x830, 0x833, 0x836, 0xffff, 0xffff, 0xffff, 0xffff, - 0x839, 0x83c, 0x83f, 0x842, 0x845, 0x848, 0x84b, 0x84e, - 0x851, 0x854, 0x857, 0x85a, 0x85d, 0x860, 0x863, 0x866, + 0x839, 0x83c, 0x83f, 0x842, 0x845, 0x848, 0x84b, 0x84e, + 0x851, 0x854, 0x857, 0x85a, 0x85d, 0x860, 0x863, 0x866, - 0x869, 0x86c, 0x86f, 0x872, 0x875, 0x878, 0x87b, 0x87e, - 0x881, 0x884, 0x887, 0x88a, 0x88d, 0x890, 0x893, 0x896, + 0x869, 0x86c, 0x86f, 0x872, 0x875, 0x878, 0x87b, 0x87e, + 0x881, 0x884, 0x887, 0x88a, 0x88d, 0x890, 0x893, 0x896, - 0x899, 0x89c, 0x89f, 0x8a2, 0x8a5, 0x8a8, 0x8ab, 0x8ae, - 0x8b1, 0x8b4, 0x8b7, 0x8ba, 0x8bd, 0x8c0, 0x8c3, 0x8c6, + 0x899, 0x89c, 0x89f, 0x8a2, 0x8a5, 0x8a8, 0x8ab, 0x8ae, + 0x8b1, 0x8b4, 0x8b7, 0x8ba, 0x8bd, 0x8c0, 0x8c3, 0x8c6, - 0x8c9, 0x8cc, 0x8cf, 0x8d2, 0x8d5, 0x8d8, 0x8db, 0x8de, - 0x8e1, 0x8e4, 0x8e7, 0x8ea, 0x8ed, 0x8f0, 0x8f3, 0x8f6, + 0x8c9, 0x8cc, 0x8cf, 0x8d2, 0x8d5, 0x8d8, 0x8db, 0x8de, + 0x8e1, 0x8e4, 0x8e7, 0x8ea, 0x8ed, 0x8f0, 0x8f3, 0x8f6, - 0x8f9, 0x8fc, 0x8ff, 0x902, 0x905, 0x908, 0x90b, 0x90e, - 0x911, 0x914, 0x917, 0x91a, 0x91d, 0x920, 0x923, 0x926, + 0x8f9, 0x8fc, 0x8ff, 0x902, 0x905, 0x908, 0x90b, 0x90e, + 0x911, 0x914, 0x917, 0x91a, 0x91d, 0x920, 0x923, 0x926, - 0x929, 0x92c, 0x92f, 0x932, 0x935, 0x938, 0x93b, 0x93e, - 0x941, 0x944, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x929, 0x92c, 0x92f, 0x932, 0x935, 0x938, 0x93b, 0x93e, + 0x941, 0x944, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x947, 0x94a, 0x94d, 0x950, 0x953, 0x956, 0x959, 0x95c, - 0x95f, 0x962, 0x965, 0x968, 0x96b, 0x96e, 0x971, 0x974, + 0x947, 0x94a, 0x94d, 0x950, 0x953, 0x956, 0x959, 0x95c, + 0x95f, 0x962, 0x965, 0x968, 0x96b, 0x96e, 0x971, 0x974, - 0x977, 0x97a, 0x97d, 0x980, 0x983, 0x986, 0xffff, 0xffff, - 0x989, 0x98c, 0x98f, 0x992, 0x995, 0x998, 0xffff, 0xffff, + 0x977, 0x97a, 0x97d, 0x980, 0x983, 0x986, 0xffff, 0xffff, + 0x989, 0x98c, 0x98f, 0x992, 0x995, 0x998, 0xffff, 0xffff, - 0x99b, 0x99e, 0x9a1, 0x9a4, 0x9a7, 0x9aa, 0x9ad, 0x9b0, - 0x9b3, 0x9b6, 0x9b9, 0x9bc, 0x9bf, 0x9c2, 0x9c5, 0x9c8, + 0x99b, 0x99e, 0x9a1, 0x9a4, 0x9a7, 0x9aa, 0x9ad, 0x9b0, + 0x9b3, 0x9b6, 0x9b9, 0x9bc, 0x9bf, 0x9c2, 0x9c5, 0x9c8, - 0x9cb, 0x9ce, 0x9d1, 0x9d4, 0x9d7, 0x9da, 0x9dd, 0x9e0, - 0x9e3, 0x9e6, 0x9e9, 0x9ec, 0x9ef, 0x9f2, 0x9f5, 0x9f8, + 0x9cb, 0x9ce, 0x9d1, 0x9d4, 0x9d7, 0x9da, 0x9dd, 0x9e0, + 0x9e3, 0x9e6, 0x9e9, 0x9ec, 0x9ef, 0x9f2, 0x9f5, 0x9f8, - 0x9fb, 0x9fe, 0xa01, 0xa04, 0xa07, 0xa0a, 0xffff, 0xffff, - 0xa0d, 0xa10, 0xa13, 0xa16, 0xa19, 0xa1c, 0xffff, 0xffff, + 0x9fb, 0x9fe, 0xa01, 0xa04, 0xa07, 0xa0a, 0xffff, 0xffff, + 0xa0d, 0xa10, 0xa13, 0xa16, 0xa19, 0xa1c, 0xffff, 0xffff, - 0xa1f, 0xa22, 0xa25, 0xa28, 0xa2b, 0xa2e, 0xa31, 0xa34, - 0xffff, 0xa37, 0xffff, 0xa3a, 0xffff, 0xa3d, 0xffff, 0xa40, + 0xa1f, 0xa22, 0xa25, 0xa28, 0xa2b, 0xa2e, 0xa31, 0xa34, + 0xffff, 0xa37, 0xffff, 0xa3a, 0xffff, 0xa3d, 0xffff, 0xa40, - 0xa43, 0xa46, 0xa49, 0xa4c, 0xa4f, 0xa52, 0xa55, 0xa58, - 0xa5b, 0xa5e, 0xa61, 0xa64, 0xa67, 0xa6a, 0xa6d, 0xa70, + 0xa43, 0xa46, 0xa49, 0xa4c, 0xa4f, 0xa52, 0xa55, 0xa58, + 0xa5b, 0xa5e, 0xa61, 0xa64, 0xa67, 0xa6a, 0xa6d, 0xa70, - 0xa73, 0xa76, 0xa78, 0xa7b, 0xa7d, 0xa80, 0xa82, 0xa85, - 0xa87, 0xa8a, 0xa8c, 0xa8f, 0xa91, 0xa94, 0xffff, 0xffff, + 0xa73, 0xa76, 0xa78, 0xa7b, 0xa7d, 0xa80, 0xa82, 0xa85, + 0xa87, 0xa8a, 0xa8c, 0xa8f, 0xa91, 0xa94, 0xffff, 0xffff, - 0xa96, 0xa99, 0xa9c, 0xa9f, 0xaa2, 0xaa5, 0xaa8, 0xaab, - 0xaae, 0xab1, 0xab4, 0xab7, 0xaba, 0xabd, 0xac0, 0xac3, + 0xa96, 0xa99, 0xa9c, 0xa9f, 0xaa2, 0xaa5, 0xaa8, 0xaab, + 0xaae, 0xab1, 0xab4, 0xab7, 0xaba, 0xabd, 0xac0, 0xac3, - 0xac6, 0xac9, 0xacc, 0xacf, 0xad2, 0xad5, 0xad8, 0xadb, - 0xade, 0xae1, 0xae4, 0xae7, 0xaea, 0xaed, 0xaf0, 0xaf3, + 0xac6, 0xac9, 0xacc, 0xacf, 0xad2, 0xad5, 0xad8, 0xadb, + 0xade, 0xae1, 0xae4, 0xae7, 0xaea, 0xaed, 0xaf0, 0xaf3, - 0xaf6, 0xaf9, 0xafc, 0xaff, 0xb02, 0xb05, 0xb08, 0xb0b, - 0xb0e, 0xb11, 0xb14, 0xb17, 0xb1a, 0xb1d, 0xb20, 0xb23, + 0xaf6, 0xaf9, 0xafc, 0xaff, 0xb02, 0xb05, 0xb08, 0xb0b, + 0xb0e, 0xb11, 0xb14, 0xb17, 0xb1a, 0xb1d, 0xb20, 0xb23, - 0xb26, 0xb29, 0xb2c, 0xb2f, 0xb32, 0xffff, 0xb35, 0xb38, - 0xb3b, 0xb3e, 0xb41, 0xb44, 0xb46, 0xb49, 0xb4c, 0xb4e, + 0xb26, 0xb29, 0xb2c, 0xb2f, 0xb32, 0xffff, 0xb35, 0xb38, + 0xb3b, 0xb3e, 0xb41, 0xb44, 0xb46, 0xb49, 0xb4c, 0xb4e, - 0xb51, 0xb54, 0xb57, 0xb5a, 0xb5d, 0xffff, 0xb60, 0xb63, - 0xb66, 0xb69, 0xb6b, 0xb6e, 0xb70, 0xb73, 0xb76, 0xb79, + 0xb51, 0xb54, 0xb57, 0xb5a, 0xb5d, 0xffff, 0xb60, 0xb63, + 0xb66, 0xb69, 0xb6b, 0xb6e, 0xb70, 0xb73, 0xb76, 0xb79, - 0xb7c, 0xb7f, 0xb82, 0xb85, 0xffff, 0xffff, 0xb87, 0xb8a, - 0xb8d, 0xb90, 0xb93, 0xb96, 0xffff, 0xb98, 0xb9b, 0xb9e, + 0xb7c, 0xb7f, 0xb82, 0xb85, 0xffff, 0xffff, 0xb87, 0xb8a, + 0xb8d, 0xb90, 0xb93, 0xb96, 0xffff, 0xb98, 0xb9b, 0xb9e, - 0xba1, 0xba4, 0xba7, 0xbaa, 0xbac, 0xbaf, 0xbb2, 0xbb5, - 0xbb8, 0xbbb, 0xbbe, 0xbc1, 0xbc3, 0xbc6, 0xbc9, 0xbcb, + 0xba1, 0xba4, 0xba7, 0xbaa, 0xbac, 0xbaf, 0xbb2, 0xbb5, + 0xbb8, 0xbbb, 0xbbe, 0xbc1, 0xbc3, 0xbc6, 0xbc9, 0xbcb, - 0xffff, 0xffff, 0xbcd, 0xbd0, 0xbd3, 0xffff, 0xbd6, 0xbd9, - 0xbdc, 0xbdf, 0xbe1, 0xbe4, 0xbe6, 0xbe9, 0xbeb, 0xffff, + 0xffff, 0xffff, 0xbcd, 0xbd0, 0xbd3, 0xffff, 0xbd6, 0xbd9, + 0xbdc, 0xbdf, 0xbe1, 0xbe4, 0xbe6, 0xbe9, 0xbeb, 0xffff, - 0xbee, 0xbf0, 0xbf2, 0xbf4, 0xbf6, 0xbf8, 0xbfa, 0xbfc, - 0xbfe, 0xc00, 0xc02, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xbee, 0xbf0, 0xbf2, 0xbf4, 0xbf6, 0xbf8, 0xbfa, 0xbfc, + 0xbfe, 0xc00, 0xc02, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xc04, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc06, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xc04, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc06, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xc09, 0xc0b, 0xc0e, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc12, + 0xffff, 0xffff, 0xffff, 0xffff, 0xc09, 0xc0b, 0xc0e, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc12, - 0xffff, 0xffff, 0xffff, 0xc14, 0xc17, 0xffff, 0xc1b, 0xc1e, - 0xffff, 0xffff, 0xffff, 0xffff, 0xc22, 0xffff, 0xc25, 0xffff, + 0xffff, 0xffff, 0xffff, 0xc14, 0xc17, 0xffff, 0xc1b, 0xc1e, + 0xffff, 0xffff, 0xffff, 0xffff, 0xc22, 0xffff, 0xc25, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc28, - 0xc2b, 0xc2e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc28, + 0xc2b, 0xc2e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc31, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc36, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc31, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc36, - 0xc38, 0xc3a, 0xffff, 0xffff, 0xc3c, 0xc3e, 0xc40, 0xc42, - 0xc44, 0xc46, 0xc48, 0xc4a, 0xc4c, 0xc4e, 0xc50, 0xc52, + 0xc38, 0xc3a, 0xffff, 0xffff, 0xc3c, 0xc3e, 0xc40, 0xc42, + 0xc44, 0xc46, 0xc48, 0xc4a, 0xc4c, 0xc4e, 0xc50, 0xc52, - 0xc54, 0xc56, 0xc58, 0xc5a, 0xc5c, 0xc5e, 0xc60, 0xc62, - 0xc64, 0xc66, 0xc68, 0xc6a, 0xc6c, 0xc6e, 0xc70, 0xffff, + 0xc54, 0xc56, 0xc58, 0xc5a, 0xc5c, 0xc5e, 0xc60, 0xc62, + 0xc64, 0xc66, 0xc68, 0xc6a, 0xc6c, 0xc6e, 0xc70, 0xffff, - 0xc72, 0xc74, 0xc76, 0xc78, 0xc7a, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xc72, 0xc74, 0xc76, 0xc78, 0xc7a, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xc7c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xc7c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xc7f, 0xc83, 0xc87, 0xc89, 0xffff, 0xc8c, 0xc90, 0xc94, - 0xffff, 0xc96, 0xc99, 0xc9b, 0xc9d, 0xc9f, 0xca1, 0xca3, + 0xc7f, 0xc83, 0xc87, 0xc89, 0xffff, 0xc8c, 0xc90, 0xc94, + 0xffff, 0xc96, 0xc99, 0xc9b, 0xc9d, 0xc9f, 0xca1, 0xca3, - 0xca5, 0xca7, 0xca9, 0xcab, 0xffff, 0xcad, 0xcaf, 0xffff, - 0xffff, 0xcb2, 0xcb4, 0xcb6, 0xcb8, 0xcba, 0xffff, 0xffff, + 0xca5, 0xca7, 0xca9, 0xcab, 0xffff, 0xcad, 0xcaf, 0xffff, + 0xffff, 0xcb2, 0xcb4, 0xcb6, 0xcb8, 0xcba, 0xffff, 0xffff, - 0xcbc, 0xcbf, 0xcc3, 0xffff, 0xcc6, 0xffff, 0xcc8, 0xffff, - 0xcca, 0xffff, 0xccc, 0xcce, 0xcd0, 0xcd2, 0xffff, 0xcd4, + 0xcbc, 0xcbf, 0xcc3, 0xffff, 0xcc6, 0xffff, 0xcc8, 0xffff, + 0xcca, 0xffff, 0xccc, 0xcce, 0xcd0, 0xcd2, 0xffff, 0xcd4, - 0xcd6, 0xcd8, 0xffff, 0xcda, 0xcdc, 0xcde, 0xce0, 0xce2, - 0xce4, 0xce6, 0xffff, 0xce8, 0xcec, 0xcee, 0xcf0, 0xcf2, + 0xcd6, 0xcd8, 0xffff, 0xcda, 0xcdc, 0xcde, 0xce0, 0xce2, + 0xce4, 0xce6, 0xffff, 0xce8, 0xcec, 0xcee, 0xcf0, 0xcf2, - 0xcf4, 0xffff, 0xffff, 0xffff, 0xffff, 0xcf6, 0xcf8, 0xcfa, - 0xcfc, 0xcfe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xcf4, 0xffff, 0xffff, 0xffff, 0xffff, 0xcf6, 0xcf8, 0xcfa, + 0xcfc, 0xcfe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xd00, 0xd04, 0xd08, 0xd0c, 0xd10, - 0xd14, 0xd18, 0xd1c, 0xd20, 0xd24, 0xd28, 0xd2c, 0xd30, + 0xffff, 0xffff, 0xffff, 0xd00, 0xd04, 0xd08, 0xd0c, 0xd10, + 0xd14, 0xd18, 0xd1c, 0xd20, 0xd24, 0xd28, 0xd2c, 0xd30, - 0xd33, 0xd35, 0xd38, 0xd3c, 0xd3f, 0xd41, 0xd44, 0xd48, - 0xd4d, 0xd50, 0xd52, 0xd55, 0xd59, 0xd5b, 0xd5d, 0xd5f, + 0xd33, 0xd35, 0xd38, 0xd3c, 0xd3f, 0xd41, 0xd44, 0xd48, + 0xd4d, 0xd50, 0xd52, 0xd55, 0xd59, 0xd5b, 0xd5d, 0xd5f, - 0xd61, 0xd63, 0xd66, 0xd6a, 0xd6d, 0xd6f, 0xd72, 0xd76, - 0xd7b, 0xd7e, 0xd80, 0xd83, 0xd87, 0xd89, 0xd8b, 0xd8d, + 0xd61, 0xd63, 0xd66, 0xd6a, 0xd6d, 0xd6f, 0xd72, 0xd76, + 0xd7b, 0xd7e, 0xd80, 0xd83, 0xd87, 0xd89, 0xd8b, 0xd8d, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xd8f, 0xd92, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xd8f, 0xd92, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd95, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd95, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd98, 0xd9b, 0xd9e, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd98, 0xd9b, 0xd9e, - 0xffff, 0xffff, 0xffff, 0xffff, 0xda1, 0xffff, 0xffff, 0xffff, - 0xffff, 0xda4, 0xffff, 0xffff, 0xda7, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xda1, 0xffff, 0xffff, 0xffff, + 0xffff, 0xda4, 0xffff, 0xffff, 0xda7, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xdaa, 0xffff, 0xdad, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xdb0, 0xdb3, 0xffff, 0xdb7, + 0xffff, 0xffff, 0xffff, 0xffff, 0xdaa, 0xffff, 0xdad, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xdb0, 0xdb3, 0xffff, 0xdb7, - 0xdba, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xdba, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xdbe, 0xffff, 0xffff, 0xdc1, 0xffff, 0xffff, 0xdc4, - 0xffff, 0xdc7, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xdbe, 0xffff, 0xffff, 0xdc1, 0xffff, 0xffff, 0xdc4, + 0xffff, 0xdc7, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xdca, 0xffff, 0xdcd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xdd0, 0xdd3, 0xdd6, + 0xdca, 0xffff, 0xdcd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xdd0, 0xdd3, 0xdd6, - 0xdd9, 0xddc, 0xffff, 0xffff, 0xddf, 0xde2, 0xffff, 0xffff, - 0xde5, 0xde8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xdd9, 0xddc, 0xffff, 0xffff, 0xddf, 0xde2, 0xffff, 0xffff, + 0xde5, 0xde8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xdeb, 0xdee, 0xffff, 0xffff, 0xdf1, 0xdf4, 0xffff, 0xffff, - 0xdf7, 0xdfa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xdeb, 0xdee, 0xffff, 0xffff, 0xdf1, 0xdf4, 0xffff, 0xffff, + 0xdf7, 0xdfa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xdfd, 0xe00, 0xe03, 0xe06, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xdfd, 0xe00, 0xe03, 0xe06, - 0xe09, 0xe0c, 0xe0f, 0xe12, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xe15, 0xe18, 0xe1b, 0xe1e, 0xffff, 0xffff, + 0xe09, 0xe0c, 0xe0f, 0xe12, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xe15, 0xe18, 0xe1b, 0xe1e, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xe21, 0xe23, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xe21, 0xe23, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xe25, 0xe27, 0xe29, 0xe2b, 0xe2d, 0xe2f, 0xe31, 0xe33, - 0xe35, 0xe37, 0xe3a, 0xe3d, 0xe40, 0xe43, 0xe46, 0xe49, + 0xe25, 0xe27, 0xe29, 0xe2b, 0xe2d, 0xe2f, 0xe31, 0xe33, + 0xe35, 0xe37, 0xe3a, 0xe3d, 0xe40, 0xe43, 0xe46, 0xe49, - 0xe4c, 0xe4f, 0xe52, 0xe55, 0xe58, 0xe5c, 0xe60, 0xe64, - 0xe68, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe81, 0xe86, + 0xe4c, 0xe4f, 0xe52, 0xe55, 0xe58, 0xe5c, 0xe60, 0xe64, + 0xe68, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe81, 0xe86, - 0xe8b, 0xe90, 0xe95, 0xe9a, 0xe9f, 0xea4, 0xea9, 0xeae, - 0xeb3, 0xeb6, 0xeb9, 0xebc, 0xebf, 0xec2, 0xec5, 0xec8, + 0xe8b, 0xe90, 0xe95, 0xe9a, 0xe9f, 0xea4, 0xea9, 0xeae, + 0xeb3, 0xeb6, 0xeb9, 0xebc, 0xebf, 0xec2, 0xec5, 0xec8, - 0xecb, 0xece, 0xed2, 0xed6, 0xeda, 0xede, 0xee2, 0xee6, - 0xeea, 0xeee, 0xef2, 0xef6, 0xefa, 0xefe, 0xf02, 0xf06, + 0xecb, 0xece, 0xed2, 0xed6, 0xeda, 0xede, 0xee2, 0xee6, + 0xeea, 0xeee, 0xef2, 0xef6, 0xefa, 0xefe, 0xf02, 0xf06, - 0xf0a, 0xf0e, 0xf12, 0xf16, 0xf1a, 0xf1e, 0xf22, 0xf26, - 0xf2a, 0xf2e, 0xf32, 0xf36, 0xf3a, 0xf3e, 0xf42, 0xf46, + 0xf0a, 0xf0e, 0xf12, 0xf16, 0xf1a, 0xf1e, 0xf22, 0xf26, + 0xf2a, 0xf2e, 0xf32, 0xf36, 0xf3a, 0xf3e, 0xf42, 0xf46, - 0xf4a, 0xf4e, 0xf52, 0xf56, 0xf5a, 0xf5e, 0xf62, 0xf64, - 0xf66, 0xf68, 0xf6a, 0xf6c, 0xf6e, 0xf70, 0xf72, 0xf74, + 0xf4a, 0xf4e, 0xf52, 0xf56, 0xf5a, 0xf5e, 0xf62, 0xf64, + 0xf66, 0xf68, 0xf6a, 0xf6c, 0xf6e, 0xf70, 0xf72, 0xf74, - 0xf76, 0xf78, 0xf7a, 0xf7c, 0xf7e, 0xf80, 0xf82, 0xf84, - 0xf86, 0xf88, 0xf8a, 0xf8c, 0xf8e, 0xf90, 0xf92, 0xf94, + 0xf76, 0xf78, 0xf7a, 0xf7c, 0xf7e, 0xf80, 0xf82, 0xf84, + 0xf86, 0xf88, 0xf8a, 0xf8c, 0xf8e, 0xf90, 0xf92, 0xf94, - 0xf96, 0xf98, 0xf9a, 0xf9c, 0xf9e, 0xfa0, 0xfa2, 0xfa4, - 0xfa6, 0xfa8, 0xfaa, 0xfac, 0xfae, 0xfb0, 0xfb2, 0xfb4, + 0xf96, 0xf98, 0xf9a, 0xf9c, 0xf9e, 0xfa0, 0xfa2, 0xfa4, + 0xfa6, 0xfa8, 0xfaa, 0xfac, 0xfae, 0xfb0, 0xfb2, 0xfb4, - 0xfb6, 0xfb8, 0xfba, 0xfbc, 0xfbe, 0xfc0, 0xfc2, 0xfc4, - 0xfc6, 0xfc8, 0xfca, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xfb6, 0xfb8, 0xfba, 0xfbc, 0xfbe, 0xfc0, 0xfc2, 0xfc4, + 0xfc6, 0xfc8, 0xfca, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xfcc, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xfcc, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xfd1, 0xfd5, 0xfd8, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xfd1, 0xfd5, 0xfd8, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xfdc, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xfdc, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfdf, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfdf, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfe1, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfe1, - 0xffff, 0xffff, 0xffff, 0xfe3, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xfe3, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xfe5, 0xfe7, 0xfe9, 0xfeb, 0xfed, 0xfef, 0xff1, 0xff3, - 0xff5, 0xff7, 0xff9, 0xffb, 0xffd, 0xfff, 0x1001, 0x1003, + 0xfe5, 0xfe7, 0xfe9, 0xfeb, 0xfed, 0xfef, 0xff1, 0xff3, + 0xff5, 0xff7, 0xff9, 0xffb, 0xffd, 0xfff, 0x1001, 0x1003, - 0x1005, 0x1007, 0x1009, 0x100b, 0x100d, 0x100f, 0x1011, 0x1013, - 0x1015, 0x1017, 0x1019, 0x101b, 0x101d, 0x101f, 0x1021, 0x1023, + 0x1005, 0x1007, 0x1009, 0x100b, 0x100d, 0x100f, 0x1011, 0x1013, + 0x1015, 0x1017, 0x1019, 0x101b, 0x101d, 0x101f, 0x1021, 0x1023, - 0x1025, 0x1027, 0x1029, 0x102b, 0x102d, 0x102f, 0x1031, 0x1033, - 0x1035, 0x1037, 0x1039, 0x103b, 0x103d, 0x103f, 0x1041, 0x1043, + 0x1025, 0x1027, 0x1029, 0x102b, 0x102d, 0x102f, 0x1031, 0x1033, + 0x1035, 0x1037, 0x1039, 0x103b, 0x103d, 0x103f, 0x1041, 0x1043, - 0x1045, 0x1047, 0x1049, 0x104b, 0x104d, 0x104f, 0x1051, 0x1053, - 0x1055, 0x1057, 0x1059, 0x105b, 0x105d, 0x105f, 0x1061, 0x1063, + 0x1045, 0x1047, 0x1049, 0x104b, 0x104d, 0x104f, 0x1051, 0x1053, + 0x1055, 0x1057, 0x1059, 0x105b, 0x105d, 0x105f, 0x1061, 0x1063, - 0x1065, 0x1067, 0x1069, 0x106b, 0x106d, 0x106f, 0x1071, 0x1073, - 0x1075, 0x1077, 0x1079, 0x107b, 0x107d, 0x107f, 0x1081, 0x1083, + 0x1065, 0x1067, 0x1069, 0x106b, 0x106d, 0x106f, 0x1071, 0x1073, + 0x1075, 0x1077, 0x1079, 0x107b, 0x107d, 0x107f, 0x1081, 0x1083, - 0x1085, 0x1087, 0x1089, 0x108b, 0x108d, 0x108f, 0x1091, 0x1093, - 0x1095, 0x1097, 0x1099, 0x109b, 0x109d, 0x109f, 0x10a1, 0x10a3, + 0x1085, 0x1087, 0x1089, 0x108b, 0x108d, 0x108f, 0x1091, 0x1093, + 0x1095, 0x1097, 0x1099, 0x109b, 0x109d, 0x109f, 0x10a1, 0x10a3, - 0x10a5, 0x10a7, 0x10a9, 0x10ab, 0x10ad, 0x10af, 0x10b1, 0x10b3, - 0x10b5, 0x10b7, 0x10b9, 0x10bb, 0x10bd, 0x10bf, 0x10c1, 0x10c3, + 0x10a5, 0x10a7, 0x10a9, 0x10ab, 0x10ad, 0x10af, 0x10b1, 0x10b3, + 0x10b5, 0x10b7, 0x10b9, 0x10bb, 0x10bd, 0x10bf, 0x10c1, 0x10c3, - 0x10c5, 0x10c7, 0x10c9, 0x10cb, 0x10cd, 0x10cf, 0x10d1, 0x10d3, - 0x10d5, 0x10d7, 0x10d9, 0x10db, 0x10dd, 0x10df, 0x10e1, 0x10e3, + 0x10c5, 0x10c7, 0x10c9, 0x10cb, 0x10cd, 0x10cf, 0x10d1, 0x10d3, + 0x10d5, 0x10d7, 0x10d9, 0x10db, 0x10dd, 0x10df, 0x10e1, 0x10e3, - 0x10e5, 0x10e7, 0x10e9, 0x10eb, 0x10ed, 0x10ef, 0x10f1, 0x10f3, - 0x10f5, 0x10f7, 0x10f9, 0x10fb, 0x10fd, 0x10ff, 0x1101, 0x1103, + 0x10e5, 0x10e7, 0x10e9, 0x10eb, 0x10ed, 0x10ef, 0x10f1, 0x10f3, + 0x10f5, 0x10f7, 0x10f9, 0x10fb, 0x10fd, 0x10ff, 0x1101, 0x1103, - 0x1105, 0x1107, 0x1109, 0x110b, 0x110d, 0x110f, 0x1111, 0x1113, - 0x1115, 0x1117, 0x1119, 0x111b, 0x111d, 0x111f, 0x1121, 0x1123, + 0x1105, 0x1107, 0x1109, 0x110b, 0x110d, 0x110f, 0x1111, 0x1113, + 0x1115, 0x1117, 0x1119, 0x111b, 0x111d, 0x111f, 0x1121, 0x1123, - 0x1125, 0x1127, 0x1129, 0x112b, 0x112d, 0x112f, 0x1131, 0x1133, - 0x1135, 0x1137, 0x1139, 0x113b, 0x113d, 0x113f, 0x1141, 0x1143, + 0x1125, 0x1127, 0x1129, 0x112b, 0x112d, 0x112f, 0x1131, 0x1133, + 0x1135, 0x1137, 0x1139, 0x113b, 0x113d, 0x113f, 0x1141, 0x1143, - 0x1145, 0x1147, 0x1149, 0x114b, 0x114d, 0x114f, 0x1151, 0x1153, - 0x1155, 0x1157, 0x1159, 0x115b, 0x115d, 0x115f, 0x1161, 0x1163, + 0x1145, 0x1147, 0x1149, 0x114b, 0x114d, 0x114f, 0x1151, 0x1153, + 0x1155, 0x1157, 0x1159, 0x115b, 0x115d, 0x115f, 0x1161, 0x1163, - 0x1165, 0x1167, 0x1169, 0x116b, 0x116d, 0x116f, 0x1171, 0x1173, - 0x1175, 0x1177, 0x1179, 0x117b, 0x117d, 0x117f, 0x1181, 0x1183, + 0x1165, 0x1167, 0x1169, 0x116b, 0x116d, 0x116f, 0x1171, 0x1173, + 0x1175, 0x1177, 0x1179, 0x117b, 0x117d, 0x117f, 0x1181, 0x1183, - 0x1185, 0x1187, 0x1189, 0x118b, 0x118d, 0x118f, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x1185, 0x1187, 0x1189, 0x118b, 0x118d, 0x118f, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x1191, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x1191, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1193, 0xffff, - 0x1195, 0x1197, 0x1199, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1193, 0xffff, + 0x1195, 0x1197, 0x1199, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x119b, 0xffff, 0x119e, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x119b, 0xffff, 0x119e, 0xffff, - 0x11a1, 0xffff, 0x11a4, 0xffff, 0x11a7, 0xffff, 0x11aa, 0xffff, - 0x11ad, 0xffff, 0x11b0, 0xffff, 0x11b3, 0xffff, 0x11b6, 0xffff, + 0x11a1, 0xffff, 0x11a4, 0xffff, 0x11a7, 0xffff, 0x11aa, 0xffff, + 0x11ad, 0xffff, 0x11b0, 0xffff, 0x11b3, 0xffff, 0x11b6, 0xffff, - 0x11b9, 0xffff, 0x11bc, 0xffff, 0xffff, 0x11bf, 0xffff, 0x11c2, - 0xffff, 0x11c5, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x11b9, 0xffff, 0x11bc, 0xffff, 0xffff, 0x11bf, 0xffff, 0x11c2, + 0xffff, 0x11c5, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x11c8, 0x11cb, 0xffff, 0x11ce, 0x11d1, 0xffff, 0x11d4, 0x11d7, - 0xffff, 0x11da, 0x11dd, 0xffff, 0x11e0, 0x11e3, 0xffff, 0xffff, + 0x11c8, 0x11cb, 0xffff, 0x11ce, 0x11d1, 0xffff, 0x11d4, 0x11d7, + 0xffff, 0x11da, 0x11dd, 0xffff, 0x11e0, 0x11e3, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x11e6, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x11e9, 0x11ec, 0xffff, 0x11ef, 0x11f2, + 0xffff, 0xffff, 0xffff, 0xffff, 0x11e6, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x11e9, 0x11ec, 0xffff, 0x11ef, 0x11f2, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x11f5, 0xffff, 0x11f8, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x11f5, 0xffff, 0x11f8, 0xffff, - 0x11fb, 0xffff, 0x11fe, 0xffff, 0x1201, 0xffff, 0x1204, 0xffff, - 0x1207, 0xffff, 0x120a, 0xffff, 0x120d, 0xffff, 0x1210, 0xffff, + 0x11fb, 0xffff, 0x11fe, 0xffff, 0x1201, 0xffff, 0x1204, 0xffff, + 0x1207, 0xffff, 0x120a, 0xffff, 0x120d, 0xffff, 0x1210, 0xffff, - 0x1213, 0xffff, 0x1216, 0xffff, 0xffff, 0x1219, 0xffff, 0x121c, - 0xffff, 0x121f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x1213, 0xffff, 0x1216, 0xffff, 0xffff, 0x1219, 0xffff, 0x121c, + 0xffff, 0x121f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x1222, 0x1225, 0xffff, 0x1228, 0x122b, 0xffff, 0x122e, 0x1231, - 0xffff, 0x1234, 0x1237, 0xffff, 0x123a, 0x123d, 0xffff, 0xffff, + 0x1222, 0x1225, 0xffff, 0x1228, 0x122b, 0xffff, 0x122e, 0x1231, + 0xffff, 0x1234, 0x1237, 0xffff, 0x123a, 0x123d, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x1240, 0xffff, 0xffff, 0x1243, - 0x1246, 0x1249, 0x124c, 0xffff, 0xffff, 0xffff, 0x124f, 0x1252, + 0xffff, 0xffff, 0xffff, 0xffff, 0x1240, 0xffff, 0xffff, 0x1243, + 0x1246, 0x1249, 0x124c, 0xffff, 0xffff, 0xffff, 0x124f, 0x1252, - 0xffff, 0x1255, 0x1257, 0x1259, 0x125b, 0x125d, 0x125f, 0x1261, - 0x1263, 0x1265, 0x1267, 0x1269, 0x126b, 0x126d, 0x126f, 0x1271, + 0xffff, 0x1255, 0x1257, 0x1259, 0x125b, 0x125d, 0x125f, 0x1261, + 0x1263, 0x1265, 0x1267, 0x1269, 0x126b, 0x126d, 0x126f, 0x1271, - 0x1273, 0x1275, 0x1277, 0x1279, 0x127b, 0x127d, 0x127f, 0x1281, - 0x1283, 0x1285, 0x1287, 0x1289, 0x128b, 0x128d, 0x128f, 0x1291, + 0x1273, 0x1275, 0x1277, 0x1279, 0x127b, 0x127d, 0x127f, 0x1281, + 0x1283, 0x1285, 0x1287, 0x1289, 0x128b, 0x128d, 0x128f, 0x1291, - 0x1293, 0x1295, 0x1297, 0x1299, 0x129b, 0x129d, 0x129f, 0x12a1, - 0x12a3, 0x12a5, 0x12a7, 0x12a9, 0x12ab, 0x12ad, 0x12af, 0x12b1, + 0x1293, 0x1295, 0x1297, 0x1299, 0x129b, 0x129d, 0x129f, 0x12a1, + 0x12a3, 0x12a5, 0x12a7, 0x12a9, 0x12ab, 0x12ad, 0x12af, 0x12b1, - 0x12b3, 0x12b5, 0x12b7, 0x12b9, 0x12bb, 0x12bd, 0x12bf, 0x12c1, - 0x12c3, 0x12c5, 0x12c7, 0x12c9, 0x12cb, 0x12cd, 0x12cf, 0x12d1, + 0x12b3, 0x12b5, 0x12b7, 0x12b9, 0x12bb, 0x12bd, 0x12bf, 0x12c1, + 0x12c3, 0x12c5, 0x12c7, 0x12c9, 0x12cb, 0x12cd, 0x12cf, 0x12d1, - 0x12d3, 0x12d5, 0x12d7, 0x12d9, 0x12db, 0x12dd, 0x12df, 0x12e1, - 0x12e3, 0x12e5, 0x12e7, 0x12e9, 0x12eb, 0x12ed, 0x12ef, 0x12f1, + 0x12d3, 0x12d5, 0x12d7, 0x12d9, 0x12db, 0x12dd, 0x12df, 0x12e1, + 0x12e3, 0x12e5, 0x12e7, 0x12e9, 0x12eb, 0x12ed, 0x12ef, 0x12f1, - 0x12f3, 0x12f5, 0x12f7, 0x12f9, 0x12fb, 0x12fd, 0x12ff, 0x1301, - 0x1303, 0x1305, 0x1307, 0x1309, 0x130b, 0x130d, 0x130f, 0xffff, + 0x12f3, 0x12f5, 0x12f7, 0x12f9, 0x12fb, 0x12fd, 0x12ff, 0x1301, + 0x1303, 0x1305, 0x1307, 0x1309, 0x130b, 0x130d, 0x130f, 0xffff, - 0xffff, 0xffff, 0x1311, 0x1313, 0x1315, 0x1317, 0x1319, 0x131b, - 0x131d, 0x131f, 0x1321, 0x1323, 0x1325, 0x1327, 0x1329, 0x132b, + 0xffff, 0xffff, 0x1311, 0x1313, 0x1315, 0x1317, 0x1319, 0x131b, + 0x131d, 0x131f, 0x1321, 0x1323, 0x1325, 0x1327, 0x1329, 0x132b, - 0x132d, 0x1331, 0x1335, 0x1339, 0x133d, 0x1341, 0x1345, 0x1349, - 0x134d, 0x1351, 0x1355, 0x1359, 0x135d, 0x1361, 0x1365, 0x136a, + 0x132d, 0x1331, 0x1335, 0x1339, 0x133d, 0x1341, 0x1345, 0x1349, + 0x134d, 0x1351, 0x1355, 0x1359, 0x135d, 0x1361, 0x1365, 0x136a, - 0x136f, 0x1374, 0x1379, 0x137e, 0x1383, 0x1388, 0x138d, 0x1392, - 0x1397, 0x139c, 0x13a1, 0x13a6, 0x13ab, 0x13b0, 0x13b8, 0xffff, + 0x136f, 0x1374, 0x1379, 0x137e, 0x1383, 0x1388, 0x138d, 0x1392, + 0x1397, 0x139c, 0x13a1, 0x13a6, 0x13ab, 0x13b0, 0x13b8, 0xffff, - 0x13bf, 0x13c3, 0x13c7, 0x13cb, 0x13cf, 0x13d3, 0x13d7, 0x13db, - 0x13df, 0x13e3, 0x13e7, 0x13eb, 0x13ef, 0x13f3, 0x13f7, 0x13fb, + 0x13bf, 0x13c3, 0x13c7, 0x13cb, 0x13cf, 0x13d3, 0x13d7, 0x13db, + 0x13df, 0x13e3, 0x13e7, 0x13eb, 0x13ef, 0x13f3, 0x13f7, 0x13fb, - 0x13ff, 0x1403, 0x1407, 0x140b, 0x140f, 0x1413, 0x1417, 0x141b, - 0x141f, 0x1423, 0x1427, 0x142b, 0x142f, 0x1433, 0x1437, 0x143b, + 0x13ff, 0x1403, 0x1407, 0x140b, 0x140f, 0x1413, 0x1417, 0x141b, + 0x141f, 0x1423, 0x1427, 0x142b, 0x142f, 0x1433, 0x1437, 0x143b, - 0x143f, 0x1443, 0x1447, 0x144b, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x143f, 0x1443, 0x1447, 0x144b, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x144f, 0x1453, 0x1456, 0x1459, 0x145c, 0x145f, 0x1462, 0x1465, - 0x1468, 0x146b, 0x146e, 0x1471, 0x1474, 0x1477, 0x147a, 0x147d, + 0x144f, 0x1453, 0x1456, 0x1459, 0x145c, 0x145f, 0x1462, 0x1465, + 0x1468, 0x146b, 0x146e, 0x1471, 0x1474, 0x1477, 0x147a, 0x147d, - 0x1480, 0x1482, 0x1484, 0x1486, 0x1488, 0x148a, 0x148c, 0x148e, - 0x1490, 0x1492, 0x1494, 0x1496, 0x1498, 0x149a, 0x149c, 0x149f, + 0x1480, 0x1482, 0x1484, 0x1486, 0x1488, 0x148a, 0x148c, 0x148e, + 0x1490, 0x1492, 0x1494, 0x1496, 0x1498, 0x149a, 0x149c, 0x149f, - 0x14a2, 0x14a5, 0x14a8, 0x14ab, 0x14ae, 0x14b1, 0x14b4, 0x14b7, - 0x14ba, 0x14bd, 0x14c0, 0x14c3, 0x14c6, 0x14cc, 0x14d1, 0xffff, + 0x14a2, 0x14a5, 0x14a8, 0x14ab, 0x14ae, 0x14b1, 0x14b4, 0x14b7, + 0x14ba, 0x14bd, 0x14c0, 0x14c3, 0x14c6, 0x14cc, 0x14d1, 0xffff, - 0x14d4, 0x14d6, 0x14d8, 0x14da, 0x14dc, 0x14de, 0x14e0, 0x14e2, - 0x14e4, 0x14e6, 0x14e8, 0x14ea, 0x14ec, 0x14ee, 0x14f0, 0x14f2, + 0x14d4, 0x14d6, 0x14d8, 0x14da, 0x14dc, 0x14de, 0x14e0, 0x14e2, + 0x14e4, 0x14e6, 0x14e8, 0x14ea, 0x14ec, 0x14ee, 0x14f0, 0x14f2, - 0x14f4, 0x14f6, 0x14f8, 0x14fa, 0x14fc, 0x14fe, 0x1500, 0x1502, - 0x1504, 0x1506, 0x1508, 0x150a, 0x150c, 0x150e, 0x1510, 0x1512, + 0x14f4, 0x14f6, 0x14f8, 0x14fa, 0x14fc, 0x14fe, 0x1500, 0x1502, + 0x1504, 0x1506, 0x1508, 0x150a, 0x150c, 0x150e, 0x1510, 0x1512, - 0x1514, 0x1516, 0x1518, 0x151a, 0x151c, 0x151e, 0x1520, 0x1522, - 0x1524, 0x1526, 0x1528, 0x152a, 0x152c, 0x152e, 0x1530, 0x1532, + 0x1514, 0x1516, 0x1518, 0x151a, 0x151c, 0x151e, 0x1520, 0x1522, + 0x1524, 0x1526, 0x1528, 0x152a, 0x152c, 0x152e, 0x1530, 0x1532, - 0x1534, 0x1536, 0x1539, 0x153c, 0x153f, 0x1542, 0x1545, 0x1548, - 0x154b, 0x154e, 0x1551, 0x1554, 0x1557, 0x155a, 0x155d, 0x1560, + 0x1534, 0x1536, 0x1539, 0x153c, 0x153f, 0x1542, 0x1545, 0x1548, + 0x154b, 0x154e, 0x1551, 0x1554, 0x1557, 0x155a, 0x155d, 0x1560, - 0x1563, 0x1566, 0x1569, 0x156c, 0x156f, 0x1572, 0x1575, 0x1578, - 0x157b, 0x157e, 0x1582, 0x1586, 0x158a, 0x158d, 0x1591, 0x1594, + 0x1563, 0x1566, 0x1569, 0x156c, 0x156f, 0x1572, 0x1575, 0x1578, + 0x157b, 0x157e, 0x1582, 0x1586, 0x158a, 0x158d, 0x1591, 0x1594, - 0x1598, 0x159a, 0x159c, 0x159e, 0x15a0, 0x15a2, 0x15a4, 0x15a6, - 0x15a8, 0x15aa, 0x15ac, 0x15ae, 0x15b0, 0x15b2, 0x15b4, 0x15b6, + 0x1598, 0x159a, 0x159c, 0x159e, 0x15a0, 0x15a2, 0x15a4, 0x15a6, + 0x15a8, 0x15aa, 0x15ac, 0x15ae, 0x15b0, 0x15b2, 0x15b4, 0x15b6, - 0x15b8, 0x15ba, 0x15bc, 0x15be, 0x15c0, 0x15c2, 0x15c4, 0x15c6, - 0x15c8, 0x15ca, 0x15cc, 0x15ce, 0x15d0, 0x15d2, 0x15d4, 0x15d6, + 0x15b8, 0x15ba, 0x15bc, 0x15be, 0x15c0, 0x15c2, 0x15c4, 0x15c6, + 0x15c8, 0x15ca, 0x15cc, 0x15ce, 0x15d0, 0x15d2, 0x15d4, 0x15d6, - 0x15d8, 0x15da, 0x15dc, 0x15de, 0x15e0, 0x15e2, 0x15e4, 0x15e6, - 0x15e8, 0x15ea, 0x15ec, 0x15ee, 0x15f0, 0x15f2, 0x15f4, 0xffff, + 0x15d8, 0x15da, 0x15dc, 0x15de, 0x15e0, 0x15e2, 0x15e4, 0x15e6, + 0x15e8, 0x15ea, 0x15ec, 0x15ee, 0x15f0, 0x15f2, 0x15f4, 0xffff, - 0x15f6, 0x15fb, 0x1600, 0x1605, 0x1609, 0x160e, 0x1612, 0x1616, - 0x161c, 0x1621, 0x1625, 0x1629, 0x162d, 0x1632, 0x1637, 0x163b, + 0x15f6, 0x15fb, 0x1600, 0x1605, 0x1609, 0x160e, 0x1612, 0x1616, + 0x161c, 0x1621, 0x1625, 0x1629, 0x162d, 0x1632, 0x1637, 0x163b, - 0x163f, 0x1642, 0x1646, 0x164b, 0x1650, 0x1653, 0x1659, 0x1660, - 0x1666, 0x166a, 0x1670, 0x1676, 0x167b, 0x167f, 0x1683, 0x1687, - - 0x168c, 0x1692, 0x1697, 0x169b, 0x169f, 0x16a3, 0x16a6, 0x16a9, - 0x16ac, 0x16af, 0x16b3, 0x16b7, 0x16bd, 0x16c1, 0x16c6, 0x16cc, - - 0x16d0, 0x16d3, 0x16d6, 0x16dc, 0x16e1, 0x16e7, 0x16eb, 0x16f1, - 0x16f4, 0x16f8, 0x16fc, 0x1700, 0x1704, 0x1708, 0x170d, 0x1711, - - 0x1714, 0x1718, 0x171c, 0x1720, 0x1725, 0x1729, 0x172d, 0x1731, - 0x1737, 0x173c, 0x173f, 0x1745, 0x1748, 0x174d, 0x1752, 0x1756, - - 0x175a, 0x175e, 0x1763, 0x1766, 0x176a, 0x176f, 0x1772, 0x1778, - 0x177c, 0x177f, 0x1782, 0x1785, 0x1788, 0x178b, 0x178e, 0x1791, - - 0x1794, 0x1797, 0x179a, 0x179e, 0x17a2, 0x17a6, 0x17aa, 0x17ae, - 0x17b2, 0x17b6, 0x17ba, 0x17be, 0x17c2, 0x17c6, 0x17ca, 0x17ce, - - 0x17d2, 0x17d6, 0x17da, 0x17dd, 0x17e0, 0x17e4, 0x17e7, 0x17ea, - 0x17ed, 0x17f1, 0x17f5, 0x17f8, 0x17fb, 0x17fe, 0x1801, 0x1804, - - 0x1809, 0x180c, 0x180f, 0x1812, 0x1815, 0x1818, 0x181b, 0x181e, - 0x1821, 0x1825, 0x182a, 0x182d, 0x1830, 0x1833, 0x1836, 0x1839, - - 0x183c, 0x183f, 0x1843, 0x1847, 0x184b, 0x184f, 0x1852, 0x1855, - 0x1858, 0x185b, 0x185e, 0x1861, 0x1864, 0x1867, 0x186a, 0x186d, - - 0x1871, 0x1875, 0x1878, 0x187c, 0x1880, 0x1884, 0x1887, 0x188b, - 0x188f, 0x1894, 0x1897, 0x189b, 0x189f, 0x18a3, 0x18a7, 0x18ad, - - 0x18b4, 0x18b7, 0x18ba, 0x18bd, 0x18c0, 0x18c3, 0x18c6, 0x18c9, - 0x18cc, 0x18cf, 0x18d2, 0x18d5, 0x18d8, 0x18db, 0x18de, 0x18e1, - - 0x18e4, 0x18e7, 0x18ea, 0x18ef, 0x18f2, 0x18f5, 0x18f8, 0x18fd, - 0x1901, 0x1904, 0x1907, 0x190a, 0x190d, 0x1910, 0x1913, 0x1916, - - 0x1919, 0x191c, 0x191f, 0x1923, 0x1926, 0x1929, 0x192d, 0x1931, - 0x1934, 0x1939, 0x193d, 0x1940, 0x1943, 0x1946, 0x1949, 0x194d, - - 0x1951, 0x1954, 0x1957, 0x195a, 0x195d, 0x1960, 0x1963, 0x1966, - 0x1969, 0x196c, 0x1970, 0x1974, 0x1978, 0x197c, 0x1980, 0x1984, - - 0x1988, 0x198c, 0x1990, 0x1994, 0x1998, 0x199c, 0x19a0, 0x19a4, - 0x19a8, 0x19ac, 0x19b0, 0x19b4, 0x19b8, 0x19bc, 0x19c0, 0x19c4, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x19c8, 0x19ca, 0x19cc, 0x19ce, 0x19d0, 0x19d2, 0x19d4, 0x19d6, - 0x19d8, 0x19da, 0x19dc, 0x19de, 0x19e0, 0x19e2, 0x19e4, 0x19e6, - 0x19e8, 0x19ea, 0x19ec, 0x19ee, 0x19f0, 0x19f2, 0x19f4, 0x19f6, - 0x19f8, 0x19fa, 0x19fc, 0x19fe, 0x1a00, 0x1a02, 0x1a04, 0x1a06, - 0x1a08, 0x1a0a, 0x1a0c, 0x1a0e, 0x1a10, 0x1a12, 0x1a14, 0x1a16, - 0x1a18, 0x1a1a, 0x1a1c, 0x1a1e, 0x1a20, 0x1a22, 0x1a24, 0x1a26, - 0x1a28, 0x1a2a, 0x1a2c, 0x1a2e, 0x1a30, 0x1a32, 0x1a34, 0x1a36, - 0x1a38, 0x1a3a, 0x1a3c, 0x1a3e, 0x1a40, 0x1a42, 0x1a44, 0x1a46, - 0x1a48, 0x1a4a, 0x1a4c, 0x1a4e, 0x1a50, 0x1a52, 0x1a54, 0x1a56, - 0x1a58, 0x1a5a, 0x1a5c, 0x1a5e, 0x1a60, 0x1a62, 0x1a64, 0x1a66, - 0x1a68, 0x1a6a, 0x1a6c, 0x1a6e, 0x1a70, 0x1a72, 0x1a74, 0x1a76, - 0x1a78, 0x1a7a, 0x1a7c, 0x1a7e, 0x1a80, 0x1a82, 0x1a84, 0x1a86, - 0x1a88, 0x1a8a, 0x1a8c, 0x1a8e, 0x1a90, 0x1a92, 0x1a94, 0x1a96, - 0x1a98, 0x1a9a, 0x1a9c, 0x1a9e, 0x1aa0, 0x1aa2, 0x1aa4, 0x1aa6, - 0x1aa8, 0x1aaa, 0x1aac, 0x1aae, 0x1ab0, 0x1ab2, 0x1ab4, 0x1ab6, - 0x1ab8, 0x1aba, 0x1abc, 0x1abe, 0x1ac0, 0x1ac2, 0x1ac4, 0x1ac6, - 0x1ac8, 0x1aca, 0x1acc, 0x1ace, 0x1ad0, 0x1ad2, 0x1ad4, 0x1ad6, - 0x1ad8, 0x1ada, 0x1adc, 0x1ade, 0x1ae0, 0x1ae2, 0x1ae4, 0x1ae6, - 0x1ae8, 0x1aea, 0x1aec, 0x1aee, 0x1af0, 0x1af2, 0x1af4, 0x1af6, - 0x1af8, 0x1afa, 0x1afc, 0x1afe, 0x1b00, 0x1b02, 0x1b04, 0x1b06, - 0x1b08, 0x1b0a, 0x1b0c, 0x1b0e, 0x1b10, 0x1b12, 0x1b14, 0x1b16, - 0x1b18, 0x1b1a, 0x1b1c, 0x1b1e, 0x1b20, 0x1b22, 0x1b24, 0x1b26, - 0x1b28, 0x1b2a, 0x1b2c, 0x1b2e, 0x1b30, 0x1b32, 0x1b34, 0x1b36, - 0x1b38, 0x1b3a, 0x1b3c, 0x1b3e, 0x1b40, 0x1b42, 0x1b44, 0x1b46, - 0x1b48, 0x1b4a, 0x1b4c, 0x1b4e, 0x1b50, 0x1b52, 0x1b54, 0x1b56, - 0x1b58, 0x1b5a, 0x1b5c, 0x1b5e, 0x1b60, 0x1b62, 0x1b64, 0x1b66, - 0x1b68, 0x1b6a, 0x1b6c, 0x1b6e, 0x1b70, 0x1b72, 0x1b74, 0x1b76, - 0x1b78, 0x1b7a, 0x1b7c, 0x1b7e, 0x1b80, 0x1b82, 0x1b84, 0x1b86, - 0x1b88, 0x1b8a, 0x1b8c, 0x1b8e, 0x1b90, 0x1b92, 0x1b94, 0x1b96, - 0x1b98, 0x1b9a, 0x1b9c, 0x1b9e, 0x1ba0, 0x1ba2, 0x1ba4, 0x1ba6, - 0x1ba8, 0x1baa, 0x1bac, 0x1bae, 0x1bb0, 0x1bb2, 0x1bb4, 0x1bb6, - 0x1bb8, 0x1bba, 0x1bbc, 0x1bbe, 0x1bc0, 0x1bc2, 0x1bc4, 0x1bc6, - - 0x1bc8, 0x1bca, 0x1bcc, 0x1bce, 0x1bd0, 0x1bd2, 0x1bd4, 0x1bd6, - 0x1bd8, 0x1bda, 0x1bdc, 0x1bde, 0x1be0, 0x1be2, 0xffff, 0xffff, - 0x1be4, 0xffff, 0x1be6, 0xffff, 0xffff, 0x1be8, 0x1bea, 0x1bec, - 0x1bee, 0x1bf0, 0x1bf2, 0x1bf4, 0x1bf6, 0x1bf8, 0x1bfa, 0xffff, - 0x1bfc, 0xffff, 0x1bfe, 0xffff, 0xffff, 0x1c00, 0x1c02, 0xffff, - 0xffff, 0xffff, 0x1c04, 0x1c06, 0x1c08, 0x1c0a, 0xffff, 0xffff, - 0x1c0c, 0x1c0e, 0x1c10, 0x1c12, 0x1c14, 0x1c16, 0x1c18, 0x1c1a, - 0x1c1c, 0x1c1e, 0x1c20, 0x1c22, 0x1c24, 0x1c26, 0x1c28, 0x1c2a, - 0x1c2c, 0x1c2e, 0x1c30, 0x1c32, 0x1c34, 0x1c36, 0x1c38, 0x1c3a, - 0x1c3c, 0x1c3e, 0x1c40, 0x1c42, 0x1c44, 0x1c46, 0x1c48, 0x1c4a, - 0x1c4c, 0x1c4e, 0x1c50, 0x1c52, 0x1c54, 0x1c56, 0x1c58, 0x1c5a, - 0x1c5c, 0x1c5e, 0x1c60, 0x1c62, 0x1c64, 0x1c66, 0x1c68, 0x1c6a, - 0x1c6c, 0x1c6e, 0x1c70, 0x1c72, 0x1c74, 0x1c76, 0x1c78, 0x1c7a, - 0x1c7c, 0x1c7e, 0x1c80, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x1c82, 0x1c84, 0x1c86, 0x1c88, 0x1c8a, 0x1c8c, 0x1c8e, 0x1c90, - 0x1c92, 0x1c94, 0x1c96, 0x1c98, 0x1c9a, 0x1c9c, 0x1c9e, 0x1ca0, - 0x1ca2, 0x1ca4, 0x1ca6, 0x1ca8, 0x1caa, 0x1cac, 0x1cae, 0x1cb0, - 0x1cb2, 0x1cb4, 0x1cb6, 0x1cb8, 0x1cba, 0x1cbc, 0x1cbe, 0x1cc0, - 0x1cc2, 0x1cc4, 0x1cc6, 0x1cc8, 0x1cca, 0x1ccc, 0x1cce, 0x1cd0, - 0x1cd2, 0x1cd4, 0x1cd6, 0x1cd8, 0x1cda, 0x1cdc, 0x1cde, 0x1ce0, - 0x1ce2, 0x1ce4, 0x1ce6, 0x1ce8, 0x1cea, 0x1cec, 0x1cee, 0x1cf0, - 0x1cf2, 0x1cf4, 0x1cf6, 0x1cf8, 0x1cfa, 0x1cfc, 0x1cfe, 0x1d00, - 0x1d02, 0x1d04, 0x1d06, 0x1d08, 0x1d0a, 0x1d0c, 0x1d0e, 0x1d10, - 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, 0x1d20, - 0x1d22, 0x1d24, 0x1d26, 0x1d28, 0x1d2a, 0x1d2c, 0x1d2e, 0x1d30, - 0x1d32, 0x1d34, 0x1d36, 0x1d38, 0x1d3a, 0x1d3c, 0x1d3e, 0x1d40, - 0x1d43, 0x1d46, 0x1d49, 0x1d4b, 0x1d4d, 0x1d4f, 0x1d52, 0x1d55, - 0x1d58, 0x1d5a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x1d5c, 0x1d5f, 0x1d62, 0x1d65, 0x1d69, 0x1d6d, 0x1d70, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x1d73, 0x1d76, 0x1d79, 0x1d7c, 0x1d7f, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1d82, 0xffff, 0x1d85, - 0x1d88, 0x1d8a, 0x1d8c, 0x1d8e, 0x1d90, 0x1d92, 0x1d94, 0x1d96, - 0x1d98, 0x1d9a, 0x1d9c, 0x1d9f, 0x1da2, 0x1da5, 0x1da8, 0x1dab, - 0x1dae, 0x1db1, 0x1db4, 0x1db7, 0x1dba, 0x1dbd, 0x1dc0, 0xffff, - 0x1dc3, 0x1dc6, 0x1dc9, 0x1dcc, 0x1dcf, 0xffff, 0x1dd2, 0xffff, - 0x1dd5, 0x1dd8, 0xffff, 0x1ddb, 0x1dde, 0xffff, 0x1de1, 0x1de4, - 0x1de7, 0x1dea, 0x1ded, 0x1df0, 0x1df3, 0x1df6, 0x1df9, 0x1dfc, - 0x1dff, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, - 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, - 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, - 0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, - 0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, - 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, - 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, - 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e7b, 0x1e7d, - 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89, 0x1e8b, 0x1e8d, - 0x1e8f, 0x1e91, 0x1e93, 0x1e95, 0x1e97, 0x1e99, 0x1e9b, 0x1e9d, - 0x1e9f, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, - 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, 0x1ebd, - 0x1ebf, 0x1ec1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb, - 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, - 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, - 0x1eed, 0x1eef, 0x1ef1, 0x1ef4, 0x1ef7, 0x1efa, 0x1efd, 0x1f00, - 0x1f03, 0x1f06, 0x1f09, 0x1f0c, 0x1f0f, 0x1f12, 0x1f15, 0x1f18, - 0x1f1b, 0x1f1e, 0x1f21, 0x1f24, 0x1f27, 0x1f29, 0x1f2b, 0x1f2d, - - 0x1f2f, 0x1f32, 0x1f35, 0x1f38, 0x1f3b, 0x1f3e, 0x1f41, 0x1f44, - 0x1f47, 0x1f4a, 0x1f4d, 0x1f50, 0x1f53, 0x1f56, 0x1f59, 0x1f5c, - 0x1f5f, 0x1f62, 0x1f65, 0x1f68, 0x1f6b, 0x1f6e, 0x1f71, 0x1f74, - 0x1f77, 0x1f7a, 0x1f7d, 0x1f80, 0x1f83, 0x1f86, 0x1f89, 0x1f8c, - 0x1f8f, 0x1f92, 0x1f95, 0x1f98, 0x1f9b, 0x1f9e, 0x1fa1, 0x1fa4, - 0x1fa7, 0x1faa, 0x1fad, 0x1fb0, 0x1fb3, 0x1fb6, 0x1fb9, 0x1fbc, - 0x1fbf, 0x1fc2, 0x1fc5, 0x1fc8, 0x1fcb, 0x1fce, 0x1fd1, 0x1fd4, - 0x1fd7, 0x1fda, 0x1fdd, 0x1fe0, 0x1fe3, 0x1fe6, 0x1fe9, 0x1fec, - 0x1fef, 0x1ff2, 0x1ff5, 0x1ff8, 0x1ffb, 0x1ffe, 0x2001, 0x2004, - 0x2007, 0x200a, 0x200d, 0x2010, 0x2013, 0x2016, 0x2019, 0x201c, - 0x201f, 0x2022, 0x2025, 0x2028, 0x202b, 0x202e, 0x2031, 0x2034, - 0x2037, 0x203a, 0x203d, 0x2040, 0x2043, 0x2046, 0x2049, 0x204d, - 0x2051, 0x2055, 0x2059, 0x205d, 0x2061, 0x2064, 0x2067, 0x206a, - 0x206d, 0x2070, 0x2073, 0x2076, 0x2079, 0x207c, 0x207f, 0x2082, - 0x2085, 0x2088, 0x208b, 0x208e, 0x2091, 0x2094, 0x2097, 0x209a, - 0x209d, 0x20a0, 0x20a3, 0x20a6, 0x20a9, 0x20ac, 0x20af, 0x20b2, - 0x20b5, 0x20b8, 0x20bb, 0x20be, 0x20c1, 0x20c4, 0x20c7, 0x20ca, - 0x20cd, 0x20d0, 0x20d3, 0x20d6, 0x20d9, 0x20dc, 0x20df, 0x20e2, - 0x20e5, 0x20e8, 0x20eb, 0x20ee, 0x20f1, 0x20f4, 0x20f7, 0x20fa, - 0x20fd, 0x2100, 0x2103, 0x2106, 0x2109, 0x210c, 0x210f, 0x2112, - 0x2115, 0x2118, 0x211b, 0x211e, 0x2121, 0x2124, 0x2127, 0x212a, - 0x212d, 0x2130, 0x2133, 0x2136, 0x2139, 0x213c, 0x213f, 0x2142, - 0x2145, 0x2148, 0x214b, 0x214e, 0x2151, 0x2154, 0x2157, 0x215a, - 0x215d, 0x2160, 0x2163, 0x2166, 0x2169, 0x216c, 0x216f, 0x2172, - 0x2175, 0x2178, 0x217b, 0x217e, 0x2181, 0x2184, 0x2187, 0x218a, - 0x218d, 0x2190, 0x2193, 0x2196, 0x2199, 0x219c, 0x219f, 0x21a2, - 0x21a5, 0x21a8, 0x21ab, 0x21ae, 0x21b1, 0x21b4, 0x21b7, 0x21ba, - 0x21bd, 0x21c0, 0x21c3, 0x21c6, 0x21c9, 0x21cc, 0x21cf, 0x21d2, - 0x21d5, 0x21d8, 0x21db, 0x21de, 0x21e1, 0x21e4, 0x21e7, 0x21ea, - 0x21ed, 0x21f0, 0x21f3, 0x21f6, 0x21f9, 0x21fc, 0x21ff, 0x2202, - 0x2205, 0x2208, 0x220b, 0x220f, 0x2213, 0x2217, 0x221a, 0x221d, - 0x2220, 0x2223, 0x2226, 0x2229, 0x222c, 0x222f, 0x2232, 0x2235, - - 0x2238, 0x223b, 0x223e, 0x2241, 0x2244, 0x2247, 0x224a, 0x224d, - 0x2250, 0x2253, 0x2256, 0x2259, 0x225c, 0x225f, 0x2262, 0x2265, - 0x2268, 0x226b, 0x226e, 0x2271, 0x2274, 0x2277, 0x227a, 0x227d, - 0x2280, 0x2283, 0x2286, 0x2289, 0x228c, 0x228f, 0x2292, 0x2295, - 0x2298, 0x229b, 0x229e, 0x22a1, 0x22a4, 0x22a7, 0x22aa, 0x22ad, - 0x22b0, 0x22b3, 0x22b6, 0x22b9, 0x22bc, 0x22bf, 0x22c2, 0x22c5, - 0x22c8, 0x22cb, 0x22ce, 0x22d1, 0x22d4, 0x22d7, 0x22da, 0x22dd, - 0x22e0, 0x22e3, 0x22e6, 0x22e9, 0x22ec, 0x22ef, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x22f2, 0x22f6, 0x22fa, 0x22fe, 0x2302, 0x2306, 0x230a, 0x230e, - 0x2312, 0x2316, 0x231a, 0x231e, 0x2322, 0x2326, 0x232a, 0x232e, - 0x2332, 0x2336, 0x233a, 0x233e, 0x2342, 0x2346, 0x234a, 0x234e, - 0x2352, 0x2356, 0x235a, 0x235e, 0x2362, 0x2366, 0x236a, 0x236e, - 0x2372, 0x2376, 0x237a, 0x237e, 0x2382, 0x2386, 0x238a, 0x238e, - 0x2392, 0x2396, 0x239a, 0x239e, 0x23a2, 0x23a6, 0x23aa, 0x23ae, - 0x23b2, 0x23b6, 0x23ba, 0x23be, 0x23c2, 0x23c6, 0x23ca, 0x23ce, - 0x23d2, 0x23d6, 0x23da, 0x23de, 0x23e2, 0x23e6, 0x23ea, 0x23ee, - 0xffff, 0xffff, 0x23f2, 0x23f6, 0x23fa, 0x23fe, 0x2402, 0x2406, - 0x240a, 0x240e, 0x2412, 0x2416, 0x241a, 0x241e, 0x2422, 0x2426, - 0x242a, 0x242e, 0x2432, 0x2436, 0x243a, 0x243e, 0x2442, 0x2446, - 0x244a, 0x244e, 0x2452, 0x2456, 0x245a, 0x245e, 0x2462, 0x2466, - 0x246a, 0x246e, 0x2472, 0x2476, 0x247a, 0x247e, 0x2482, 0x2486, - 0x248a, 0x248e, 0x2492, 0x2496, 0x249a, 0x249e, 0x24a2, 0x24a6, - 0x24aa, 0x24ae, 0x24b2, 0x24b6, 0x24ba, 0x24be, 0x24c2, 0x24c6, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x24ca, 0x24ce, 0x24d2, 0x24d7, 0x24dc, 0x24e1, 0x24e6, 0x24eb, - 0x24f0, 0x24f5, 0x24f9, 0x250c, 0x2515, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x251a, 0x251c, 0x251e, 0x2520, 0x2522, 0x2524, 0x2526, 0x2528, - 0x252a, 0x252c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x252e, 0x2530, 0x2532, 0x2534, 0x2536, 0x2538, 0x253a, 0x253c, - 0x253e, 0x2540, 0x2542, 0x2544, 0x2546, 0x2548, 0x254a, 0x254c, - 0x254e, 0x2550, 0x2552, 0x2554, 0x2556, 0xffff, 0xffff, 0x2558, - 0x255a, 0x255c, 0x255e, 0x2560, 0x2562, 0x2564, 0x2566, 0x2568, - 0x256a, 0x256c, 0x256e, 0xffff, 0x2570, 0x2572, 0x2574, 0x2576, - 0x2578, 0x257a, 0x257c, 0x257e, 0x2580, 0x2582, 0x2584, 0x2586, - 0x2588, 0x258a, 0x258c, 0x258e, 0x2590, 0x2592, 0x2594, 0xffff, - 0x2596, 0x2598, 0x259a, 0x259c, 0xffff, 0xffff, 0xffff, 0xffff, - 0x259e, 0x25a1, 0x25a4, 0xffff, 0x25a7, 0xffff, 0x25aa, 0x25ad, - 0x25b0, 0x25b3, 0x25b6, 0x25b9, 0x25bc, 0x25bf, 0x25c2, 0x25c5, - 0x25c8, 0x25ca, 0x25cc, 0x25ce, 0x25d0, 0x25d2, 0x25d4, 0x25d6, - 0x25d8, 0x25da, 0x25dc, 0x25de, 0x25e0, 0x25e2, 0x25e4, 0x25e6, - 0x25e8, 0x25ea, 0x25ec, 0x25ee, 0x25f0, 0x25f2, 0x25f4, 0x25f6, - 0x25f8, 0x25fa, 0x25fc, 0x25fe, 0x2600, 0x2602, 0x2604, 0x2606, - 0x2608, 0x260a, 0x260c, 0x260e, 0x2610, 0x2612, 0x2614, 0x2616, - 0x2618, 0x261a, 0x261c, 0x261e, 0x2620, 0x2622, 0x2624, 0x2626, - 0x2628, 0x262a, 0x262c, 0x262e, 0x2630, 0x2632, 0x2634, 0x2636, - 0x2638, 0x263a, 0x263c, 0x263e, 0x2640, 0x2642, 0x2644, 0x2646, - 0x2648, 0x264a, 0x264c, 0x264e, 0x2650, 0x2652, 0x2654, 0x2656, - 0x2658, 0x265a, 0x265c, 0x265e, 0x2660, 0x2662, 0x2664, 0x2666, - 0x2668, 0x266a, 0x266c, 0x266e, 0x2670, 0x2672, 0x2674, 0x2676, - 0x2678, 0x267a, 0x267c, 0x267e, 0x2680, 0x2682, 0x2684, 0x2686, - 0x2688, 0x268a, 0x268c, 0x268e, 0x2690, 0x2692, 0x2694, 0x2696, - 0x2698, 0x269a, 0x269c, 0x269e, 0x26a0, 0x26a2, 0x26a4, 0x26a6, - 0x26a8, 0x26aa, 0x26ac, 0x26ae, 0x26b0, 0x26b2, 0x26b5, 0x26b8, - 0x26bb, 0x26be, 0x26c1, 0x26c4, 0x26c7, 0xffff, 0xffff, 0xffff, - - 0xffff, 0x26ca, 0x26cc, 0x26ce, 0x26d0, 0x26d2, 0x26d4, 0x26d6, - 0x26d8, 0x26da, 0x26dc, 0x26de, 0x26e0, 0x26e2, 0x26e4, 0x26e6, - 0x26e8, 0x26ea, 0x26ec, 0x26ee, 0x26f0, 0x26f2, 0x26f4, 0x26f6, - 0x26f8, 0x26fa, 0x26fc, 0x26fe, 0x2700, 0x2702, 0x2704, 0x2706, - 0x2708, 0x270a, 0x270c, 0x270e, 0x2710, 0x2712, 0x2714, 0x2716, - 0x2718, 0x271a, 0x271c, 0x271e, 0x2720, 0x2722, 0x2724, 0x2726, - 0x2728, 0x272a, 0x272c, 0x272e, 0x2730, 0x2732, 0x2734, 0x2736, - 0x2738, 0x273a, 0x273c, 0x273e, 0x2740, 0x2742, 0x2744, 0x2746, - 0x2748, 0x274a, 0x274c, 0x274e, 0x2750, 0x2752, 0x2754, 0x2756, - 0x2758, 0x275a, 0x275c, 0x275e, 0x2760, 0x2762, 0x2764, 0x2766, - 0x2768, 0x276a, 0x276c, 0x276e, 0x2770, 0x2772, 0x2774, 0x2776, - 0x2778, 0x277a, 0x277c, 0x277e, 0x2780, 0x2782, 0x2784, 0x2786, - 0x2788, 0x278a, 0x278c, 0x278e, 0x2790, 0x2792, 0x2794, 0x2796, - 0x2798, 0x279a, 0x279c, 0x279e, 0x27a0, 0x27a2, 0x27a4, 0x27a6, - 0x27a8, 0x27aa, 0x27ac, 0x27ae, 0x27b0, 0x27b2, 0x27b4, 0x27b6, - 0x27b8, 0x27ba, 0x27bc, 0x27be, 0x27c0, 0x27c2, 0x27c4, 0x27c6, - 0x27c8, 0x27ca, 0x27cc, 0x27ce, 0x27d0, 0x27d2, 0x27d4, 0x27d6, - 0x27d8, 0x27da, 0x27dc, 0x27de, 0x27e0, 0x27e2, 0x27e4, 0x27e6, - 0x27e8, 0x27ea, 0x27ec, 0x27ee, 0x27f0, 0x27f2, 0x27f4, 0x27f6, - 0x27f8, 0x27fa, 0x27fc, 0x27fe, 0x2800, 0x2802, 0x2804, 0x2806, - 0x2808, 0x280a, 0x280c, 0x280e, 0x2810, 0x2812, 0x2814, 0x2816, - 0x2818, 0x281a, 0x281c, 0x281e, 0x2820, 0x2822, 0x2824, 0x2826, - 0x2828, 0x282a, 0x282c, 0x282e, 0x2830, 0x2832, 0x2834, 0x2836, - 0x2838, 0x283a, 0x283c, 0x283e, 0x2840, 0x2842, 0x2844, 0xffff, - 0xffff, 0xffff, 0x2846, 0x2848, 0x284a, 0x284c, 0x284e, 0x2850, - 0xffff, 0xffff, 0x2852, 0x2854, 0x2856, 0x2858, 0x285a, 0x285c, - 0xffff, 0xffff, 0x285e, 0x2860, 0x2862, 0x2864, 0x2866, 0x2868, - 0xffff, 0xffff, 0x286a, 0x286c, 0x286e, 0xffff, 0xffff, 0xffff, - 0x2870, 0x2872, 0x2874, 0x2876, 0x2878, 0x287a, 0x287c, 0xffff, - 0x287e, 0x2880, 0x2882, 0x2884, 0x2886, 0x2888, 0x288a, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x288c, 0x2891, - 0x2896, 0x289b, 0x28a0, 0x28a5, 0x28aa, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x28af, 0x28b4, 0x28b9, 0x28be, 0x28c3, - 0x28c8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x28cd, 0x28cf, 0x28d1, 0x28d3, 0x28d5, 0x28d7, 0x28d9, 0x28db, - 0x28dd, 0x28df, 0x28e1, 0x28e3, 0x28e5, 0x28e7, 0x28e9, 0x28eb, - 0x28ed, 0x28ef, 0x28f1, 0x28f3, 0x28f5, 0x28f7, 0x28f9, 0x28fb, - 0x28fd, 0x28ff, 0x2901, 0x2903, 0x2905, 0x2907, 0x2909, 0x290b, - 0x290d, 0x290f, 0x2911, 0x2913, 0x2915, 0x2917, 0x2919, 0x291b, - 0x291d, 0x291f, 0x2921, 0x2923, 0x2925, 0x2927, 0x2929, 0x292b, - 0x292d, 0x292f, 0x2931, 0x2933, 0x2935, 0x2937, 0x2939, 0x293b, - 0x293d, 0x293f, 0x2941, 0x2943, 0x2945, 0x2947, 0x2949, 0x294b, - 0x294d, 0x294f, 0x2951, 0x2953, 0x2955, 0x2957, 0x2959, 0x295b, - 0x295d, 0x295f, 0x2961, 0x2963, 0x2965, 0x2967, 0x2969, 0x296b, - 0x296d, 0x296f, 0x2971, 0x2973, 0x2975, 0xffff, 0x2977, 0x2979, - 0x297b, 0x297d, 0x297f, 0x2981, 0x2983, 0x2985, 0x2987, 0x2989, - 0x298b, 0x298d, 0x298f, 0x2991, 0x2993, 0x2995, 0x2997, 0x2999, - 0x299b, 0x299d, 0x299f, 0x29a1, 0x29a3, 0x29a5, 0x29a7, 0x29a9, - 0x29ab, 0x29ad, 0x29af, 0x29b1, 0x29b3, 0x29b5, 0x29b7, 0x29b9, - 0x29bb, 0x29bd, 0x29bf, 0x29c1, 0x29c3, 0x29c5, 0x29c7, 0x29c9, - 0x29cb, 0x29cd, 0x29cf, 0x29d1, 0x29d3, 0x29d5, 0x29d7, 0x29d9, - 0x29db, 0x29dd, 0x29df, 0x29e1, 0x29e3, 0x29e5, 0x29e7, 0x29e9, - 0x29eb, 0x29ed, 0x29ef, 0x29f1, 0x29f3, 0x29f5, 0x29f7, 0x29f9, - 0x29fb, 0x29fd, 0x29ff, 0x2a01, 0x2a03, 0xffff, 0x2a05, 0x2a07, - 0xffff, 0xffff, 0x2a09, 0xffff, 0xffff, 0x2a0b, 0x2a0d, 0xffff, - 0xffff, 0x2a0f, 0x2a11, 0x2a13, 0x2a15, 0xffff, 0x2a17, 0x2a19, - 0x2a1b, 0x2a1d, 0x2a1f, 0x2a21, 0x2a23, 0x2a25, 0x2a27, 0x2a29, - 0x2a2b, 0x2a2d, 0xffff, 0x2a2f, 0xffff, 0x2a31, 0x2a33, 0x2a35, - 0x2a37, 0x2a39, 0x2a3b, 0x2a3d, 0xffff, 0x2a3f, 0x2a41, 0x2a43, - 0x2a45, 0x2a47, 0x2a49, 0x2a4b, 0x2a4d, 0x2a4f, 0x2a51, 0x2a53, - 0x2a55, 0x2a57, 0x2a59, 0x2a5b, 0x2a5d, 0x2a5f, 0x2a61, 0x2a63, - 0x2a65, 0x2a67, 0x2a69, 0x2a6b, 0x2a6d, 0x2a6f, 0x2a71, 0x2a73, - 0x2a75, 0x2a77, 0x2a79, 0x2a7b, 0x2a7d, 0x2a7f, 0x2a81, 0x2a83, - 0x2a85, 0x2a87, 0x2a89, 0x2a8b, 0x2a8d, 0x2a8f, 0x2a91, 0x2a93, - 0x2a95, 0x2a97, 0x2a99, 0x2a9b, 0x2a9d, 0x2a9f, 0x2aa1, 0x2aa3, - 0x2aa5, 0x2aa7, 0x2aa9, 0x2aab, 0x2aad, 0x2aaf, 0x2ab1, 0x2ab3, - - 0x2ab5, 0x2ab7, 0x2ab9, 0x2abb, 0x2abd, 0x2abf, 0xffff, 0x2ac1, - 0x2ac3, 0x2ac5, 0x2ac7, 0xffff, 0xffff, 0x2ac9, 0x2acb, 0x2acd, - 0x2acf, 0x2ad1, 0x2ad3, 0x2ad5, 0x2ad7, 0xffff, 0x2ad9, 0x2adb, - 0x2add, 0x2adf, 0x2ae1, 0x2ae3, 0x2ae5, 0xffff, 0x2ae7, 0x2ae9, - 0x2aeb, 0x2aed, 0x2aef, 0x2af1, 0x2af3, 0x2af5, 0x2af7, 0x2af9, - 0x2afb, 0x2afd, 0x2aff, 0x2b01, 0x2b03, 0x2b05, 0x2b07, 0x2b09, - 0x2b0b, 0x2b0d, 0x2b0f, 0x2b11, 0x2b13, 0x2b15, 0x2b17, 0x2b19, - 0x2b1b, 0x2b1d, 0xffff, 0x2b1f, 0x2b21, 0x2b23, 0x2b25, 0xffff, - 0x2b27, 0x2b29, 0x2b2b, 0x2b2d, 0x2b2f, 0xffff, 0x2b31, 0xffff, - 0xffff, 0xffff, 0x2b33, 0x2b35, 0x2b37, 0x2b39, 0x2b3b, 0x2b3d, - 0x2b3f, 0xffff, 0x2b41, 0x2b43, 0x2b45, 0x2b47, 0x2b49, 0x2b4b, - 0x2b4d, 0x2b4f, 0x2b51, 0x2b53, 0x2b55, 0x2b57, 0x2b59, 0x2b5b, - 0x2b5d, 0x2b5f, 0x2b61, 0x2b63, 0x2b65, 0x2b67, 0x2b69, 0x2b6b, - 0x2b6d, 0x2b6f, 0x2b71, 0x2b73, 0x2b75, 0x2b77, 0x2b79, 0x2b7b, - 0x2b7d, 0x2b7f, 0x2b81, 0x2b83, 0x2b85, 0x2b87, 0x2b89, 0x2b8b, - 0x2b8d, 0x2b8f, 0x2b91, 0x2b93, 0x2b95, 0x2b97, 0x2b99, 0x2b9b, - 0x2b9d, 0x2b9f, 0x2ba1, 0x2ba3, 0x2ba5, 0x2ba7, 0x2ba9, 0x2bab, - 0x2bad, 0x2baf, 0x2bb1, 0x2bb3, 0x2bb5, 0x2bb7, 0x2bb9, 0x2bbb, - 0x2bbd, 0x2bbf, 0x2bc1, 0x2bc3, 0x2bc5, 0x2bc7, 0x2bc9, 0x2bcb, - 0x2bcd, 0x2bcf, 0x2bd1, 0x2bd3, 0x2bd5, 0x2bd7, 0x2bd9, 0x2bdb, - 0x2bdd, 0x2bdf, 0x2be1, 0x2be3, 0x2be5, 0x2be7, 0x2be9, 0x2beb, - 0x2bed, 0x2bef, 0x2bf1, 0x2bf3, 0x2bf5, 0x2bf7, 0x2bf9, 0x2bfb, - 0x2bfd, 0x2bff, 0x2c01, 0x2c03, 0x2c05, 0x2c07, 0x2c09, 0x2c0b, - 0x2c0d, 0x2c0f, 0x2c11, 0x2c13, 0x2c15, 0x2c17, 0x2c19, 0x2c1b, - 0x2c1d, 0x2c1f, 0x2c21, 0x2c23, 0x2c25, 0x2c27, 0x2c29, 0x2c2b, - 0x2c2d, 0x2c2f, 0x2c31, 0x2c33, 0x2c35, 0x2c37, 0x2c39, 0x2c3b, - 0x2c3d, 0x2c3f, 0x2c41, 0x2c43, 0x2c45, 0x2c47, 0x2c49, 0x2c4b, - 0x2c4d, 0x2c4f, 0x2c51, 0x2c53, 0x2c55, 0x2c57, 0x2c59, 0x2c5b, - 0x2c5d, 0x2c5f, 0x2c61, 0x2c63, 0x2c65, 0x2c67, 0x2c69, 0x2c6b, - 0x2c6d, 0x2c6f, 0x2c71, 0x2c73, 0x2c75, 0x2c77, 0x2c79, 0x2c7b, - 0x2c7d, 0x2c7f, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b, - 0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b, - - 0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab, - 0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb, - 0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb, - 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb, - 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce5, 0x2ce7, 0x2ce9, 0x2ceb, - 0x2ced, 0x2cef, 0x2cf1, 0x2cf3, 0x2cf5, 0x2cf7, 0x2cf9, 0x2cfb, - 0x2cfd, 0x2cff, 0x2d01, 0x2d03, 0x2d05, 0x2d07, 0x2d09, 0x2d0b, - 0x2d0d, 0x2d0f, 0x2d11, 0x2d13, 0x2d15, 0x2d17, 0x2d19, 0x2d1b, - 0x2d1d, 0x2d1f, 0x2d21, 0x2d23, 0x2d25, 0x2d27, 0x2d29, 0x2d2b, - 0x2d2d, 0x2d2f, 0x2d31, 0x2d33, 0x2d35, 0x2d37, 0x2d39, 0x2d3b, - 0x2d3d, 0x2d3f, 0x2d41, 0x2d43, 0x2d45, 0x2d47, 0x2d49, 0x2d4b, - 0x2d4d, 0x2d4f, 0x2d51, 0x2d53, 0x2d55, 0x2d57, 0x2d59, 0x2d5b, - 0x2d5d, 0x2d5f, 0x2d61, 0x2d63, 0x2d65, 0x2d67, 0x2d69, 0x2d6b, - 0x2d6d, 0x2d6f, 0x2d71, 0x2d73, 0x2d75, 0x2d77, 0x2d79, 0x2d7b, - 0x2d7d, 0x2d7f, 0x2d81, 0x2d83, 0x2d85, 0x2d87, 0x2d89, 0x2d8b, - 0x2d8d, 0x2d8f, 0x2d91, 0x2d93, 0x2d95, 0x2d97, 0x2d99, 0x2d9b, - 0x2d9d, 0x2d9f, 0x2da1, 0x2da3, 0x2da5, 0x2da7, 0x2da9, 0x2dab, - 0x2dad, 0x2daf, 0x2db1, 0x2db3, 0x2db5, 0x2db7, 0x2db9, 0x2dbb, - 0x2dbd, 0x2dbf, 0x2dc1, 0x2dc3, 0x2dc5, 0x2dc7, 0x2dc9, 0x2dcb, - 0x2dcd, 0x2dcf, 0x2dd1, 0x2dd3, 0x2dd5, 0x2dd7, 0x2dd9, 0x2ddb, - 0x2ddd, 0x2ddf, 0x2de1, 0x2de3, 0x2de5, 0x2de7, 0xffff, 0xffff, - 0x2de9, 0x2deb, 0x2ded, 0x2def, 0x2df1, 0x2df3, 0x2df5, 0x2df7, - 0x2df9, 0x2dfb, 0x2dfd, 0x2dff, 0x2e01, 0x2e03, 0x2e05, 0x2e07, - 0x2e09, 0x2e0b, 0x2e0d, 0x2e0f, 0x2e11, 0x2e13, 0x2e15, 0x2e17, - 0x2e19, 0x2e1b, 0x2e1d, 0x2e1f, 0x2e21, 0x2e23, 0x2e25, 0x2e27, - 0x2e29, 0x2e2b, 0x2e2d, 0x2e2f, 0x2e31, 0x2e33, 0x2e35, 0x2e37, - 0x2e39, 0x2e3b, 0x2e3d, 0x2e3f, 0x2e41, 0x2e43, 0x2e45, 0x2e47, - 0x2e49, 0x2e4b, 0x2e4d, 0x2e4f, 0x2e51, 0x2e53, 0x2e55, 0x2e57, - 0x2e59, 0x2e5b, 0x2e5d, 0x2e5f, 0x2e61, 0x2e63, 0x2e65, 0x2e67, - 0x2e69, 0x2e6b, 0x2e6d, 0x2e6f, 0x2e71, 0x2e73, 0x2e75, 0x2e77, - 0x2e79, 0x2e7b, 0x2e7d, 0x2e7f, 0x2e81, 0x2e83, 0x2e85, 0x2e87, - 0x2e89, 0x2e8b, 0x2e8d, 0x2e8f, 0x2e91, 0x2e93, 0x2e95, 0x2e97, - - 0x2e99, 0x2e9b, 0x2e9d, 0x2e9f, 0x2ea1, 0x2ea3, 0x2ea5, 0x2ea7, - 0x2ea9, 0x2eab, 0x2ead, 0x2eaf, 0x2eb1, 0x2eb3, 0x2eb5, 0x2eb7, - 0x2eb9, 0x2ebb, 0x2ebd, 0x2ebf, 0x2ec1, 0x2ec3, 0x2ec5, 0x2ec7, - 0x2ec9, 0x2ecb, 0x2ecd, 0x2ecf, 0x2ed1, 0x2ed3, 0x2ed5, 0x2ed7, - 0x2ed9, 0x2edb, 0x2edd, 0x2edf, 0x2ee1, 0x2ee3, 0x2ee5, 0x2ee7, - 0x2ee9, 0x2eeb, 0x2eed, 0x2eef, 0x2ef1, 0x2ef3, 0x2ef5, 0x2ef7, - 0x2ef9, 0x2efb, 0x2efd, 0x2eff, 0x2f01, 0x2f03, 0x2f05, 0x2f07, - 0x2f09, 0x2f0b, 0x2f0d, 0x2f0f, 0x2f11, 0x2f13, 0x2f15, 0x2f17, - 0x2f19, 0x2f1b, 0x2f1d, 0x2f1f, 0x2f21, 0x2f23, 0x2f25, 0x2f27, - 0x2f29, 0x2f2b, 0x2f2d, 0x2f2f, 0x2f31, 0x2f33, 0x2f35, 0x2f37, - 0x2f39, 0x2f3b, 0x2f3d, 0x2f3f, 0x2f41, 0x2f43, 0x2f45, 0x2f47, - 0x2f49, 0x2f4b, 0x2f4d, 0x2f4f, 0x2f51, 0x2f53, 0x2f55, 0x2f57, - 0x2f59, 0x2f5b, 0x2f5d, 0x2f5f, 0x2f61, 0x2f63, 0x2f65, 0x2f67, - 0x2f69, 0x2f6b, 0x2f6d, 0x2f6f, 0x2f71, 0x2f73, 0x2f75, 0x2f77, - 0x2f79, 0x2f7b, 0x2f7d, 0x2f7f, 0x2f81, 0x2f83, 0x2f85, 0x2f87, - 0x2f89, 0x2f8b, 0x2f8d, 0x2f8f, 0x2f91, 0x2f93, 0x2f95, 0x2f97, - 0x2f99, 0x2f9b, 0x2f9d, 0x2f9f, 0x2fa1, 0x2fa3, 0x2fa5, 0x2fa7, - 0x2fa9, 0x2fab, 0x2fad, 0x2faf, 0x2fb1, 0x2fb3, 0x2fb5, 0x2fb7, - 0x2fb9, 0x2fbb, 0x2fbd, 0x2fbf, 0x2fc1, 0x2fc3, 0x2fc5, 0x2fc7, - 0x2fc9, 0x2fcb, 0x2fcd, 0x2fcf, 0x2fd1, 0x2fd3, 0x2fd5, 0x2fd7, - 0x2fd9, 0x2fdb, 0x2fdd, 0x2fdf, 0x2fe1, 0x2fe3, 0x2fe5, 0x2fe7, - 0x2fe9, 0x2feb, 0x2fed, 0x2fef, 0x2ff1, 0x2ff3, 0x2ff5, 0x2ff7, - 0x2ff9, 0x2ffb, 0x2ffd, 0x2fff, 0x3001, 0x3003, 0x3005, 0x3007, - 0x3009, 0x300b, 0x300d, 0x300f, 0x3011, 0x3013, 0x3015, 0x3017, - 0x3019, 0x301b, 0x301d, 0x301f, 0x3021, 0x3023, 0x3025, 0x3027, - 0x3029, 0x302b, 0x302d, 0x302f, 0xffff, 0xffff, 0x3031, 0x3033, - 0x3035, 0x3037, 0x3039, 0x303b, 0x303d, 0x303f, 0x3041, 0x3043, - 0x3045, 0x3047, 0x3049, 0x304b, 0x304d, 0x304f, 0x3051, 0x3053, - 0x3055, 0x3057, 0x3059, 0x305b, 0x305d, 0x305f, 0x3061, 0x3063, - 0x3065, 0x3067, 0x3069, 0x306b, 0x306d, 0x306f, 0x3071, 0x3073, - 0x3075, 0x3077, 0x3079, 0x307b, 0x307d, 0x307f, 0x3081, 0x3083, - 0x3085, 0x3087, 0x3089, 0x308b, 0x308d, 0x308f, 0x3091, 0x3093, - - 0x3095, 0x3097, 0x3099, 0x309b, 0x309e, 0x30a0, 0x30a2, 0x30a4, - 0x30a6, 0x30a8, 0x30aa, 0x30ac, 0x30ae, 0x30b0, 0x30b3, 0x30b5, - 0x30b7, 0x30b9, 0x30bb, 0x30be, 0x30c0, 0x30c2, 0x30c4, 0x30c7, - 0x30c9, 0x30cb, 0x30cd, 0x30cf, 0x30d1, 0x30d4, 0x30d6, 0x30d8, - 0x30da, 0x30dc, 0x30de, 0x30e0, 0x30e2, 0x30e4, 0x30e6, 0x30e8, - 0x30ea, 0x30ec, 0x30ee, 0x30f0, 0x30f2, 0x30f4, 0x30f6, 0x30f8, - 0x30fa, 0x30fc, 0x30fe, 0x3100, 0x3102, 0x3105, 0x3107, 0x3109, - 0x310b, 0x310e, 0x3110, 0x3112, 0x3114, 0x3116, 0x3118, 0x311a, - 0x311c, 0x311e, 0x3120, 0x3122, 0x3124, 0x3126, 0x3128, 0x312a, - 0x312c, 0x312e, 0x3130, 0x3132, 0x3134, 0x3136, 0x3138, 0x313a, - 0x313c, 0x313e, 0x3140, 0x3142, 0x3144, 0x3146, 0x3148, 0x314a, - 0x314c, 0x314e, 0x3151, 0x3153, 0x3155, 0x3157, 0x3159, 0x315b, - 0x315d, 0x3160, 0x3163, 0x3165, 0x3167, 0x3169, 0x316b, 0x316d, - 0x316f, 0x3171, 0x3173, 0x3175, 0x3177, 0x317a, 0x317c, 0x317e, - 0x3180, 0x3182, 0x3185, 0x3187, 0x3189, 0x318b, 0x318d, 0x318f, - 0x3191, 0x3193, 0x3195, 0x3197, 0x319a, 0x319c, 0x319f, 0x31a1, - 0x31a3, 0x31a5, 0x31a7, 0x31a9, 0x31ab, 0x31ad, 0x31af, 0x31b1, - 0x31b3, 0x31b5, 0x31b8, 0x31ba, 0x31bc, 0x31be, 0x31c0, 0x31c2, - 0x31c5, 0x31c7, 0x31ca, 0x31cd, 0x31cf, 0x31d1, 0x31d3, 0x31d5, - 0x31d8, 0x31db, 0x31dd, 0x31df, 0x31e1, 0x31e3, 0x31e5, 0x31e7, - 0x31e9, 0x31eb, 0x31ed, 0x31ef, 0x31f1, 0x31f4, 0x31f6, 0x31f8, - 0x31fa, 0x31fc, 0x31fe, 0x3200, 0x3202, 0x3204, 0x3206, 0x3208, - 0x320a, 0x320c, 0x320e, 0x3210, 0x3212, 0x3214, 0x3216, 0x3218, - 0x321a, 0x321d, 0x321f, 0x3221, 0x3223, 0x3225, 0x3227, 0x322a, - 0x322c, 0x322e, 0x3230, 0x3232, 0x3234, 0x3236, 0x3238, 0x323a, - 0x323c, 0x323e, 0x3240, 0x3243, 0x3245, 0x3247, 0x3249, 0x324b, - 0x324d, 0x324f, 0x3251, 0x3253, 0x3255, 0x3257, 0x3259, 0x325b, - 0x325d, 0x325f, 0x3261, 0x3263, 0x3265, 0x3267, 0x326a, 0x326c, - 0x326e, 0x3270, 0x3272, 0x3274, 0x3277, 0x3279, 0x327b, 0x327d, - 0x327f, 0x3281, 0x3283, 0x3285, 0x3287, 0x328a, 0x328c, 0x328e, - 0x3290, 0x3293, 0x3295, 0x3297, 0x3299, 0x329b, 0x329d, 0x329f, - 0x32a2, 0x32a5, 0x32a8, 0x32aa, 0x32ad, 0x32af, 0x32b1, 0x32b3, - - 0x32b5, 0x32b7, 0x32b9, 0x32bb, 0x32bd, 0x32bf, 0x32c1, 0x32c4, - 0x32c6, 0x32c8, 0x32ca, 0x32cc, 0x32ce, 0x32d0, 0x32d3, 0x32d5, - 0x32d7, 0x32da, 0x32dd, 0x32df, 0x32e1, 0x32e3, 0x32e5, 0x32e7, - 0x32e9, 0x32eb, 0x32ed, 0x32ef, 0x32f2, 0x32f4, 0x32f7, 0x32f9, - 0x32fc, 0x32fe, 0x3300, 0x3302, 0x3305, 0x3307, 0x3309, 0x330c, - 0x330f, 0x3311, 0x3313, 0x3315, 0x3317, 0x3319, 0x331b, 0x331d, - 0x331f, 0x3321, 0x3323, 0x3325, 0x3327, 0x3329, 0x332c, 0x332e, - 0x3331, 0x3333, 0x3336, 0x3338, 0x333b, 0x333e, 0x3341, 0x3343, - 0x3345, 0x3347, 0x334a, 0x334d, 0x3350, 0x3353, 0x3355, 0x3357, - 0x3359, 0x335b, 0x335d, 0x335f, 0x3361, 0x3363, 0x3366, 0x3368, - 0x336a, 0x336c, 0x336e, 0x3371, 0x3373, 0x3376, 0x3379, 0x337b, - 0x337d, 0x337f, 0x3381, 0x3383, 0x3385, 0x3388, 0x338b, 0x338e, - 0x3390, 0x3392, 0x3395, 0x3397, 0x3399, 0x339b, 0x339e, 0x33a0, - 0x33a2, 0x33a4, 0x33a6, 0x33a8, 0x33ab, 0x33ad, 0x33af, 0x33b1, - 0x33b3, 0x33b5, 0x33b7, 0x33ba, 0x33bd, 0x33bf, 0x33c2, 0x33c4, - 0x33c7, 0x33c9, 0x33cb, 0x33cd, 0x33d0, 0x33d3, 0x33d5, 0x33d8, - 0x33da, 0x33dd, 0x33df, 0x33e1, 0x33e3, 0x33e5, 0x33e7, 0x33e9, - 0x33ec, 0x33ef, 0x33f2, 0x33f5, 0x33f7, 0x33f9, 0x33fb, 0x33fd, - 0x33ff, 0x3401, 0x3403, 0x3405, 0x3407, 0x3409, 0x340b, 0x340d, - 0x3410, 0x3412, 0x3414, 0x3416, 0x3418, 0x341a, 0x341c, 0x341e, - 0x3420, 0x3422, 0x3424, 0x3426, 0x3428, 0x342b, 0x342e, 0x3431, - 0x3433, 0x3435, 0x3437, 0x3439, 0x343c, 0x343e, 0x3441, 0x3443, - 0x3445, 0x3448, 0x344b, 0x344d, 0x344f, 0x3451, 0x3453, 0x3455, - 0x3457, 0x3459, 0x345b, 0x345d, 0x345f, 0x3461, 0x3463, 0x3465, - 0x3467, 0x3469, 0x346b, 0x346d, 0x346f, 0x3471, 0x3474, 0x3476, - 0x3478, 0x347a, 0x347c, 0x347e, 0x3481, 0x3484, 0x3486, 0x3488, - 0x348a, 0x348c, 0x348e, 0x3490, 0x3493, 0x3495, 0x3497, 0x3499, - 0x349b, 0x349e, 0x34a1, 0x34a3, 0x34a5, 0x34a7, 0x34aa, 0x34ac, - 0x34ae, 0x34b1, 0x34b4, 0x34b6, 0x34b8, 0x34ba, 0x34bd, 0x34bf, - 0x34c1, 0x34c3, 0x34c5, 0x34c7, 0x34c9, 0x34cb, 0x34ce, 0x34d0, - 0x34d2, 0x34d4, 0x34d7, 0x34d9, 0x34db, 0x34dd, 0x34df, 0x34e2, - 0x34e5, 0x34e7, 0x34e9, 0x34eb, 0x34ee, 0x34f0, 0x34f3, 0x34f5, - - 0x34f7, 0x34f9, 0x34fc, 0x34fe, 0x3500, 0x3502, 0x3504, 0x3506, - 0x3508, 0x350a, 0x350d, 0x350f, 0x3511, 0x3513, 0x3515, 0x3517, - 0x3519, 0x351c, 0x351e, 0x3521, 0x3524, 0x3527, 0x3529, 0x352b, - 0x352d, 0x352f, 0x3531, 0x3533, 0x3535, 0x3537, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x163f, 0x1642, 0x1646, 0x164b, 0x1650, 0x1653, 0x1659, 0x1660, + 0x1666, 0x166a, 0x1670, 0x1676, 0x167b, 0x167f, 0x1683, 0x1687, + + 0x168c, 0x1692, 0x1697, 0x169b, 0x169f, 0x16a3, 0x16a6, 0x16a9, + 0x16ac, 0x16af, 0x16b3, 0x16b7, 0x16bd, 0x16c1, 0x16c6, 0x16cc, + + 0x16d0, 0x16d3, 0x16d6, 0x16dc, 0x16e1, 0x16e7, 0x16eb, 0x16f1, + 0x16f4, 0x16f8, 0x16fc, 0x1700, 0x1704, 0x1708, 0x170d, 0x1711, + + 0x1714, 0x1718, 0x171c, 0x1720, 0x1725, 0x1729, 0x172d, 0x1731, + 0x1737, 0x173c, 0x173f, 0x1745, 0x1748, 0x174d, 0x1752, 0x1756, + + 0x175a, 0x175e, 0x1763, 0x1766, 0x176a, 0x176f, 0x1772, 0x1778, + 0x177c, 0x177f, 0x1782, 0x1785, 0x1788, 0x178b, 0x178e, 0x1791, + + 0x1794, 0x1797, 0x179a, 0x179e, 0x17a2, 0x17a6, 0x17aa, 0x17ae, + 0x17b2, 0x17b6, 0x17ba, 0x17be, 0x17c2, 0x17c6, 0x17ca, 0x17ce, + + 0x17d2, 0x17d6, 0x17da, 0x17dd, 0x17e0, 0x17e4, 0x17e7, 0x17ea, + 0x17ed, 0x17f1, 0x17f5, 0x17f8, 0x17fb, 0x17fe, 0x1801, 0x1804, + + 0x1809, 0x180c, 0x180f, 0x1812, 0x1815, 0x1818, 0x181b, 0x181e, + 0x1821, 0x1825, 0x182a, 0x182d, 0x1830, 0x1833, 0x1836, 0x1839, + + 0x183c, 0x183f, 0x1843, 0x1847, 0x184b, 0x184f, 0x1852, 0x1855, + 0x1858, 0x185b, 0x185e, 0x1861, 0x1864, 0x1867, 0x186a, 0x186d, + + 0x1871, 0x1875, 0x1878, 0x187c, 0x1880, 0x1884, 0x1887, 0x188b, + 0x188f, 0x1894, 0x1897, 0x189b, 0x189f, 0x18a3, 0x18a7, 0x18ad, + + 0x18b4, 0x18b7, 0x18ba, 0x18bd, 0x18c0, 0x18c3, 0x18c6, 0x18c9, + 0x18cc, 0x18cf, 0x18d2, 0x18d5, 0x18d8, 0x18db, 0x18de, 0x18e1, + + 0x18e4, 0x18e7, 0x18ea, 0x18ef, 0x18f2, 0x18f5, 0x18f8, 0x18fd, + 0x1901, 0x1904, 0x1907, 0x190a, 0x190d, 0x1910, 0x1913, 0x1916, + + 0x1919, 0x191c, 0x191f, 0x1923, 0x1926, 0x1929, 0x192d, 0x1931, + 0x1934, 0x1939, 0x193d, 0x1940, 0x1943, 0x1946, 0x1949, 0x194d, + + 0x1951, 0x1954, 0x1957, 0x195a, 0x195d, 0x1960, 0x1963, 0x1966, + 0x1969, 0x196c, 0x1970, 0x1974, 0x1978, 0x197c, 0x1980, 0x1984, + + 0x1988, 0x198c, 0x1990, 0x1994, 0x1998, 0x199c, 0x19a0, 0x19a4, + 0x19a8, 0x19ac, 0x19b0, 0x19b4, 0x19b8, 0x19bc, 0x19c0, 0x19c4, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x19c8, 0x19ca, 0x19cc, 0x19ce, 0x19d0, 0x19d2, 0x19d4, 0x19d6, + 0x19d8, 0x19da, 0x19dc, 0x19de, 0x19e0, 0x19e2, 0x19e4, 0x19e6, + 0x19e8, 0x19ea, 0x19ec, 0x19ee, 0x19f0, 0x19f2, 0x19f4, 0x19f6, + 0x19f8, 0x19fa, 0x19fc, 0x19fe, 0x1a00, 0x1a02, 0x1a04, 0x1a06, + 0x1a08, 0x1a0a, 0x1a0c, 0x1a0e, 0x1a10, 0x1a12, 0x1a14, 0x1a16, + 0x1a18, 0x1a1a, 0x1a1c, 0x1a1e, 0x1a20, 0x1a22, 0x1a24, 0x1a26, + 0x1a28, 0x1a2a, 0x1a2c, 0x1a2e, 0x1a30, 0x1a32, 0x1a34, 0x1a36, + 0x1a38, 0x1a3a, 0x1a3c, 0x1a3e, 0x1a40, 0x1a42, 0x1a44, 0x1a46, + 0x1a48, 0x1a4a, 0x1a4c, 0x1a4e, 0x1a50, 0x1a52, 0x1a54, 0x1a56, + 0x1a58, 0x1a5a, 0x1a5c, 0x1a5e, 0x1a60, 0x1a62, 0x1a64, 0x1a66, + 0x1a68, 0x1a6a, 0x1a6c, 0x1a6e, 0x1a70, 0x1a72, 0x1a74, 0x1a76, + 0x1a78, 0x1a7a, 0x1a7c, 0x1a7e, 0x1a80, 0x1a82, 0x1a84, 0x1a86, + 0x1a88, 0x1a8a, 0x1a8c, 0x1a8e, 0x1a90, 0x1a92, 0x1a94, 0x1a96, + 0x1a98, 0x1a9a, 0x1a9c, 0x1a9e, 0x1aa0, 0x1aa2, 0x1aa4, 0x1aa6, + 0x1aa8, 0x1aaa, 0x1aac, 0x1aae, 0x1ab0, 0x1ab2, 0x1ab4, 0x1ab6, + 0x1ab8, 0x1aba, 0x1abc, 0x1abe, 0x1ac0, 0x1ac2, 0x1ac4, 0x1ac6, + 0x1ac8, 0x1aca, 0x1acc, 0x1ace, 0x1ad0, 0x1ad2, 0x1ad4, 0x1ad6, + 0x1ad8, 0x1ada, 0x1adc, 0x1ade, 0x1ae0, 0x1ae2, 0x1ae4, 0x1ae6, + 0x1ae8, 0x1aea, 0x1aec, 0x1aee, 0x1af0, 0x1af2, 0x1af4, 0x1af6, + 0x1af8, 0x1afa, 0x1afc, 0x1afe, 0x1b00, 0x1b02, 0x1b04, 0x1b06, + 0x1b08, 0x1b0a, 0x1b0c, 0x1b0e, 0x1b10, 0x1b12, 0x1b14, 0x1b16, + 0x1b18, 0x1b1a, 0x1b1c, 0x1b1e, 0x1b20, 0x1b22, 0x1b24, 0x1b26, + 0x1b28, 0x1b2a, 0x1b2c, 0x1b2e, 0x1b30, 0x1b32, 0x1b34, 0x1b36, + 0x1b38, 0x1b3a, 0x1b3c, 0x1b3e, 0x1b40, 0x1b42, 0x1b44, 0x1b46, + 0x1b48, 0x1b4a, 0x1b4c, 0x1b4e, 0x1b50, 0x1b52, 0x1b54, 0x1b56, + 0x1b58, 0x1b5a, 0x1b5c, 0x1b5e, 0x1b60, 0x1b62, 0x1b64, 0x1b66, + 0x1b68, 0x1b6a, 0x1b6c, 0x1b6e, 0x1b70, 0x1b72, 0x1b74, 0x1b76, + 0x1b78, 0x1b7a, 0x1b7c, 0x1b7e, 0x1b80, 0x1b82, 0x1b84, 0x1b86, + 0x1b88, 0x1b8a, 0x1b8c, 0x1b8e, 0x1b90, 0x1b92, 0x1b94, 0x1b96, + 0x1b98, 0x1b9a, 0x1b9c, 0x1b9e, 0x1ba0, 0x1ba2, 0x1ba4, 0x1ba6, + 0x1ba8, 0x1baa, 0x1bac, 0x1bae, 0x1bb0, 0x1bb2, 0x1bb4, 0x1bb6, + 0x1bb8, 0x1bba, 0x1bbc, 0x1bbe, 0x1bc0, 0x1bc2, 0x1bc4, 0x1bc6, + + 0x1bc8, 0x1bca, 0x1bcc, 0x1bce, 0x1bd0, 0x1bd2, 0x1bd4, 0x1bd6, + 0x1bd8, 0x1bda, 0x1bdc, 0x1bde, 0x1be0, 0x1be2, 0xffff, 0xffff, + 0x1be4, 0xffff, 0x1be6, 0xffff, 0xffff, 0x1be8, 0x1bea, 0x1bec, + 0x1bee, 0x1bf0, 0x1bf2, 0x1bf4, 0x1bf6, 0x1bf8, 0x1bfa, 0xffff, + 0x1bfc, 0xffff, 0x1bfe, 0xffff, 0xffff, 0x1c00, 0x1c02, 0xffff, + 0xffff, 0xffff, 0x1c04, 0x1c06, 0x1c08, 0x1c0a, 0xffff, 0xffff, + 0x1c0c, 0x1c0e, 0x1c10, 0x1c12, 0x1c14, 0x1c16, 0x1c18, 0x1c1a, + 0x1c1c, 0x1c1e, 0x1c20, 0x1c22, 0x1c24, 0x1c26, 0x1c28, 0x1c2a, + 0x1c2c, 0x1c2e, 0x1c30, 0x1c32, 0x1c34, 0x1c36, 0x1c38, 0x1c3a, + 0x1c3c, 0x1c3e, 0x1c40, 0x1c42, 0x1c44, 0x1c46, 0x1c48, 0x1c4a, + 0x1c4c, 0x1c4e, 0x1c50, 0x1c52, 0x1c54, 0x1c56, 0x1c58, 0x1c5a, + 0x1c5c, 0x1c5e, 0x1c60, 0x1c62, 0x1c64, 0x1c66, 0x1c68, 0x1c6a, + 0x1c6c, 0x1c6e, 0x1c70, 0x1c72, 0x1c74, 0x1c76, 0x1c78, 0x1c7a, + 0x1c7c, 0x1c7e, 0x1c80, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x1c82, 0x1c84, 0x1c86, 0x1c88, 0x1c8a, 0x1c8c, 0x1c8e, 0x1c90, + 0x1c92, 0x1c94, 0x1c96, 0x1c98, 0x1c9a, 0x1c9c, 0x1c9e, 0x1ca0, + 0x1ca2, 0x1ca4, 0x1ca6, 0x1ca8, 0x1caa, 0x1cac, 0x1cae, 0x1cb0, + 0x1cb2, 0x1cb4, 0x1cb6, 0x1cb8, 0x1cba, 0x1cbc, 0x1cbe, 0x1cc0, + 0x1cc2, 0x1cc4, 0x1cc6, 0x1cc8, 0x1cca, 0x1ccc, 0x1cce, 0x1cd0, + 0x1cd2, 0x1cd4, 0x1cd6, 0x1cd8, 0x1cda, 0x1cdc, 0x1cde, 0x1ce0, + 0x1ce2, 0x1ce4, 0x1ce6, 0x1ce8, 0x1cea, 0x1cec, 0x1cee, 0x1cf0, + 0x1cf2, 0x1cf4, 0x1cf6, 0x1cf8, 0x1cfa, 0x1cfc, 0x1cfe, 0x1d00, + 0x1d02, 0x1d04, 0x1d06, 0x1d08, 0x1d0a, 0x1d0c, 0x1d0e, 0x1d10, + 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, 0x1d20, + 0x1d22, 0x1d24, 0x1d26, 0x1d28, 0x1d2a, 0x1d2c, 0x1d2e, 0x1d30, + 0x1d32, 0x1d34, 0x1d36, 0x1d38, 0x1d3a, 0x1d3c, 0x1d3e, 0x1d40, + 0x1d43, 0x1d46, 0x1d49, 0x1d4b, 0x1d4d, 0x1d4f, 0x1d52, 0x1d55, + 0x1d58, 0x1d5a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x1d5c, 0x1d5f, 0x1d62, 0x1d65, 0x1d69, 0x1d6d, 0x1d70, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x1d73, 0x1d76, 0x1d79, 0x1d7c, 0x1d7f, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1d82, 0xffff, 0x1d85, + 0x1d88, 0x1d8a, 0x1d8c, 0x1d8e, 0x1d90, 0x1d92, 0x1d94, 0x1d96, + 0x1d98, 0x1d9a, 0x1d9c, 0x1d9f, 0x1da2, 0x1da5, 0x1da8, 0x1dab, + 0x1dae, 0x1db1, 0x1db4, 0x1db7, 0x1dba, 0x1dbd, 0x1dc0, 0xffff, + 0x1dc3, 0x1dc6, 0x1dc9, 0x1dcc, 0x1dcf, 0xffff, 0x1dd2, 0xffff, + 0x1dd5, 0x1dd8, 0xffff, 0x1ddb, 0x1dde, 0xffff, 0x1de1, 0x1de4, + 0x1de7, 0x1dea, 0x1ded, 0x1df0, 0x1df3, 0x1df6, 0x1df9, 0x1dfc, + 0x1dff, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, + 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, + 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, + 0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, + 0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, + 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, + 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, + 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e7b, 0x1e7d, + 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89, 0x1e8b, 0x1e8d, + 0x1e8f, 0x1e91, 0x1e93, 0x1e95, 0x1e97, 0x1e99, 0x1e9b, 0x1e9d, + 0x1e9f, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, + 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, 0x1ebd, + 0x1ebf, 0x1ec1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb, + 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, + 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, + 0x1eed, 0x1eef, 0x1ef1, 0x1ef4, 0x1ef7, 0x1efa, 0x1efd, 0x1f00, + 0x1f03, 0x1f06, 0x1f09, 0x1f0c, 0x1f0f, 0x1f12, 0x1f15, 0x1f18, + 0x1f1b, 0x1f1e, 0x1f21, 0x1f24, 0x1f27, 0x1f29, 0x1f2b, 0x1f2d, + + 0x1f2f, 0x1f32, 0x1f35, 0x1f38, 0x1f3b, 0x1f3e, 0x1f41, 0x1f44, + 0x1f47, 0x1f4a, 0x1f4d, 0x1f50, 0x1f53, 0x1f56, 0x1f59, 0x1f5c, + 0x1f5f, 0x1f62, 0x1f65, 0x1f68, 0x1f6b, 0x1f6e, 0x1f71, 0x1f74, + 0x1f77, 0x1f7a, 0x1f7d, 0x1f80, 0x1f83, 0x1f86, 0x1f89, 0x1f8c, + 0x1f8f, 0x1f92, 0x1f95, 0x1f98, 0x1f9b, 0x1f9e, 0x1fa1, 0x1fa4, + 0x1fa7, 0x1faa, 0x1fad, 0x1fb0, 0x1fb3, 0x1fb6, 0x1fb9, 0x1fbc, + 0x1fbf, 0x1fc2, 0x1fc5, 0x1fc8, 0x1fcb, 0x1fce, 0x1fd1, 0x1fd4, + 0x1fd7, 0x1fda, 0x1fdd, 0x1fe0, 0x1fe3, 0x1fe6, 0x1fe9, 0x1fec, + 0x1fef, 0x1ff2, 0x1ff5, 0x1ff8, 0x1ffb, 0x1ffe, 0x2001, 0x2004, + 0x2007, 0x200a, 0x200d, 0x2010, 0x2013, 0x2016, 0x2019, 0x201c, + 0x201f, 0x2022, 0x2025, 0x2028, 0x202b, 0x202e, 0x2031, 0x2034, + 0x2037, 0x203a, 0x203d, 0x2040, 0x2043, 0x2046, 0x2049, 0x204d, + 0x2051, 0x2055, 0x2059, 0x205d, 0x2061, 0x2064, 0x2067, 0x206a, + 0x206d, 0x2070, 0x2073, 0x2076, 0x2079, 0x207c, 0x207f, 0x2082, + 0x2085, 0x2088, 0x208b, 0x208e, 0x2091, 0x2094, 0x2097, 0x209a, + 0x209d, 0x20a0, 0x20a3, 0x20a6, 0x20a9, 0x20ac, 0x20af, 0x20b2, + 0x20b5, 0x20b8, 0x20bb, 0x20be, 0x20c1, 0x20c4, 0x20c7, 0x20ca, + 0x20cd, 0x20d0, 0x20d3, 0x20d6, 0x20d9, 0x20dc, 0x20df, 0x20e2, + 0x20e5, 0x20e8, 0x20eb, 0x20ee, 0x20f1, 0x20f4, 0x20f7, 0x20fa, + 0x20fd, 0x2100, 0x2103, 0x2106, 0x2109, 0x210c, 0x210f, 0x2112, + 0x2115, 0x2118, 0x211b, 0x211e, 0x2121, 0x2124, 0x2127, 0x212a, + 0x212d, 0x2130, 0x2133, 0x2136, 0x2139, 0x213c, 0x213f, 0x2142, + 0x2145, 0x2148, 0x214b, 0x214e, 0x2151, 0x2154, 0x2157, 0x215a, + 0x215d, 0x2160, 0x2163, 0x2166, 0x2169, 0x216c, 0x216f, 0x2172, + 0x2175, 0x2178, 0x217b, 0x217e, 0x2181, 0x2184, 0x2187, 0x218a, + 0x218d, 0x2190, 0x2193, 0x2196, 0x2199, 0x219c, 0x219f, 0x21a2, + 0x21a5, 0x21a8, 0x21ab, 0x21ae, 0x21b1, 0x21b4, 0x21b7, 0x21ba, + 0x21bd, 0x21c0, 0x21c3, 0x21c6, 0x21c9, 0x21cc, 0x21cf, 0x21d2, + 0x21d5, 0x21d8, 0x21db, 0x21de, 0x21e1, 0x21e4, 0x21e7, 0x21ea, + 0x21ed, 0x21f0, 0x21f3, 0x21f6, 0x21f9, 0x21fc, 0x21ff, 0x2202, + 0x2205, 0x2208, 0x220b, 0x220f, 0x2213, 0x2217, 0x221a, 0x221d, + 0x2220, 0x2223, 0x2226, 0x2229, 0x222c, 0x222f, 0x2232, 0x2235, + + 0x2238, 0x223b, 0x223e, 0x2241, 0x2244, 0x2247, 0x224a, 0x224d, + 0x2250, 0x2253, 0x2256, 0x2259, 0x225c, 0x225f, 0x2262, 0x2265, + 0x2268, 0x226b, 0x226e, 0x2271, 0x2274, 0x2277, 0x227a, 0x227d, + 0x2280, 0x2283, 0x2286, 0x2289, 0x228c, 0x228f, 0x2292, 0x2295, + 0x2298, 0x229b, 0x229e, 0x22a1, 0x22a4, 0x22a7, 0x22aa, 0x22ad, + 0x22b0, 0x22b3, 0x22b6, 0x22b9, 0x22bc, 0x22bf, 0x22c2, 0x22c5, + 0x22c8, 0x22cb, 0x22ce, 0x22d1, 0x22d4, 0x22d7, 0x22da, 0x22dd, + 0x22e0, 0x22e3, 0x22e6, 0x22e9, 0x22ec, 0x22ef, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x22f2, 0x22f6, 0x22fa, 0x22fe, 0x2302, 0x2306, 0x230a, 0x230e, + 0x2312, 0x2316, 0x231a, 0x231e, 0x2322, 0x2326, 0x232a, 0x232e, + 0x2332, 0x2336, 0x233a, 0x233e, 0x2342, 0x2346, 0x234a, 0x234e, + 0x2352, 0x2356, 0x235a, 0x235e, 0x2362, 0x2366, 0x236a, 0x236e, + 0x2372, 0x2376, 0x237a, 0x237e, 0x2382, 0x2386, 0x238a, 0x238e, + 0x2392, 0x2396, 0x239a, 0x239e, 0x23a2, 0x23a6, 0x23aa, 0x23ae, + 0x23b2, 0x23b6, 0x23ba, 0x23be, 0x23c2, 0x23c6, 0x23ca, 0x23ce, + 0x23d2, 0x23d6, 0x23da, 0x23de, 0x23e2, 0x23e6, 0x23ea, 0x23ee, + 0xffff, 0xffff, 0x23f2, 0x23f6, 0x23fa, 0x23fe, 0x2402, 0x2406, + 0x240a, 0x240e, 0x2412, 0x2416, 0x241a, 0x241e, 0x2422, 0x2426, + 0x242a, 0x242e, 0x2432, 0x2436, 0x243a, 0x243e, 0x2442, 0x2446, + 0x244a, 0x244e, 0x2452, 0x2456, 0x245a, 0x245e, 0x2462, 0x2466, + 0x246a, 0x246e, 0x2472, 0x2476, 0x247a, 0x247e, 0x2482, 0x2486, + 0x248a, 0x248e, 0x2492, 0x2496, 0x249a, 0x249e, 0x24a2, 0x24a6, + 0x24aa, 0x24ae, 0x24b2, 0x24b6, 0x24ba, 0x24be, 0x24c2, 0x24c6, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x24ca, 0x24ce, 0x24d2, 0x24d7, 0x24dc, 0x24e1, 0x24e6, 0x24eb, + 0x24f0, 0x24f5, 0x24f9, 0x250c, 0x2515, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x251a, 0x251c, 0x251e, 0x2520, 0x2522, 0x2524, 0x2526, 0x2528, + 0x252a, 0x252c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x252e, 0x2530, 0x2532, 0x2534, 0x2536, 0x2538, 0x253a, 0x253c, + 0x253e, 0x2540, 0x2542, 0x2544, 0x2546, 0x2548, 0x254a, 0x254c, + 0x254e, 0x2550, 0x2552, 0x2554, 0x2556, 0xffff, 0xffff, 0x2558, + 0x255a, 0x255c, 0x255e, 0x2560, 0x2562, 0x2564, 0x2566, 0x2568, + 0x256a, 0x256c, 0x256e, 0xffff, 0x2570, 0x2572, 0x2574, 0x2576, + 0x2578, 0x257a, 0x257c, 0x257e, 0x2580, 0x2582, 0x2584, 0x2586, + 0x2588, 0x258a, 0x258c, 0x258e, 0x2590, 0x2592, 0x2594, 0xffff, + 0x2596, 0x2598, 0x259a, 0x259c, 0xffff, 0xffff, 0xffff, 0xffff, + 0x259e, 0x25a1, 0x25a4, 0xffff, 0x25a7, 0xffff, 0x25aa, 0x25ad, + 0x25b0, 0x25b3, 0x25b6, 0x25b9, 0x25bc, 0x25bf, 0x25c2, 0x25c5, + 0x25c8, 0x25ca, 0x25cc, 0x25ce, 0x25d0, 0x25d2, 0x25d4, 0x25d6, + 0x25d8, 0x25da, 0x25dc, 0x25de, 0x25e0, 0x25e2, 0x25e4, 0x25e6, + 0x25e8, 0x25ea, 0x25ec, 0x25ee, 0x25f0, 0x25f2, 0x25f4, 0x25f6, + 0x25f8, 0x25fa, 0x25fc, 0x25fe, 0x2600, 0x2602, 0x2604, 0x2606, + 0x2608, 0x260a, 0x260c, 0x260e, 0x2610, 0x2612, 0x2614, 0x2616, + 0x2618, 0x261a, 0x261c, 0x261e, 0x2620, 0x2622, 0x2624, 0x2626, + 0x2628, 0x262a, 0x262c, 0x262e, 0x2630, 0x2632, 0x2634, 0x2636, + 0x2638, 0x263a, 0x263c, 0x263e, 0x2640, 0x2642, 0x2644, 0x2646, + 0x2648, 0x264a, 0x264c, 0x264e, 0x2650, 0x2652, 0x2654, 0x2656, + 0x2658, 0x265a, 0x265c, 0x265e, 0x2660, 0x2662, 0x2664, 0x2666, + 0x2668, 0x266a, 0x266c, 0x266e, 0x2670, 0x2672, 0x2674, 0x2676, + 0x2678, 0x267a, 0x267c, 0x267e, 0x2680, 0x2682, 0x2684, 0x2686, + 0x2688, 0x268a, 0x268c, 0x268e, 0x2690, 0x2692, 0x2694, 0x2696, + 0x2698, 0x269a, 0x269c, 0x269e, 0x26a0, 0x26a2, 0x26a4, 0x26a6, + 0x26a8, 0x26aa, 0x26ac, 0x26ae, 0x26b0, 0x26b2, 0x26b5, 0x26b8, + 0x26bb, 0x26be, 0x26c1, 0x26c4, 0x26c7, 0xffff, 0xffff, 0xffff, + + 0xffff, 0x26ca, 0x26cc, 0x26ce, 0x26d0, 0x26d2, 0x26d4, 0x26d6, + 0x26d8, 0x26da, 0x26dc, 0x26de, 0x26e0, 0x26e2, 0x26e4, 0x26e6, + 0x26e8, 0x26ea, 0x26ec, 0x26ee, 0x26f0, 0x26f2, 0x26f4, 0x26f6, + 0x26f8, 0x26fa, 0x26fc, 0x26fe, 0x2700, 0x2702, 0x2704, 0x2706, + 0x2708, 0x270a, 0x270c, 0x270e, 0x2710, 0x2712, 0x2714, 0x2716, + 0x2718, 0x271a, 0x271c, 0x271e, 0x2720, 0x2722, 0x2724, 0x2726, + 0x2728, 0x272a, 0x272c, 0x272e, 0x2730, 0x2732, 0x2734, 0x2736, + 0x2738, 0x273a, 0x273c, 0x273e, 0x2740, 0x2742, 0x2744, 0x2746, + 0x2748, 0x274a, 0x274c, 0x274e, 0x2750, 0x2752, 0x2754, 0x2756, + 0x2758, 0x275a, 0x275c, 0x275e, 0x2760, 0x2762, 0x2764, 0x2766, + 0x2768, 0x276a, 0x276c, 0x276e, 0x2770, 0x2772, 0x2774, 0x2776, + 0x2778, 0x277a, 0x277c, 0x277e, 0x2780, 0x2782, 0x2784, 0x2786, + 0x2788, 0x278a, 0x278c, 0x278e, 0x2790, 0x2792, 0x2794, 0x2796, + 0x2798, 0x279a, 0x279c, 0x279e, 0x27a0, 0x27a2, 0x27a4, 0x27a6, + 0x27a8, 0x27aa, 0x27ac, 0x27ae, 0x27b0, 0x27b2, 0x27b4, 0x27b6, + 0x27b8, 0x27ba, 0x27bc, 0x27be, 0x27c0, 0x27c2, 0x27c4, 0x27c6, + 0x27c8, 0x27ca, 0x27cc, 0x27ce, 0x27d0, 0x27d2, 0x27d4, 0x27d6, + 0x27d8, 0x27da, 0x27dc, 0x27de, 0x27e0, 0x27e2, 0x27e4, 0x27e6, + 0x27e8, 0x27ea, 0x27ec, 0x27ee, 0x27f0, 0x27f2, 0x27f4, 0x27f6, + 0x27f8, 0x27fa, 0x27fc, 0x27fe, 0x2800, 0x2802, 0x2804, 0x2806, + 0x2808, 0x280a, 0x280c, 0x280e, 0x2810, 0x2812, 0x2814, 0x2816, + 0x2818, 0x281a, 0x281c, 0x281e, 0x2820, 0x2822, 0x2824, 0x2826, + 0x2828, 0x282a, 0x282c, 0x282e, 0x2830, 0x2832, 0x2834, 0x2836, + 0x2838, 0x283a, 0x283c, 0x283e, 0x2840, 0x2842, 0x2844, 0xffff, + 0xffff, 0xffff, 0x2846, 0x2848, 0x284a, 0x284c, 0x284e, 0x2850, + 0xffff, 0xffff, 0x2852, 0x2854, 0x2856, 0x2858, 0x285a, 0x285c, + 0xffff, 0xffff, 0x285e, 0x2860, 0x2862, 0x2864, 0x2866, 0x2868, + 0xffff, 0xffff, 0x286a, 0x286c, 0x286e, 0xffff, 0xffff, 0xffff, + 0x2870, 0x2872, 0x2874, 0x2876, 0x2878, 0x287a, 0x287c, 0xffff, + 0x287e, 0x2880, 0x2882, 0x2884, 0x2886, 0x2888, 0x288a, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x288c, 0x2891, + 0x2896, 0x289b, 0x28a0, 0x28a5, 0x28aa, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x28af, 0x28b4, 0x28b9, 0x28be, 0x28c3, + 0x28c8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x28cd, 0x28cf, 0x28d1, 0x28d3, 0x28d5, 0x28d7, 0x28d9, 0x28db, + 0x28dd, 0x28df, 0x28e1, 0x28e3, 0x28e5, 0x28e7, 0x28e9, 0x28eb, + 0x28ed, 0x28ef, 0x28f1, 0x28f3, 0x28f5, 0x28f7, 0x28f9, 0x28fb, + 0x28fd, 0x28ff, 0x2901, 0x2903, 0x2905, 0x2907, 0x2909, 0x290b, + 0x290d, 0x290f, 0x2911, 0x2913, 0x2915, 0x2917, 0x2919, 0x291b, + 0x291d, 0x291f, 0x2921, 0x2923, 0x2925, 0x2927, 0x2929, 0x292b, + 0x292d, 0x292f, 0x2931, 0x2933, 0x2935, 0x2937, 0x2939, 0x293b, + 0x293d, 0x293f, 0x2941, 0x2943, 0x2945, 0x2947, 0x2949, 0x294b, + 0x294d, 0x294f, 0x2951, 0x2953, 0x2955, 0x2957, 0x2959, 0x295b, + 0x295d, 0x295f, 0x2961, 0x2963, 0x2965, 0x2967, 0x2969, 0x296b, + 0x296d, 0x296f, 0x2971, 0x2973, 0x2975, 0xffff, 0x2977, 0x2979, + 0x297b, 0x297d, 0x297f, 0x2981, 0x2983, 0x2985, 0x2987, 0x2989, + 0x298b, 0x298d, 0x298f, 0x2991, 0x2993, 0x2995, 0x2997, 0x2999, + 0x299b, 0x299d, 0x299f, 0x29a1, 0x29a3, 0x29a5, 0x29a7, 0x29a9, + 0x29ab, 0x29ad, 0x29af, 0x29b1, 0x29b3, 0x29b5, 0x29b7, 0x29b9, + 0x29bb, 0x29bd, 0x29bf, 0x29c1, 0x29c3, 0x29c5, 0x29c7, 0x29c9, + 0x29cb, 0x29cd, 0x29cf, 0x29d1, 0x29d3, 0x29d5, 0x29d7, 0x29d9, + 0x29db, 0x29dd, 0x29df, 0x29e1, 0x29e3, 0x29e5, 0x29e7, 0x29e9, + 0x29eb, 0x29ed, 0x29ef, 0x29f1, 0x29f3, 0x29f5, 0x29f7, 0x29f9, + 0x29fb, 0x29fd, 0x29ff, 0x2a01, 0x2a03, 0xffff, 0x2a05, 0x2a07, + 0xffff, 0xffff, 0x2a09, 0xffff, 0xffff, 0x2a0b, 0x2a0d, 0xffff, + 0xffff, 0x2a0f, 0x2a11, 0x2a13, 0x2a15, 0xffff, 0x2a17, 0x2a19, + 0x2a1b, 0x2a1d, 0x2a1f, 0x2a21, 0x2a23, 0x2a25, 0x2a27, 0x2a29, + 0x2a2b, 0x2a2d, 0xffff, 0x2a2f, 0xffff, 0x2a31, 0x2a33, 0x2a35, + 0x2a37, 0x2a39, 0x2a3b, 0x2a3d, 0xffff, 0x2a3f, 0x2a41, 0x2a43, + 0x2a45, 0x2a47, 0x2a49, 0x2a4b, 0x2a4d, 0x2a4f, 0x2a51, 0x2a53, + 0x2a55, 0x2a57, 0x2a59, 0x2a5b, 0x2a5d, 0x2a5f, 0x2a61, 0x2a63, + 0x2a65, 0x2a67, 0x2a69, 0x2a6b, 0x2a6d, 0x2a6f, 0x2a71, 0x2a73, + 0x2a75, 0x2a77, 0x2a79, 0x2a7b, 0x2a7d, 0x2a7f, 0x2a81, 0x2a83, + 0x2a85, 0x2a87, 0x2a89, 0x2a8b, 0x2a8d, 0x2a8f, 0x2a91, 0x2a93, + 0x2a95, 0x2a97, 0x2a99, 0x2a9b, 0x2a9d, 0x2a9f, 0x2aa1, 0x2aa3, + 0x2aa5, 0x2aa7, 0x2aa9, 0x2aab, 0x2aad, 0x2aaf, 0x2ab1, 0x2ab3, + + 0x2ab5, 0x2ab7, 0x2ab9, 0x2abb, 0x2abd, 0x2abf, 0xffff, 0x2ac1, + 0x2ac3, 0x2ac5, 0x2ac7, 0xffff, 0xffff, 0x2ac9, 0x2acb, 0x2acd, + 0x2acf, 0x2ad1, 0x2ad3, 0x2ad5, 0x2ad7, 0xffff, 0x2ad9, 0x2adb, + 0x2add, 0x2adf, 0x2ae1, 0x2ae3, 0x2ae5, 0xffff, 0x2ae7, 0x2ae9, + 0x2aeb, 0x2aed, 0x2aef, 0x2af1, 0x2af3, 0x2af5, 0x2af7, 0x2af9, + 0x2afb, 0x2afd, 0x2aff, 0x2b01, 0x2b03, 0x2b05, 0x2b07, 0x2b09, + 0x2b0b, 0x2b0d, 0x2b0f, 0x2b11, 0x2b13, 0x2b15, 0x2b17, 0x2b19, + 0x2b1b, 0x2b1d, 0xffff, 0x2b1f, 0x2b21, 0x2b23, 0x2b25, 0xffff, + 0x2b27, 0x2b29, 0x2b2b, 0x2b2d, 0x2b2f, 0xffff, 0x2b31, 0xffff, + 0xffff, 0xffff, 0x2b33, 0x2b35, 0x2b37, 0x2b39, 0x2b3b, 0x2b3d, + 0x2b3f, 0xffff, 0x2b41, 0x2b43, 0x2b45, 0x2b47, 0x2b49, 0x2b4b, + 0x2b4d, 0x2b4f, 0x2b51, 0x2b53, 0x2b55, 0x2b57, 0x2b59, 0x2b5b, + 0x2b5d, 0x2b5f, 0x2b61, 0x2b63, 0x2b65, 0x2b67, 0x2b69, 0x2b6b, + 0x2b6d, 0x2b6f, 0x2b71, 0x2b73, 0x2b75, 0x2b77, 0x2b79, 0x2b7b, + 0x2b7d, 0x2b7f, 0x2b81, 0x2b83, 0x2b85, 0x2b87, 0x2b89, 0x2b8b, + 0x2b8d, 0x2b8f, 0x2b91, 0x2b93, 0x2b95, 0x2b97, 0x2b99, 0x2b9b, + 0x2b9d, 0x2b9f, 0x2ba1, 0x2ba3, 0x2ba5, 0x2ba7, 0x2ba9, 0x2bab, + 0x2bad, 0x2baf, 0x2bb1, 0x2bb3, 0x2bb5, 0x2bb7, 0x2bb9, 0x2bbb, + 0x2bbd, 0x2bbf, 0x2bc1, 0x2bc3, 0x2bc5, 0x2bc7, 0x2bc9, 0x2bcb, + 0x2bcd, 0x2bcf, 0x2bd1, 0x2bd3, 0x2bd5, 0x2bd7, 0x2bd9, 0x2bdb, + 0x2bdd, 0x2bdf, 0x2be1, 0x2be3, 0x2be5, 0x2be7, 0x2be9, 0x2beb, + 0x2bed, 0x2bef, 0x2bf1, 0x2bf3, 0x2bf5, 0x2bf7, 0x2bf9, 0x2bfb, + 0x2bfd, 0x2bff, 0x2c01, 0x2c03, 0x2c05, 0x2c07, 0x2c09, 0x2c0b, + 0x2c0d, 0x2c0f, 0x2c11, 0x2c13, 0x2c15, 0x2c17, 0x2c19, 0x2c1b, + 0x2c1d, 0x2c1f, 0x2c21, 0x2c23, 0x2c25, 0x2c27, 0x2c29, 0x2c2b, + 0x2c2d, 0x2c2f, 0x2c31, 0x2c33, 0x2c35, 0x2c37, 0x2c39, 0x2c3b, + 0x2c3d, 0x2c3f, 0x2c41, 0x2c43, 0x2c45, 0x2c47, 0x2c49, 0x2c4b, + 0x2c4d, 0x2c4f, 0x2c51, 0x2c53, 0x2c55, 0x2c57, 0x2c59, 0x2c5b, + 0x2c5d, 0x2c5f, 0x2c61, 0x2c63, 0x2c65, 0x2c67, 0x2c69, 0x2c6b, + 0x2c6d, 0x2c6f, 0x2c71, 0x2c73, 0x2c75, 0x2c77, 0x2c79, 0x2c7b, + 0x2c7d, 0x2c7f, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b, + 0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b, + + 0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab, + 0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb, + 0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb, + 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb, + 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce5, 0x2ce7, 0x2ce9, 0x2ceb, + 0x2ced, 0x2cef, 0x2cf1, 0x2cf3, 0x2cf5, 0x2cf7, 0x2cf9, 0x2cfb, + 0x2cfd, 0x2cff, 0x2d01, 0x2d03, 0x2d05, 0x2d07, 0x2d09, 0x2d0b, + 0x2d0d, 0x2d0f, 0x2d11, 0x2d13, 0x2d15, 0x2d17, 0x2d19, 0x2d1b, + 0x2d1d, 0x2d1f, 0x2d21, 0x2d23, 0x2d25, 0x2d27, 0x2d29, 0x2d2b, + 0x2d2d, 0x2d2f, 0x2d31, 0x2d33, 0x2d35, 0x2d37, 0x2d39, 0x2d3b, + 0x2d3d, 0x2d3f, 0x2d41, 0x2d43, 0x2d45, 0x2d47, 0x2d49, 0x2d4b, + 0x2d4d, 0x2d4f, 0x2d51, 0x2d53, 0x2d55, 0x2d57, 0x2d59, 0x2d5b, + 0x2d5d, 0x2d5f, 0x2d61, 0x2d63, 0x2d65, 0x2d67, 0x2d69, 0x2d6b, + 0x2d6d, 0x2d6f, 0x2d71, 0x2d73, 0x2d75, 0x2d77, 0x2d79, 0x2d7b, + 0x2d7d, 0x2d7f, 0x2d81, 0x2d83, 0x2d85, 0x2d87, 0x2d89, 0x2d8b, + 0x2d8d, 0x2d8f, 0x2d91, 0x2d93, 0x2d95, 0x2d97, 0x2d99, 0x2d9b, + 0x2d9d, 0x2d9f, 0x2da1, 0x2da3, 0x2da5, 0x2da7, 0x2da9, 0x2dab, + 0x2dad, 0x2daf, 0x2db1, 0x2db3, 0x2db5, 0x2db7, 0x2db9, 0x2dbb, + 0x2dbd, 0x2dbf, 0x2dc1, 0x2dc3, 0x2dc5, 0x2dc7, 0x2dc9, 0x2dcb, + 0x2dcd, 0x2dcf, 0x2dd1, 0x2dd3, 0x2dd5, 0x2dd7, 0x2dd9, 0x2ddb, + 0x2ddd, 0x2ddf, 0x2de1, 0x2de3, 0x2de5, 0x2de7, 0xffff, 0xffff, + 0x2de9, 0x2deb, 0x2ded, 0x2def, 0x2df1, 0x2df3, 0x2df5, 0x2df7, + 0x2df9, 0x2dfb, 0x2dfd, 0x2dff, 0x2e01, 0x2e03, 0x2e05, 0x2e07, + 0x2e09, 0x2e0b, 0x2e0d, 0x2e0f, 0x2e11, 0x2e13, 0x2e15, 0x2e17, + 0x2e19, 0x2e1b, 0x2e1d, 0x2e1f, 0x2e21, 0x2e23, 0x2e25, 0x2e27, + 0x2e29, 0x2e2b, 0x2e2d, 0x2e2f, 0x2e31, 0x2e33, 0x2e35, 0x2e37, + 0x2e39, 0x2e3b, 0x2e3d, 0x2e3f, 0x2e41, 0x2e43, 0x2e45, 0x2e47, + 0x2e49, 0x2e4b, 0x2e4d, 0x2e4f, 0x2e51, 0x2e53, 0x2e55, 0x2e57, + 0x2e59, 0x2e5b, 0x2e5d, 0x2e5f, 0x2e61, 0x2e63, 0x2e65, 0x2e67, + 0x2e69, 0x2e6b, 0x2e6d, 0x2e6f, 0x2e71, 0x2e73, 0x2e75, 0x2e77, + 0x2e79, 0x2e7b, 0x2e7d, 0x2e7f, 0x2e81, 0x2e83, 0x2e85, 0x2e87, + 0x2e89, 0x2e8b, 0x2e8d, 0x2e8f, 0x2e91, 0x2e93, 0x2e95, 0x2e97, + + 0x2e99, 0x2e9b, 0x2e9d, 0x2e9f, 0x2ea1, 0x2ea3, 0x2ea5, 0x2ea7, + 0x2ea9, 0x2eab, 0x2ead, 0x2eaf, 0x2eb1, 0x2eb3, 0x2eb5, 0x2eb7, + 0x2eb9, 0x2ebb, 0x2ebd, 0x2ebf, 0x2ec1, 0x2ec3, 0x2ec5, 0x2ec7, + 0x2ec9, 0x2ecb, 0x2ecd, 0x2ecf, 0x2ed1, 0x2ed3, 0x2ed5, 0x2ed7, + 0x2ed9, 0x2edb, 0x2edd, 0x2edf, 0x2ee1, 0x2ee3, 0x2ee5, 0x2ee7, + 0x2ee9, 0x2eeb, 0x2eed, 0x2eef, 0x2ef1, 0x2ef3, 0x2ef5, 0x2ef7, + 0x2ef9, 0x2efb, 0x2efd, 0x2eff, 0x2f01, 0x2f03, 0x2f05, 0x2f07, + 0x2f09, 0x2f0b, 0x2f0d, 0x2f0f, 0x2f11, 0x2f13, 0x2f15, 0x2f17, + 0x2f19, 0x2f1b, 0x2f1d, 0x2f1f, 0x2f21, 0x2f23, 0x2f25, 0x2f27, + 0x2f29, 0x2f2b, 0x2f2d, 0x2f2f, 0x2f31, 0x2f33, 0x2f35, 0x2f37, + 0x2f39, 0x2f3b, 0x2f3d, 0x2f3f, 0x2f41, 0x2f43, 0x2f45, 0x2f47, + 0x2f49, 0x2f4b, 0x2f4d, 0x2f4f, 0x2f51, 0x2f53, 0x2f55, 0x2f57, + 0x2f59, 0x2f5b, 0x2f5d, 0x2f5f, 0x2f61, 0x2f63, 0x2f65, 0x2f67, + 0x2f69, 0x2f6b, 0x2f6d, 0x2f6f, 0x2f71, 0x2f73, 0x2f75, 0x2f77, + 0x2f79, 0x2f7b, 0x2f7d, 0x2f7f, 0x2f81, 0x2f83, 0x2f85, 0x2f87, + 0x2f89, 0x2f8b, 0x2f8d, 0x2f8f, 0x2f91, 0x2f93, 0x2f95, 0x2f97, + 0x2f99, 0x2f9b, 0x2f9d, 0x2f9f, 0x2fa1, 0x2fa3, 0x2fa5, 0x2fa7, + 0x2fa9, 0x2fab, 0x2fad, 0x2faf, 0x2fb1, 0x2fb3, 0x2fb5, 0x2fb7, + 0x2fb9, 0x2fbb, 0x2fbd, 0x2fbf, 0x2fc1, 0x2fc3, 0x2fc5, 0x2fc7, + 0x2fc9, 0x2fcb, 0x2fcd, 0x2fcf, 0x2fd1, 0x2fd3, 0x2fd5, 0x2fd7, + 0x2fd9, 0x2fdb, 0x2fdd, 0x2fdf, 0x2fe1, 0x2fe3, 0x2fe5, 0x2fe7, + 0x2fe9, 0x2feb, 0x2fed, 0x2fef, 0x2ff1, 0x2ff3, 0x2ff5, 0x2ff7, + 0x2ff9, 0x2ffb, 0x2ffd, 0x2fff, 0x3001, 0x3003, 0x3005, 0x3007, + 0x3009, 0x300b, 0x300d, 0x300f, 0x3011, 0x3013, 0x3015, 0x3017, + 0x3019, 0x301b, 0x301d, 0x301f, 0x3021, 0x3023, 0x3025, 0x3027, + 0x3029, 0x302b, 0x302d, 0x302f, 0xffff, 0xffff, 0x3031, 0x3033, + 0x3035, 0x3037, 0x3039, 0x303b, 0x303d, 0x303f, 0x3041, 0x3043, + 0x3045, 0x3047, 0x3049, 0x304b, 0x304d, 0x304f, 0x3051, 0x3053, + 0x3055, 0x3057, 0x3059, 0x305b, 0x305d, 0x305f, 0x3061, 0x3063, + 0x3065, 0x3067, 0x3069, 0x306b, 0x306d, 0x306f, 0x3071, 0x3073, + 0x3075, 0x3077, 0x3079, 0x307b, 0x307d, 0x307f, 0x3081, 0x3083, + 0x3085, 0x3087, 0x3089, 0x308b, 0x308d, 0x308f, 0x3091, 0x3093, + + 0x3095, 0x3097, 0x3099, 0x309b, 0x309e, 0x30a0, 0x30a2, 0x30a4, + 0x30a6, 0x30a8, 0x30aa, 0x30ac, 0x30ae, 0x30b0, 0x30b3, 0x30b5, + 0x30b7, 0x30b9, 0x30bb, 0x30be, 0x30c0, 0x30c2, 0x30c4, 0x30c7, + 0x30c9, 0x30cb, 0x30cd, 0x30cf, 0x30d1, 0x30d4, 0x30d6, 0x30d8, + 0x30da, 0x30dc, 0x30de, 0x30e0, 0x30e2, 0x30e4, 0x30e6, 0x30e8, + 0x30ea, 0x30ec, 0x30ee, 0x30f0, 0x30f2, 0x30f4, 0x30f6, 0x30f8, + 0x30fa, 0x30fc, 0x30fe, 0x3100, 0x3102, 0x3105, 0x3107, 0x3109, + 0x310b, 0x310e, 0x3110, 0x3112, 0x3114, 0x3116, 0x3118, 0x311a, + 0x311c, 0x311e, 0x3120, 0x3122, 0x3124, 0x3126, 0x3128, 0x312a, + 0x312c, 0x312e, 0x3130, 0x3132, 0x3134, 0x3136, 0x3138, 0x313a, + 0x313c, 0x313e, 0x3140, 0x3142, 0x3144, 0x3146, 0x3148, 0x314a, + 0x314c, 0x314e, 0x3151, 0x3153, 0x3155, 0x3157, 0x3159, 0x315b, + 0x315d, 0x3160, 0x3163, 0x3165, 0x3167, 0x3169, 0x316b, 0x316d, + 0x316f, 0x3171, 0x3173, 0x3175, 0x3177, 0x317a, 0x317c, 0x317e, + 0x3180, 0x3182, 0x3185, 0x3187, 0x3189, 0x318b, 0x318d, 0x318f, + 0x3191, 0x3193, 0x3195, 0x3197, 0x319a, 0x319c, 0x319f, 0x31a1, + 0x31a3, 0x31a5, 0x31a7, 0x31a9, 0x31ab, 0x31ad, 0x31af, 0x31b1, + 0x31b3, 0x31b5, 0x31b8, 0x31ba, 0x31bc, 0x31be, 0x31c0, 0x31c2, + 0x31c5, 0x31c7, 0x31ca, 0x31cd, 0x31cf, 0x31d1, 0x31d3, 0x31d5, + 0x31d8, 0x31db, 0x31dd, 0x31df, 0x31e1, 0x31e3, 0x31e5, 0x31e7, + 0x31e9, 0x31eb, 0x31ed, 0x31ef, 0x31f1, 0x31f4, 0x31f6, 0x31f8, + 0x31fa, 0x31fc, 0x31fe, 0x3200, 0x3202, 0x3204, 0x3206, 0x3208, + 0x320a, 0x320c, 0x320e, 0x3210, 0x3212, 0x3214, 0x3216, 0x3218, + 0x321a, 0x321d, 0x321f, 0x3221, 0x3223, 0x3225, 0x3227, 0x322a, + 0x322c, 0x322e, 0x3230, 0x3232, 0x3234, 0x3236, 0x3238, 0x323a, + 0x323c, 0x323e, 0x3240, 0x3243, 0x3245, 0x3247, 0x3249, 0x324b, + 0x324d, 0x324f, 0x3251, 0x3253, 0x3255, 0x3257, 0x3259, 0x325b, + 0x325d, 0x325f, 0x3261, 0x3263, 0x3265, 0x3267, 0x326a, 0x326c, + 0x326e, 0x3270, 0x3272, 0x3274, 0x3277, 0x3279, 0x327b, 0x327d, + 0x327f, 0x3281, 0x3283, 0x3285, 0x3287, 0x328a, 0x328c, 0x328e, + 0x3290, 0x3293, 0x3295, 0x3297, 0x3299, 0x329b, 0x329d, 0x329f, + 0x32a2, 0x32a5, 0x32a8, 0x32aa, 0x32ad, 0x32af, 0x32b1, 0x32b3, + + 0x32b5, 0x32b7, 0x32b9, 0x32bb, 0x32bd, 0x32bf, 0x32c1, 0x32c4, + 0x32c6, 0x32c8, 0x32ca, 0x32cc, 0x32ce, 0x32d0, 0x32d3, 0x32d5, + 0x32d7, 0x32da, 0x32dd, 0x32df, 0x32e1, 0x32e3, 0x32e5, 0x32e7, + 0x32e9, 0x32eb, 0x32ed, 0x32ef, 0x32f2, 0x32f4, 0x32f7, 0x32f9, + 0x32fc, 0x32fe, 0x3300, 0x3302, 0x3305, 0x3307, 0x3309, 0x330c, + 0x330f, 0x3311, 0x3313, 0x3315, 0x3317, 0x3319, 0x331b, 0x331d, + 0x331f, 0x3321, 0x3323, 0x3325, 0x3327, 0x3329, 0x332c, 0x332e, + 0x3331, 0x3333, 0x3336, 0x3338, 0x333b, 0x333e, 0x3341, 0x3343, + 0x3345, 0x3347, 0x334a, 0x334d, 0x3350, 0x3353, 0x3355, 0x3357, + 0x3359, 0x335b, 0x335d, 0x335f, 0x3361, 0x3363, 0x3366, 0x3368, + 0x336a, 0x336c, 0x336e, 0x3371, 0x3373, 0x3376, 0x3379, 0x337b, + 0x337d, 0x337f, 0x3381, 0x3383, 0x3385, 0x3388, 0x338b, 0x338e, + 0x3390, 0x3392, 0x3395, 0x3397, 0x3399, 0x339b, 0x339e, 0x33a0, + 0x33a2, 0x33a4, 0x33a6, 0x33a8, 0x33ab, 0x33ad, 0x33af, 0x33b1, + 0x33b3, 0x33b5, 0x33b7, 0x33ba, 0x33bd, 0x33bf, 0x33c2, 0x33c4, + 0x33c7, 0x33c9, 0x33cb, 0x33cd, 0x33d0, 0x33d3, 0x33d5, 0x33d8, + 0x33da, 0x33dd, 0x33df, 0x33e1, 0x33e3, 0x33e5, 0x33e7, 0x33e9, + 0x33ec, 0x33ef, 0x33f2, 0x33f5, 0x33f7, 0x33f9, 0x33fb, 0x33fd, + 0x33ff, 0x3401, 0x3403, 0x3405, 0x3407, 0x3409, 0x340b, 0x340d, + 0x3410, 0x3412, 0x3414, 0x3416, 0x3418, 0x341a, 0x341c, 0x341e, + 0x3420, 0x3422, 0x3424, 0x3426, 0x3428, 0x342b, 0x342e, 0x3431, + 0x3433, 0x3435, 0x3437, 0x3439, 0x343c, 0x343e, 0x3441, 0x3443, + 0x3445, 0x3448, 0x344b, 0x344d, 0x344f, 0x3451, 0x3453, 0x3455, + 0x3457, 0x3459, 0x345b, 0x345d, 0x345f, 0x3461, 0x3463, 0x3465, + 0x3467, 0x3469, 0x346b, 0x346d, 0x346f, 0x3471, 0x3474, 0x3476, + 0x3478, 0x347a, 0x347c, 0x347e, 0x3481, 0x3484, 0x3486, 0x3488, + 0x348a, 0x348c, 0x348e, 0x3490, 0x3493, 0x3495, 0x3497, 0x3499, + 0x349b, 0x349e, 0x34a1, 0x34a3, 0x34a5, 0x34a7, 0x34aa, 0x34ac, + 0x34ae, 0x34b1, 0x34b4, 0x34b6, 0x34b8, 0x34ba, 0x34bd, 0x34bf, + 0x34c1, 0x34c3, 0x34c5, 0x34c7, 0x34c9, 0x34cb, 0x34ce, 0x34d0, + 0x34d2, 0x34d4, 0x34d7, 0x34d9, 0x34db, 0x34dd, 0x34df, 0x34e2, + 0x34e5, 0x34e7, 0x34e9, 0x34eb, 0x34ee, 0x34f0, 0x34f3, 0x34f5, + + 0x34f7, 0x34f9, 0x34fc, 0x34fe, 0x3500, 0x3502, 0x3504, 0x3506, + 0x3508, 0x350a, 0x350d, 0x350f, 0x3511, 0x3513, 0x3515, 0x3517, + 0x3519, 0x351c, 0x351e, 0x3521, 0x3524, 0x3527, 0x3529, 0x352b, + 0x352d, 0x352f, 0x3531, 0x3533, 0x3535, 0x3537, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, }; #define GET_DECOMPOSITION_INDEX(ucs4) \ @@ -5833,2113 +5834,2113 @@ static const unsigned short uc_decomposition_trie[] = { static const unsigned short uc_decomposition_map[] = { - 0x103, 0x20, 0x210, 0x20, 0x308, 0x109, 0x61, 0x210, - 0x20, 0x304, 0x109, 0x32, 0x109, 0x33, 0x210, 0x20, - 0x301, 0x110, 0x3bc, 0x210, 0x20, 0x327, 0x109, 0x31, - 0x109, 0x6f, 0x311, 0x31, 0x2044, 0x34, 0x311, 0x31, - 0x2044, 0x32, 0x311, 0x33, 0x2044, 0x34, 0x201, 0x41, - 0x300, 0x201, 0x41, 0x301, 0x201, 0x41, 0x302, 0x201, - 0x41, 0x303, 0x201, 0x41, 0x308, 0x201, 0x41, 0x30a, - 0x201, 0x43, 0x327, 0x201, 0x45, 0x300, 0x201, 0x45, - 0x301, 0x201, 0x45, 0x302, 0x201, 0x45, 0x308, 0x201, - 0x49, 0x300, 0x201, 0x49, 0x301, 0x201, 0x49, 0x302, - 0x201, 0x49, 0x308, 0x201, 0x4e, 0x303, 0x201, 0x4f, - 0x300, 0x201, 0x4f, 0x301, 0x201, 0x4f, 0x302, 0x201, - 0x4f, 0x303, 0x201, 0x4f, 0x308, 0x201, 0x55, 0x300, - 0x201, 0x55, 0x301, 0x201, 0x55, 0x302, 0x201, 0x55, - 0x308, 0x201, 0x59, 0x301, 0x201, 0x61, 0x300, 0x201, - 0x61, 0x301, 0x201, 0x61, 0x302, 0x201, 0x61, 0x303, - 0x201, 0x61, 0x308, 0x201, 0x61, 0x30a, 0x201, 0x63, - 0x327, 0x201, 0x65, 0x300, 0x201, 0x65, 0x301, 0x201, - 0x65, 0x302, 0x201, 0x65, 0x308, 0x201, 0x69, 0x300, - 0x201, 0x69, 0x301, 0x201, 0x69, 0x302, 0x201, 0x69, - 0x308, 0x201, 0x6e, 0x303, 0x201, 0x6f, 0x300, 0x201, - 0x6f, 0x301, 0x201, 0x6f, 0x302, 0x201, 0x6f, 0x303, - 0x201, 0x6f, 0x308, 0x201, 0x75, 0x300, 0x201, 0x75, - 0x301, 0x201, 0x75, 0x302, 0x201, 0x75, 0x308, 0x201, - 0x79, 0x301, 0x201, 0x79, 0x308, 0x201, 0x41, 0x304, - 0x201, 0x61, 0x304, 0x201, 0x41, 0x306, 0x201, 0x61, - 0x306, 0x201, 0x41, 0x328, 0x201, 0x61, 0x328, 0x201, - 0x43, 0x301, 0x201, 0x63, 0x301, 0x201, 0x43, 0x302, - 0x201, 0x63, 0x302, 0x201, 0x43, 0x307, 0x201, 0x63, - 0x307, 0x201, 0x43, 0x30c, 0x201, 0x63, 0x30c, 0x201, - 0x44, 0x30c, 0x201, 0x64, 0x30c, 0x201, 0x45, 0x304, - 0x201, 0x65, 0x304, 0x201, 0x45, 0x306, 0x201, 0x65, - 0x306, 0x201, 0x45, 0x307, 0x201, 0x65, 0x307, 0x201, - 0x45, 0x328, 0x201, 0x65, 0x328, 0x201, 0x45, 0x30c, - 0x201, 0x65, 0x30c, 0x201, 0x47, 0x302, 0x201, 0x67, - 0x302, 0x201, 0x47, 0x306, 0x201, 0x67, 0x306, 0x201, - 0x47, 0x307, 0x201, 0x67, 0x307, 0x201, 0x47, 0x327, - 0x201, 0x67, 0x327, 0x201, 0x48, 0x302, 0x201, 0x68, - 0x302, 0x201, 0x49, 0x303, 0x201, 0x69, 0x303, 0x201, - 0x49, 0x304, 0x201, 0x69, 0x304, 0x201, 0x49, 0x306, - 0x201, 0x69, 0x306, 0x201, 0x49, 0x328, 0x201, 0x69, - 0x328, 0x201, 0x49, 0x307, 0x210, 0x49, 0x4a, 0x210, - 0x69, 0x6a, 0x201, 0x4a, 0x302, 0x201, 0x6a, 0x302, - 0x201, 0x4b, 0x327, 0x201, 0x6b, 0x327, 0x201, 0x4c, - 0x301, 0x201, 0x6c, 0x301, 0x201, 0x4c, 0x327, 0x201, - 0x6c, 0x327, 0x201, 0x4c, 0x30c, 0x201, 0x6c, 0x30c, - 0x210, 0x4c, 0xb7, 0x210, 0x6c, 0xb7, 0x201, 0x4e, - 0x301, 0x201, 0x6e, 0x301, 0x201, 0x4e, 0x327, 0x201, - 0x6e, 0x327, 0x201, 0x4e, 0x30c, 0x201, 0x6e, 0x30c, - 0x210, 0x2bc, 0x6e, 0x201, 0x4f, 0x304, 0x201, 0x6f, - 0x304, 0x201, 0x4f, 0x306, 0x201, 0x6f, 0x306, 0x201, - 0x4f, 0x30b, 0x201, 0x6f, 0x30b, 0x201, 0x52, 0x301, - 0x201, 0x72, 0x301, 0x201, 0x52, 0x327, 0x201, 0x72, - 0x327, 0x201, 0x52, 0x30c, 0x201, 0x72, 0x30c, 0x201, - 0x53, 0x301, 0x201, 0x73, 0x301, 0x201, 0x53, 0x302, - 0x201, 0x73, 0x302, 0x201, 0x53, 0x327, 0x201, 0x73, - 0x327, 0x201, 0x53, 0x30c, 0x201, 0x73, 0x30c, 0x201, - 0x54, 0x327, 0x201, 0x74, 0x327, 0x201, 0x54, 0x30c, - 0x201, 0x74, 0x30c, 0x201, 0x55, 0x303, 0x201, 0x75, - 0x303, 0x201, 0x55, 0x304, 0x201, 0x75, 0x304, 0x201, - 0x55, 0x306, 0x201, 0x75, 0x306, 0x201, 0x55, 0x30a, - 0x201, 0x75, 0x30a, 0x201, 0x55, 0x30b, 0x201, 0x75, - 0x30b, 0x201, 0x55, 0x328, 0x201, 0x75, 0x328, 0x201, - 0x57, 0x302, 0x201, 0x77, 0x302, 0x201, 0x59, 0x302, - 0x201, 0x79, 0x302, 0x201, 0x59, 0x308, 0x201, 0x5a, - 0x301, 0x201, 0x7a, 0x301, 0x201, 0x5a, 0x307, 0x201, - 0x7a, 0x307, 0x201, 0x5a, 0x30c, 0x201, 0x7a, 0x30c, - 0x110, 0x73, 0x201, 0x4f, 0x31b, 0x201, 0x6f, 0x31b, - 0x201, 0x55, 0x31b, 0x201, 0x75, 0x31b, 0x210, 0x44, - 0x17d, 0x210, 0x44, 0x17e, 0x210, 0x64, 0x17e, 0x210, - 0x4c, 0x4a, 0x210, 0x4c, 0x6a, 0x210, 0x6c, 0x6a, - 0x210, 0x4e, 0x4a, 0x210, 0x4e, 0x6a, 0x210, 0x6e, - 0x6a, 0x201, 0x41, 0x30c, 0x201, 0x61, 0x30c, 0x201, - 0x49, 0x30c, 0x201, 0x69, 0x30c, 0x201, 0x4f, 0x30c, - 0x201, 0x6f, 0x30c, 0x201, 0x55, 0x30c, 0x201, 0x75, - 0x30c, 0x201, 0xdc, 0x304, 0x201, 0xfc, 0x304, 0x201, - 0xdc, 0x301, 0x201, 0xfc, 0x301, 0x201, 0xdc, 0x30c, - 0x201, 0xfc, 0x30c, 0x201, 0xdc, 0x300, 0x201, 0xfc, - 0x300, 0x201, 0xc4, 0x304, 0x201, 0xe4, 0x304, 0x201, - 0x226, 0x304, 0x201, 0x227, 0x304, 0x201, 0xc6, 0x304, - 0x201, 0xe6, 0x304, 0x201, 0x47, 0x30c, 0x201, 0x67, - 0x30c, 0x201, 0x4b, 0x30c, 0x201, 0x6b, 0x30c, 0x201, - 0x4f, 0x328, 0x201, 0x6f, 0x328, 0x201, 0x1ea, 0x304, - 0x201, 0x1eb, 0x304, 0x201, 0x1b7, 0x30c, 0x201, 0x292, - 0x30c, 0x201, 0x6a, 0x30c, 0x210, 0x44, 0x5a, 0x210, - 0x44, 0x7a, 0x210, 0x64, 0x7a, 0x201, 0x47, 0x301, - 0x201, 0x67, 0x301, 0x201, 0x4e, 0x300, 0x201, 0x6e, - 0x300, 0x201, 0xc5, 0x301, 0x201, 0xe5, 0x301, 0x201, - 0xc6, 0x301, 0x201, 0xe6, 0x301, 0x201, 0xd8, 0x301, - 0x201, 0xf8, 0x301, 0x201, 0x41, 0x30f, 0x201, 0x61, - 0x30f, 0x201, 0x41, 0x311, 0x201, 0x61, 0x311, 0x201, - 0x45, 0x30f, 0x201, 0x65, 0x30f, 0x201, 0x45, 0x311, - 0x201, 0x65, 0x311, 0x201, 0x49, 0x30f, 0x201, 0x69, - 0x30f, 0x201, 0x49, 0x311, 0x201, 0x69, 0x311, 0x201, - 0x4f, 0x30f, 0x201, 0x6f, 0x30f, 0x201, 0x4f, 0x311, - 0x201, 0x6f, 0x311, 0x201, 0x52, 0x30f, 0x201, 0x72, - 0x30f, 0x201, 0x52, 0x311, 0x201, 0x72, 0x311, 0x201, - 0x55, 0x30f, 0x201, 0x75, 0x30f, 0x201, 0x55, 0x311, - 0x201, 0x75, 0x311, 0x201, 0x53, 0x326, 0x201, 0x73, - 0x326, 0x201, 0x54, 0x326, 0x201, 0x74, 0x326, 0x201, - 0x48, 0x30c, 0x201, 0x68, 0x30c, 0x201, 0x41, 0x307, - 0x201, 0x61, 0x307, 0x201, 0x45, 0x327, 0x201, 0x65, - 0x327, 0x201, 0xd6, 0x304, 0x201, 0xf6, 0x304, 0x201, - 0xd5, 0x304, 0x201, 0xf5, 0x304, 0x201, 0x4f, 0x307, - 0x201, 0x6f, 0x307, 0x201, 0x22e, 0x304, 0x201, 0x22f, - 0x304, 0x201, 0x59, 0x304, 0x201, 0x79, 0x304, 0x109, - 0x68, 0x109, 0x266, 0x109, 0x6a, 0x109, 0x72, 0x109, - 0x279, 0x109, 0x27b, 0x109, 0x281, 0x109, 0x77, 0x109, - 0x79, 0x210, 0x20, 0x306, 0x210, 0x20, 0x307, 0x210, - 0x20, 0x30a, 0x210, 0x20, 0x328, 0x210, 0x20, 0x303, - 0x210, 0x20, 0x30b, 0x109, 0x263, 0x109, 0x6c, 0x109, - 0x73, 0x109, 0x78, 0x109, 0x295, 0x101, 0x300, 0x101, - 0x301, 0x101, 0x313, 0x201, 0x308, 0x301, 0x101, 0x2b9, - 0x210, 0x20, 0x345, 0x101, 0x3b, 0x210, 0x20, 0x301, - 0x201, 0xa8, 0x301, 0x201, 0x391, 0x301, 0x101, 0xb7, - 0x201, 0x395, 0x301, 0x201, 0x397, 0x301, 0x201, 0x399, - 0x301, 0x201, 0x39f, 0x301, 0x201, 0x3a5, 0x301, 0x201, - 0x3a9, 0x301, 0x201, 0x3ca, 0x301, 0x201, 0x399, 0x308, - 0x201, 0x3a5, 0x308, 0x201, 0x3b1, 0x301, 0x201, 0x3b5, - 0x301, 0x201, 0x3b7, 0x301, 0x201, 0x3b9, 0x301, 0x201, - 0x3cb, 0x301, 0x201, 0x3b9, 0x308, 0x201, 0x3c5, 0x308, - 0x201, 0x3bf, 0x301, 0x201, 0x3c5, 0x301, 0x201, 0x3c9, - 0x301, 0x110, 0x3b2, 0x110, 0x3b8, 0x110, 0x3a5, 0x201, - 0x3d2, 0x301, 0x201, 0x3d2, 0x308, 0x110, 0x3c6, 0x110, - 0x3c0, 0x110, 0x3ba, 0x110, 0x3c1, 0x110, 0x3c2, 0x110, - 0x398, 0x110, 0x3b5, 0x110, 0x3a3, 0x201, 0x415, 0x300, - 0x201, 0x415, 0x308, 0x201, 0x413, 0x301, 0x201, 0x406, - 0x308, 0x201, 0x41a, 0x301, 0x201, 0x418, 0x300, 0x201, - 0x423, 0x306, 0x201, 0x418, 0x306, 0x201, 0x438, 0x306, - 0x201, 0x435, 0x300, 0x201, 0x435, 0x308, 0x201, 0x433, - 0x301, 0x201, 0x456, 0x308, 0x201, 0x43a, 0x301, 0x201, - 0x438, 0x300, 0x201, 0x443, 0x306, 0x201, 0x474, 0x30f, - 0x201, 0x475, 0x30f, 0x201, 0x416, 0x306, 0x201, 0x436, - 0x306, 0x201, 0x410, 0x306, 0x201, 0x430, 0x306, 0x201, - 0x410, 0x308, 0x201, 0x430, 0x308, 0x201, 0x415, 0x306, - 0x201, 0x435, 0x306, 0x201, 0x4d8, 0x308, 0x201, 0x4d9, - 0x308, 0x201, 0x416, 0x308, 0x201, 0x436, 0x308, 0x201, - 0x417, 0x308, 0x201, 0x437, 0x308, 0x201, 0x418, 0x304, - 0x201, 0x438, 0x304, 0x201, 0x418, 0x308, 0x201, 0x438, - 0x308, 0x201, 0x41e, 0x308, 0x201, 0x43e, 0x308, 0x201, - 0x4e8, 0x308, 0x201, 0x4e9, 0x308, 0x201, 0x42d, 0x308, - 0x201, 0x44d, 0x308, 0x201, 0x423, 0x304, 0x201, 0x443, - 0x304, 0x201, 0x423, 0x308, 0x201, 0x443, 0x308, 0x201, - 0x423, 0x30b, 0x201, 0x443, 0x30b, 0x201, 0x427, 0x308, - 0x201, 0x447, 0x308, 0x201, 0x42b, 0x308, 0x201, 0x44b, - 0x308, 0x210, 0x565, 0x582, 0x201, 0x627, 0x653, 0x201, - 0x627, 0x654, 0x201, 0x648, 0x654, 0x201, 0x627, 0x655, - 0x201, 0x64a, 0x654, 0x210, 0x627, 0x674, 0x210, 0x648, - 0x674, 0x210, 0x6c7, 0x674, 0x210, 0x64a, 0x674, 0x201, - 0x6d5, 0x654, 0x201, 0x6c1, 0x654, 0x201, 0x6d2, 0x654, - 0x201, 0x928, 0x93c, 0x201, 0x930, 0x93c, 0x201, 0x933, - 0x93c, 0x201, 0x915, 0x93c, 0x201, 0x916, 0x93c, 0x201, - 0x917, 0x93c, 0x201, 0x91c, 0x93c, 0x201, 0x921, 0x93c, - 0x201, 0x922, 0x93c, 0x201, 0x92b, 0x93c, 0x201, 0x92f, - 0x93c, 0x201, 0x9c7, 0x9be, 0x201, 0x9c7, 0x9d7, 0x201, - 0x9a1, 0x9bc, 0x201, 0x9a2, 0x9bc, 0x201, 0x9af, 0x9bc, - 0x201, 0xa32, 0xa3c, 0x201, 0xa38, 0xa3c, 0x201, 0xa16, - 0xa3c, 0x201, 0xa17, 0xa3c, 0x201, 0xa1c, 0xa3c, 0x201, - 0xa2b, 0xa3c, 0x201, 0xb47, 0xb56, 0x201, 0xb47, 0xb3e, - 0x201, 0xb47, 0xb57, 0x201, 0xb21, 0xb3c, 0x201, 0xb22, - 0xb3c, 0x201, 0xb92, 0xbd7, 0x201, 0xbc6, 0xbbe, 0x201, - 0xbc7, 0xbbe, 0x201, 0xbc6, 0xbd7, 0x201, 0xc46, 0xc56, - 0x201, 0xcbf, 0xcd5, 0x201, 0xcc6, 0xcd5, 0x201, 0xcc6, - 0xcd6, 0x201, 0xcc6, 0xcc2, 0x201, 0xcca, 0xcd5, 0x201, - 0xd46, 0xd3e, 0x201, 0xd47, 0xd3e, 0x201, 0xd46, 0xd57, - 0x201, 0xdd9, 0xdca, 0x201, 0xdd9, 0xdcf, 0x201, 0xddc, - 0xdca, 0x201, 0xdd9, 0xddf, 0x210, 0xe4d, 0xe32, 0x210, - 0xecd, 0xeb2, 0x210, 0xeab, 0xe99, 0x210, 0xeab, 0xea1, - 0x103, 0xf0b, 0x201, 0xf42, 0xfb7, 0x201, 0xf4c, 0xfb7, - 0x201, 0xf51, 0xfb7, 0x201, 0xf56, 0xfb7, 0x201, 0xf5b, - 0xfb7, 0x201, 0xf40, 0xfb5, 0x201, 0xf71, 0xf72, 0x201, - 0xf71, 0xf74, 0x201, 0xfb2, 0xf80, 0x210, 0xfb2, 0xf81, - 0x201, 0xfb3, 0xf80, 0x210, 0xfb3, 0xf81, 0x201, 0xf71, - 0xf80, 0x201, 0xf92, 0xfb7, 0x201, 0xf9c, 0xfb7, 0x201, - 0xfa1, 0xfb7, 0x201, 0xfa6, 0xfb7, 0x201, 0xfab, 0xfb7, - 0x201, 0xf90, 0xfb5, 0x201, 0x1025, 0x102e, 0x109, 0x10dc, - 0x201, 0x1b05, 0x1b35, 0x201, 0x1b07, 0x1b35, 0x201, 0x1b09, - 0x1b35, 0x201, 0x1b0b, 0x1b35, 0x201, 0x1b0d, 0x1b35, 0x201, - 0x1b11, 0x1b35, 0x201, 0x1b3a, 0x1b35, 0x201, 0x1b3c, 0x1b35, - 0x201, 0x1b3e, 0x1b35, 0x201, 0x1b3f, 0x1b35, 0x201, 0x1b42, - 0x1b35, 0x109, 0x41, 0x109, 0xc6, 0x109, 0x42, 0x109, - 0x44, 0x109, 0x45, 0x109, 0x18e, 0x109, 0x47, 0x109, - 0x48, 0x109, 0x49, 0x109, 0x4a, 0x109, 0x4b, 0x109, - 0x4c, 0x109, 0x4d, 0x109, 0x4e, 0x109, 0x4f, 0x109, - 0x222, 0x109, 0x50, 0x109, 0x52, 0x109, 0x54, 0x109, - 0x55, 0x109, 0x57, 0x109, 0x61, 0x109, 0x250, 0x109, - 0x251, 0x109, 0x1d02, 0x109, 0x62, 0x109, 0x64, 0x109, - 0x65, 0x109, 0x259, 0x109, 0x25b, 0x109, 0x25c, 0x109, - 0x67, 0x109, 0x6b, 0x109, 0x6d, 0x109, 0x14b, 0x109, - 0x6f, 0x109, 0x254, 0x109, 0x1d16, 0x109, 0x1d17, 0x109, - 0x70, 0x109, 0x74, 0x109, 0x75, 0x109, 0x1d1d, 0x109, - 0x26f, 0x109, 0x76, 0x109, 0x1d25, 0x109, 0x3b2, 0x109, - 0x3b3, 0x109, 0x3b4, 0x109, 0x3c6, 0x109, 0x3c7, 0x10a, - 0x69, 0x10a, 0x72, 0x10a, 0x75, 0x10a, 0x76, 0x10a, - 0x3b2, 0x10a, 0x3b3, 0x10a, 0x3c1, 0x10a, 0x3c6, 0x10a, - 0x3c7, 0x109, 0x43d, 0x109, 0x252, 0x109, 0x63, 0x109, - 0x255, 0x109, 0xf0, 0x109, 0x25c, 0x109, 0x66, 0x109, - 0x25f, 0x109, 0x261, 0x109, 0x265, 0x109, 0x268, 0x109, - 0x269, 0x109, 0x26a, 0x109, 0x1d7b, 0x109, 0x29d, 0x109, - 0x26d, 0x109, 0x1d85, 0x109, 0x29f, 0x109, 0x271, 0x109, - 0x270, 0x109, 0x272, 0x109, 0x273, 0x109, 0x274, 0x109, - 0x275, 0x109, 0x278, 0x109, 0x282, 0x109, 0x283, 0x109, - 0x1ab, 0x109, 0x289, 0x109, 0x28a, 0x109, 0x1d1c, 0x109, - 0x28b, 0x109, 0x28c, 0x109, 0x7a, 0x109, 0x290, 0x109, - 0x291, 0x109, 0x292, 0x109, 0x3b8, 0x201, 0x41, 0x325, - 0x201, 0x61, 0x325, 0x201, 0x42, 0x307, 0x201, 0x62, - 0x307, 0x201, 0x42, 0x323, 0x201, 0x62, 0x323, 0x201, - 0x42, 0x331, 0x201, 0x62, 0x331, 0x201, 0xc7, 0x301, - 0x201, 0xe7, 0x301, 0x201, 0x44, 0x307, 0x201, 0x64, - 0x307, 0x201, 0x44, 0x323, 0x201, 0x64, 0x323, 0x201, - 0x44, 0x331, 0x201, 0x64, 0x331, 0x201, 0x44, 0x327, - 0x201, 0x64, 0x327, 0x201, 0x44, 0x32d, 0x201, 0x64, - 0x32d, 0x201, 0x112, 0x300, 0x201, 0x113, 0x300, 0x201, - 0x112, 0x301, 0x201, 0x113, 0x301, 0x201, 0x45, 0x32d, - 0x201, 0x65, 0x32d, 0x201, 0x45, 0x330, 0x201, 0x65, - 0x330, 0x201, 0x228, 0x306, 0x201, 0x229, 0x306, 0x201, - 0x46, 0x307, 0x201, 0x66, 0x307, 0x201, 0x47, 0x304, - 0x201, 0x67, 0x304, 0x201, 0x48, 0x307, 0x201, 0x68, - 0x307, 0x201, 0x48, 0x323, 0x201, 0x68, 0x323, 0x201, - 0x48, 0x308, 0x201, 0x68, 0x308, 0x201, 0x48, 0x327, - 0x201, 0x68, 0x327, 0x201, 0x48, 0x32e, 0x201, 0x68, - 0x32e, 0x201, 0x49, 0x330, 0x201, 0x69, 0x330, 0x201, - 0xcf, 0x301, 0x201, 0xef, 0x301, 0x201, 0x4b, 0x301, - 0x201, 0x6b, 0x301, 0x201, 0x4b, 0x323, 0x201, 0x6b, - 0x323, 0x201, 0x4b, 0x331, 0x201, 0x6b, 0x331, 0x201, - 0x4c, 0x323, 0x201, 0x6c, 0x323, 0x201, 0x1e36, 0x304, - 0x201, 0x1e37, 0x304, 0x201, 0x4c, 0x331, 0x201, 0x6c, - 0x331, 0x201, 0x4c, 0x32d, 0x201, 0x6c, 0x32d, 0x201, - 0x4d, 0x301, 0x201, 0x6d, 0x301, 0x201, 0x4d, 0x307, - 0x201, 0x6d, 0x307, 0x201, 0x4d, 0x323, 0x201, 0x6d, - 0x323, 0x201, 0x4e, 0x307, 0x201, 0x6e, 0x307, 0x201, - 0x4e, 0x323, 0x201, 0x6e, 0x323, 0x201, 0x4e, 0x331, - 0x201, 0x6e, 0x331, 0x201, 0x4e, 0x32d, 0x201, 0x6e, - 0x32d, 0x201, 0xd5, 0x301, 0x201, 0xf5, 0x301, 0x201, - 0xd5, 0x308, 0x201, 0xf5, 0x308, 0x201, 0x14c, 0x300, - 0x201, 0x14d, 0x300, 0x201, 0x14c, 0x301, 0x201, 0x14d, - 0x301, 0x201, 0x50, 0x301, 0x201, 0x70, 0x301, 0x201, - 0x50, 0x307, 0x201, 0x70, 0x307, 0x201, 0x52, 0x307, - 0x201, 0x72, 0x307, 0x201, 0x52, 0x323, 0x201, 0x72, - 0x323, 0x201, 0x1e5a, 0x304, 0x201, 0x1e5b, 0x304, 0x201, - 0x52, 0x331, 0x201, 0x72, 0x331, 0x201, 0x53, 0x307, - 0x201, 0x73, 0x307, 0x201, 0x53, 0x323, 0x201, 0x73, - 0x323, 0x201, 0x15a, 0x307, 0x201, 0x15b, 0x307, 0x201, - 0x160, 0x307, 0x201, 0x161, 0x307, 0x201, 0x1e62, 0x307, - 0x201, 0x1e63, 0x307, 0x201, 0x54, 0x307, 0x201, 0x74, - 0x307, 0x201, 0x54, 0x323, 0x201, 0x74, 0x323, 0x201, - 0x54, 0x331, 0x201, 0x74, 0x331, 0x201, 0x54, 0x32d, - 0x201, 0x74, 0x32d, 0x201, 0x55, 0x324, 0x201, 0x75, - 0x324, 0x201, 0x55, 0x330, 0x201, 0x75, 0x330, 0x201, - 0x55, 0x32d, 0x201, 0x75, 0x32d, 0x201, 0x168, 0x301, - 0x201, 0x169, 0x301, 0x201, 0x16a, 0x308, 0x201, 0x16b, - 0x308, 0x201, 0x56, 0x303, 0x201, 0x76, 0x303, 0x201, - 0x56, 0x323, 0x201, 0x76, 0x323, 0x201, 0x57, 0x300, - 0x201, 0x77, 0x300, 0x201, 0x57, 0x301, 0x201, 0x77, - 0x301, 0x201, 0x57, 0x308, 0x201, 0x77, 0x308, 0x201, - 0x57, 0x307, 0x201, 0x77, 0x307, 0x201, 0x57, 0x323, - 0x201, 0x77, 0x323, 0x201, 0x58, 0x307, 0x201, 0x78, - 0x307, 0x201, 0x58, 0x308, 0x201, 0x78, 0x308, 0x201, - 0x59, 0x307, 0x201, 0x79, 0x307, 0x201, 0x5a, 0x302, - 0x201, 0x7a, 0x302, 0x201, 0x5a, 0x323, 0x201, 0x7a, - 0x323, 0x201, 0x5a, 0x331, 0x201, 0x7a, 0x331, 0x201, - 0x68, 0x331, 0x201, 0x74, 0x308, 0x201, 0x77, 0x30a, - 0x201, 0x79, 0x30a, 0x210, 0x61, 0x2be, 0x201, 0x17f, - 0x307, 0x201, 0x41, 0x323, 0x201, 0x61, 0x323, 0x201, - 0x41, 0x309, 0x201, 0x61, 0x309, 0x201, 0xc2, 0x301, - 0x201, 0xe2, 0x301, 0x201, 0xc2, 0x300, 0x201, 0xe2, - 0x300, 0x201, 0xc2, 0x309, 0x201, 0xe2, 0x309, 0x201, - 0xc2, 0x303, 0x201, 0xe2, 0x303, 0x201, 0x1ea0, 0x302, - 0x201, 0x1ea1, 0x302, 0x201, 0x102, 0x301, 0x201, 0x103, - 0x301, 0x201, 0x102, 0x300, 0x201, 0x103, 0x300, 0x201, - 0x102, 0x309, 0x201, 0x103, 0x309, 0x201, 0x102, 0x303, - 0x201, 0x103, 0x303, 0x201, 0x1ea0, 0x306, 0x201, 0x1ea1, - 0x306, 0x201, 0x45, 0x323, 0x201, 0x65, 0x323, 0x201, - 0x45, 0x309, 0x201, 0x65, 0x309, 0x201, 0x45, 0x303, - 0x201, 0x65, 0x303, 0x201, 0xca, 0x301, 0x201, 0xea, - 0x301, 0x201, 0xca, 0x300, 0x201, 0xea, 0x300, 0x201, - 0xca, 0x309, 0x201, 0xea, 0x309, 0x201, 0xca, 0x303, - 0x201, 0xea, 0x303, 0x201, 0x1eb8, 0x302, 0x201, 0x1eb9, - 0x302, 0x201, 0x49, 0x309, 0x201, 0x69, 0x309, 0x201, - 0x49, 0x323, 0x201, 0x69, 0x323, 0x201, 0x4f, 0x323, - 0x201, 0x6f, 0x323, 0x201, 0x4f, 0x309, 0x201, 0x6f, - 0x309, 0x201, 0xd4, 0x301, 0x201, 0xf4, 0x301, 0x201, - 0xd4, 0x300, 0x201, 0xf4, 0x300, 0x201, 0xd4, 0x309, - 0x201, 0xf4, 0x309, 0x201, 0xd4, 0x303, 0x201, 0xf4, - 0x303, 0x201, 0x1ecc, 0x302, 0x201, 0x1ecd, 0x302, 0x201, - 0x1a0, 0x301, 0x201, 0x1a1, 0x301, 0x201, 0x1a0, 0x300, - 0x201, 0x1a1, 0x300, 0x201, 0x1a0, 0x309, 0x201, 0x1a1, - 0x309, 0x201, 0x1a0, 0x303, 0x201, 0x1a1, 0x303, 0x201, - 0x1a0, 0x323, 0x201, 0x1a1, 0x323, 0x201, 0x55, 0x323, - 0x201, 0x75, 0x323, 0x201, 0x55, 0x309, 0x201, 0x75, - 0x309, 0x201, 0x1af, 0x301, 0x201, 0x1b0, 0x301, 0x201, - 0x1af, 0x300, 0x201, 0x1b0, 0x300, 0x201, 0x1af, 0x309, - 0x201, 0x1b0, 0x309, 0x201, 0x1af, 0x303, 0x201, 0x1b0, - 0x303, 0x201, 0x1af, 0x323, 0x201, 0x1b0, 0x323, 0x201, - 0x59, 0x300, 0x201, 0x79, 0x300, 0x201, 0x59, 0x323, - 0x201, 0x79, 0x323, 0x201, 0x59, 0x309, 0x201, 0x79, - 0x309, 0x201, 0x59, 0x303, 0x201, 0x79, 0x303, 0x201, - 0x3b1, 0x313, 0x201, 0x3b1, 0x314, 0x201, 0x1f00, 0x300, - 0x201, 0x1f01, 0x300, 0x201, 0x1f00, 0x301, 0x201, 0x1f01, - 0x301, 0x201, 0x1f00, 0x342, 0x201, 0x1f01, 0x342, 0x201, - 0x391, 0x313, 0x201, 0x391, 0x314, 0x201, 0x1f08, 0x300, - 0x201, 0x1f09, 0x300, 0x201, 0x1f08, 0x301, 0x201, 0x1f09, - 0x301, 0x201, 0x1f08, 0x342, 0x201, 0x1f09, 0x342, 0x201, - 0x3b5, 0x313, 0x201, 0x3b5, 0x314, 0x201, 0x1f10, 0x300, - 0x201, 0x1f11, 0x300, 0x201, 0x1f10, 0x301, 0x201, 0x1f11, - 0x301, 0x201, 0x395, 0x313, 0x201, 0x395, 0x314, 0x201, - 0x1f18, 0x300, 0x201, 0x1f19, 0x300, 0x201, 0x1f18, 0x301, - 0x201, 0x1f19, 0x301, 0x201, 0x3b7, 0x313, 0x201, 0x3b7, - 0x314, 0x201, 0x1f20, 0x300, 0x201, 0x1f21, 0x300, 0x201, - 0x1f20, 0x301, 0x201, 0x1f21, 0x301, 0x201, 0x1f20, 0x342, - 0x201, 0x1f21, 0x342, 0x201, 0x397, 0x313, 0x201, 0x397, - 0x314, 0x201, 0x1f28, 0x300, 0x201, 0x1f29, 0x300, 0x201, - 0x1f28, 0x301, 0x201, 0x1f29, 0x301, 0x201, 0x1f28, 0x342, - 0x201, 0x1f29, 0x342, 0x201, 0x3b9, 0x313, 0x201, 0x3b9, - 0x314, 0x201, 0x1f30, 0x300, 0x201, 0x1f31, 0x300, 0x201, - 0x1f30, 0x301, 0x201, 0x1f31, 0x301, 0x201, 0x1f30, 0x342, - 0x201, 0x1f31, 0x342, 0x201, 0x399, 0x313, 0x201, 0x399, - 0x314, 0x201, 0x1f38, 0x300, 0x201, 0x1f39, 0x300, 0x201, - 0x1f38, 0x301, 0x201, 0x1f39, 0x301, 0x201, 0x1f38, 0x342, - 0x201, 0x1f39, 0x342, 0x201, 0x3bf, 0x313, 0x201, 0x3bf, - 0x314, 0x201, 0x1f40, 0x300, 0x201, 0x1f41, 0x300, 0x201, - 0x1f40, 0x301, 0x201, 0x1f41, 0x301, 0x201, 0x39f, 0x313, - 0x201, 0x39f, 0x314, 0x201, 0x1f48, 0x300, 0x201, 0x1f49, - 0x300, 0x201, 0x1f48, 0x301, 0x201, 0x1f49, 0x301, 0x201, - 0x3c5, 0x313, 0x201, 0x3c5, 0x314, 0x201, 0x1f50, 0x300, - 0x201, 0x1f51, 0x300, 0x201, 0x1f50, 0x301, 0x201, 0x1f51, - 0x301, 0x201, 0x1f50, 0x342, 0x201, 0x1f51, 0x342, 0x201, - 0x3a5, 0x314, 0x201, 0x1f59, 0x300, 0x201, 0x1f59, 0x301, - 0x201, 0x1f59, 0x342, 0x201, 0x3c9, 0x313, 0x201, 0x3c9, - 0x314, 0x201, 0x1f60, 0x300, 0x201, 0x1f61, 0x300, 0x201, - 0x1f60, 0x301, 0x201, 0x1f61, 0x301, 0x201, 0x1f60, 0x342, - 0x201, 0x1f61, 0x342, 0x201, 0x3a9, 0x313, 0x201, 0x3a9, - 0x314, 0x201, 0x1f68, 0x300, 0x201, 0x1f69, 0x300, 0x201, - 0x1f68, 0x301, 0x201, 0x1f69, 0x301, 0x201, 0x1f68, 0x342, - 0x201, 0x1f69, 0x342, 0x201, 0x3b1, 0x300, 0x101, 0x3ac, - 0x201, 0x3b5, 0x300, 0x101, 0x3ad, 0x201, 0x3b7, 0x300, - 0x101, 0x3ae, 0x201, 0x3b9, 0x300, 0x101, 0x3af, 0x201, - 0x3bf, 0x300, 0x101, 0x3cc, 0x201, 0x3c5, 0x300, 0x101, - 0x3cd, 0x201, 0x3c9, 0x300, 0x101, 0x3ce, 0x201, 0x1f00, - 0x345, 0x201, 0x1f01, 0x345, 0x201, 0x1f02, 0x345, 0x201, - 0x1f03, 0x345, 0x201, 0x1f04, 0x345, 0x201, 0x1f05, 0x345, - 0x201, 0x1f06, 0x345, 0x201, 0x1f07, 0x345, 0x201, 0x1f08, - 0x345, 0x201, 0x1f09, 0x345, 0x201, 0x1f0a, 0x345, 0x201, - 0x1f0b, 0x345, 0x201, 0x1f0c, 0x345, 0x201, 0x1f0d, 0x345, - 0x201, 0x1f0e, 0x345, 0x201, 0x1f0f, 0x345, 0x201, 0x1f20, - 0x345, 0x201, 0x1f21, 0x345, 0x201, 0x1f22, 0x345, 0x201, - 0x1f23, 0x345, 0x201, 0x1f24, 0x345, 0x201, 0x1f25, 0x345, - 0x201, 0x1f26, 0x345, 0x201, 0x1f27, 0x345, 0x201, 0x1f28, - 0x345, 0x201, 0x1f29, 0x345, 0x201, 0x1f2a, 0x345, 0x201, - 0x1f2b, 0x345, 0x201, 0x1f2c, 0x345, 0x201, 0x1f2d, 0x345, - 0x201, 0x1f2e, 0x345, 0x201, 0x1f2f, 0x345, 0x201, 0x1f60, - 0x345, 0x201, 0x1f61, 0x345, 0x201, 0x1f62, 0x345, 0x201, - 0x1f63, 0x345, 0x201, 0x1f64, 0x345, 0x201, 0x1f65, 0x345, - 0x201, 0x1f66, 0x345, 0x201, 0x1f67, 0x345, 0x201, 0x1f68, - 0x345, 0x201, 0x1f69, 0x345, 0x201, 0x1f6a, 0x345, 0x201, - 0x1f6b, 0x345, 0x201, 0x1f6c, 0x345, 0x201, 0x1f6d, 0x345, - 0x201, 0x1f6e, 0x345, 0x201, 0x1f6f, 0x345, 0x201, 0x3b1, - 0x306, 0x201, 0x3b1, 0x304, 0x201, 0x1f70, 0x345, 0x201, - 0x3b1, 0x345, 0x201, 0x3ac, 0x345, 0x201, 0x3b1, 0x342, - 0x201, 0x1fb6, 0x345, 0x201, 0x391, 0x306, 0x201, 0x391, - 0x304, 0x201, 0x391, 0x300, 0x101, 0x386, 0x201, 0x391, - 0x345, 0x210, 0x20, 0x313, 0x101, 0x3b9, 0x210, 0x20, - 0x313, 0x210, 0x20, 0x342, 0x201, 0xa8, 0x342, 0x201, - 0x1f74, 0x345, 0x201, 0x3b7, 0x345, 0x201, 0x3ae, 0x345, - 0x201, 0x3b7, 0x342, 0x201, 0x1fc6, 0x345, 0x201, 0x395, - 0x300, 0x101, 0x388, 0x201, 0x397, 0x300, 0x101, 0x389, - 0x201, 0x397, 0x345, 0x201, 0x1fbf, 0x300, 0x201, 0x1fbf, - 0x301, 0x201, 0x1fbf, 0x342, 0x201, 0x3b9, 0x306, 0x201, - 0x3b9, 0x304, 0x201, 0x3ca, 0x300, 0x101, 0x390, 0x201, - 0x3b9, 0x342, 0x201, 0x3ca, 0x342, 0x201, 0x399, 0x306, - 0x201, 0x399, 0x304, 0x201, 0x399, 0x300, 0x101, 0x38a, - 0x201, 0x1ffe, 0x300, 0x201, 0x1ffe, 0x301, 0x201, 0x1ffe, - 0x342, 0x201, 0x3c5, 0x306, 0x201, 0x3c5, 0x304, 0x201, - 0x3cb, 0x300, 0x101, 0x3b0, 0x201, 0x3c1, 0x313, 0x201, - 0x3c1, 0x314, 0x201, 0x3c5, 0x342, 0x201, 0x3cb, 0x342, - 0x201, 0x3a5, 0x306, 0x201, 0x3a5, 0x304, 0x201, 0x3a5, - 0x300, 0x101, 0x38e, 0x201, 0x3a1, 0x314, 0x201, 0xa8, - 0x300, 0x101, 0x385, 0x101, 0x60, 0x201, 0x1f7c, 0x345, - 0x201, 0x3c9, 0x345, 0x201, 0x3ce, 0x345, 0x201, 0x3c9, - 0x342, 0x201, 0x1ff6, 0x345, 0x201, 0x39f, 0x300, 0x101, - 0x38c, 0x201, 0x3a9, 0x300, 0x101, 0x38f, 0x201, 0x3a9, - 0x345, 0x101, 0xb4, 0x210, 0x20, 0x314, 0x101, 0x2002, - 0x101, 0x2003, 0x110, 0x20, 0x110, 0x20, 0x110, 0x20, - 0x110, 0x20, 0x110, 0x20, 0x103, 0x20, 0x110, 0x20, - 0x110, 0x20, 0x110, 0x20, 0x103, 0x2010, 0x210, 0x20, - 0x333, 0x110, 0x2e, 0x210, 0x2e, 0x2e, 0x310, 0x2e, - 0x2e, 0x2e, 0x103, 0x20, 0x210, 0x2032, 0x2032, 0x310, - 0x2032, 0x2032, 0x2032, 0x210, 0x2035, 0x2035, 0x310, 0x2035, - 0x2035, 0x2035, 0x210, 0x21, 0x21, 0x210, 0x20, 0x305, - 0x210, 0x3f, 0x3f, 0x210, 0x3f, 0x21, 0x210, 0x21, - 0x3f, 0x410, 0x2032, 0x2032, 0x2032, 0x2032, 0x110, 0x20, - 0x109, 0x30, 0x109, 0x69, 0x109, 0x34, 0x109, 0x35, - 0x109, 0x36, 0x109, 0x37, 0x109, 0x38, 0x109, 0x39, - 0x109, 0x2b, 0x109, 0x2212, 0x109, 0x3d, 0x109, 0x28, - 0x109, 0x29, 0x109, 0x6e, 0x10a, 0x30, 0x10a, 0x31, - 0x10a, 0x32, 0x10a, 0x33, 0x10a, 0x34, 0x10a, 0x35, - 0x10a, 0x36, 0x10a, 0x37, 0x10a, 0x38, 0x10a, 0x39, - 0x10a, 0x2b, 0x10a, 0x2212, 0x10a, 0x3d, 0x10a, 0x28, - 0x10a, 0x29, 0x10a, 0x61, 0x10a, 0x65, 0x10a, 0x6f, - 0x10a, 0x78, 0x10a, 0x259, 0x210, 0x52, 0x73, 0x310, - 0x61, 0x2f, 0x63, 0x310, 0x61, 0x2f, 0x73, 0x102, - 0x43, 0x210, 0xb0, 0x43, 0x310, 0x63, 0x2f, 0x6f, - 0x310, 0x63, 0x2f, 0x75, 0x110, 0x190, 0x210, 0xb0, - 0x46, 0x102, 0x67, 0x102, 0x48, 0x102, 0x48, 0x102, - 0x48, 0x102, 0x68, 0x102, 0x127, 0x102, 0x49, 0x102, - 0x49, 0x102, 0x4c, 0x102, 0x6c, 0x102, 0x4e, 0x210, - 0x4e, 0x6f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52, - 0x102, 0x52, 0x102, 0x52, 0x209, 0x53, 0x4d, 0x310, - 0x54, 0x45, 0x4c, 0x209, 0x54, 0x4d, 0x102, 0x5a, - 0x101, 0x3a9, 0x102, 0x5a, 0x101, 0x4b, 0x101, 0xc5, - 0x102, 0x42, 0x102, 0x43, 0x102, 0x65, 0x102, 0x45, - 0x102, 0x46, 0x102, 0x4d, 0x102, 0x6f, 0x110, 0x5d0, - 0x110, 0x5d1, 0x110, 0x5d2, 0x110, 0x5d3, 0x102, 0x69, - 0x310, 0x46, 0x41, 0x58, 0x102, 0x3c0, 0x102, 0x3b3, - 0x102, 0x393, 0x102, 0x3a0, 0x102, 0x2211, 0x102, 0x44, - 0x102, 0x64, 0x102, 0x65, 0x102, 0x69, 0x102, 0x6a, - 0x311, 0x31, 0x2044, 0x33, 0x311, 0x32, 0x2044, 0x33, - 0x311, 0x31, 0x2044, 0x35, 0x311, 0x32, 0x2044, 0x35, - 0x311, 0x33, 0x2044, 0x35, 0x311, 0x34, 0x2044, 0x35, - 0x311, 0x31, 0x2044, 0x36, 0x311, 0x35, 0x2044, 0x36, - 0x311, 0x31, 0x2044, 0x38, 0x311, 0x33, 0x2044, 0x38, - 0x311, 0x35, 0x2044, 0x38, 0x311, 0x37, 0x2044, 0x38, - 0x211, 0x31, 0x2044, 0x110, 0x49, 0x210, 0x49, 0x49, - 0x310, 0x49, 0x49, 0x49, 0x210, 0x49, 0x56, 0x110, - 0x56, 0x210, 0x56, 0x49, 0x310, 0x56, 0x49, 0x49, - 0x410, 0x56, 0x49, 0x49, 0x49, 0x210, 0x49, 0x58, - 0x110, 0x58, 0x210, 0x58, 0x49, 0x310, 0x58, 0x49, - 0x49, 0x110, 0x4c, 0x110, 0x43, 0x110, 0x44, 0x110, - 0x4d, 0x110, 0x69, 0x210, 0x69, 0x69, 0x310, 0x69, - 0x69, 0x69, 0x210, 0x69, 0x76, 0x110, 0x76, 0x210, - 0x76, 0x69, 0x310, 0x76, 0x69, 0x69, 0x410, 0x76, - 0x69, 0x69, 0x69, 0x210, 0x69, 0x78, 0x110, 0x78, - 0x210, 0x78, 0x69, 0x310, 0x78, 0x69, 0x69, 0x110, - 0x6c, 0x110, 0x63, 0x110, 0x64, 0x110, 0x6d, 0x201, - 0x2190, 0x338, 0x201, 0x2192, 0x338, 0x201, 0x2194, 0x338, - 0x201, 0x21d0, 0x338, 0x201, 0x21d4, 0x338, 0x201, 0x21d2, - 0x338, 0x201, 0x2203, 0x338, 0x201, 0x2208, 0x338, 0x201, - 0x220b, 0x338, 0x201, 0x2223, 0x338, 0x201, 0x2225, 0x338, - 0x210, 0x222b, 0x222b, 0x310, 0x222b, 0x222b, 0x222b, 0x210, - 0x222e, 0x222e, 0x310, 0x222e, 0x222e, 0x222e, 0x201, 0x223c, - 0x338, 0x201, 0x2243, 0x338, 0x201, 0x2245, 0x338, 0x201, - 0x2248, 0x338, 0x201, 0x3d, 0x338, 0x201, 0x2261, 0x338, - 0x201, 0x224d, 0x338, 0x201, 0x3c, 0x338, 0x201, 0x3e, - 0x338, 0x201, 0x2264, 0x338, 0x201, 0x2265, 0x338, 0x201, - 0x2272, 0x338, 0x201, 0x2273, 0x338, 0x201, 0x2276, 0x338, - 0x201, 0x2277, 0x338, 0x201, 0x227a, 0x338, 0x201, 0x227b, - 0x338, 0x201, 0x2282, 0x338, 0x201, 0x2283, 0x338, 0x201, - 0x2286, 0x338, 0x201, 0x2287, 0x338, 0x201, 0x22a2, 0x338, - 0x201, 0x22a8, 0x338, 0x201, 0x22a9, 0x338, 0x201, 0x22ab, - 0x338, 0x201, 0x227c, 0x338, 0x201, 0x227d, 0x338, 0x201, - 0x2291, 0x338, 0x201, 0x2292, 0x338, 0x201, 0x22b2, 0x338, - 0x201, 0x22b3, 0x338, 0x201, 0x22b4, 0x338, 0x201, 0x22b5, - 0x338, 0x101, 0x3008, 0x101, 0x3009, 0x108, 0x31, 0x108, - 0x32, 0x108, 0x33, 0x108, 0x34, 0x108, 0x35, 0x108, - 0x36, 0x108, 0x37, 0x108, 0x38, 0x108, 0x39, 0x208, - 0x31, 0x30, 0x208, 0x31, 0x31, 0x208, 0x31, 0x32, - 0x208, 0x31, 0x33, 0x208, 0x31, 0x34, 0x208, 0x31, - 0x35, 0x208, 0x31, 0x36, 0x208, 0x31, 0x37, 0x208, - 0x31, 0x38, 0x208, 0x31, 0x39, 0x208, 0x32, 0x30, - 0x310, 0x28, 0x31, 0x29, 0x310, 0x28, 0x32, 0x29, - 0x310, 0x28, 0x33, 0x29, 0x310, 0x28, 0x34, 0x29, - 0x310, 0x28, 0x35, 0x29, 0x310, 0x28, 0x36, 0x29, - 0x310, 0x28, 0x37, 0x29, 0x310, 0x28, 0x38, 0x29, - 0x310, 0x28, 0x39, 0x29, 0x410, 0x28, 0x31, 0x30, - 0x29, 0x410, 0x28, 0x31, 0x31, 0x29, 0x410, 0x28, - 0x31, 0x32, 0x29, 0x410, 0x28, 0x31, 0x33, 0x29, - 0x410, 0x28, 0x31, 0x34, 0x29, 0x410, 0x28, 0x31, - 0x35, 0x29, 0x410, 0x28, 0x31, 0x36, 0x29, 0x410, - 0x28, 0x31, 0x37, 0x29, 0x410, 0x28, 0x31, 0x38, - 0x29, 0x410, 0x28, 0x31, 0x39, 0x29, 0x410, 0x28, - 0x32, 0x30, 0x29, 0x210, 0x31, 0x2e, 0x210, 0x32, - 0x2e, 0x210, 0x33, 0x2e, 0x210, 0x34, 0x2e, 0x210, - 0x35, 0x2e, 0x210, 0x36, 0x2e, 0x210, 0x37, 0x2e, - 0x210, 0x38, 0x2e, 0x210, 0x39, 0x2e, 0x310, 0x31, - 0x30, 0x2e, 0x310, 0x31, 0x31, 0x2e, 0x310, 0x31, - 0x32, 0x2e, 0x310, 0x31, 0x33, 0x2e, 0x310, 0x31, - 0x34, 0x2e, 0x310, 0x31, 0x35, 0x2e, 0x310, 0x31, - 0x36, 0x2e, 0x310, 0x31, 0x37, 0x2e, 0x310, 0x31, - 0x38, 0x2e, 0x310, 0x31, 0x39, 0x2e, 0x310, 0x32, - 0x30, 0x2e, 0x310, 0x28, 0x61, 0x29, 0x310, 0x28, - 0x62, 0x29, 0x310, 0x28, 0x63, 0x29, 0x310, 0x28, - 0x64, 0x29, 0x310, 0x28, 0x65, 0x29, 0x310, 0x28, - 0x66, 0x29, 0x310, 0x28, 0x67, 0x29, 0x310, 0x28, - 0x68, 0x29, 0x310, 0x28, 0x69, 0x29, 0x310, 0x28, - 0x6a, 0x29, 0x310, 0x28, 0x6b, 0x29, 0x310, 0x28, - 0x6c, 0x29, 0x310, 0x28, 0x6d, 0x29, 0x310, 0x28, - 0x6e, 0x29, 0x310, 0x28, 0x6f, 0x29, 0x310, 0x28, - 0x70, 0x29, 0x310, 0x28, 0x71, 0x29, 0x310, 0x28, - 0x72, 0x29, 0x310, 0x28, 0x73, 0x29, 0x310, 0x28, - 0x74, 0x29, 0x310, 0x28, 0x75, 0x29, 0x310, 0x28, - 0x76, 0x29, 0x310, 0x28, 0x77, 0x29, 0x310, 0x28, - 0x78, 0x29, 0x310, 0x28, 0x79, 0x29, 0x310, 0x28, - 0x7a, 0x29, 0x108, 0x41, 0x108, 0x42, 0x108, 0x43, - 0x108, 0x44, 0x108, 0x45, 0x108, 0x46, 0x108, 0x47, - 0x108, 0x48, 0x108, 0x49, 0x108, 0x4a, 0x108, 0x4b, - 0x108, 0x4c, 0x108, 0x4d, 0x108, 0x4e, 0x108, 0x4f, - 0x108, 0x50, 0x108, 0x51, 0x108, 0x52, 0x108, 0x53, - 0x108, 0x54, 0x108, 0x55, 0x108, 0x56, 0x108, 0x57, - 0x108, 0x58, 0x108, 0x59, 0x108, 0x5a, 0x108, 0x61, - 0x108, 0x62, 0x108, 0x63, 0x108, 0x64, 0x108, 0x65, - 0x108, 0x66, 0x108, 0x67, 0x108, 0x68, 0x108, 0x69, - 0x108, 0x6a, 0x108, 0x6b, 0x108, 0x6c, 0x108, 0x6d, - 0x108, 0x6e, 0x108, 0x6f, 0x108, 0x70, 0x108, 0x71, - 0x108, 0x72, 0x108, 0x73, 0x108, 0x74, 0x108, 0x75, - 0x108, 0x76, 0x108, 0x77, 0x108, 0x78, 0x108, 0x79, - 0x108, 0x7a, 0x108, 0x30, 0x410, 0x222b, 0x222b, 0x222b, - 0x222b, 0x310, 0x3a, 0x3a, 0x3d, 0x210, 0x3d, 0x3d, - 0x310, 0x3d, 0x3d, 0x3d, 0x201, 0x2add, 0x338, 0x109, - 0x2d61, 0x110, 0x6bcd, 0x110, 0x9f9f, 0x110, 0x4e00, 0x110, - 0x4e28, 0x110, 0x4e36, 0x110, 0x4e3f, 0x110, 0x4e59, 0x110, - 0x4e85, 0x110, 0x4e8c, 0x110, 0x4ea0, 0x110, 0x4eba, 0x110, - 0x513f, 0x110, 0x5165, 0x110, 0x516b, 0x110, 0x5182, 0x110, - 0x5196, 0x110, 0x51ab, 0x110, 0x51e0, 0x110, 0x51f5, 0x110, - 0x5200, 0x110, 0x529b, 0x110, 0x52f9, 0x110, 0x5315, 0x110, - 0x531a, 0x110, 0x5338, 0x110, 0x5341, 0x110, 0x535c, 0x110, - 0x5369, 0x110, 0x5382, 0x110, 0x53b6, 0x110, 0x53c8, 0x110, - 0x53e3, 0x110, 0x56d7, 0x110, 0x571f, 0x110, 0x58eb, 0x110, - 0x5902, 0x110, 0x590a, 0x110, 0x5915, 0x110, 0x5927, 0x110, - 0x5973, 0x110, 0x5b50, 0x110, 0x5b80, 0x110, 0x5bf8, 0x110, - 0x5c0f, 0x110, 0x5c22, 0x110, 0x5c38, 0x110, 0x5c6e, 0x110, - 0x5c71, 0x110, 0x5ddb, 0x110, 0x5de5, 0x110, 0x5df1, 0x110, - 0x5dfe, 0x110, 0x5e72, 0x110, 0x5e7a, 0x110, 0x5e7f, 0x110, - 0x5ef4, 0x110, 0x5efe, 0x110, 0x5f0b, 0x110, 0x5f13, 0x110, - 0x5f50, 0x110, 0x5f61, 0x110, 0x5f73, 0x110, 0x5fc3, 0x110, - 0x6208, 0x110, 0x6236, 0x110, 0x624b, 0x110, 0x652f, 0x110, - 0x6534, 0x110, 0x6587, 0x110, 0x6597, 0x110, 0x65a4, 0x110, - 0x65b9, 0x110, 0x65e0, 0x110, 0x65e5, 0x110, 0x66f0, 0x110, - 0x6708, 0x110, 0x6728, 0x110, 0x6b20, 0x110, 0x6b62, 0x110, - 0x6b79, 0x110, 0x6bb3, 0x110, 0x6bcb, 0x110, 0x6bd4, 0x110, - 0x6bdb, 0x110, 0x6c0f, 0x110, 0x6c14, 0x110, 0x6c34, 0x110, - 0x706b, 0x110, 0x722a, 0x110, 0x7236, 0x110, 0x723b, 0x110, - 0x723f, 0x110, 0x7247, 0x110, 0x7259, 0x110, 0x725b, 0x110, - 0x72ac, 0x110, 0x7384, 0x110, 0x7389, 0x110, 0x74dc, 0x110, - 0x74e6, 0x110, 0x7518, 0x110, 0x751f, 0x110, 0x7528, 0x110, - 0x7530, 0x110, 0x758b, 0x110, 0x7592, 0x110, 0x7676, 0x110, - 0x767d, 0x110, 0x76ae, 0x110, 0x76bf, 0x110, 0x76ee, 0x110, - 0x77db, 0x110, 0x77e2, 0x110, 0x77f3, 0x110, 0x793a, 0x110, - 0x79b8, 0x110, 0x79be, 0x110, 0x7a74, 0x110, 0x7acb, 0x110, - 0x7af9, 0x110, 0x7c73, 0x110, 0x7cf8, 0x110, 0x7f36, 0x110, - 0x7f51, 0x110, 0x7f8a, 0x110, 0x7fbd, 0x110, 0x8001, 0x110, - 0x800c, 0x110, 0x8012, 0x110, 0x8033, 0x110, 0x807f, 0x110, - 0x8089, 0x110, 0x81e3, 0x110, 0x81ea, 0x110, 0x81f3, 0x110, - 0x81fc, 0x110, 0x820c, 0x110, 0x821b, 0x110, 0x821f, 0x110, - 0x826e, 0x110, 0x8272, 0x110, 0x8278, 0x110, 0x864d, 0x110, - 0x866b, 0x110, 0x8840, 0x110, 0x884c, 0x110, 0x8863, 0x110, - 0x897e, 0x110, 0x898b, 0x110, 0x89d2, 0x110, 0x8a00, 0x110, - 0x8c37, 0x110, 0x8c46, 0x110, 0x8c55, 0x110, 0x8c78, 0x110, - 0x8c9d, 0x110, 0x8d64, 0x110, 0x8d70, 0x110, 0x8db3, 0x110, - 0x8eab, 0x110, 0x8eca, 0x110, 0x8f9b, 0x110, 0x8fb0, 0x110, - 0x8fb5, 0x110, 0x9091, 0x110, 0x9149, 0x110, 0x91c6, 0x110, - 0x91cc, 0x110, 0x91d1, 0x110, 0x9577, 0x110, 0x9580, 0x110, - 0x961c, 0x110, 0x96b6, 0x110, 0x96b9, 0x110, 0x96e8, 0x110, - 0x9751, 0x110, 0x975e, 0x110, 0x9762, 0x110, 0x9769, 0x110, - 0x97cb, 0x110, 0x97ed, 0x110, 0x97f3, 0x110, 0x9801, 0x110, - 0x98a8, 0x110, 0x98db, 0x110, 0x98df, 0x110, 0x9996, 0x110, - 0x9999, 0x110, 0x99ac, 0x110, 0x9aa8, 0x110, 0x9ad8, 0x110, - 0x9adf, 0x110, 0x9b25, 0x110, 0x9b2f, 0x110, 0x9b32, 0x110, - 0x9b3c, 0x110, 0x9b5a, 0x110, 0x9ce5, 0x110, 0x9e75, 0x110, - 0x9e7f, 0x110, 0x9ea5, 0x110, 0x9ebb, 0x110, 0x9ec3, 0x110, - 0x9ecd, 0x110, 0x9ed1, 0x110, 0x9ef9, 0x110, 0x9efd, 0x110, - 0x9f0e, 0x110, 0x9f13, 0x110, 0x9f20, 0x110, 0x9f3b, 0x110, - 0x9f4a, 0x110, 0x9f52, 0x110, 0x9f8d, 0x110, 0x9f9c, 0x110, - 0x9fa0, 0x10c, 0x20, 0x110, 0x3012, 0x110, 0x5341, 0x110, - 0x5344, 0x110, 0x5345, 0x201, 0x304b, 0x3099, 0x201, 0x304d, - 0x3099, 0x201, 0x304f, 0x3099, 0x201, 0x3051, 0x3099, 0x201, - 0x3053, 0x3099, 0x201, 0x3055, 0x3099, 0x201, 0x3057, 0x3099, - 0x201, 0x3059, 0x3099, 0x201, 0x305b, 0x3099, 0x201, 0x305d, - 0x3099, 0x201, 0x305f, 0x3099, 0x201, 0x3061, 0x3099, 0x201, - 0x3064, 0x3099, 0x201, 0x3066, 0x3099, 0x201, 0x3068, 0x3099, - 0x201, 0x306f, 0x3099, 0x201, 0x306f, 0x309a, 0x201, 0x3072, - 0x3099, 0x201, 0x3072, 0x309a, 0x201, 0x3075, 0x3099, 0x201, - 0x3075, 0x309a, 0x201, 0x3078, 0x3099, 0x201, 0x3078, 0x309a, - 0x201, 0x307b, 0x3099, 0x201, 0x307b, 0x309a, 0x201, 0x3046, - 0x3099, 0x210, 0x20, 0x3099, 0x210, 0x20, 0x309a, 0x201, - 0x309d, 0x3099, 0x20b, 0x3088, 0x308a, 0x201, 0x30ab, 0x3099, - 0x201, 0x30ad, 0x3099, 0x201, 0x30af, 0x3099, 0x201, 0x30b1, - 0x3099, 0x201, 0x30b3, 0x3099, 0x201, 0x30b5, 0x3099, 0x201, - 0x30b7, 0x3099, 0x201, 0x30b9, 0x3099, 0x201, 0x30bb, 0x3099, - 0x201, 0x30bd, 0x3099, 0x201, 0x30bf, 0x3099, 0x201, 0x30c1, - 0x3099, 0x201, 0x30c4, 0x3099, 0x201, 0x30c6, 0x3099, 0x201, - 0x30c8, 0x3099, 0x201, 0x30cf, 0x3099, 0x201, 0x30cf, 0x309a, - 0x201, 0x30d2, 0x3099, 0x201, 0x30d2, 0x309a, 0x201, 0x30d5, - 0x3099, 0x201, 0x30d5, 0x309a, 0x201, 0x30d8, 0x3099, 0x201, - 0x30d8, 0x309a, 0x201, 0x30db, 0x3099, 0x201, 0x30db, 0x309a, - 0x201, 0x30a6, 0x3099, 0x201, 0x30ef, 0x3099, 0x201, 0x30f0, - 0x3099, 0x201, 0x30f1, 0x3099, 0x201, 0x30f2, 0x3099, 0x201, - 0x30fd, 0x3099, 0x20b, 0x30b3, 0x30c8, 0x110, 0x1100, 0x110, - 0x1101, 0x110, 0x11aa, 0x110, 0x1102, 0x110, 0x11ac, 0x110, - 0x11ad, 0x110, 0x1103, 0x110, 0x1104, 0x110, 0x1105, 0x110, - 0x11b0, 0x110, 0x11b1, 0x110, 0x11b2, 0x110, 0x11b3, 0x110, - 0x11b4, 0x110, 0x11b5, 0x110, 0x111a, 0x110, 0x1106, 0x110, - 0x1107, 0x110, 0x1108, 0x110, 0x1121, 0x110, 0x1109, 0x110, - 0x110a, 0x110, 0x110b, 0x110, 0x110c, 0x110, 0x110d, 0x110, - 0x110e, 0x110, 0x110f, 0x110, 0x1110, 0x110, 0x1111, 0x110, - 0x1112, 0x110, 0x1161, 0x110, 0x1162, 0x110, 0x1163, 0x110, - 0x1164, 0x110, 0x1165, 0x110, 0x1166, 0x110, 0x1167, 0x110, - 0x1168, 0x110, 0x1169, 0x110, 0x116a, 0x110, 0x116b, 0x110, - 0x116c, 0x110, 0x116d, 0x110, 0x116e, 0x110, 0x116f, 0x110, - 0x1170, 0x110, 0x1171, 0x110, 0x1172, 0x110, 0x1173, 0x110, - 0x1174, 0x110, 0x1175, 0x110, 0x1160, 0x110, 0x1114, 0x110, - 0x1115, 0x110, 0x11c7, 0x110, 0x11c8, 0x110, 0x11cc, 0x110, - 0x11ce, 0x110, 0x11d3, 0x110, 0x11d7, 0x110, 0x11d9, 0x110, - 0x111c, 0x110, 0x11dd, 0x110, 0x11df, 0x110, 0x111d, 0x110, - 0x111e, 0x110, 0x1120, 0x110, 0x1122, 0x110, 0x1123, 0x110, - 0x1127, 0x110, 0x1129, 0x110, 0x112b, 0x110, 0x112c, 0x110, - 0x112d, 0x110, 0x112e, 0x110, 0x112f, 0x110, 0x1132, 0x110, - 0x1136, 0x110, 0x1140, 0x110, 0x1147, 0x110, 0x114c, 0x110, - 0x11f1, 0x110, 0x11f2, 0x110, 0x1157, 0x110, 0x1158, 0x110, - 0x1159, 0x110, 0x1184, 0x110, 0x1185, 0x110, 0x1188, 0x110, - 0x1191, 0x110, 0x1192, 0x110, 0x1194, 0x110, 0x119e, 0x110, - 0x11a1, 0x109, 0x4e00, 0x109, 0x4e8c, 0x109, 0x4e09, 0x109, - 0x56db, 0x109, 0x4e0a, 0x109, 0x4e2d, 0x109, 0x4e0b, 0x109, - 0x7532, 0x109, 0x4e59, 0x109, 0x4e19, 0x109, 0x4e01, 0x109, - 0x5929, 0x109, 0x5730, 0x109, 0x4eba, 0x310, 0x28, 0x1100, - 0x29, 0x310, 0x28, 0x1102, 0x29, 0x310, 0x28, 0x1103, - 0x29, 0x310, 0x28, 0x1105, 0x29, 0x310, 0x28, 0x1106, - 0x29, 0x310, 0x28, 0x1107, 0x29, 0x310, 0x28, 0x1109, - 0x29, 0x310, 0x28, 0x110b, 0x29, 0x310, 0x28, 0x110c, - 0x29, 0x310, 0x28, 0x110e, 0x29, 0x310, 0x28, 0x110f, - 0x29, 0x310, 0x28, 0x1110, 0x29, 0x310, 0x28, 0x1111, - 0x29, 0x310, 0x28, 0x1112, 0x29, 0x410, 0x28, 0x1100, - 0x1161, 0x29, 0x410, 0x28, 0x1102, 0x1161, 0x29, 0x410, - 0x28, 0x1103, 0x1161, 0x29, 0x410, 0x28, 0x1105, 0x1161, - 0x29, 0x410, 0x28, 0x1106, 0x1161, 0x29, 0x410, 0x28, - 0x1107, 0x1161, 0x29, 0x410, 0x28, 0x1109, 0x1161, 0x29, - 0x410, 0x28, 0x110b, 0x1161, 0x29, 0x410, 0x28, 0x110c, - 0x1161, 0x29, 0x410, 0x28, 0x110e, 0x1161, 0x29, 0x410, - 0x28, 0x110f, 0x1161, 0x29, 0x410, 0x28, 0x1110, 0x1161, - 0x29, 0x410, 0x28, 0x1111, 0x1161, 0x29, 0x410, 0x28, - 0x1112, 0x1161, 0x29, 0x410, 0x28, 0x110c, 0x116e, 0x29, - 0x710, 0x28, 0x110b, 0x1169, 0x110c, 0x1165, 0x11ab, 0x29, - 0x610, 0x28, 0x110b, 0x1169, 0x1112, 0x116e, 0x29, 0x310, - 0x28, 0x4e00, 0x29, 0x310, 0x28, 0x4e8c, 0x29, 0x310, - 0x28, 0x4e09, 0x29, 0x310, 0x28, 0x56db, 0x29, 0x310, - 0x28, 0x4e94, 0x29, 0x310, 0x28, 0x516d, 0x29, 0x310, - 0x28, 0x4e03, 0x29, 0x310, 0x28, 0x516b, 0x29, 0x310, - 0x28, 0x4e5d, 0x29, 0x310, 0x28, 0x5341, 0x29, 0x310, - 0x28, 0x6708, 0x29, 0x310, 0x28, 0x706b, 0x29, 0x310, - 0x28, 0x6c34, 0x29, 0x310, 0x28, 0x6728, 0x29, 0x310, - 0x28, 0x91d1, 0x29, 0x310, 0x28, 0x571f, 0x29, 0x310, - 0x28, 0x65e5, 0x29, 0x310, 0x28, 0x682a, 0x29, 0x310, - 0x28, 0x6709, 0x29, 0x310, 0x28, 0x793e, 0x29, 0x310, - 0x28, 0x540d, 0x29, 0x310, 0x28, 0x7279, 0x29, 0x310, - 0x28, 0x8ca1, 0x29, 0x310, 0x28, 0x795d, 0x29, 0x310, - 0x28, 0x52b4, 0x29, 0x310, 0x28, 0x4ee3, 0x29, 0x310, - 0x28, 0x547c, 0x29, 0x310, 0x28, 0x5b66, 0x29, 0x310, - 0x28, 0x76e3, 0x29, 0x310, 0x28, 0x4f01, 0x29, 0x310, - 0x28, 0x8cc7, 0x29, 0x310, 0x28, 0x5354, 0x29, 0x310, - 0x28, 0x796d, 0x29, 0x310, 0x28, 0x4f11, 0x29, 0x310, - 0x28, 0x81ea, 0x29, 0x310, 0x28, 0x81f3, 0x29, 0x30f, - 0x50, 0x54, 0x45, 0x208, 0x32, 0x31, 0x208, 0x32, - 0x32, 0x208, 0x32, 0x33, 0x208, 0x32, 0x34, 0x208, - 0x32, 0x35, 0x208, 0x32, 0x36, 0x208, 0x32, 0x37, - 0x208, 0x32, 0x38, 0x208, 0x32, 0x39, 0x208, 0x33, - 0x30, 0x208, 0x33, 0x31, 0x208, 0x33, 0x32, 0x208, - 0x33, 0x33, 0x208, 0x33, 0x34, 0x208, 0x33, 0x35, - 0x108, 0x1100, 0x108, 0x1102, 0x108, 0x1103, 0x108, 0x1105, - 0x108, 0x1106, 0x108, 0x1107, 0x108, 0x1109, 0x108, 0x110b, - 0x108, 0x110c, 0x108, 0x110e, 0x108, 0x110f, 0x108, 0x1110, - 0x108, 0x1111, 0x108, 0x1112, 0x208, 0x1100, 0x1161, 0x208, - 0x1102, 0x1161, 0x208, 0x1103, 0x1161, 0x208, 0x1105, 0x1161, - 0x208, 0x1106, 0x1161, 0x208, 0x1107, 0x1161, 0x208, 0x1109, - 0x1161, 0x208, 0x110b, 0x1161, 0x208, 0x110c, 0x1161, 0x208, - 0x110e, 0x1161, 0x208, 0x110f, 0x1161, 0x208, 0x1110, 0x1161, - 0x208, 0x1111, 0x1161, 0x208, 0x1112, 0x1161, 0x508, 0x110e, - 0x1161, 0x11b7, 0x1100, 0x1169, 0x408, 0x110c, 0x116e, 0x110b, - 0x1174, 0x208, 0x110b, 0x116e, 0x108, 0x4e00, 0x108, 0x4e8c, - 0x108, 0x4e09, 0x108, 0x56db, 0x108, 0x4e94, 0x108, 0x516d, - 0x108, 0x4e03, 0x108, 0x516b, 0x108, 0x4e5d, 0x108, 0x5341, - 0x108, 0x6708, 0x108, 0x706b, 0x108, 0x6c34, 0x108, 0x6728, - 0x108, 0x91d1, 0x108, 0x571f, 0x108, 0x65e5, 0x108, 0x682a, - 0x108, 0x6709, 0x108, 0x793e, 0x108, 0x540d, 0x108, 0x7279, - 0x108, 0x8ca1, 0x108, 0x795d, 0x108, 0x52b4, 0x108, 0x79d8, - 0x108, 0x7537, 0x108, 0x5973, 0x108, 0x9069, 0x108, 0x512a, - 0x108, 0x5370, 0x108, 0x6ce8, 0x108, 0x9805, 0x108, 0x4f11, - 0x108, 0x5199, 0x108, 0x6b63, 0x108, 0x4e0a, 0x108, 0x4e2d, - 0x108, 0x4e0b, 0x108, 0x5de6, 0x108, 0x53f3, 0x108, 0x533b, - 0x108, 0x5b97, 0x108, 0x5b66, 0x108, 0x76e3, 0x108, 0x4f01, - 0x108, 0x8cc7, 0x108, 0x5354, 0x108, 0x591c, 0x208, 0x33, - 0x36, 0x208, 0x33, 0x37, 0x208, 0x33, 0x38, 0x208, - 0x33, 0x39, 0x208, 0x34, 0x30, 0x208, 0x34, 0x31, - 0x208, 0x34, 0x32, 0x208, 0x34, 0x33, 0x208, 0x34, - 0x34, 0x208, 0x34, 0x35, 0x208, 0x34, 0x36, 0x208, - 0x34, 0x37, 0x208, 0x34, 0x38, 0x208, 0x34, 0x39, - 0x208, 0x35, 0x30, 0x210, 0x31, 0x6708, 0x210, 0x32, - 0x6708, 0x210, 0x33, 0x6708, 0x210, 0x34, 0x6708, 0x210, - 0x35, 0x6708, 0x210, 0x36, 0x6708, 0x210, 0x37, 0x6708, - 0x210, 0x38, 0x6708, 0x210, 0x39, 0x6708, 0x310, 0x31, - 0x30, 0x6708, 0x310, 0x31, 0x31, 0x6708, 0x310, 0x31, - 0x32, 0x6708, 0x20f, 0x48, 0x67, 0x30f, 0x65, 0x72, - 0x67, 0x20f, 0x65, 0x56, 0x30f, 0x4c, 0x54, 0x44, - 0x108, 0x30a2, 0x108, 0x30a4, 0x108, 0x30a6, 0x108, 0x30a8, - 0x108, 0x30aa, 0x108, 0x30ab, 0x108, 0x30ad, 0x108, 0x30af, - 0x108, 0x30b1, 0x108, 0x30b3, 0x108, 0x30b5, 0x108, 0x30b7, - 0x108, 0x30b9, 0x108, 0x30bb, 0x108, 0x30bd, 0x108, 0x30bf, - 0x108, 0x30c1, 0x108, 0x30c4, 0x108, 0x30c6, 0x108, 0x30c8, - 0x108, 0x30ca, 0x108, 0x30cb, 0x108, 0x30cc, 0x108, 0x30cd, - 0x108, 0x30ce, 0x108, 0x30cf, 0x108, 0x30d2, 0x108, 0x30d5, - 0x108, 0x30d8, 0x108, 0x30db, 0x108, 0x30de, 0x108, 0x30df, - 0x108, 0x30e0, 0x108, 0x30e1, 0x108, 0x30e2, 0x108, 0x30e4, - 0x108, 0x30e6, 0x108, 0x30e8, 0x108, 0x30e9, 0x108, 0x30ea, - 0x108, 0x30eb, 0x108, 0x30ec, 0x108, 0x30ed, 0x108, 0x30ef, - 0x108, 0x30f0, 0x108, 0x30f1, 0x108, 0x30f2, 0x40f, 0x30a2, - 0x30d1, 0x30fc, 0x30c8, 0x40f, 0x30a2, 0x30eb, 0x30d5, 0x30a1, - 0x40f, 0x30a2, 0x30f3, 0x30da, 0x30a2, 0x30f, 0x30a2, 0x30fc, - 0x30eb, 0x40f, 0x30a4, 0x30cb, 0x30f3, 0x30b0, 0x30f, 0x30a4, - 0x30f3, 0x30c1, 0x30f, 0x30a6, 0x30a9, 0x30f3, 0x50f, 0x30a8, - 0x30b9, 0x30af, 0x30fc, 0x30c9, 0x40f, 0x30a8, 0x30fc, 0x30ab, - 0x30fc, 0x30f, 0x30aa, 0x30f3, 0x30b9, 0x30f, 0x30aa, 0x30fc, - 0x30e0, 0x30f, 0x30ab, 0x30a4, 0x30ea, 0x40f, 0x30ab, 0x30e9, - 0x30c3, 0x30c8, 0x40f, 0x30ab, 0x30ed, 0x30ea, 0x30fc, 0x30f, - 0x30ac, 0x30ed, 0x30f3, 0x30f, 0x30ac, 0x30f3, 0x30de, 0x20f, - 0x30ae, 0x30ac, 0x30f, 0x30ae, 0x30cb, 0x30fc, 0x40f, 0x30ad, - 0x30e5, 0x30ea, 0x30fc, 0x40f, 0x30ae, 0x30eb, 0x30c0, 0x30fc, - 0x20f, 0x30ad, 0x30ed, 0x50f, 0x30ad, 0x30ed, 0x30b0, 0x30e9, - 0x30e0, 0x60f, 0x30ad, 0x30ed, 0x30e1, 0x30fc, 0x30c8, 0x30eb, - 0x50f, 0x30ad, 0x30ed, 0x30ef, 0x30c3, 0x30c8, 0x30f, 0x30b0, - 0x30e9, 0x30e0, 0x50f, 0x30b0, 0x30e9, 0x30e0, 0x30c8, 0x30f3, - 0x50f, 0x30af, 0x30eb, 0x30bc, 0x30a4, 0x30ed, 0x40f, 0x30af, - 0x30ed, 0x30fc, 0x30cd, 0x30f, 0x30b1, 0x30fc, 0x30b9, 0x30f, - 0x30b3, 0x30eb, 0x30ca, 0x30f, 0x30b3, 0x30fc, 0x30dd, 0x40f, - 0x30b5, 0x30a4, 0x30af, 0x30eb, 0x50f, 0x30b5, 0x30f3, 0x30c1, - 0x30fc, 0x30e0, 0x40f, 0x30b7, 0x30ea, 0x30f3, 0x30b0, 0x30f, - 0x30bb, 0x30f3, 0x30c1, 0x30f, 0x30bb, 0x30f3, 0x30c8, 0x30f, - 0x30c0, 0x30fc, 0x30b9, 0x20f, 0x30c7, 0x30b7, 0x20f, 0x30c9, - 0x30eb, 0x20f, 0x30c8, 0x30f3, 0x20f, 0x30ca, 0x30ce, 0x30f, - 0x30ce, 0x30c3, 0x30c8, 0x30f, 0x30cf, 0x30a4, 0x30c4, 0x50f, - 0x30d1, 0x30fc, 0x30bb, 0x30f3, 0x30c8, 0x30f, 0x30d1, 0x30fc, - 0x30c4, 0x40f, 0x30d0, 0x30fc, 0x30ec, 0x30eb, 0x50f, 0x30d4, - 0x30a2, 0x30b9, 0x30c8, 0x30eb, 0x30f, 0x30d4, 0x30af, 0x30eb, - 0x20f, 0x30d4, 0x30b3, 0x20f, 0x30d3, 0x30eb, 0x50f, 0x30d5, - 0x30a1, 0x30e9, 0x30c3, 0x30c9, 0x40f, 0x30d5, 0x30a3, 0x30fc, - 0x30c8, 0x50f, 0x30d6, 0x30c3, 0x30b7, 0x30a7, 0x30eb, 0x30f, - 0x30d5, 0x30e9, 0x30f3, 0x50f, 0x30d8, 0x30af, 0x30bf, 0x30fc, - 0x30eb, 0x20f, 0x30da, 0x30bd, 0x30f, 0x30da, 0x30cb, 0x30d2, - 0x30f, 0x30d8, 0x30eb, 0x30c4, 0x30f, 0x30da, 0x30f3, 0x30b9, - 0x30f, 0x30da, 0x30fc, 0x30b8, 0x30f, 0x30d9, 0x30fc, 0x30bf, - 0x40f, 0x30dd, 0x30a4, 0x30f3, 0x30c8, 0x30f, 0x30dc, 0x30eb, - 0x30c8, 0x20f, 0x30db, 0x30f3, 0x30f, 0x30dd, 0x30f3, 0x30c9, - 0x30f, 0x30db, 0x30fc, 0x30eb, 0x30f, 0x30db, 0x30fc, 0x30f3, - 0x40f, 0x30de, 0x30a4, 0x30af, 0x30ed, 0x30f, 0x30de, 0x30a4, - 0x30eb, 0x30f, 0x30de, 0x30c3, 0x30cf, 0x30f, 0x30de, 0x30eb, - 0x30af, 0x50f, 0x30de, 0x30f3, 0x30b7, 0x30e7, 0x30f3, 0x40f, - 0x30df, 0x30af, 0x30ed, 0x30f3, 0x20f, 0x30df, 0x30ea, 0x50f, - 0x30df, 0x30ea, 0x30d0, 0x30fc, 0x30eb, 0x20f, 0x30e1, 0x30ac, - 0x40f, 0x30e1, 0x30ac, 0x30c8, 0x30f3, 0x40f, 0x30e1, 0x30fc, - 0x30c8, 0x30eb, 0x30f, 0x30e4, 0x30fc, 0x30c9, 0x30f, 0x30e4, - 0x30fc, 0x30eb, 0x30f, 0x30e6, 0x30a2, 0x30f3, 0x40f, 0x30ea, - 0x30c3, 0x30c8, 0x30eb, 0x20f, 0x30ea, 0x30e9, 0x30f, 0x30eb, - 0x30d4, 0x30fc, 0x40f, 0x30eb, 0x30fc, 0x30d6, 0x30eb, 0x20f, - 0x30ec, 0x30e0, 0x50f, 0x30ec, 0x30f3, 0x30c8, 0x30b2, 0x30f3, - 0x30f, 0x30ef, 0x30c3, 0x30c8, 0x210, 0x30, 0x70b9, 0x210, - 0x31, 0x70b9, 0x210, 0x32, 0x70b9, 0x210, 0x33, 0x70b9, - 0x210, 0x34, 0x70b9, 0x210, 0x35, 0x70b9, 0x210, 0x36, - 0x70b9, 0x210, 0x37, 0x70b9, 0x210, 0x38, 0x70b9, 0x210, - 0x39, 0x70b9, 0x310, 0x31, 0x30, 0x70b9, 0x310, 0x31, - 0x31, 0x70b9, 0x310, 0x31, 0x32, 0x70b9, 0x310, 0x31, - 0x33, 0x70b9, 0x310, 0x31, 0x34, 0x70b9, 0x310, 0x31, - 0x35, 0x70b9, 0x310, 0x31, 0x36, 0x70b9, 0x310, 0x31, - 0x37, 0x70b9, 0x310, 0x31, 0x38, 0x70b9, 0x310, 0x31, - 0x39, 0x70b9, 0x310, 0x32, 0x30, 0x70b9, 0x310, 0x32, - 0x31, 0x70b9, 0x310, 0x32, 0x32, 0x70b9, 0x310, 0x32, - 0x33, 0x70b9, 0x310, 0x32, 0x34, 0x70b9, 0x30f, 0x68, - 0x50, 0x61, 0x20f, 0x64, 0x61, 0x20f, 0x41, 0x55, - 0x30f, 0x62, 0x61, 0x72, 0x20f, 0x6f, 0x56, 0x20f, - 0x70, 0x63, 0x20f, 0x64, 0x6d, 0x30f, 0x64, 0x6d, - 0xb2, 0x30f, 0x64, 0x6d, 0xb3, 0x20f, 0x49, 0x55, - 0x20f, 0x5e73, 0x6210, 0x20f, 0x662d, 0x548c, 0x20f, 0x5927, - 0x6b63, 0x20f, 0x660e, 0x6cbb, 0x40f, 0x682a, 0x5f0f, 0x4f1a, - 0x793e, 0x20f, 0x70, 0x41, 0x20f, 0x6e, 0x41, 0x20f, - 0x3bc, 0x41, 0x20f, 0x6d, 0x41, 0x20f, 0x6b, 0x41, - 0x20f, 0x4b, 0x42, 0x20f, 0x4d, 0x42, 0x20f, 0x47, - 0x42, 0x30f, 0x63, 0x61, 0x6c, 0x40f, 0x6b, 0x63, - 0x61, 0x6c, 0x20f, 0x70, 0x46, 0x20f, 0x6e, 0x46, - 0x20f, 0x3bc, 0x46, 0x20f, 0x3bc, 0x67, 0x20f, 0x6d, - 0x67, 0x20f, 0x6b, 0x67, 0x20f, 0x48, 0x7a, 0x30f, - 0x6b, 0x48, 0x7a, 0x30f, 0x4d, 0x48, 0x7a, 0x30f, - 0x47, 0x48, 0x7a, 0x30f, 0x54, 0x48, 0x7a, 0x20f, - 0x3bc, 0x2113, 0x20f, 0x6d, 0x2113, 0x20f, 0x64, 0x2113, - 0x20f, 0x6b, 0x2113, 0x20f, 0x66, 0x6d, 0x20f, 0x6e, - 0x6d, 0x20f, 0x3bc, 0x6d, 0x20f, 0x6d, 0x6d, 0x20f, - 0x63, 0x6d, 0x20f, 0x6b, 0x6d, 0x30f, 0x6d, 0x6d, - 0xb2, 0x30f, 0x63, 0x6d, 0xb2, 0x20f, 0x6d, 0xb2, - 0x30f, 0x6b, 0x6d, 0xb2, 0x30f, 0x6d, 0x6d, 0xb3, - 0x30f, 0x63, 0x6d, 0xb3, 0x20f, 0x6d, 0xb3, 0x30f, - 0x6b, 0x6d, 0xb3, 0x30f, 0x6d, 0x2215, 0x73, 0x40f, - 0x6d, 0x2215, 0x73, 0xb2, 0x20f, 0x50, 0x61, 0x30f, - 0x6b, 0x50, 0x61, 0x30f, 0x4d, 0x50, 0x61, 0x30f, - 0x47, 0x50, 0x61, 0x30f, 0x72, 0x61, 0x64, 0x50f, - 0x72, 0x61, 0x64, 0x2215, 0x73, 0x60f, 0x72, 0x61, - 0x64, 0x2215, 0x73, 0xb2, 0x20f, 0x70, 0x73, 0x20f, - 0x6e, 0x73, 0x20f, 0x3bc, 0x73, 0x20f, 0x6d, 0x73, - 0x20f, 0x70, 0x56, 0x20f, 0x6e, 0x56, 0x20f, 0x3bc, - 0x56, 0x20f, 0x6d, 0x56, 0x20f, 0x6b, 0x56, 0x20f, - 0x4d, 0x56, 0x20f, 0x70, 0x57, 0x20f, 0x6e, 0x57, - 0x20f, 0x3bc, 0x57, 0x20f, 0x6d, 0x57, 0x20f, 0x6b, - 0x57, 0x20f, 0x4d, 0x57, 0x20f, 0x6b, 0x3a9, 0x20f, - 0x4d, 0x3a9, 0x40f, 0x61, 0x2e, 0x6d, 0x2e, 0x20f, - 0x42, 0x71, 0x20f, 0x63, 0x63, 0x20f, 0x63, 0x64, - 0x40f, 0x43, 0x2215, 0x6b, 0x67, 0x30f, 0x43, 0x6f, - 0x2e, 0x20f, 0x64, 0x42, 0x20f, 0x47, 0x79, 0x20f, - 0x68, 0x61, 0x20f, 0x48, 0x50, 0x20f, 0x69, 0x6e, - 0x20f, 0x4b, 0x4b, 0x20f, 0x4b, 0x4d, 0x20f, 0x6b, - 0x74, 0x20f, 0x6c, 0x6d, 0x20f, 0x6c, 0x6e, 0x30f, - 0x6c, 0x6f, 0x67, 0x20f, 0x6c, 0x78, 0x20f, 0x6d, - 0x62, 0x30f, 0x6d, 0x69, 0x6c, 0x30f, 0x6d, 0x6f, - 0x6c, 0x20f, 0x50, 0x48, 0x40f, 0x70, 0x2e, 0x6d, - 0x2e, 0x30f, 0x50, 0x50, 0x4d, 0x20f, 0x50, 0x52, - 0x20f, 0x73, 0x72, 0x20f, 0x53, 0x76, 0x20f, 0x57, - 0x62, 0x30f, 0x56, 0x2215, 0x6d, 0x30f, 0x41, 0x2215, - 0x6d, 0x210, 0x31, 0x65e5, 0x210, 0x32, 0x65e5, 0x210, - 0x33, 0x65e5, 0x210, 0x34, 0x65e5, 0x210, 0x35, 0x65e5, - 0x210, 0x36, 0x65e5, 0x210, 0x37, 0x65e5, 0x210, 0x38, - 0x65e5, 0x210, 0x39, 0x65e5, 0x310, 0x31, 0x30, 0x65e5, - 0x310, 0x31, 0x31, 0x65e5, 0x310, 0x31, 0x32, 0x65e5, - 0x310, 0x31, 0x33, 0x65e5, 0x310, 0x31, 0x34, 0x65e5, - 0x310, 0x31, 0x35, 0x65e5, 0x310, 0x31, 0x36, 0x65e5, - 0x310, 0x31, 0x37, 0x65e5, 0x310, 0x31, 0x38, 0x65e5, - 0x310, 0x31, 0x39, 0x65e5, 0x310, 0x32, 0x30, 0x65e5, - 0x310, 0x32, 0x31, 0x65e5, 0x310, 0x32, 0x32, 0x65e5, - 0x310, 0x32, 0x33, 0x65e5, 0x310, 0x32, 0x34, 0x65e5, - 0x310, 0x32, 0x35, 0x65e5, 0x310, 0x32, 0x36, 0x65e5, - 0x310, 0x32, 0x37, 0x65e5, 0x310, 0x32, 0x38, 0x65e5, - 0x310, 0x32, 0x39, 0x65e5, 0x310, 0x33, 0x30, 0x65e5, - 0x310, 0x33, 0x31, 0x65e5, 0x30f, 0x67, 0x61, 0x6c, - 0x101, 0x8c48, 0x101, 0x66f4, 0x101, 0x8eca, 0x101, 0x8cc8, - 0x101, 0x6ed1, 0x101, 0x4e32, 0x101, 0x53e5, 0x101, 0x9f9c, - 0x101, 0x9f9c, 0x101, 0x5951, 0x101, 0x91d1, 0x101, 0x5587, - 0x101, 0x5948, 0x101, 0x61f6, 0x101, 0x7669, 0x101, 0x7f85, - 0x101, 0x863f, 0x101, 0x87ba, 0x101, 0x88f8, 0x101, 0x908f, - 0x101, 0x6a02, 0x101, 0x6d1b, 0x101, 0x70d9, 0x101, 0x73de, - 0x101, 0x843d, 0x101, 0x916a, 0x101, 0x99f1, 0x101, 0x4e82, - 0x101, 0x5375, 0x101, 0x6b04, 0x101, 0x721b, 0x101, 0x862d, - 0x101, 0x9e1e, 0x101, 0x5d50, 0x101, 0x6feb, 0x101, 0x85cd, - 0x101, 0x8964, 0x101, 0x62c9, 0x101, 0x81d8, 0x101, 0x881f, - 0x101, 0x5eca, 0x101, 0x6717, 0x101, 0x6d6a, 0x101, 0x72fc, - 0x101, 0x90ce, 0x101, 0x4f86, 0x101, 0x51b7, 0x101, 0x52de, - 0x101, 0x64c4, 0x101, 0x6ad3, 0x101, 0x7210, 0x101, 0x76e7, - 0x101, 0x8001, 0x101, 0x8606, 0x101, 0x865c, 0x101, 0x8def, - 0x101, 0x9732, 0x101, 0x9b6f, 0x101, 0x9dfa, 0x101, 0x788c, - 0x101, 0x797f, 0x101, 0x7da0, 0x101, 0x83c9, 0x101, 0x9304, - 0x101, 0x9e7f, 0x101, 0x8ad6, 0x101, 0x58df, 0x101, 0x5f04, - 0x101, 0x7c60, 0x101, 0x807e, 0x101, 0x7262, 0x101, 0x78ca, - 0x101, 0x8cc2, 0x101, 0x96f7, 0x101, 0x58d8, 0x101, 0x5c62, - 0x101, 0x6a13, 0x101, 0x6dda, 0x101, 0x6f0f, 0x101, 0x7d2f, - 0x101, 0x7e37, 0x101, 0x964b, 0x101, 0x52d2, 0x101, 0x808b, - 0x101, 0x51dc, 0x101, 0x51cc, 0x101, 0x7a1c, 0x101, 0x7dbe, - 0x101, 0x83f1, 0x101, 0x9675, 0x101, 0x8b80, 0x101, 0x62cf, - 0x101, 0x6a02, 0x101, 0x8afe, 0x101, 0x4e39, 0x101, 0x5be7, - 0x101, 0x6012, 0x101, 0x7387, 0x101, 0x7570, 0x101, 0x5317, - 0x101, 0x78fb, 0x101, 0x4fbf, 0x101, 0x5fa9, 0x101, 0x4e0d, - 0x101, 0x6ccc, 0x101, 0x6578, 0x101, 0x7d22, 0x101, 0x53c3, - 0x101, 0x585e, 0x101, 0x7701, 0x101, 0x8449, 0x101, 0x8aaa, - 0x101, 0x6bba, 0x101, 0x8fb0, 0x101, 0x6c88, 0x101, 0x62fe, - 0x101, 0x82e5, 0x101, 0x63a0, 0x101, 0x7565, 0x101, 0x4eae, - 0x101, 0x5169, 0x101, 0x51c9, 0x101, 0x6881, 0x101, 0x7ce7, - 0x101, 0x826f, 0x101, 0x8ad2, 0x101, 0x91cf, 0x101, 0x52f5, - 0x101, 0x5442, 0x101, 0x5973, 0x101, 0x5eec, 0x101, 0x65c5, - 0x101, 0x6ffe, 0x101, 0x792a, 0x101, 0x95ad, 0x101, 0x9a6a, - 0x101, 0x9e97, 0x101, 0x9ece, 0x101, 0x529b, 0x101, 0x66c6, - 0x101, 0x6b77, 0x101, 0x8f62, 0x101, 0x5e74, 0x101, 0x6190, - 0x101, 0x6200, 0x101, 0x649a, 0x101, 0x6f23, 0x101, 0x7149, - 0x101, 0x7489, 0x101, 0x79ca, 0x101, 0x7df4, 0x101, 0x806f, - 0x101, 0x8f26, 0x101, 0x84ee, 0x101, 0x9023, 0x101, 0x934a, - 0x101, 0x5217, 0x101, 0x52a3, 0x101, 0x54bd, 0x101, 0x70c8, - 0x101, 0x88c2, 0x101, 0x8aaa, 0x101, 0x5ec9, 0x101, 0x5ff5, - 0x101, 0x637b, 0x101, 0x6bae, 0x101, 0x7c3e, 0x101, 0x7375, - 0x101, 0x4ee4, 0x101, 0x56f9, 0x101, 0x5be7, 0x101, 0x5dba, - 0x101, 0x601c, 0x101, 0x73b2, 0x101, 0x7469, 0x101, 0x7f9a, - 0x101, 0x8046, 0x101, 0x9234, 0x101, 0x96f6, 0x101, 0x9748, - 0x101, 0x9818, 0x101, 0x4f8b, 0x101, 0x79ae, 0x101, 0x91b4, - 0x101, 0x96b8, 0x101, 0x60e1, 0x101, 0x4e86, 0x101, 0x50da, - 0x101, 0x5bee, 0x101, 0x5c3f, 0x101, 0x6599, 0x101, 0x6a02, - 0x101, 0x71ce, 0x101, 0x7642, 0x101, 0x84fc, 0x101, 0x907c, - 0x101, 0x9f8d, 0x101, 0x6688, 0x101, 0x962e, 0x101, 0x5289, - 0x101, 0x677b, 0x101, 0x67f3, 0x101, 0x6d41, 0x101, 0x6e9c, - 0x101, 0x7409, 0x101, 0x7559, 0x101, 0x786b, 0x101, 0x7d10, - 0x101, 0x985e, 0x101, 0x516d, 0x101, 0x622e, 0x101, 0x9678, - 0x101, 0x502b, 0x101, 0x5d19, 0x101, 0x6dea, 0x101, 0x8f2a, - 0x101, 0x5f8b, 0x101, 0x6144, 0x101, 0x6817, 0x101, 0x7387, - 0x101, 0x9686, 0x101, 0x5229, 0x101, 0x540f, 0x101, 0x5c65, - 0x101, 0x6613, 0x101, 0x674e, 0x101, 0x68a8, 0x101, 0x6ce5, - 0x101, 0x7406, 0x101, 0x75e2, 0x101, 0x7f79, 0x101, 0x88cf, - 0x101, 0x88e1, 0x101, 0x91cc, 0x101, 0x96e2, 0x101, 0x533f, - 0x101, 0x6eba, 0x101, 0x541d, 0x101, 0x71d0, 0x101, 0x7498, - 0x101, 0x85fa, 0x101, 0x96a3, 0x101, 0x9c57, 0x101, 0x9e9f, - 0x101, 0x6797, 0x101, 0x6dcb, 0x101, 0x81e8, 0x101, 0x7acb, - 0x101, 0x7b20, 0x101, 0x7c92, 0x101, 0x72c0, 0x101, 0x7099, - 0x101, 0x8b58, 0x101, 0x4ec0, 0x101, 0x8336, 0x101, 0x523a, - 0x101, 0x5207, 0x101, 0x5ea6, 0x101, 0x62d3, 0x101, 0x7cd6, - 0x101, 0x5b85, 0x101, 0x6d1e, 0x101, 0x66b4, 0x101, 0x8f3b, - 0x101, 0x884c, 0x101, 0x964d, 0x101, 0x898b, 0x101, 0x5ed3, - 0x101, 0x5140, 0x101, 0x55c0, 0x101, 0x585a, 0x101, 0x6674, - 0x101, 0x51de, 0x101, 0x732a, 0x101, 0x76ca, 0x101, 0x793c, - 0x101, 0x795e, 0x101, 0x7965, 0x101, 0x798f, 0x101, 0x9756, - 0x101, 0x7cbe, 0x101, 0x7fbd, 0x101, 0x8612, 0x101, 0x8af8, - 0x101, 0x9038, 0x101, 0x90fd, 0x101, 0x98ef, 0x101, 0x98fc, - 0x101, 0x9928, 0x101, 0x9db4, 0x101, 0x4fae, 0x101, 0x50e7, - 0x101, 0x514d, 0x101, 0x52c9, 0x101, 0x52e4, 0x101, 0x5351, - 0x101, 0x559d, 0x101, 0x5606, 0x101, 0x5668, 0x101, 0x5840, - 0x101, 0x58a8, 0x101, 0x5c64, 0x101, 0x5c6e, 0x101, 0x6094, - 0x101, 0x6168, 0x101, 0x618e, 0x101, 0x61f2, 0x101, 0x654f, - 0x101, 0x65e2, 0x101, 0x6691, 0x101, 0x6885, 0x101, 0x6d77, - 0x101, 0x6e1a, 0x101, 0x6f22, 0x101, 0x716e, 0x101, 0x722b, - 0x101, 0x7422, 0x101, 0x7891, 0x101, 0x793e, 0x101, 0x7949, - 0x101, 0x7948, 0x101, 0x7950, 0x101, 0x7956, 0x101, 0x795d, - 0x101, 0x798d, 0x101, 0x798e, 0x101, 0x7a40, 0x101, 0x7a81, - 0x101, 0x7bc0, 0x101, 0x7df4, 0x101, 0x7e09, 0x101, 0x7e41, - 0x101, 0x7f72, 0x101, 0x8005, 0x101, 0x81ed, 0x101, 0x8279, - 0x101, 0x8279, 0x101, 0x8457, 0x101, 0x8910, 0x101, 0x8996, - 0x101, 0x8b01, 0x101, 0x8b39, 0x101, 0x8cd3, 0x101, 0x8d08, - 0x101, 0x8fb6, 0x101, 0x9038, 0x101, 0x96e3, 0x101, 0x97ff, - 0x101, 0x983b, 0x101, 0x4e26, 0x101, 0x51b5, 0x101, 0x5168, - 0x101, 0x4f80, 0x101, 0x5145, 0x101, 0x5180, 0x101, 0x52c7, - 0x101, 0x52fa, 0x101, 0x559d, 0x101, 0x5555, 0x101, 0x5599, - 0x101, 0x55e2, 0x101, 0x585a, 0x101, 0x58b3, 0x101, 0x5944, - 0x101, 0x5954, 0x101, 0x5a62, 0x101, 0x5b28, 0x101, 0x5ed2, - 0x101, 0x5ed9, 0x101, 0x5f69, 0x101, 0x5fad, 0x101, 0x60d8, - 0x101, 0x614e, 0x101, 0x6108, 0x101, 0x618e, 0x101, 0x6160, - 0x101, 0x61f2, 0x101, 0x6234, 0x101, 0x63c4, 0x101, 0x641c, - 0x101, 0x6452, 0x101, 0x6556, 0x101, 0x6674, 0x101, 0x6717, - 0x101, 0x671b, 0x101, 0x6756, 0x101, 0x6b79, 0x101, 0x6bba, - 0x101, 0x6d41, 0x101, 0x6edb, 0x101, 0x6ecb, 0x101, 0x6f22, - 0x101, 0x701e, 0x101, 0x716e, 0x101, 0x77a7, 0x101, 0x7235, - 0x101, 0x72af, 0x101, 0x732a, 0x101, 0x7471, 0x101, 0x7506, - 0x101, 0x753b, 0x101, 0x761d, 0x101, 0x761f, 0x101, 0x76ca, - 0x101, 0x76db, 0x101, 0x76f4, 0x101, 0x774a, 0x101, 0x7740, - 0x101, 0x78cc, 0x101, 0x7ab1, 0x101, 0x7bc0, 0x101, 0x7c7b, - 0x101, 0x7d5b, 0x101, 0x7df4, 0x101, 0x7f3e, 0x101, 0x8005, - 0x101, 0x8352, 0x101, 0x83ef, 0x101, 0x8779, 0x101, 0x8941, - 0x101, 0x8986, 0x101, 0x8996, 0x101, 0x8abf, 0x101, 0x8af8, - 0x101, 0x8acb, 0x101, 0x8b01, 0x101, 0x8afe, 0x101, 0x8aed, - 0x101, 0x8b39, 0x101, 0x8b8a, 0x101, 0x8d08, 0x101, 0x8f38, - 0x101, 0x9072, 0x101, 0x9199, 0x101, 0x9276, 0x101, 0x967c, - 0x101, 0x96e3, 0x101, 0x9756, 0x101, 0x97db, 0x101, 0x97ff, - 0x101, 0x980b, 0x101, 0x983b, 0x101, 0x9b12, 0x101, 0x9f9c, - 0x201, 0xd84a, 0xdc4a, 0x201, 0xd84a, 0xdc44, 0x201, 0xd84c, - 0xdfd5, 0x101, 0x3b9d, 0x101, 0x4018, 0x101, 0x4039, 0x201, - 0xd854, 0xde49, 0x201, 0xd857, 0xdcd0, 0x201, 0xd85f, 0xded3, - 0x101, 0x9f43, 0x101, 0x9f8e, 0x210, 0x66, 0x66, 0x210, - 0x66, 0x69, 0x210, 0x66, 0x6c, 0x310, 0x66, 0x66, - 0x69, 0x310, 0x66, 0x66, 0x6c, 0x210, 0x17f, 0x74, - 0x210, 0x73, 0x74, 0x210, 0x574, 0x576, 0x210, 0x574, - 0x565, 0x210, 0x574, 0x56b, 0x210, 0x57e, 0x576, 0x210, - 0x574, 0x56d, 0x201, 0x5d9, 0x5b4, 0x201, 0x5f2, 0x5b7, - 0x102, 0x5e2, 0x102, 0x5d0, 0x102, 0x5d3, 0x102, 0x5d4, - 0x102, 0x5db, 0x102, 0x5dc, 0x102, 0x5dd, 0x102, 0x5e8, - 0x102, 0x5ea, 0x102, 0x2b, 0x201, 0x5e9, 0x5c1, 0x201, - 0x5e9, 0x5c2, 0x201, 0xfb49, 0x5c1, 0x201, 0xfb49, 0x5c2, - 0x201, 0x5d0, 0x5b7, 0x201, 0x5d0, 0x5b8, 0x201, 0x5d0, - 0x5bc, 0x201, 0x5d1, 0x5bc, 0x201, 0x5d2, 0x5bc, 0x201, - 0x5d3, 0x5bc, 0x201, 0x5d4, 0x5bc, 0x201, 0x5d5, 0x5bc, - 0x201, 0x5d6, 0x5bc, 0x201, 0x5d8, 0x5bc, 0x201, 0x5d9, - 0x5bc, 0x201, 0x5da, 0x5bc, 0x201, 0x5db, 0x5bc, 0x201, - 0x5dc, 0x5bc, 0x201, 0x5de, 0x5bc, 0x201, 0x5e0, 0x5bc, - 0x201, 0x5e1, 0x5bc, 0x201, 0x5e3, 0x5bc, 0x201, 0x5e4, - 0x5bc, 0x201, 0x5e6, 0x5bc, 0x201, 0x5e7, 0x5bc, 0x201, - 0x5e8, 0x5bc, 0x201, 0x5e9, 0x5bc, 0x201, 0x5ea, 0x5bc, - 0x201, 0x5d5, 0x5b9, 0x201, 0x5d1, 0x5bf, 0x201, 0x5db, - 0x5bf, 0x201, 0x5e4, 0x5bf, 0x210, 0x5d0, 0x5dc, 0x107, - 0x671, 0x106, 0x671, 0x107, 0x67b, 0x106, 0x67b, 0x104, - 0x67b, 0x105, 0x67b, 0x107, 0x67e, 0x106, 0x67e, 0x104, - 0x67e, 0x105, 0x67e, 0x107, 0x680, 0x106, 0x680, 0x104, - 0x680, 0x105, 0x680, 0x107, 0x67a, 0x106, 0x67a, 0x104, - 0x67a, 0x105, 0x67a, 0x107, 0x67f, 0x106, 0x67f, 0x104, - 0x67f, 0x105, 0x67f, 0x107, 0x679, 0x106, 0x679, 0x104, - 0x679, 0x105, 0x679, 0x107, 0x6a4, 0x106, 0x6a4, 0x104, - 0x6a4, 0x105, 0x6a4, 0x107, 0x6a6, 0x106, 0x6a6, 0x104, - 0x6a6, 0x105, 0x6a6, 0x107, 0x684, 0x106, 0x684, 0x104, - 0x684, 0x105, 0x684, 0x107, 0x683, 0x106, 0x683, 0x104, - 0x683, 0x105, 0x683, 0x107, 0x686, 0x106, 0x686, 0x104, - 0x686, 0x105, 0x686, 0x107, 0x687, 0x106, 0x687, 0x104, - 0x687, 0x105, 0x687, 0x107, 0x68d, 0x106, 0x68d, 0x107, - 0x68c, 0x106, 0x68c, 0x107, 0x68e, 0x106, 0x68e, 0x107, - 0x688, 0x106, 0x688, 0x107, 0x698, 0x106, 0x698, 0x107, - 0x691, 0x106, 0x691, 0x107, 0x6a9, 0x106, 0x6a9, 0x104, - 0x6a9, 0x105, 0x6a9, 0x107, 0x6af, 0x106, 0x6af, 0x104, - 0x6af, 0x105, 0x6af, 0x107, 0x6b3, 0x106, 0x6b3, 0x104, - 0x6b3, 0x105, 0x6b3, 0x107, 0x6b1, 0x106, 0x6b1, 0x104, - 0x6b1, 0x105, 0x6b1, 0x107, 0x6ba, 0x106, 0x6ba, 0x107, - 0x6bb, 0x106, 0x6bb, 0x104, 0x6bb, 0x105, 0x6bb, 0x107, - 0x6c0, 0x106, 0x6c0, 0x107, 0x6c1, 0x106, 0x6c1, 0x104, - 0x6c1, 0x105, 0x6c1, 0x107, 0x6be, 0x106, 0x6be, 0x104, - 0x6be, 0x105, 0x6be, 0x107, 0x6d2, 0x106, 0x6d2, 0x107, - 0x6d3, 0x106, 0x6d3, 0x107, 0x6ad, 0x106, 0x6ad, 0x104, - 0x6ad, 0x105, 0x6ad, 0x107, 0x6c7, 0x106, 0x6c7, 0x107, - 0x6c6, 0x106, 0x6c6, 0x107, 0x6c8, 0x106, 0x6c8, 0x107, - 0x677, 0x107, 0x6cb, 0x106, 0x6cb, 0x107, 0x6c5, 0x106, - 0x6c5, 0x107, 0x6c9, 0x106, 0x6c9, 0x107, 0x6d0, 0x106, - 0x6d0, 0x104, 0x6d0, 0x105, 0x6d0, 0x104, 0x649, 0x105, - 0x649, 0x207, 0x626, 0x627, 0x206, 0x626, 0x627, 0x207, - 0x626, 0x6d5, 0x206, 0x626, 0x6d5, 0x207, 0x626, 0x648, - 0x206, 0x626, 0x648, 0x207, 0x626, 0x6c7, 0x206, 0x626, - 0x6c7, 0x207, 0x626, 0x6c6, 0x206, 0x626, 0x6c6, 0x207, - 0x626, 0x6c8, 0x206, 0x626, 0x6c8, 0x207, 0x626, 0x6d0, - 0x206, 0x626, 0x6d0, 0x204, 0x626, 0x6d0, 0x207, 0x626, - 0x649, 0x206, 0x626, 0x649, 0x204, 0x626, 0x649, 0x107, - 0x6cc, 0x106, 0x6cc, 0x104, 0x6cc, 0x105, 0x6cc, 0x207, - 0x626, 0x62c, 0x207, 0x626, 0x62d, 0x207, 0x626, 0x645, - 0x207, 0x626, 0x649, 0x207, 0x626, 0x64a, 0x207, 0x628, - 0x62c, 0x207, 0x628, 0x62d, 0x207, 0x628, 0x62e, 0x207, - 0x628, 0x645, 0x207, 0x628, 0x649, 0x207, 0x628, 0x64a, - 0x207, 0x62a, 0x62c, 0x207, 0x62a, 0x62d, 0x207, 0x62a, - 0x62e, 0x207, 0x62a, 0x645, 0x207, 0x62a, 0x649, 0x207, - 0x62a, 0x64a, 0x207, 0x62b, 0x62c, 0x207, 0x62b, 0x645, - 0x207, 0x62b, 0x649, 0x207, 0x62b, 0x64a, 0x207, 0x62c, - 0x62d, 0x207, 0x62c, 0x645, 0x207, 0x62d, 0x62c, 0x207, - 0x62d, 0x645, 0x207, 0x62e, 0x62c, 0x207, 0x62e, 0x62d, - 0x207, 0x62e, 0x645, 0x207, 0x633, 0x62c, 0x207, 0x633, - 0x62d, 0x207, 0x633, 0x62e, 0x207, 0x633, 0x645, 0x207, - 0x635, 0x62d, 0x207, 0x635, 0x645, 0x207, 0x636, 0x62c, - 0x207, 0x636, 0x62d, 0x207, 0x636, 0x62e, 0x207, 0x636, - 0x645, 0x207, 0x637, 0x62d, 0x207, 0x637, 0x645, 0x207, - 0x638, 0x645, 0x207, 0x639, 0x62c, 0x207, 0x639, 0x645, - 0x207, 0x63a, 0x62c, 0x207, 0x63a, 0x645, 0x207, 0x641, - 0x62c, 0x207, 0x641, 0x62d, 0x207, 0x641, 0x62e, 0x207, - 0x641, 0x645, 0x207, 0x641, 0x649, 0x207, 0x641, 0x64a, - 0x207, 0x642, 0x62d, 0x207, 0x642, 0x645, 0x207, 0x642, - 0x649, 0x207, 0x642, 0x64a, 0x207, 0x643, 0x627, 0x207, - 0x643, 0x62c, 0x207, 0x643, 0x62d, 0x207, 0x643, 0x62e, - 0x207, 0x643, 0x644, 0x207, 0x643, 0x645, 0x207, 0x643, - 0x649, 0x207, 0x643, 0x64a, 0x207, 0x644, 0x62c, 0x207, - 0x644, 0x62d, 0x207, 0x644, 0x62e, 0x207, 0x644, 0x645, - 0x207, 0x644, 0x649, 0x207, 0x644, 0x64a, 0x207, 0x645, - 0x62c, 0x207, 0x645, 0x62d, 0x207, 0x645, 0x62e, 0x207, - 0x645, 0x645, 0x207, 0x645, 0x649, 0x207, 0x645, 0x64a, - 0x207, 0x646, 0x62c, 0x207, 0x646, 0x62d, 0x207, 0x646, - 0x62e, 0x207, 0x646, 0x645, 0x207, 0x646, 0x649, 0x207, - 0x646, 0x64a, 0x207, 0x647, 0x62c, 0x207, 0x647, 0x645, - 0x207, 0x647, 0x649, 0x207, 0x647, 0x64a, 0x207, 0x64a, - 0x62c, 0x207, 0x64a, 0x62d, 0x207, 0x64a, 0x62e, 0x207, - 0x64a, 0x645, 0x207, 0x64a, 0x649, 0x207, 0x64a, 0x64a, - 0x207, 0x630, 0x670, 0x207, 0x631, 0x670, 0x207, 0x649, - 0x670, 0x307, 0x20, 0x64c, 0x651, 0x307, 0x20, 0x64d, - 0x651, 0x307, 0x20, 0x64e, 0x651, 0x307, 0x20, 0x64f, - 0x651, 0x307, 0x20, 0x650, 0x651, 0x307, 0x20, 0x651, - 0x670, 0x206, 0x626, 0x631, 0x206, 0x626, 0x632, 0x206, - 0x626, 0x645, 0x206, 0x626, 0x646, 0x206, 0x626, 0x649, - 0x206, 0x626, 0x64a, 0x206, 0x628, 0x631, 0x206, 0x628, - 0x632, 0x206, 0x628, 0x645, 0x206, 0x628, 0x646, 0x206, - 0x628, 0x649, 0x206, 0x628, 0x64a, 0x206, 0x62a, 0x631, - 0x206, 0x62a, 0x632, 0x206, 0x62a, 0x645, 0x206, 0x62a, - 0x646, 0x206, 0x62a, 0x649, 0x206, 0x62a, 0x64a, 0x206, - 0x62b, 0x631, 0x206, 0x62b, 0x632, 0x206, 0x62b, 0x645, - 0x206, 0x62b, 0x646, 0x206, 0x62b, 0x649, 0x206, 0x62b, - 0x64a, 0x206, 0x641, 0x649, 0x206, 0x641, 0x64a, 0x206, - 0x642, 0x649, 0x206, 0x642, 0x64a, 0x206, 0x643, 0x627, - 0x206, 0x643, 0x644, 0x206, 0x643, 0x645, 0x206, 0x643, - 0x649, 0x206, 0x643, 0x64a, 0x206, 0x644, 0x645, 0x206, - 0x644, 0x649, 0x206, 0x644, 0x64a, 0x206, 0x645, 0x627, - 0x206, 0x645, 0x645, 0x206, 0x646, 0x631, 0x206, 0x646, - 0x632, 0x206, 0x646, 0x645, 0x206, 0x646, 0x646, 0x206, - 0x646, 0x649, 0x206, 0x646, 0x64a, 0x206, 0x649, 0x670, - 0x206, 0x64a, 0x631, 0x206, 0x64a, 0x632, 0x206, 0x64a, - 0x645, 0x206, 0x64a, 0x646, 0x206, 0x64a, 0x649, 0x206, - 0x64a, 0x64a, 0x204, 0x626, 0x62c, 0x204, 0x626, 0x62d, - 0x204, 0x626, 0x62e, 0x204, 0x626, 0x645, 0x204, 0x626, - 0x647, 0x204, 0x628, 0x62c, 0x204, 0x628, 0x62d, 0x204, - 0x628, 0x62e, 0x204, 0x628, 0x645, 0x204, 0x628, 0x647, - 0x204, 0x62a, 0x62c, 0x204, 0x62a, 0x62d, 0x204, 0x62a, - 0x62e, 0x204, 0x62a, 0x645, 0x204, 0x62a, 0x647, 0x204, - 0x62b, 0x645, 0x204, 0x62c, 0x62d, 0x204, 0x62c, 0x645, - 0x204, 0x62d, 0x62c, 0x204, 0x62d, 0x645, 0x204, 0x62e, - 0x62c, 0x204, 0x62e, 0x645, 0x204, 0x633, 0x62c, 0x204, - 0x633, 0x62d, 0x204, 0x633, 0x62e, 0x204, 0x633, 0x645, - 0x204, 0x635, 0x62d, 0x204, 0x635, 0x62e, 0x204, 0x635, - 0x645, 0x204, 0x636, 0x62c, 0x204, 0x636, 0x62d, 0x204, - 0x636, 0x62e, 0x204, 0x636, 0x645, 0x204, 0x637, 0x62d, - 0x204, 0x638, 0x645, 0x204, 0x639, 0x62c, 0x204, 0x639, - 0x645, 0x204, 0x63a, 0x62c, 0x204, 0x63a, 0x645, 0x204, - 0x641, 0x62c, 0x204, 0x641, 0x62d, 0x204, 0x641, 0x62e, - 0x204, 0x641, 0x645, 0x204, 0x642, 0x62d, 0x204, 0x642, - 0x645, 0x204, 0x643, 0x62c, 0x204, 0x643, 0x62d, 0x204, - 0x643, 0x62e, 0x204, 0x643, 0x644, 0x204, 0x643, 0x645, - 0x204, 0x644, 0x62c, 0x204, 0x644, 0x62d, 0x204, 0x644, - 0x62e, 0x204, 0x644, 0x645, 0x204, 0x644, 0x647, 0x204, - 0x645, 0x62c, 0x204, 0x645, 0x62d, 0x204, 0x645, 0x62e, - 0x204, 0x645, 0x645, 0x204, 0x646, 0x62c, 0x204, 0x646, - 0x62d, 0x204, 0x646, 0x62e, 0x204, 0x646, 0x645, 0x204, - 0x646, 0x647, 0x204, 0x647, 0x62c, 0x204, 0x647, 0x645, - 0x204, 0x647, 0x670, 0x204, 0x64a, 0x62c, 0x204, 0x64a, - 0x62d, 0x204, 0x64a, 0x62e, 0x204, 0x64a, 0x645, 0x204, - 0x64a, 0x647, 0x205, 0x626, 0x645, 0x205, 0x626, 0x647, - 0x205, 0x628, 0x645, 0x205, 0x628, 0x647, 0x205, 0x62a, - 0x645, 0x205, 0x62a, 0x647, 0x205, 0x62b, 0x645, 0x205, - 0x62b, 0x647, 0x205, 0x633, 0x645, 0x205, 0x633, 0x647, - 0x205, 0x634, 0x645, 0x205, 0x634, 0x647, 0x205, 0x643, - 0x644, 0x205, 0x643, 0x645, 0x205, 0x644, 0x645, 0x205, - 0x646, 0x645, 0x205, 0x646, 0x647, 0x205, 0x64a, 0x645, - 0x205, 0x64a, 0x647, 0x305, 0x640, 0x64e, 0x651, 0x305, - 0x640, 0x64f, 0x651, 0x305, 0x640, 0x650, 0x651, 0x207, - 0x637, 0x649, 0x207, 0x637, 0x64a, 0x207, 0x639, 0x649, - 0x207, 0x639, 0x64a, 0x207, 0x63a, 0x649, 0x207, 0x63a, - 0x64a, 0x207, 0x633, 0x649, 0x207, 0x633, 0x64a, 0x207, - 0x634, 0x649, 0x207, 0x634, 0x64a, 0x207, 0x62d, 0x649, - 0x207, 0x62d, 0x64a, 0x207, 0x62c, 0x649, 0x207, 0x62c, - 0x64a, 0x207, 0x62e, 0x649, 0x207, 0x62e, 0x64a, 0x207, - 0x635, 0x649, 0x207, 0x635, 0x64a, 0x207, 0x636, 0x649, - 0x207, 0x636, 0x64a, 0x207, 0x634, 0x62c, 0x207, 0x634, - 0x62d, 0x207, 0x634, 0x62e, 0x207, 0x634, 0x645, 0x207, - 0x634, 0x631, 0x207, 0x633, 0x631, 0x207, 0x635, 0x631, - 0x207, 0x636, 0x631, 0x206, 0x637, 0x649, 0x206, 0x637, - 0x64a, 0x206, 0x639, 0x649, 0x206, 0x639, 0x64a, 0x206, - 0x63a, 0x649, 0x206, 0x63a, 0x64a, 0x206, 0x633, 0x649, - 0x206, 0x633, 0x64a, 0x206, 0x634, 0x649, 0x206, 0x634, - 0x64a, 0x206, 0x62d, 0x649, 0x206, 0x62d, 0x64a, 0x206, - 0x62c, 0x649, 0x206, 0x62c, 0x64a, 0x206, 0x62e, 0x649, - 0x206, 0x62e, 0x64a, 0x206, 0x635, 0x649, 0x206, 0x635, - 0x64a, 0x206, 0x636, 0x649, 0x206, 0x636, 0x64a, 0x206, - 0x634, 0x62c, 0x206, 0x634, 0x62d, 0x206, 0x634, 0x62e, - 0x206, 0x634, 0x645, 0x206, 0x634, 0x631, 0x206, 0x633, - 0x631, 0x206, 0x635, 0x631, 0x206, 0x636, 0x631, 0x204, - 0x634, 0x62c, 0x204, 0x634, 0x62d, 0x204, 0x634, 0x62e, - 0x204, 0x634, 0x645, 0x204, 0x633, 0x647, 0x204, 0x634, - 0x647, 0x204, 0x637, 0x645, 0x205, 0x633, 0x62c, 0x205, - 0x633, 0x62d, 0x205, 0x633, 0x62e, 0x205, 0x634, 0x62c, - 0x205, 0x634, 0x62d, 0x205, 0x634, 0x62e, 0x205, 0x637, - 0x645, 0x205, 0x638, 0x645, 0x206, 0x627, 0x64b, 0x207, - 0x627, 0x64b, 0x304, 0x62a, 0x62c, 0x645, 0x306, 0x62a, - 0x62d, 0x62c, 0x304, 0x62a, 0x62d, 0x62c, 0x304, 0x62a, - 0x62d, 0x645, 0x304, 0x62a, 0x62e, 0x645, 0x304, 0x62a, - 0x645, 0x62c, 0x304, 0x62a, 0x645, 0x62d, 0x304, 0x62a, - 0x645, 0x62e, 0x306, 0x62c, 0x645, 0x62d, 0x304, 0x62c, - 0x645, 0x62d, 0x306, 0x62d, 0x645, 0x64a, 0x306, 0x62d, - 0x645, 0x649, 0x304, 0x633, 0x62d, 0x62c, 0x304, 0x633, - 0x62c, 0x62d, 0x306, 0x633, 0x62c, 0x649, 0x306, 0x633, - 0x645, 0x62d, 0x304, 0x633, 0x645, 0x62d, 0x304, 0x633, - 0x645, 0x62c, 0x306, 0x633, 0x645, 0x645, 0x304, 0x633, - 0x645, 0x645, 0x306, 0x635, 0x62d, 0x62d, 0x304, 0x635, - 0x62d, 0x62d, 0x306, 0x635, 0x645, 0x645, 0x306, 0x634, - 0x62d, 0x645, 0x304, 0x634, 0x62d, 0x645, 0x306, 0x634, - 0x62c, 0x64a, 0x306, 0x634, 0x645, 0x62e, 0x304, 0x634, - 0x645, 0x62e, 0x306, 0x634, 0x645, 0x645, 0x304, 0x634, - 0x645, 0x645, 0x306, 0x636, 0x62d, 0x649, 0x306, 0x636, - 0x62e, 0x645, 0x304, 0x636, 0x62e, 0x645, 0x306, 0x637, - 0x645, 0x62d, 0x304, 0x637, 0x645, 0x62d, 0x304, 0x637, - 0x645, 0x645, 0x306, 0x637, 0x645, 0x64a, 0x306, 0x639, - 0x62c, 0x645, 0x306, 0x639, 0x645, 0x645, 0x304, 0x639, - 0x645, 0x645, 0x306, 0x639, 0x645, 0x649, 0x306, 0x63a, - 0x645, 0x645, 0x306, 0x63a, 0x645, 0x64a, 0x306, 0x63a, - 0x645, 0x649, 0x306, 0x641, 0x62e, 0x645, 0x304, 0x641, - 0x62e, 0x645, 0x306, 0x642, 0x645, 0x62d, 0x306, 0x642, - 0x645, 0x645, 0x306, 0x644, 0x62d, 0x645, 0x306, 0x644, - 0x62d, 0x64a, 0x306, 0x644, 0x62d, 0x649, 0x304, 0x644, - 0x62c, 0x62c, 0x306, 0x644, 0x62c, 0x62c, 0x306, 0x644, - 0x62e, 0x645, 0x304, 0x644, 0x62e, 0x645, 0x306, 0x644, - 0x645, 0x62d, 0x304, 0x644, 0x645, 0x62d, 0x304, 0x645, - 0x62d, 0x62c, 0x304, 0x645, 0x62d, 0x645, 0x306, 0x645, - 0x62d, 0x64a, 0x304, 0x645, 0x62c, 0x62d, 0x304, 0x645, - 0x62c, 0x645, 0x304, 0x645, 0x62e, 0x62c, 0x304, 0x645, - 0x62e, 0x645, 0x304, 0x645, 0x62c, 0x62e, 0x304, 0x647, - 0x645, 0x62c, 0x304, 0x647, 0x645, 0x645, 0x304, 0x646, - 0x62d, 0x645, 0x306, 0x646, 0x62d, 0x649, 0x306, 0x646, - 0x62c, 0x645, 0x304, 0x646, 0x62c, 0x645, 0x306, 0x646, - 0x62c, 0x649, 0x306, 0x646, 0x645, 0x64a, 0x306, 0x646, - 0x645, 0x649, 0x306, 0x64a, 0x645, 0x645, 0x304, 0x64a, - 0x645, 0x645, 0x306, 0x628, 0x62e, 0x64a, 0x306, 0x62a, - 0x62c, 0x64a, 0x306, 0x62a, 0x62c, 0x649, 0x306, 0x62a, - 0x62e, 0x64a, 0x306, 0x62a, 0x62e, 0x649, 0x306, 0x62a, - 0x645, 0x64a, 0x306, 0x62a, 0x645, 0x649, 0x306, 0x62c, - 0x645, 0x64a, 0x306, 0x62c, 0x62d, 0x649, 0x306, 0x62c, - 0x645, 0x649, 0x306, 0x633, 0x62e, 0x649, 0x306, 0x635, - 0x62d, 0x64a, 0x306, 0x634, 0x62d, 0x64a, 0x306, 0x636, - 0x62d, 0x64a, 0x306, 0x644, 0x62c, 0x64a, 0x306, 0x644, - 0x645, 0x64a, 0x306, 0x64a, 0x62d, 0x64a, 0x306, 0x64a, - 0x62c, 0x64a, 0x306, 0x64a, 0x645, 0x64a, 0x306, 0x645, - 0x645, 0x64a, 0x306, 0x642, 0x645, 0x64a, 0x306, 0x646, - 0x62d, 0x64a, 0x304, 0x642, 0x645, 0x62d, 0x304, 0x644, - 0x62d, 0x645, 0x306, 0x639, 0x645, 0x64a, 0x306, 0x643, - 0x645, 0x64a, 0x304, 0x646, 0x62c, 0x62d, 0x306, 0x645, - 0x62e, 0x64a, 0x304, 0x644, 0x62c, 0x645, 0x306, 0x643, - 0x645, 0x645, 0x306, 0x644, 0x62c, 0x645, 0x306, 0x646, - 0x62c, 0x62d, 0x306, 0x62c, 0x62d, 0x64a, 0x306, 0x62d, - 0x62c, 0x64a, 0x306, 0x645, 0x62c, 0x64a, 0x306, 0x641, - 0x645, 0x64a, 0x306, 0x628, 0x62d, 0x64a, 0x304, 0x643, - 0x645, 0x645, 0x304, 0x639, 0x62c, 0x645, 0x304, 0x635, - 0x645, 0x645, 0x306, 0x633, 0x62e, 0x64a, 0x306, 0x646, - 0x62c, 0x64a, 0x307, 0x635, 0x644, 0x6d2, 0x307, 0x642, - 0x644, 0x6d2, 0x407, 0x627, 0x644, 0x644, 0x647, 0x407, - 0x627, 0x643, 0x628, 0x631, 0x407, 0x645, 0x62d, 0x645, - 0x62f, 0x407, 0x635, 0x644, 0x639, 0x645, 0x407, 0x631, - 0x633, 0x648, 0x644, 0x407, 0x639, 0x644, 0x64a, 0x647, - 0x407, 0x648, 0x633, 0x644, 0x645, 0x307, 0x635, 0x644, - 0x649, 0x1207, 0x635, 0x644, 0x649, 0x20, 0x627, 0x644, - 0x644, 0x647, 0x20, 0x639, 0x644, 0x64a, 0x647, 0x20, - 0x648, 0x633, 0x644, 0x645, 0x807, 0x62c, 0x644, 0x20, - 0x62c, 0x644, 0x627, 0x644, 0x647, 0x407, 0x631, 0x6cc, - 0x627, 0x644, 0x10b, 0x2c, 0x10b, 0x3001, 0x10b, 0x3002, - 0x10b, 0x3a, 0x10b, 0x3b, 0x10b, 0x21, 0x10b, 0x3f, - 0x10b, 0x3016, 0x10b, 0x3017, 0x10b, 0x2026, 0x10b, 0x2025, - 0x10b, 0x2014, 0x10b, 0x2013, 0x10b, 0x5f, 0x10b, 0x5f, - 0x10b, 0x28, 0x10b, 0x29, 0x10b, 0x7b, 0x10b, 0x7d, - 0x10b, 0x3014, 0x10b, 0x3015, 0x10b, 0x3010, 0x10b, 0x3011, - 0x10b, 0x300a, 0x10b, 0x300b, 0x10b, 0x3008, 0x10b, 0x3009, - 0x10b, 0x300c, 0x10b, 0x300d, 0x10b, 0x300e, 0x10b, 0x300f, - 0x10b, 0x5b, 0x10b, 0x5d, 0x110, 0x203e, 0x110, 0x203e, - 0x110, 0x203e, 0x110, 0x203e, 0x110, 0x5f, 0x110, 0x5f, - 0x110, 0x5f, 0x10e, 0x2c, 0x10e, 0x3001, 0x10e, 0x2e, - 0x10e, 0x3b, 0x10e, 0x3a, 0x10e, 0x3f, 0x10e, 0x21, - 0x10e, 0x2014, 0x10e, 0x28, 0x10e, 0x29, 0x10e, 0x7b, - 0x10e, 0x7d, 0x10e, 0x3014, 0x10e, 0x3015, 0x10e, 0x23, - 0x10e, 0x26, 0x10e, 0x2a, 0x10e, 0x2b, 0x10e, 0x2d, - 0x10e, 0x3c, 0x10e, 0x3e, 0x10e, 0x3d, 0x10e, 0x5c, - 0x10e, 0x24, 0x10e, 0x25, 0x10e, 0x40, 0x207, 0x20, - 0x64b, 0x205, 0x640, 0x64b, 0x207, 0x20, 0x64c, 0x207, - 0x20, 0x64d, 0x207, 0x20, 0x64e, 0x205, 0x640, 0x64e, - 0x207, 0x20, 0x64f, 0x205, 0x640, 0x64f, 0x207, 0x20, - 0x650, 0x205, 0x640, 0x650, 0x207, 0x20, 0x651, 0x205, - 0x640, 0x651, 0x207, 0x20, 0x652, 0x205, 0x640, 0x652, - 0x107, 0x621, 0x107, 0x622, 0x106, 0x622, 0x107, 0x623, - 0x106, 0x623, 0x107, 0x624, 0x106, 0x624, 0x107, 0x625, - 0x106, 0x625, 0x107, 0x626, 0x106, 0x626, 0x104, 0x626, - 0x105, 0x626, 0x107, 0x627, 0x106, 0x627, 0x107, 0x628, - 0x106, 0x628, 0x104, 0x628, 0x105, 0x628, 0x107, 0x629, - 0x106, 0x629, 0x107, 0x62a, 0x106, 0x62a, 0x104, 0x62a, - 0x105, 0x62a, 0x107, 0x62b, 0x106, 0x62b, 0x104, 0x62b, - 0x105, 0x62b, 0x107, 0x62c, 0x106, 0x62c, 0x104, 0x62c, - 0x105, 0x62c, 0x107, 0x62d, 0x106, 0x62d, 0x104, 0x62d, - 0x105, 0x62d, 0x107, 0x62e, 0x106, 0x62e, 0x104, 0x62e, - 0x105, 0x62e, 0x107, 0x62f, 0x106, 0x62f, 0x107, 0x630, - 0x106, 0x630, 0x107, 0x631, 0x106, 0x631, 0x107, 0x632, - 0x106, 0x632, 0x107, 0x633, 0x106, 0x633, 0x104, 0x633, - 0x105, 0x633, 0x107, 0x634, 0x106, 0x634, 0x104, 0x634, - 0x105, 0x634, 0x107, 0x635, 0x106, 0x635, 0x104, 0x635, - 0x105, 0x635, 0x107, 0x636, 0x106, 0x636, 0x104, 0x636, - 0x105, 0x636, 0x107, 0x637, 0x106, 0x637, 0x104, 0x637, - 0x105, 0x637, 0x107, 0x638, 0x106, 0x638, 0x104, 0x638, - 0x105, 0x638, 0x107, 0x639, 0x106, 0x639, 0x104, 0x639, - 0x105, 0x639, 0x107, 0x63a, 0x106, 0x63a, 0x104, 0x63a, - 0x105, 0x63a, 0x107, 0x641, 0x106, 0x641, 0x104, 0x641, - 0x105, 0x641, 0x107, 0x642, 0x106, 0x642, 0x104, 0x642, - 0x105, 0x642, 0x107, 0x643, 0x106, 0x643, 0x104, 0x643, - 0x105, 0x643, 0x107, 0x644, 0x106, 0x644, 0x104, 0x644, - 0x105, 0x644, 0x107, 0x645, 0x106, 0x645, 0x104, 0x645, - 0x105, 0x645, 0x107, 0x646, 0x106, 0x646, 0x104, 0x646, - 0x105, 0x646, 0x107, 0x647, 0x106, 0x647, 0x104, 0x647, - 0x105, 0x647, 0x107, 0x648, 0x106, 0x648, 0x107, 0x649, - 0x106, 0x649, 0x107, 0x64a, 0x106, 0x64a, 0x104, 0x64a, - 0x105, 0x64a, 0x207, 0x644, 0x622, 0x206, 0x644, 0x622, - 0x207, 0x644, 0x623, 0x206, 0x644, 0x623, 0x207, 0x644, - 0x625, 0x206, 0x644, 0x625, 0x207, 0x644, 0x627, 0x206, - 0x644, 0x627, 0x10c, 0x21, 0x10c, 0x22, 0x10c, 0x23, - 0x10c, 0x24, 0x10c, 0x25, 0x10c, 0x26, 0x10c, 0x27, - 0x10c, 0x28, 0x10c, 0x29, 0x10c, 0x2a, 0x10c, 0x2b, - 0x10c, 0x2c, 0x10c, 0x2d, 0x10c, 0x2e, 0x10c, 0x2f, - 0x10c, 0x30, 0x10c, 0x31, 0x10c, 0x32, 0x10c, 0x33, - 0x10c, 0x34, 0x10c, 0x35, 0x10c, 0x36, 0x10c, 0x37, - 0x10c, 0x38, 0x10c, 0x39, 0x10c, 0x3a, 0x10c, 0x3b, - 0x10c, 0x3c, 0x10c, 0x3d, 0x10c, 0x3e, 0x10c, 0x3f, - 0x10c, 0x40, 0x10c, 0x41, 0x10c, 0x42, 0x10c, 0x43, - 0x10c, 0x44, 0x10c, 0x45, 0x10c, 0x46, 0x10c, 0x47, - 0x10c, 0x48, 0x10c, 0x49, 0x10c, 0x4a, 0x10c, 0x4b, - 0x10c, 0x4c, 0x10c, 0x4d, 0x10c, 0x4e, 0x10c, 0x4f, - 0x10c, 0x50, 0x10c, 0x51, 0x10c, 0x52, 0x10c, 0x53, - 0x10c, 0x54, 0x10c, 0x55, 0x10c, 0x56, 0x10c, 0x57, - 0x10c, 0x58, 0x10c, 0x59, 0x10c, 0x5a, 0x10c, 0x5b, - 0x10c, 0x5c, 0x10c, 0x5d, 0x10c, 0x5e, 0x10c, 0x5f, - 0x10c, 0x60, 0x10c, 0x61, 0x10c, 0x62, 0x10c, 0x63, - 0x10c, 0x64, 0x10c, 0x65, 0x10c, 0x66, 0x10c, 0x67, - 0x10c, 0x68, 0x10c, 0x69, 0x10c, 0x6a, 0x10c, 0x6b, - 0x10c, 0x6c, 0x10c, 0x6d, 0x10c, 0x6e, 0x10c, 0x6f, - 0x10c, 0x70, 0x10c, 0x71, 0x10c, 0x72, 0x10c, 0x73, - 0x10c, 0x74, 0x10c, 0x75, 0x10c, 0x76, 0x10c, 0x77, - 0x10c, 0x78, 0x10c, 0x79, 0x10c, 0x7a, 0x10c, 0x7b, - 0x10c, 0x7c, 0x10c, 0x7d, 0x10c, 0x7e, 0x10c, 0x2985, - 0x10c, 0x2986, 0x10d, 0x3002, 0x10d, 0x300c, 0x10d, 0x300d, - 0x10d, 0x3001, 0x10d, 0x30fb, 0x10d, 0x30f2, 0x10d, 0x30a1, - 0x10d, 0x30a3, 0x10d, 0x30a5, 0x10d, 0x30a7, 0x10d, 0x30a9, - 0x10d, 0x30e3, 0x10d, 0x30e5, 0x10d, 0x30e7, 0x10d, 0x30c3, - 0x10d, 0x30fc, 0x10d, 0x30a2, 0x10d, 0x30a4, 0x10d, 0x30a6, - 0x10d, 0x30a8, 0x10d, 0x30aa, 0x10d, 0x30ab, 0x10d, 0x30ad, - 0x10d, 0x30af, 0x10d, 0x30b1, 0x10d, 0x30b3, 0x10d, 0x30b5, - 0x10d, 0x30b7, 0x10d, 0x30b9, 0x10d, 0x30bb, 0x10d, 0x30bd, - 0x10d, 0x30bf, 0x10d, 0x30c1, 0x10d, 0x30c4, 0x10d, 0x30c6, - 0x10d, 0x30c8, 0x10d, 0x30ca, 0x10d, 0x30cb, 0x10d, 0x30cc, - 0x10d, 0x30cd, 0x10d, 0x30ce, 0x10d, 0x30cf, 0x10d, 0x30d2, - 0x10d, 0x30d5, 0x10d, 0x30d8, 0x10d, 0x30db, 0x10d, 0x30de, - 0x10d, 0x30df, 0x10d, 0x30e0, 0x10d, 0x30e1, 0x10d, 0x30e2, - 0x10d, 0x30e4, 0x10d, 0x30e6, 0x10d, 0x30e8, 0x10d, 0x30e9, - 0x10d, 0x30ea, 0x10d, 0x30eb, 0x10d, 0x30ec, 0x10d, 0x30ed, - 0x10d, 0x30ef, 0x10d, 0x30f3, 0x10d, 0x3099, 0x10d, 0x309a, - 0x10d, 0x3164, 0x10d, 0x3131, 0x10d, 0x3132, 0x10d, 0x3133, - 0x10d, 0x3134, 0x10d, 0x3135, 0x10d, 0x3136, 0x10d, 0x3137, - 0x10d, 0x3138, 0x10d, 0x3139, 0x10d, 0x313a, 0x10d, 0x313b, - 0x10d, 0x313c, 0x10d, 0x313d, 0x10d, 0x313e, 0x10d, 0x313f, - 0x10d, 0x3140, 0x10d, 0x3141, 0x10d, 0x3142, 0x10d, 0x3143, - 0x10d, 0x3144, 0x10d, 0x3145, 0x10d, 0x3146, 0x10d, 0x3147, - 0x10d, 0x3148, 0x10d, 0x3149, 0x10d, 0x314a, 0x10d, 0x314b, - 0x10d, 0x314c, 0x10d, 0x314d, 0x10d, 0x314e, 0x10d, 0x314f, - 0x10d, 0x3150, 0x10d, 0x3151, 0x10d, 0x3152, 0x10d, 0x3153, - 0x10d, 0x3154, 0x10d, 0x3155, 0x10d, 0x3156, 0x10d, 0x3157, - 0x10d, 0x3158, 0x10d, 0x3159, 0x10d, 0x315a, 0x10d, 0x315b, - 0x10d, 0x315c, 0x10d, 0x315d, 0x10d, 0x315e, 0x10d, 0x315f, - 0x10d, 0x3160, 0x10d, 0x3161, 0x10d, 0x3162, 0x10d, 0x3163, - 0x10c, 0xa2, 0x10c, 0xa3, 0x10c, 0xac, 0x10c, 0xaf, - 0x10c, 0xa6, 0x10c, 0xa5, 0x10c, 0x20a9, 0x10d, 0x2502, - 0x10d, 0x2190, 0x10d, 0x2191, 0x10d, 0x2192, 0x10d, 0x2193, - 0x10d, 0x25a0, 0x10d, 0x25cb, 0x401, 0xd834, 0xdd57, 0xd834, - 0xdd65, 0x401, 0xd834, 0xdd58, 0xd834, 0xdd65, 0x401, 0xd834, - 0xdd5f, 0xd834, 0xdd6e, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd6f, - 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd70, 0x401, 0xd834, 0xdd5f, - 0xd834, 0xdd71, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd72, 0x401, - 0xd834, 0xddb9, 0xd834, 0xdd65, 0x401, 0xd834, 0xddba, 0xd834, - 0xdd65, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6e, 0x401, 0xd834, - 0xddbc, 0xd834, 0xdd6e, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6f, - 0x401, 0xd834, 0xddbc, 0xd834, 0xdd6f, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, - 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, - 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, - 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, - 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102, - 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, - 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, 0x4a, 0x102, - 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, 0x4e, 0x102, - 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52, 0x102, - 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102, - 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102, - 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, - 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102, - 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, - 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, - 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, - 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, - 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x43, 0x102, - 0x44, 0x102, 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102, - 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102, - 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, - 0x66, 0x102, 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, - 0x6b, 0x102, 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, - 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, - 0x4d, 0x102, 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, - 0x51, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, - 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102, - 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, - 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, - 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, - 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, - 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102, - 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, 0x47, 0x102, - 0x49, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, - 0x4d, 0x102, 0x4f, 0x102, 0x53, 0x102, 0x54, 0x102, - 0x55, 0x102, 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, - 0x59, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x131, 0x102, - 0x237, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, - 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, - 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, - 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, - 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, - 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, - 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, - 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, - 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, - 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, - 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, - 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, - 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, - 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, - 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102, - 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102, - 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102, - 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102, - 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102, - 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102, - 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102, - 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102, - 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102, - 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102, - 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102, - 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102, - 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102, - 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102, - 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102, - 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, - 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, - 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, - 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, - 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, - 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, - 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, - 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, - 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, - 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, - 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, - 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, - 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, - 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, - 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102, - 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102, - 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102, - 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102, - 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102, - 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102, - 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102, - 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102, - 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102, - 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102, - 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102, - 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102, - 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102, - 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102, - 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102, - 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, - 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, - 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, - 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, - 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, - 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, - 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, - 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, - 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, - 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, - 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, - 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, - 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, - 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, - 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x3dc, 0x102, - 0x3dd, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, - 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, - 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102, - 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102, - 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102, - 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, - 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, - 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102, - 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102, - 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102, - 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, - 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, - 0x37, 0x102, 0x38, 0x102, 0x39, 0x101, 0x4e3d, 0x101, - 0x4e38, 0x101, 0x4e41, 0x201, 0xd840, 0xdd22, 0x101, 0x4f60, - 0x101, 0x4fae, 0x101, 0x4fbb, 0x101, 0x5002, 0x101, 0x507a, - 0x101, 0x5099, 0x101, 0x50e7, 0x101, 0x50cf, 0x101, 0x349e, - 0x201, 0xd841, 0xde3a, 0x101, 0x514d, 0x101, 0x5154, 0x101, - 0x5164, 0x101, 0x5177, 0x201, 0xd841, 0xdd1c, 0x101, 0x34b9, - 0x101, 0x5167, 0x101, 0x518d, 0x201, 0xd841, 0xdd4b, 0x101, - 0x5197, 0x101, 0x51a4, 0x101, 0x4ecc, 0x101, 0x51ac, 0x101, - 0x51b5, 0x201, 0xd864, 0xdddf, 0x101, 0x51f5, 0x101, 0x5203, - 0x101, 0x34df, 0x101, 0x523b, 0x101, 0x5246, 0x101, 0x5272, - 0x101, 0x5277, 0x101, 0x3515, 0x101, 0x52c7, 0x101, 0x52c9, - 0x101, 0x52e4, 0x101, 0x52fa, 0x101, 0x5305, 0x101, 0x5306, - 0x101, 0x5317, 0x101, 0x5349, 0x101, 0x5351, 0x101, 0x535a, - 0x101, 0x5373, 0x101, 0x537d, 0x101, 0x537f, 0x101, 0x537f, - 0x101, 0x537f, 0x201, 0xd842, 0xde2c, 0x101, 0x7070, 0x101, - 0x53ca, 0x101, 0x53df, 0x201, 0xd842, 0xdf63, 0x101, 0x53eb, - 0x101, 0x53f1, 0x101, 0x5406, 0x101, 0x549e, 0x101, 0x5438, - 0x101, 0x5448, 0x101, 0x5468, 0x101, 0x54a2, 0x101, 0x54f6, - 0x101, 0x5510, 0x101, 0x5553, 0x101, 0x5563, 0x101, 0x5584, - 0x101, 0x5584, 0x101, 0x5599, 0x101, 0x55ab, 0x101, 0x55b3, - 0x101, 0x55c2, 0x101, 0x5716, 0x101, 0x5606, 0x101, 0x5717, - 0x101, 0x5651, 0x101, 0x5674, 0x101, 0x5207, 0x101, 0x58ee, - 0x101, 0x57ce, 0x101, 0x57f4, 0x101, 0x580d, 0x101, 0x578b, - 0x101, 0x5832, 0x101, 0x5831, 0x101, 0x58ac, 0x201, 0xd845, - 0xdce4, 0x101, 0x58f2, 0x101, 0x58f7, 0x101, 0x5906, 0x101, - 0x591a, 0x101, 0x5922, 0x101, 0x5962, 0x201, 0xd845, 0xdea8, - 0x201, 0xd845, 0xdeea, 0x101, 0x59ec, 0x101, 0x5a1b, 0x101, - 0x5a27, 0x101, 0x59d8, 0x101, 0x5a66, 0x101, 0x36ee, 0x101, - 0x36fc, 0x101, 0x5b08, 0x101, 0x5b3e, 0x101, 0x5b3e, 0x201, - 0xd846, 0xddc8, 0x101, 0x5bc3, 0x101, 0x5bd8, 0x101, 0x5be7, - 0x101, 0x5bf3, 0x201, 0xd846, 0xdf18, 0x101, 0x5bff, 0x101, - 0x5c06, 0x101, 0x5f53, 0x101, 0x5c22, 0x101, 0x3781, 0x101, - 0x5c60, 0x101, 0x5c6e, 0x101, 0x5cc0, 0x101, 0x5c8d, 0x201, - 0xd847, 0xdde4, 0x101, 0x5d43, 0x201, 0xd847, 0xdde6, 0x101, - 0x5d6e, 0x101, 0x5d6b, 0x101, 0x5d7c, 0x101, 0x5de1, 0x101, - 0x5de2, 0x101, 0x382f, 0x101, 0x5dfd, 0x101, 0x5e28, 0x101, - 0x5e3d, 0x101, 0x5e69, 0x101, 0x3862, 0x201, 0xd848, 0xdd83, - 0x101, 0x387c, 0x101, 0x5eb0, 0x101, 0x5eb3, 0x101, 0x5eb6, - 0x101, 0x5eca, 0x201, 0xd868, 0xdf92, 0x101, 0x5efe, 0x201, - 0xd848, 0xdf31, 0x201, 0xd848, 0xdf31, 0x101, 0x8201, 0x101, - 0x5f22, 0x101, 0x5f22, 0x101, 0x38c7, 0x201, 0xd84c, 0xdeb8, - 0x201, 0xd858, 0xddda, 0x101, 0x5f62, 0x101, 0x5f6b, 0x101, - 0x38e3, 0x101, 0x5f9a, 0x101, 0x5fcd, 0x101, 0x5fd7, 0x101, - 0x5ff9, 0x101, 0x6081, 0x101, 0x393a, 0x101, 0x391c, 0x101, - 0x6094, 0x201, 0xd849, 0xded4, 0x101, 0x60c7, 0x101, 0x6148, - 0x101, 0x614c, 0x101, 0x614e, 0x101, 0x614c, 0x101, 0x617a, - 0x101, 0x618e, 0x101, 0x61b2, 0x101, 0x61a4, 0x101, 0x61af, - 0x101, 0x61de, 0x101, 0x61f2, 0x101, 0x61f6, 0x101, 0x6210, - 0x101, 0x621b, 0x101, 0x625d, 0x101, 0x62b1, 0x101, 0x62d4, - 0x101, 0x6350, 0x201, 0xd84a, 0xdf0c, 0x101, 0x633d, 0x101, - 0x62fc, 0x101, 0x6368, 0x101, 0x6383, 0x101, 0x63e4, 0x201, - 0xd84a, 0xdff1, 0x101, 0x6422, 0x101, 0x63c5, 0x101, 0x63a9, - 0x101, 0x3a2e, 0x101, 0x6469, 0x101, 0x647e, 0x101, 0x649d, - 0x101, 0x6477, 0x101, 0x3a6c, 0x101, 0x654f, 0x101, 0x656c, - 0x201, 0xd84c, 0xdc0a, 0x101, 0x65e3, 0x101, 0x66f8, 0x101, - 0x6649, 0x101, 0x3b19, 0x101, 0x6691, 0x101, 0x3b08, 0x101, - 0x3ae4, 0x101, 0x5192, 0x101, 0x5195, 0x101, 0x6700, 0x101, - 0x669c, 0x101, 0x80ad, 0x101, 0x43d9, 0x101, 0x6717, 0x101, - 0x671b, 0x101, 0x6721, 0x101, 0x675e, 0x101, 0x6753, 0x201, - 0xd84c, 0xdfc3, 0x101, 0x3b49, 0x101, 0x67fa, 0x101, 0x6785, - 0x101, 0x6852, 0x101, 0x6885, 0x201, 0xd84d, 0xdc6d, 0x101, - 0x688e, 0x101, 0x681f, 0x101, 0x6914, 0x101, 0x3b9d, 0x101, - 0x6942, 0x101, 0x69a3, 0x101, 0x69ea, 0x101, 0x6aa8, 0x201, - 0xd84d, 0xdea3, 0x101, 0x6adb, 0x101, 0x3c18, 0x101, 0x6b21, - 0x201, 0xd84e, 0xdca7, 0x101, 0x6b54, 0x101, 0x3c4e, 0x101, - 0x6b72, 0x101, 0x6b9f, 0x101, 0x6bba, 0x101, 0x6bbb, 0x201, - 0xd84e, 0xde8d, 0x201, 0xd847, 0xdd0b, 0x201, 0xd84e, 0xdefa, - 0x101, 0x6c4e, 0x201, 0xd84f, 0xdcbc, 0x101, 0x6cbf, 0x101, - 0x6ccd, 0x101, 0x6c67, 0x101, 0x6d16, 0x101, 0x6d3e, 0x101, - 0x6d77, 0x101, 0x6d41, 0x101, 0x6d69, 0x101, 0x6d78, 0x101, - 0x6d85, 0x201, 0xd84f, 0xdd1e, 0x101, 0x6d34, 0x101, 0x6e2f, - 0x101, 0x6e6e, 0x101, 0x3d33, 0x101, 0x6ecb, 0x101, 0x6ec7, - 0x201, 0xd84f, 0xded1, 0x101, 0x6df9, 0x101, 0x6f6e, 0x201, - 0xd84f, 0xdf5e, 0x201, 0xd84f, 0xdf8e, 0x101, 0x6fc6, 0x101, - 0x7039, 0x101, 0x701e, 0x101, 0x701b, 0x101, 0x3d96, 0x101, - 0x704a, 0x101, 0x707d, 0x101, 0x7077, 0x101, 0x70ad, 0x201, - 0xd841, 0xdd25, 0x101, 0x7145, 0x201, 0xd850, 0xde63, 0x101, - 0x719c, 0x201, 0xd850, 0xdfab, 0x101, 0x7228, 0x101, 0x7235, - 0x101, 0x7250, 0x201, 0xd851, 0xde08, 0x101, 0x7280, 0x101, - 0x7295, 0x201, 0xd851, 0xdf35, 0x201, 0xd852, 0xdc14, 0x101, - 0x737a, 0x101, 0x738b, 0x101, 0x3eac, 0x101, 0x73a5, 0x101, - 0x3eb8, 0x101, 0x3eb8, 0x101, 0x7447, 0x101, 0x745c, 0x101, - 0x7471, 0x101, 0x7485, 0x101, 0x74ca, 0x101, 0x3f1b, 0x101, - 0x7524, 0x201, 0xd853, 0xdc36, 0x101, 0x753e, 0x201, 0xd853, - 0xdc92, 0x101, 0x7570, 0x201, 0xd848, 0xdd9f, 0x101, 0x7610, - 0x201, 0xd853, 0xdfa1, 0x201, 0xd853, 0xdfb8, 0x201, 0xd854, - 0xdc44, 0x101, 0x3ffc, 0x101, 0x4008, 0x101, 0x76f4, 0x201, - 0xd854, 0xdcf3, 0x201, 0xd854, 0xdcf2, 0x201, 0xd854, 0xdd19, - 0x201, 0xd854, 0xdd33, 0x101, 0x771e, 0x101, 0x771f, 0x101, - 0x771f, 0x101, 0x774a, 0x101, 0x4039, 0x101, 0x778b, 0x101, - 0x4046, 0x101, 0x4096, 0x201, 0xd855, 0xdc1d, 0x101, 0x784e, - 0x101, 0x788c, 0x101, 0x78cc, 0x101, 0x40e3, 0x201, 0xd855, - 0xde26, 0x101, 0x7956, 0x201, 0xd855, 0xde9a, 0x201, 0xd855, - 0xdec5, 0x101, 0x798f, 0x101, 0x79eb, 0x101, 0x412f, 0x101, - 0x7a40, 0x101, 0x7a4a, 0x101, 0x7a4f, 0x201, 0xd856, 0xdd7c, - 0x201, 0xd856, 0xdea7, 0x201, 0xd856, 0xdea7, 0x101, 0x7aee, - 0x101, 0x4202, 0x201, 0xd856, 0xdfab, 0x101, 0x7bc6, 0x101, - 0x7bc9, 0x101, 0x4227, 0x201, 0xd857, 0xdc80, 0x101, 0x7cd2, - 0x101, 0x42a0, 0x101, 0x7ce8, 0x101, 0x7ce3, 0x101, 0x7d00, - 0x201, 0xd857, 0xdf86, 0x101, 0x7d63, 0x101, 0x4301, 0x101, - 0x7dc7, 0x101, 0x7e02, 0x101, 0x7e45, 0x101, 0x4334, 0x201, - 0xd858, 0xde28, 0x201, 0xd858, 0xde47, 0x101, 0x4359, 0x201, - 0xd858, 0xded9, 0x101, 0x7f7a, 0x201, 0xd858, 0xdf3e, 0x101, - 0x7f95, 0x101, 0x7ffa, 0x101, 0x8005, 0x201, 0xd859, 0xdcda, - 0x201, 0xd859, 0xdd23, 0x101, 0x8060, 0x201, 0xd859, 0xdda8, - 0x101, 0x8070, 0x201, 0xd84c, 0xdf5f, 0x101, 0x43d5, 0x101, - 0x80b2, 0x101, 0x8103, 0x101, 0x440b, 0x101, 0x813e, 0x101, - 0x5ab5, 0x201, 0xd859, 0xdfa7, 0x201, 0xd859, 0xdfb5, 0x201, - 0xd84c, 0xdf93, 0x201, 0xd84c, 0xdf9c, 0x101, 0x8201, 0x101, - 0x8204, 0x101, 0x8f9e, 0x101, 0x446b, 0x101, 0x8291, 0x101, - 0x828b, 0x101, 0x829d, 0x101, 0x52b3, 0x101, 0x82b1, 0x101, - 0x82b3, 0x101, 0x82bd, 0x101, 0x82e6, 0x201, 0xd85a, 0xdf3c, - 0x101, 0x82e5, 0x101, 0x831d, 0x101, 0x8363, 0x101, 0x83ad, - 0x101, 0x8323, 0x101, 0x83bd, 0x101, 0x83e7, 0x101, 0x8457, - 0x101, 0x8353, 0x101, 0x83ca, 0x101, 0x83cc, 0x101, 0x83dc, - 0x201, 0xd85b, 0xdc36, 0x201, 0xd85b, 0xdd6b, 0x201, 0xd85b, - 0xdcd5, 0x101, 0x452b, 0x101, 0x84f1, 0x101, 0x84f3, 0x101, - 0x8516, 0x201, 0xd85c, 0xdfca, 0x101, 0x8564, 0x201, 0xd85b, - 0xdf2c, 0x101, 0x455d, 0x101, 0x4561, 0x201, 0xd85b, 0xdfb1, - 0x201, 0xd85c, 0xdcd2, 0x101, 0x456b, 0x101, 0x8650, 0x101, - 0x865c, 0x101, 0x8667, 0x101, 0x8669, 0x101, 0x86a9, 0x101, - 0x8688, 0x101, 0x870e, 0x101, 0x86e2, 0x101, 0x8779, 0x101, - 0x8728, 0x101, 0x876b, 0x101, 0x8786, 0x101, 0x45d7, 0x101, - 0x87e1, 0x101, 0x8801, 0x101, 0x45f9, 0x101, 0x8860, 0x101, - 0x8863, 0x201, 0xd85d, 0xde67, 0x101, 0x88d7, 0x101, 0x88de, - 0x101, 0x4635, 0x101, 0x88fa, 0x101, 0x34bb, 0x201, 0xd85e, - 0xdcae, 0x201, 0xd85e, 0xdd66, 0x101, 0x46be, 0x101, 0x46c7, - 0x101, 0x8aa0, 0x101, 0x8aed, 0x101, 0x8b8a, 0x101, 0x8c55, - 0x201, 0xd85f, 0xdca8, 0x101, 0x8cab, 0x101, 0x8cc1, 0x101, - 0x8d1b, 0x101, 0x8d77, 0x201, 0xd85f, 0xdf2f, 0x201, 0xd842, - 0xdc04, 0x101, 0x8dcb, 0x101, 0x8dbc, 0x101, 0x8df0, 0x201, - 0xd842, 0xdcde, 0x101, 0x8ed4, 0x101, 0x8f38, 0x201, 0xd861, - 0xddd2, 0x201, 0xd861, 0xdded, 0x101, 0x9094, 0x101, 0x90f1, - 0x101, 0x9111, 0x201, 0xd861, 0xdf2e, 0x101, 0x911b, 0x101, - 0x9238, 0x101, 0x92d7, 0x101, 0x92d8, 0x101, 0x927c, 0x101, - 0x93f9, 0x101, 0x9415, 0x201, 0xd862, 0xdffa, 0x101, 0x958b, - 0x101, 0x4995, 0x101, 0x95b7, 0x201, 0xd863, 0xdd77, 0x101, - 0x49e6, 0x101, 0x96c3, 0x101, 0x5db2, 0x101, 0x9723, 0x201, - 0xd864, 0xdd45, 0x201, 0xd864, 0xde1a, 0x101, 0x4a6e, 0x101, - 0x4a76, 0x101, 0x97e0, 0x201, 0xd865, 0xdc0a, 0x101, 0x4ab2, - 0x201, 0xd865, 0xdc96, 0x101, 0x980b, 0x101, 0x980b, 0x101, - 0x9829, 0x201, 0xd865, 0xddb6, 0x101, 0x98e2, 0x101, 0x4b33, - 0x101, 0x9929, 0x101, 0x99a7, 0x101, 0x99c2, 0x101, 0x99fe, - 0x101, 0x4bce, 0x201, 0xd866, 0xdf30, 0x101, 0x9b12, 0x101, - 0x9c40, 0x101, 0x9cfd, 0x101, 0x4cce, 0x101, 0x4ced, 0x101, - 0x9d67, 0x201, 0xd868, 0xdcce, 0x101, 0x4cf8, 0x201, 0xd868, - 0xdd05, 0x201, 0xd868, 0xde0e, 0x201, 0xd868, 0xde91, 0x101, - 0x9ebb, 0x101, 0x4d56, 0x101, 0x9ef9, 0x101, 0x9efe, 0x101, - 0x9f05, 0x101, 0x9f0f, 0x101, 0x9f16, 0x101, 0x9f3b, 0x201, - 0xd869, 0xde00, + 0x103, 0x20, 0x210, 0x20, 0x308, 0x109, 0x61, 0x210, + 0x20, 0x304, 0x109, 0x32, 0x109, 0x33, 0x210, 0x20, + 0x301, 0x110, 0x3bc, 0x210, 0x20, 0x327, 0x109, 0x31, + 0x109, 0x6f, 0x311, 0x31, 0x2044, 0x34, 0x311, 0x31, + 0x2044, 0x32, 0x311, 0x33, 0x2044, 0x34, 0x201, 0x41, + 0x300, 0x201, 0x41, 0x301, 0x201, 0x41, 0x302, 0x201, + 0x41, 0x303, 0x201, 0x41, 0x308, 0x201, 0x41, 0x30a, + 0x201, 0x43, 0x327, 0x201, 0x45, 0x300, 0x201, 0x45, + 0x301, 0x201, 0x45, 0x302, 0x201, 0x45, 0x308, 0x201, + 0x49, 0x300, 0x201, 0x49, 0x301, 0x201, 0x49, 0x302, + 0x201, 0x49, 0x308, 0x201, 0x4e, 0x303, 0x201, 0x4f, + 0x300, 0x201, 0x4f, 0x301, 0x201, 0x4f, 0x302, 0x201, + 0x4f, 0x303, 0x201, 0x4f, 0x308, 0x201, 0x55, 0x300, + 0x201, 0x55, 0x301, 0x201, 0x55, 0x302, 0x201, 0x55, + 0x308, 0x201, 0x59, 0x301, 0x201, 0x61, 0x300, 0x201, + 0x61, 0x301, 0x201, 0x61, 0x302, 0x201, 0x61, 0x303, + 0x201, 0x61, 0x308, 0x201, 0x61, 0x30a, 0x201, 0x63, + 0x327, 0x201, 0x65, 0x300, 0x201, 0x65, 0x301, 0x201, + 0x65, 0x302, 0x201, 0x65, 0x308, 0x201, 0x69, 0x300, + 0x201, 0x69, 0x301, 0x201, 0x69, 0x302, 0x201, 0x69, + 0x308, 0x201, 0x6e, 0x303, 0x201, 0x6f, 0x300, 0x201, + 0x6f, 0x301, 0x201, 0x6f, 0x302, 0x201, 0x6f, 0x303, + 0x201, 0x6f, 0x308, 0x201, 0x75, 0x300, 0x201, 0x75, + 0x301, 0x201, 0x75, 0x302, 0x201, 0x75, 0x308, 0x201, + 0x79, 0x301, 0x201, 0x79, 0x308, 0x201, 0x41, 0x304, + 0x201, 0x61, 0x304, 0x201, 0x41, 0x306, 0x201, 0x61, + 0x306, 0x201, 0x41, 0x328, 0x201, 0x61, 0x328, 0x201, + 0x43, 0x301, 0x201, 0x63, 0x301, 0x201, 0x43, 0x302, + 0x201, 0x63, 0x302, 0x201, 0x43, 0x307, 0x201, 0x63, + 0x307, 0x201, 0x43, 0x30c, 0x201, 0x63, 0x30c, 0x201, + 0x44, 0x30c, 0x201, 0x64, 0x30c, 0x201, 0x45, 0x304, + 0x201, 0x65, 0x304, 0x201, 0x45, 0x306, 0x201, 0x65, + 0x306, 0x201, 0x45, 0x307, 0x201, 0x65, 0x307, 0x201, + 0x45, 0x328, 0x201, 0x65, 0x328, 0x201, 0x45, 0x30c, + 0x201, 0x65, 0x30c, 0x201, 0x47, 0x302, 0x201, 0x67, + 0x302, 0x201, 0x47, 0x306, 0x201, 0x67, 0x306, 0x201, + 0x47, 0x307, 0x201, 0x67, 0x307, 0x201, 0x47, 0x327, + 0x201, 0x67, 0x327, 0x201, 0x48, 0x302, 0x201, 0x68, + 0x302, 0x201, 0x49, 0x303, 0x201, 0x69, 0x303, 0x201, + 0x49, 0x304, 0x201, 0x69, 0x304, 0x201, 0x49, 0x306, + 0x201, 0x69, 0x306, 0x201, 0x49, 0x328, 0x201, 0x69, + 0x328, 0x201, 0x49, 0x307, 0x210, 0x49, 0x4a, 0x210, + 0x69, 0x6a, 0x201, 0x4a, 0x302, 0x201, 0x6a, 0x302, + 0x201, 0x4b, 0x327, 0x201, 0x6b, 0x327, 0x201, 0x4c, + 0x301, 0x201, 0x6c, 0x301, 0x201, 0x4c, 0x327, 0x201, + 0x6c, 0x327, 0x201, 0x4c, 0x30c, 0x201, 0x6c, 0x30c, + 0x210, 0x4c, 0xb7, 0x210, 0x6c, 0xb7, 0x201, 0x4e, + 0x301, 0x201, 0x6e, 0x301, 0x201, 0x4e, 0x327, 0x201, + 0x6e, 0x327, 0x201, 0x4e, 0x30c, 0x201, 0x6e, 0x30c, + 0x210, 0x2bc, 0x6e, 0x201, 0x4f, 0x304, 0x201, 0x6f, + 0x304, 0x201, 0x4f, 0x306, 0x201, 0x6f, 0x306, 0x201, + 0x4f, 0x30b, 0x201, 0x6f, 0x30b, 0x201, 0x52, 0x301, + 0x201, 0x72, 0x301, 0x201, 0x52, 0x327, 0x201, 0x72, + 0x327, 0x201, 0x52, 0x30c, 0x201, 0x72, 0x30c, 0x201, + 0x53, 0x301, 0x201, 0x73, 0x301, 0x201, 0x53, 0x302, + 0x201, 0x73, 0x302, 0x201, 0x53, 0x327, 0x201, 0x73, + 0x327, 0x201, 0x53, 0x30c, 0x201, 0x73, 0x30c, 0x201, + 0x54, 0x327, 0x201, 0x74, 0x327, 0x201, 0x54, 0x30c, + 0x201, 0x74, 0x30c, 0x201, 0x55, 0x303, 0x201, 0x75, + 0x303, 0x201, 0x55, 0x304, 0x201, 0x75, 0x304, 0x201, + 0x55, 0x306, 0x201, 0x75, 0x306, 0x201, 0x55, 0x30a, + 0x201, 0x75, 0x30a, 0x201, 0x55, 0x30b, 0x201, 0x75, + 0x30b, 0x201, 0x55, 0x328, 0x201, 0x75, 0x328, 0x201, + 0x57, 0x302, 0x201, 0x77, 0x302, 0x201, 0x59, 0x302, + 0x201, 0x79, 0x302, 0x201, 0x59, 0x308, 0x201, 0x5a, + 0x301, 0x201, 0x7a, 0x301, 0x201, 0x5a, 0x307, 0x201, + 0x7a, 0x307, 0x201, 0x5a, 0x30c, 0x201, 0x7a, 0x30c, + 0x110, 0x73, 0x201, 0x4f, 0x31b, 0x201, 0x6f, 0x31b, + 0x201, 0x55, 0x31b, 0x201, 0x75, 0x31b, 0x210, 0x44, + 0x17d, 0x210, 0x44, 0x17e, 0x210, 0x64, 0x17e, 0x210, + 0x4c, 0x4a, 0x210, 0x4c, 0x6a, 0x210, 0x6c, 0x6a, + 0x210, 0x4e, 0x4a, 0x210, 0x4e, 0x6a, 0x210, 0x6e, + 0x6a, 0x201, 0x41, 0x30c, 0x201, 0x61, 0x30c, 0x201, + 0x49, 0x30c, 0x201, 0x69, 0x30c, 0x201, 0x4f, 0x30c, + 0x201, 0x6f, 0x30c, 0x201, 0x55, 0x30c, 0x201, 0x75, + 0x30c, 0x201, 0xdc, 0x304, 0x201, 0xfc, 0x304, 0x201, + 0xdc, 0x301, 0x201, 0xfc, 0x301, 0x201, 0xdc, 0x30c, + 0x201, 0xfc, 0x30c, 0x201, 0xdc, 0x300, 0x201, 0xfc, + 0x300, 0x201, 0xc4, 0x304, 0x201, 0xe4, 0x304, 0x201, + 0x226, 0x304, 0x201, 0x227, 0x304, 0x201, 0xc6, 0x304, + 0x201, 0xe6, 0x304, 0x201, 0x47, 0x30c, 0x201, 0x67, + 0x30c, 0x201, 0x4b, 0x30c, 0x201, 0x6b, 0x30c, 0x201, + 0x4f, 0x328, 0x201, 0x6f, 0x328, 0x201, 0x1ea, 0x304, + 0x201, 0x1eb, 0x304, 0x201, 0x1b7, 0x30c, 0x201, 0x292, + 0x30c, 0x201, 0x6a, 0x30c, 0x210, 0x44, 0x5a, 0x210, + 0x44, 0x7a, 0x210, 0x64, 0x7a, 0x201, 0x47, 0x301, + 0x201, 0x67, 0x301, 0x201, 0x4e, 0x300, 0x201, 0x6e, + 0x300, 0x201, 0xc5, 0x301, 0x201, 0xe5, 0x301, 0x201, + 0xc6, 0x301, 0x201, 0xe6, 0x301, 0x201, 0xd8, 0x301, + 0x201, 0xf8, 0x301, 0x201, 0x41, 0x30f, 0x201, 0x61, + 0x30f, 0x201, 0x41, 0x311, 0x201, 0x61, 0x311, 0x201, + 0x45, 0x30f, 0x201, 0x65, 0x30f, 0x201, 0x45, 0x311, + 0x201, 0x65, 0x311, 0x201, 0x49, 0x30f, 0x201, 0x69, + 0x30f, 0x201, 0x49, 0x311, 0x201, 0x69, 0x311, 0x201, + 0x4f, 0x30f, 0x201, 0x6f, 0x30f, 0x201, 0x4f, 0x311, + 0x201, 0x6f, 0x311, 0x201, 0x52, 0x30f, 0x201, 0x72, + 0x30f, 0x201, 0x52, 0x311, 0x201, 0x72, 0x311, 0x201, + 0x55, 0x30f, 0x201, 0x75, 0x30f, 0x201, 0x55, 0x311, + 0x201, 0x75, 0x311, 0x201, 0x53, 0x326, 0x201, 0x73, + 0x326, 0x201, 0x54, 0x326, 0x201, 0x74, 0x326, 0x201, + 0x48, 0x30c, 0x201, 0x68, 0x30c, 0x201, 0x41, 0x307, + 0x201, 0x61, 0x307, 0x201, 0x45, 0x327, 0x201, 0x65, + 0x327, 0x201, 0xd6, 0x304, 0x201, 0xf6, 0x304, 0x201, + 0xd5, 0x304, 0x201, 0xf5, 0x304, 0x201, 0x4f, 0x307, + 0x201, 0x6f, 0x307, 0x201, 0x22e, 0x304, 0x201, 0x22f, + 0x304, 0x201, 0x59, 0x304, 0x201, 0x79, 0x304, 0x109, + 0x68, 0x109, 0x266, 0x109, 0x6a, 0x109, 0x72, 0x109, + 0x279, 0x109, 0x27b, 0x109, 0x281, 0x109, 0x77, 0x109, + 0x79, 0x210, 0x20, 0x306, 0x210, 0x20, 0x307, 0x210, + 0x20, 0x30a, 0x210, 0x20, 0x328, 0x210, 0x20, 0x303, + 0x210, 0x20, 0x30b, 0x109, 0x263, 0x109, 0x6c, 0x109, + 0x73, 0x109, 0x78, 0x109, 0x295, 0x101, 0x300, 0x101, + 0x301, 0x101, 0x313, 0x201, 0x308, 0x301, 0x101, 0x2b9, + 0x210, 0x20, 0x345, 0x101, 0x3b, 0x210, 0x20, 0x301, + 0x201, 0xa8, 0x301, 0x201, 0x391, 0x301, 0x101, 0xb7, + 0x201, 0x395, 0x301, 0x201, 0x397, 0x301, 0x201, 0x399, + 0x301, 0x201, 0x39f, 0x301, 0x201, 0x3a5, 0x301, 0x201, + 0x3a9, 0x301, 0x201, 0x3ca, 0x301, 0x201, 0x399, 0x308, + 0x201, 0x3a5, 0x308, 0x201, 0x3b1, 0x301, 0x201, 0x3b5, + 0x301, 0x201, 0x3b7, 0x301, 0x201, 0x3b9, 0x301, 0x201, + 0x3cb, 0x301, 0x201, 0x3b9, 0x308, 0x201, 0x3c5, 0x308, + 0x201, 0x3bf, 0x301, 0x201, 0x3c5, 0x301, 0x201, 0x3c9, + 0x301, 0x110, 0x3b2, 0x110, 0x3b8, 0x110, 0x3a5, 0x201, + 0x3d2, 0x301, 0x201, 0x3d2, 0x308, 0x110, 0x3c6, 0x110, + 0x3c0, 0x110, 0x3ba, 0x110, 0x3c1, 0x110, 0x3c2, 0x110, + 0x398, 0x110, 0x3b5, 0x110, 0x3a3, 0x201, 0x415, 0x300, + 0x201, 0x415, 0x308, 0x201, 0x413, 0x301, 0x201, 0x406, + 0x308, 0x201, 0x41a, 0x301, 0x201, 0x418, 0x300, 0x201, + 0x423, 0x306, 0x201, 0x418, 0x306, 0x201, 0x438, 0x306, + 0x201, 0x435, 0x300, 0x201, 0x435, 0x308, 0x201, 0x433, + 0x301, 0x201, 0x456, 0x308, 0x201, 0x43a, 0x301, 0x201, + 0x438, 0x300, 0x201, 0x443, 0x306, 0x201, 0x474, 0x30f, + 0x201, 0x475, 0x30f, 0x201, 0x416, 0x306, 0x201, 0x436, + 0x306, 0x201, 0x410, 0x306, 0x201, 0x430, 0x306, 0x201, + 0x410, 0x308, 0x201, 0x430, 0x308, 0x201, 0x415, 0x306, + 0x201, 0x435, 0x306, 0x201, 0x4d8, 0x308, 0x201, 0x4d9, + 0x308, 0x201, 0x416, 0x308, 0x201, 0x436, 0x308, 0x201, + 0x417, 0x308, 0x201, 0x437, 0x308, 0x201, 0x418, 0x304, + 0x201, 0x438, 0x304, 0x201, 0x418, 0x308, 0x201, 0x438, + 0x308, 0x201, 0x41e, 0x308, 0x201, 0x43e, 0x308, 0x201, + 0x4e8, 0x308, 0x201, 0x4e9, 0x308, 0x201, 0x42d, 0x308, + 0x201, 0x44d, 0x308, 0x201, 0x423, 0x304, 0x201, 0x443, + 0x304, 0x201, 0x423, 0x308, 0x201, 0x443, 0x308, 0x201, + 0x423, 0x30b, 0x201, 0x443, 0x30b, 0x201, 0x427, 0x308, + 0x201, 0x447, 0x308, 0x201, 0x42b, 0x308, 0x201, 0x44b, + 0x308, 0x210, 0x565, 0x582, 0x201, 0x627, 0x653, 0x201, + 0x627, 0x654, 0x201, 0x648, 0x654, 0x201, 0x627, 0x655, + 0x201, 0x64a, 0x654, 0x210, 0x627, 0x674, 0x210, 0x648, + 0x674, 0x210, 0x6c7, 0x674, 0x210, 0x64a, 0x674, 0x201, + 0x6d5, 0x654, 0x201, 0x6c1, 0x654, 0x201, 0x6d2, 0x654, + 0x201, 0x928, 0x93c, 0x201, 0x930, 0x93c, 0x201, 0x933, + 0x93c, 0x201, 0x915, 0x93c, 0x201, 0x916, 0x93c, 0x201, + 0x917, 0x93c, 0x201, 0x91c, 0x93c, 0x201, 0x921, 0x93c, + 0x201, 0x922, 0x93c, 0x201, 0x92b, 0x93c, 0x201, 0x92f, + 0x93c, 0x201, 0x9c7, 0x9be, 0x201, 0x9c7, 0x9d7, 0x201, + 0x9a1, 0x9bc, 0x201, 0x9a2, 0x9bc, 0x201, 0x9af, 0x9bc, + 0x201, 0xa32, 0xa3c, 0x201, 0xa38, 0xa3c, 0x201, 0xa16, + 0xa3c, 0x201, 0xa17, 0xa3c, 0x201, 0xa1c, 0xa3c, 0x201, + 0xa2b, 0xa3c, 0x201, 0xb47, 0xb56, 0x201, 0xb47, 0xb3e, + 0x201, 0xb47, 0xb57, 0x201, 0xb21, 0xb3c, 0x201, 0xb22, + 0xb3c, 0x201, 0xb92, 0xbd7, 0x201, 0xbc6, 0xbbe, 0x201, + 0xbc7, 0xbbe, 0x201, 0xbc6, 0xbd7, 0x201, 0xc46, 0xc56, + 0x201, 0xcbf, 0xcd5, 0x201, 0xcc6, 0xcd5, 0x201, 0xcc6, + 0xcd6, 0x201, 0xcc6, 0xcc2, 0x201, 0xcca, 0xcd5, 0x201, + 0xd46, 0xd3e, 0x201, 0xd47, 0xd3e, 0x201, 0xd46, 0xd57, + 0x201, 0xdd9, 0xdca, 0x201, 0xdd9, 0xdcf, 0x201, 0xddc, + 0xdca, 0x201, 0xdd9, 0xddf, 0x210, 0xe4d, 0xe32, 0x210, + 0xecd, 0xeb2, 0x210, 0xeab, 0xe99, 0x210, 0xeab, 0xea1, + 0x103, 0xf0b, 0x201, 0xf42, 0xfb7, 0x201, 0xf4c, 0xfb7, + 0x201, 0xf51, 0xfb7, 0x201, 0xf56, 0xfb7, 0x201, 0xf5b, + 0xfb7, 0x201, 0xf40, 0xfb5, 0x201, 0xf71, 0xf72, 0x201, + 0xf71, 0xf74, 0x201, 0xfb2, 0xf80, 0x210, 0xfb2, 0xf81, + 0x201, 0xfb3, 0xf80, 0x210, 0xfb3, 0xf81, 0x201, 0xf71, + 0xf80, 0x201, 0xf92, 0xfb7, 0x201, 0xf9c, 0xfb7, 0x201, + 0xfa1, 0xfb7, 0x201, 0xfa6, 0xfb7, 0x201, 0xfab, 0xfb7, + 0x201, 0xf90, 0xfb5, 0x201, 0x1025, 0x102e, 0x109, 0x10dc, + 0x201, 0x1b05, 0x1b35, 0x201, 0x1b07, 0x1b35, 0x201, 0x1b09, + 0x1b35, 0x201, 0x1b0b, 0x1b35, 0x201, 0x1b0d, 0x1b35, 0x201, + 0x1b11, 0x1b35, 0x201, 0x1b3a, 0x1b35, 0x201, 0x1b3c, 0x1b35, + 0x201, 0x1b3e, 0x1b35, 0x201, 0x1b3f, 0x1b35, 0x201, 0x1b42, + 0x1b35, 0x109, 0x41, 0x109, 0xc6, 0x109, 0x42, 0x109, + 0x44, 0x109, 0x45, 0x109, 0x18e, 0x109, 0x47, 0x109, + 0x48, 0x109, 0x49, 0x109, 0x4a, 0x109, 0x4b, 0x109, + 0x4c, 0x109, 0x4d, 0x109, 0x4e, 0x109, 0x4f, 0x109, + 0x222, 0x109, 0x50, 0x109, 0x52, 0x109, 0x54, 0x109, + 0x55, 0x109, 0x57, 0x109, 0x61, 0x109, 0x250, 0x109, + 0x251, 0x109, 0x1d02, 0x109, 0x62, 0x109, 0x64, 0x109, + 0x65, 0x109, 0x259, 0x109, 0x25b, 0x109, 0x25c, 0x109, + 0x67, 0x109, 0x6b, 0x109, 0x6d, 0x109, 0x14b, 0x109, + 0x6f, 0x109, 0x254, 0x109, 0x1d16, 0x109, 0x1d17, 0x109, + 0x70, 0x109, 0x74, 0x109, 0x75, 0x109, 0x1d1d, 0x109, + 0x26f, 0x109, 0x76, 0x109, 0x1d25, 0x109, 0x3b2, 0x109, + 0x3b3, 0x109, 0x3b4, 0x109, 0x3c6, 0x109, 0x3c7, 0x10a, + 0x69, 0x10a, 0x72, 0x10a, 0x75, 0x10a, 0x76, 0x10a, + 0x3b2, 0x10a, 0x3b3, 0x10a, 0x3c1, 0x10a, 0x3c6, 0x10a, + 0x3c7, 0x109, 0x43d, 0x109, 0x252, 0x109, 0x63, 0x109, + 0x255, 0x109, 0xf0, 0x109, 0x25c, 0x109, 0x66, 0x109, + 0x25f, 0x109, 0x261, 0x109, 0x265, 0x109, 0x268, 0x109, + 0x269, 0x109, 0x26a, 0x109, 0x1d7b, 0x109, 0x29d, 0x109, + 0x26d, 0x109, 0x1d85, 0x109, 0x29f, 0x109, 0x271, 0x109, + 0x270, 0x109, 0x272, 0x109, 0x273, 0x109, 0x274, 0x109, + 0x275, 0x109, 0x278, 0x109, 0x282, 0x109, 0x283, 0x109, + 0x1ab, 0x109, 0x289, 0x109, 0x28a, 0x109, 0x1d1c, 0x109, + 0x28b, 0x109, 0x28c, 0x109, 0x7a, 0x109, 0x290, 0x109, + 0x291, 0x109, 0x292, 0x109, 0x3b8, 0x201, 0x41, 0x325, + 0x201, 0x61, 0x325, 0x201, 0x42, 0x307, 0x201, 0x62, + 0x307, 0x201, 0x42, 0x323, 0x201, 0x62, 0x323, 0x201, + 0x42, 0x331, 0x201, 0x62, 0x331, 0x201, 0xc7, 0x301, + 0x201, 0xe7, 0x301, 0x201, 0x44, 0x307, 0x201, 0x64, + 0x307, 0x201, 0x44, 0x323, 0x201, 0x64, 0x323, 0x201, + 0x44, 0x331, 0x201, 0x64, 0x331, 0x201, 0x44, 0x327, + 0x201, 0x64, 0x327, 0x201, 0x44, 0x32d, 0x201, 0x64, + 0x32d, 0x201, 0x112, 0x300, 0x201, 0x113, 0x300, 0x201, + 0x112, 0x301, 0x201, 0x113, 0x301, 0x201, 0x45, 0x32d, + 0x201, 0x65, 0x32d, 0x201, 0x45, 0x330, 0x201, 0x65, + 0x330, 0x201, 0x228, 0x306, 0x201, 0x229, 0x306, 0x201, + 0x46, 0x307, 0x201, 0x66, 0x307, 0x201, 0x47, 0x304, + 0x201, 0x67, 0x304, 0x201, 0x48, 0x307, 0x201, 0x68, + 0x307, 0x201, 0x48, 0x323, 0x201, 0x68, 0x323, 0x201, + 0x48, 0x308, 0x201, 0x68, 0x308, 0x201, 0x48, 0x327, + 0x201, 0x68, 0x327, 0x201, 0x48, 0x32e, 0x201, 0x68, + 0x32e, 0x201, 0x49, 0x330, 0x201, 0x69, 0x330, 0x201, + 0xcf, 0x301, 0x201, 0xef, 0x301, 0x201, 0x4b, 0x301, + 0x201, 0x6b, 0x301, 0x201, 0x4b, 0x323, 0x201, 0x6b, + 0x323, 0x201, 0x4b, 0x331, 0x201, 0x6b, 0x331, 0x201, + 0x4c, 0x323, 0x201, 0x6c, 0x323, 0x201, 0x1e36, 0x304, + 0x201, 0x1e37, 0x304, 0x201, 0x4c, 0x331, 0x201, 0x6c, + 0x331, 0x201, 0x4c, 0x32d, 0x201, 0x6c, 0x32d, 0x201, + 0x4d, 0x301, 0x201, 0x6d, 0x301, 0x201, 0x4d, 0x307, + 0x201, 0x6d, 0x307, 0x201, 0x4d, 0x323, 0x201, 0x6d, + 0x323, 0x201, 0x4e, 0x307, 0x201, 0x6e, 0x307, 0x201, + 0x4e, 0x323, 0x201, 0x6e, 0x323, 0x201, 0x4e, 0x331, + 0x201, 0x6e, 0x331, 0x201, 0x4e, 0x32d, 0x201, 0x6e, + 0x32d, 0x201, 0xd5, 0x301, 0x201, 0xf5, 0x301, 0x201, + 0xd5, 0x308, 0x201, 0xf5, 0x308, 0x201, 0x14c, 0x300, + 0x201, 0x14d, 0x300, 0x201, 0x14c, 0x301, 0x201, 0x14d, + 0x301, 0x201, 0x50, 0x301, 0x201, 0x70, 0x301, 0x201, + 0x50, 0x307, 0x201, 0x70, 0x307, 0x201, 0x52, 0x307, + 0x201, 0x72, 0x307, 0x201, 0x52, 0x323, 0x201, 0x72, + 0x323, 0x201, 0x1e5a, 0x304, 0x201, 0x1e5b, 0x304, 0x201, + 0x52, 0x331, 0x201, 0x72, 0x331, 0x201, 0x53, 0x307, + 0x201, 0x73, 0x307, 0x201, 0x53, 0x323, 0x201, 0x73, + 0x323, 0x201, 0x15a, 0x307, 0x201, 0x15b, 0x307, 0x201, + 0x160, 0x307, 0x201, 0x161, 0x307, 0x201, 0x1e62, 0x307, + 0x201, 0x1e63, 0x307, 0x201, 0x54, 0x307, 0x201, 0x74, + 0x307, 0x201, 0x54, 0x323, 0x201, 0x74, 0x323, 0x201, + 0x54, 0x331, 0x201, 0x74, 0x331, 0x201, 0x54, 0x32d, + 0x201, 0x74, 0x32d, 0x201, 0x55, 0x324, 0x201, 0x75, + 0x324, 0x201, 0x55, 0x330, 0x201, 0x75, 0x330, 0x201, + 0x55, 0x32d, 0x201, 0x75, 0x32d, 0x201, 0x168, 0x301, + 0x201, 0x169, 0x301, 0x201, 0x16a, 0x308, 0x201, 0x16b, + 0x308, 0x201, 0x56, 0x303, 0x201, 0x76, 0x303, 0x201, + 0x56, 0x323, 0x201, 0x76, 0x323, 0x201, 0x57, 0x300, + 0x201, 0x77, 0x300, 0x201, 0x57, 0x301, 0x201, 0x77, + 0x301, 0x201, 0x57, 0x308, 0x201, 0x77, 0x308, 0x201, + 0x57, 0x307, 0x201, 0x77, 0x307, 0x201, 0x57, 0x323, + 0x201, 0x77, 0x323, 0x201, 0x58, 0x307, 0x201, 0x78, + 0x307, 0x201, 0x58, 0x308, 0x201, 0x78, 0x308, 0x201, + 0x59, 0x307, 0x201, 0x79, 0x307, 0x201, 0x5a, 0x302, + 0x201, 0x7a, 0x302, 0x201, 0x5a, 0x323, 0x201, 0x7a, + 0x323, 0x201, 0x5a, 0x331, 0x201, 0x7a, 0x331, 0x201, + 0x68, 0x331, 0x201, 0x74, 0x308, 0x201, 0x77, 0x30a, + 0x201, 0x79, 0x30a, 0x210, 0x61, 0x2be, 0x201, 0x17f, + 0x307, 0x201, 0x41, 0x323, 0x201, 0x61, 0x323, 0x201, + 0x41, 0x309, 0x201, 0x61, 0x309, 0x201, 0xc2, 0x301, + 0x201, 0xe2, 0x301, 0x201, 0xc2, 0x300, 0x201, 0xe2, + 0x300, 0x201, 0xc2, 0x309, 0x201, 0xe2, 0x309, 0x201, + 0xc2, 0x303, 0x201, 0xe2, 0x303, 0x201, 0x1ea0, 0x302, + 0x201, 0x1ea1, 0x302, 0x201, 0x102, 0x301, 0x201, 0x103, + 0x301, 0x201, 0x102, 0x300, 0x201, 0x103, 0x300, 0x201, + 0x102, 0x309, 0x201, 0x103, 0x309, 0x201, 0x102, 0x303, + 0x201, 0x103, 0x303, 0x201, 0x1ea0, 0x306, 0x201, 0x1ea1, + 0x306, 0x201, 0x45, 0x323, 0x201, 0x65, 0x323, 0x201, + 0x45, 0x309, 0x201, 0x65, 0x309, 0x201, 0x45, 0x303, + 0x201, 0x65, 0x303, 0x201, 0xca, 0x301, 0x201, 0xea, + 0x301, 0x201, 0xca, 0x300, 0x201, 0xea, 0x300, 0x201, + 0xca, 0x309, 0x201, 0xea, 0x309, 0x201, 0xca, 0x303, + 0x201, 0xea, 0x303, 0x201, 0x1eb8, 0x302, 0x201, 0x1eb9, + 0x302, 0x201, 0x49, 0x309, 0x201, 0x69, 0x309, 0x201, + 0x49, 0x323, 0x201, 0x69, 0x323, 0x201, 0x4f, 0x323, + 0x201, 0x6f, 0x323, 0x201, 0x4f, 0x309, 0x201, 0x6f, + 0x309, 0x201, 0xd4, 0x301, 0x201, 0xf4, 0x301, 0x201, + 0xd4, 0x300, 0x201, 0xf4, 0x300, 0x201, 0xd4, 0x309, + 0x201, 0xf4, 0x309, 0x201, 0xd4, 0x303, 0x201, 0xf4, + 0x303, 0x201, 0x1ecc, 0x302, 0x201, 0x1ecd, 0x302, 0x201, + 0x1a0, 0x301, 0x201, 0x1a1, 0x301, 0x201, 0x1a0, 0x300, + 0x201, 0x1a1, 0x300, 0x201, 0x1a0, 0x309, 0x201, 0x1a1, + 0x309, 0x201, 0x1a0, 0x303, 0x201, 0x1a1, 0x303, 0x201, + 0x1a0, 0x323, 0x201, 0x1a1, 0x323, 0x201, 0x55, 0x323, + 0x201, 0x75, 0x323, 0x201, 0x55, 0x309, 0x201, 0x75, + 0x309, 0x201, 0x1af, 0x301, 0x201, 0x1b0, 0x301, 0x201, + 0x1af, 0x300, 0x201, 0x1b0, 0x300, 0x201, 0x1af, 0x309, + 0x201, 0x1b0, 0x309, 0x201, 0x1af, 0x303, 0x201, 0x1b0, + 0x303, 0x201, 0x1af, 0x323, 0x201, 0x1b0, 0x323, 0x201, + 0x59, 0x300, 0x201, 0x79, 0x300, 0x201, 0x59, 0x323, + 0x201, 0x79, 0x323, 0x201, 0x59, 0x309, 0x201, 0x79, + 0x309, 0x201, 0x59, 0x303, 0x201, 0x79, 0x303, 0x201, + 0x3b1, 0x313, 0x201, 0x3b1, 0x314, 0x201, 0x1f00, 0x300, + 0x201, 0x1f01, 0x300, 0x201, 0x1f00, 0x301, 0x201, 0x1f01, + 0x301, 0x201, 0x1f00, 0x342, 0x201, 0x1f01, 0x342, 0x201, + 0x391, 0x313, 0x201, 0x391, 0x314, 0x201, 0x1f08, 0x300, + 0x201, 0x1f09, 0x300, 0x201, 0x1f08, 0x301, 0x201, 0x1f09, + 0x301, 0x201, 0x1f08, 0x342, 0x201, 0x1f09, 0x342, 0x201, + 0x3b5, 0x313, 0x201, 0x3b5, 0x314, 0x201, 0x1f10, 0x300, + 0x201, 0x1f11, 0x300, 0x201, 0x1f10, 0x301, 0x201, 0x1f11, + 0x301, 0x201, 0x395, 0x313, 0x201, 0x395, 0x314, 0x201, + 0x1f18, 0x300, 0x201, 0x1f19, 0x300, 0x201, 0x1f18, 0x301, + 0x201, 0x1f19, 0x301, 0x201, 0x3b7, 0x313, 0x201, 0x3b7, + 0x314, 0x201, 0x1f20, 0x300, 0x201, 0x1f21, 0x300, 0x201, + 0x1f20, 0x301, 0x201, 0x1f21, 0x301, 0x201, 0x1f20, 0x342, + 0x201, 0x1f21, 0x342, 0x201, 0x397, 0x313, 0x201, 0x397, + 0x314, 0x201, 0x1f28, 0x300, 0x201, 0x1f29, 0x300, 0x201, + 0x1f28, 0x301, 0x201, 0x1f29, 0x301, 0x201, 0x1f28, 0x342, + 0x201, 0x1f29, 0x342, 0x201, 0x3b9, 0x313, 0x201, 0x3b9, + 0x314, 0x201, 0x1f30, 0x300, 0x201, 0x1f31, 0x300, 0x201, + 0x1f30, 0x301, 0x201, 0x1f31, 0x301, 0x201, 0x1f30, 0x342, + 0x201, 0x1f31, 0x342, 0x201, 0x399, 0x313, 0x201, 0x399, + 0x314, 0x201, 0x1f38, 0x300, 0x201, 0x1f39, 0x300, 0x201, + 0x1f38, 0x301, 0x201, 0x1f39, 0x301, 0x201, 0x1f38, 0x342, + 0x201, 0x1f39, 0x342, 0x201, 0x3bf, 0x313, 0x201, 0x3bf, + 0x314, 0x201, 0x1f40, 0x300, 0x201, 0x1f41, 0x300, 0x201, + 0x1f40, 0x301, 0x201, 0x1f41, 0x301, 0x201, 0x39f, 0x313, + 0x201, 0x39f, 0x314, 0x201, 0x1f48, 0x300, 0x201, 0x1f49, + 0x300, 0x201, 0x1f48, 0x301, 0x201, 0x1f49, 0x301, 0x201, + 0x3c5, 0x313, 0x201, 0x3c5, 0x314, 0x201, 0x1f50, 0x300, + 0x201, 0x1f51, 0x300, 0x201, 0x1f50, 0x301, 0x201, 0x1f51, + 0x301, 0x201, 0x1f50, 0x342, 0x201, 0x1f51, 0x342, 0x201, + 0x3a5, 0x314, 0x201, 0x1f59, 0x300, 0x201, 0x1f59, 0x301, + 0x201, 0x1f59, 0x342, 0x201, 0x3c9, 0x313, 0x201, 0x3c9, + 0x314, 0x201, 0x1f60, 0x300, 0x201, 0x1f61, 0x300, 0x201, + 0x1f60, 0x301, 0x201, 0x1f61, 0x301, 0x201, 0x1f60, 0x342, + 0x201, 0x1f61, 0x342, 0x201, 0x3a9, 0x313, 0x201, 0x3a9, + 0x314, 0x201, 0x1f68, 0x300, 0x201, 0x1f69, 0x300, 0x201, + 0x1f68, 0x301, 0x201, 0x1f69, 0x301, 0x201, 0x1f68, 0x342, + 0x201, 0x1f69, 0x342, 0x201, 0x3b1, 0x300, 0x101, 0x3ac, + 0x201, 0x3b5, 0x300, 0x101, 0x3ad, 0x201, 0x3b7, 0x300, + 0x101, 0x3ae, 0x201, 0x3b9, 0x300, 0x101, 0x3af, 0x201, + 0x3bf, 0x300, 0x101, 0x3cc, 0x201, 0x3c5, 0x300, 0x101, + 0x3cd, 0x201, 0x3c9, 0x300, 0x101, 0x3ce, 0x201, 0x1f00, + 0x345, 0x201, 0x1f01, 0x345, 0x201, 0x1f02, 0x345, 0x201, + 0x1f03, 0x345, 0x201, 0x1f04, 0x345, 0x201, 0x1f05, 0x345, + 0x201, 0x1f06, 0x345, 0x201, 0x1f07, 0x345, 0x201, 0x1f08, + 0x345, 0x201, 0x1f09, 0x345, 0x201, 0x1f0a, 0x345, 0x201, + 0x1f0b, 0x345, 0x201, 0x1f0c, 0x345, 0x201, 0x1f0d, 0x345, + 0x201, 0x1f0e, 0x345, 0x201, 0x1f0f, 0x345, 0x201, 0x1f20, + 0x345, 0x201, 0x1f21, 0x345, 0x201, 0x1f22, 0x345, 0x201, + 0x1f23, 0x345, 0x201, 0x1f24, 0x345, 0x201, 0x1f25, 0x345, + 0x201, 0x1f26, 0x345, 0x201, 0x1f27, 0x345, 0x201, 0x1f28, + 0x345, 0x201, 0x1f29, 0x345, 0x201, 0x1f2a, 0x345, 0x201, + 0x1f2b, 0x345, 0x201, 0x1f2c, 0x345, 0x201, 0x1f2d, 0x345, + 0x201, 0x1f2e, 0x345, 0x201, 0x1f2f, 0x345, 0x201, 0x1f60, + 0x345, 0x201, 0x1f61, 0x345, 0x201, 0x1f62, 0x345, 0x201, + 0x1f63, 0x345, 0x201, 0x1f64, 0x345, 0x201, 0x1f65, 0x345, + 0x201, 0x1f66, 0x345, 0x201, 0x1f67, 0x345, 0x201, 0x1f68, + 0x345, 0x201, 0x1f69, 0x345, 0x201, 0x1f6a, 0x345, 0x201, + 0x1f6b, 0x345, 0x201, 0x1f6c, 0x345, 0x201, 0x1f6d, 0x345, + 0x201, 0x1f6e, 0x345, 0x201, 0x1f6f, 0x345, 0x201, 0x3b1, + 0x306, 0x201, 0x3b1, 0x304, 0x201, 0x1f70, 0x345, 0x201, + 0x3b1, 0x345, 0x201, 0x3ac, 0x345, 0x201, 0x3b1, 0x342, + 0x201, 0x1fb6, 0x345, 0x201, 0x391, 0x306, 0x201, 0x391, + 0x304, 0x201, 0x391, 0x300, 0x101, 0x386, 0x201, 0x391, + 0x345, 0x210, 0x20, 0x313, 0x101, 0x3b9, 0x210, 0x20, + 0x313, 0x210, 0x20, 0x342, 0x201, 0xa8, 0x342, 0x201, + 0x1f74, 0x345, 0x201, 0x3b7, 0x345, 0x201, 0x3ae, 0x345, + 0x201, 0x3b7, 0x342, 0x201, 0x1fc6, 0x345, 0x201, 0x395, + 0x300, 0x101, 0x388, 0x201, 0x397, 0x300, 0x101, 0x389, + 0x201, 0x397, 0x345, 0x201, 0x1fbf, 0x300, 0x201, 0x1fbf, + 0x301, 0x201, 0x1fbf, 0x342, 0x201, 0x3b9, 0x306, 0x201, + 0x3b9, 0x304, 0x201, 0x3ca, 0x300, 0x101, 0x390, 0x201, + 0x3b9, 0x342, 0x201, 0x3ca, 0x342, 0x201, 0x399, 0x306, + 0x201, 0x399, 0x304, 0x201, 0x399, 0x300, 0x101, 0x38a, + 0x201, 0x1ffe, 0x300, 0x201, 0x1ffe, 0x301, 0x201, 0x1ffe, + 0x342, 0x201, 0x3c5, 0x306, 0x201, 0x3c5, 0x304, 0x201, + 0x3cb, 0x300, 0x101, 0x3b0, 0x201, 0x3c1, 0x313, 0x201, + 0x3c1, 0x314, 0x201, 0x3c5, 0x342, 0x201, 0x3cb, 0x342, + 0x201, 0x3a5, 0x306, 0x201, 0x3a5, 0x304, 0x201, 0x3a5, + 0x300, 0x101, 0x38e, 0x201, 0x3a1, 0x314, 0x201, 0xa8, + 0x300, 0x101, 0x385, 0x101, 0x60, 0x201, 0x1f7c, 0x345, + 0x201, 0x3c9, 0x345, 0x201, 0x3ce, 0x345, 0x201, 0x3c9, + 0x342, 0x201, 0x1ff6, 0x345, 0x201, 0x39f, 0x300, 0x101, + 0x38c, 0x201, 0x3a9, 0x300, 0x101, 0x38f, 0x201, 0x3a9, + 0x345, 0x101, 0xb4, 0x210, 0x20, 0x314, 0x101, 0x2002, + 0x101, 0x2003, 0x110, 0x20, 0x110, 0x20, 0x110, 0x20, + 0x110, 0x20, 0x110, 0x20, 0x103, 0x20, 0x110, 0x20, + 0x110, 0x20, 0x110, 0x20, 0x103, 0x2010, 0x210, 0x20, + 0x333, 0x110, 0x2e, 0x210, 0x2e, 0x2e, 0x310, 0x2e, + 0x2e, 0x2e, 0x103, 0x20, 0x210, 0x2032, 0x2032, 0x310, + 0x2032, 0x2032, 0x2032, 0x210, 0x2035, 0x2035, 0x310, 0x2035, + 0x2035, 0x2035, 0x210, 0x21, 0x21, 0x210, 0x20, 0x305, + 0x210, 0x3f, 0x3f, 0x210, 0x3f, 0x21, 0x210, 0x21, + 0x3f, 0x410, 0x2032, 0x2032, 0x2032, 0x2032, 0x110, 0x20, + 0x109, 0x30, 0x109, 0x69, 0x109, 0x34, 0x109, 0x35, + 0x109, 0x36, 0x109, 0x37, 0x109, 0x38, 0x109, 0x39, + 0x109, 0x2b, 0x109, 0x2212, 0x109, 0x3d, 0x109, 0x28, + 0x109, 0x29, 0x109, 0x6e, 0x10a, 0x30, 0x10a, 0x31, + 0x10a, 0x32, 0x10a, 0x33, 0x10a, 0x34, 0x10a, 0x35, + 0x10a, 0x36, 0x10a, 0x37, 0x10a, 0x38, 0x10a, 0x39, + 0x10a, 0x2b, 0x10a, 0x2212, 0x10a, 0x3d, 0x10a, 0x28, + 0x10a, 0x29, 0x10a, 0x61, 0x10a, 0x65, 0x10a, 0x6f, + 0x10a, 0x78, 0x10a, 0x259, 0x210, 0x52, 0x73, 0x310, + 0x61, 0x2f, 0x63, 0x310, 0x61, 0x2f, 0x73, 0x102, + 0x43, 0x210, 0xb0, 0x43, 0x310, 0x63, 0x2f, 0x6f, + 0x310, 0x63, 0x2f, 0x75, 0x110, 0x190, 0x210, 0xb0, + 0x46, 0x102, 0x67, 0x102, 0x48, 0x102, 0x48, 0x102, + 0x48, 0x102, 0x68, 0x102, 0x127, 0x102, 0x49, 0x102, + 0x49, 0x102, 0x4c, 0x102, 0x6c, 0x102, 0x4e, 0x210, + 0x4e, 0x6f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52, + 0x102, 0x52, 0x102, 0x52, 0x209, 0x53, 0x4d, 0x310, + 0x54, 0x45, 0x4c, 0x209, 0x54, 0x4d, 0x102, 0x5a, + 0x101, 0x3a9, 0x102, 0x5a, 0x101, 0x4b, 0x101, 0xc5, + 0x102, 0x42, 0x102, 0x43, 0x102, 0x65, 0x102, 0x45, + 0x102, 0x46, 0x102, 0x4d, 0x102, 0x6f, 0x110, 0x5d0, + 0x110, 0x5d1, 0x110, 0x5d2, 0x110, 0x5d3, 0x102, 0x69, + 0x310, 0x46, 0x41, 0x58, 0x102, 0x3c0, 0x102, 0x3b3, + 0x102, 0x393, 0x102, 0x3a0, 0x102, 0x2211, 0x102, 0x44, + 0x102, 0x64, 0x102, 0x65, 0x102, 0x69, 0x102, 0x6a, + 0x311, 0x31, 0x2044, 0x33, 0x311, 0x32, 0x2044, 0x33, + 0x311, 0x31, 0x2044, 0x35, 0x311, 0x32, 0x2044, 0x35, + 0x311, 0x33, 0x2044, 0x35, 0x311, 0x34, 0x2044, 0x35, + 0x311, 0x31, 0x2044, 0x36, 0x311, 0x35, 0x2044, 0x36, + 0x311, 0x31, 0x2044, 0x38, 0x311, 0x33, 0x2044, 0x38, + 0x311, 0x35, 0x2044, 0x38, 0x311, 0x37, 0x2044, 0x38, + 0x211, 0x31, 0x2044, 0x110, 0x49, 0x210, 0x49, 0x49, + 0x310, 0x49, 0x49, 0x49, 0x210, 0x49, 0x56, 0x110, + 0x56, 0x210, 0x56, 0x49, 0x310, 0x56, 0x49, 0x49, + 0x410, 0x56, 0x49, 0x49, 0x49, 0x210, 0x49, 0x58, + 0x110, 0x58, 0x210, 0x58, 0x49, 0x310, 0x58, 0x49, + 0x49, 0x110, 0x4c, 0x110, 0x43, 0x110, 0x44, 0x110, + 0x4d, 0x110, 0x69, 0x210, 0x69, 0x69, 0x310, 0x69, + 0x69, 0x69, 0x210, 0x69, 0x76, 0x110, 0x76, 0x210, + 0x76, 0x69, 0x310, 0x76, 0x69, 0x69, 0x410, 0x76, + 0x69, 0x69, 0x69, 0x210, 0x69, 0x78, 0x110, 0x78, + 0x210, 0x78, 0x69, 0x310, 0x78, 0x69, 0x69, 0x110, + 0x6c, 0x110, 0x63, 0x110, 0x64, 0x110, 0x6d, 0x201, + 0x2190, 0x338, 0x201, 0x2192, 0x338, 0x201, 0x2194, 0x338, + 0x201, 0x21d0, 0x338, 0x201, 0x21d4, 0x338, 0x201, 0x21d2, + 0x338, 0x201, 0x2203, 0x338, 0x201, 0x2208, 0x338, 0x201, + 0x220b, 0x338, 0x201, 0x2223, 0x338, 0x201, 0x2225, 0x338, + 0x210, 0x222b, 0x222b, 0x310, 0x222b, 0x222b, 0x222b, 0x210, + 0x222e, 0x222e, 0x310, 0x222e, 0x222e, 0x222e, 0x201, 0x223c, + 0x338, 0x201, 0x2243, 0x338, 0x201, 0x2245, 0x338, 0x201, + 0x2248, 0x338, 0x201, 0x3d, 0x338, 0x201, 0x2261, 0x338, + 0x201, 0x224d, 0x338, 0x201, 0x3c, 0x338, 0x201, 0x3e, + 0x338, 0x201, 0x2264, 0x338, 0x201, 0x2265, 0x338, 0x201, + 0x2272, 0x338, 0x201, 0x2273, 0x338, 0x201, 0x2276, 0x338, + 0x201, 0x2277, 0x338, 0x201, 0x227a, 0x338, 0x201, 0x227b, + 0x338, 0x201, 0x2282, 0x338, 0x201, 0x2283, 0x338, 0x201, + 0x2286, 0x338, 0x201, 0x2287, 0x338, 0x201, 0x22a2, 0x338, + 0x201, 0x22a8, 0x338, 0x201, 0x22a9, 0x338, 0x201, 0x22ab, + 0x338, 0x201, 0x227c, 0x338, 0x201, 0x227d, 0x338, 0x201, + 0x2291, 0x338, 0x201, 0x2292, 0x338, 0x201, 0x22b2, 0x338, + 0x201, 0x22b3, 0x338, 0x201, 0x22b4, 0x338, 0x201, 0x22b5, + 0x338, 0x101, 0x3008, 0x101, 0x3009, 0x108, 0x31, 0x108, + 0x32, 0x108, 0x33, 0x108, 0x34, 0x108, 0x35, 0x108, + 0x36, 0x108, 0x37, 0x108, 0x38, 0x108, 0x39, 0x208, + 0x31, 0x30, 0x208, 0x31, 0x31, 0x208, 0x31, 0x32, + 0x208, 0x31, 0x33, 0x208, 0x31, 0x34, 0x208, 0x31, + 0x35, 0x208, 0x31, 0x36, 0x208, 0x31, 0x37, 0x208, + 0x31, 0x38, 0x208, 0x31, 0x39, 0x208, 0x32, 0x30, + 0x310, 0x28, 0x31, 0x29, 0x310, 0x28, 0x32, 0x29, + 0x310, 0x28, 0x33, 0x29, 0x310, 0x28, 0x34, 0x29, + 0x310, 0x28, 0x35, 0x29, 0x310, 0x28, 0x36, 0x29, + 0x310, 0x28, 0x37, 0x29, 0x310, 0x28, 0x38, 0x29, + 0x310, 0x28, 0x39, 0x29, 0x410, 0x28, 0x31, 0x30, + 0x29, 0x410, 0x28, 0x31, 0x31, 0x29, 0x410, 0x28, + 0x31, 0x32, 0x29, 0x410, 0x28, 0x31, 0x33, 0x29, + 0x410, 0x28, 0x31, 0x34, 0x29, 0x410, 0x28, 0x31, + 0x35, 0x29, 0x410, 0x28, 0x31, 0x36, 0x29, 0x410, + 0x28, 0x31, 0x37, 0x29, 0x410, 0x28, 0x31, 0x38, + 0x29, 0x410, 0x28, 0x31, 0x39, 0x29, 0x410, 0x28, + 0x32, 0x30, 0x29, 0x210, 0x31, 0x2e, 0x210, 0x32, + 0x2e, 0x210, 0x33, 0x2e, 0x210, 0x34, 0x2e, 0x210, + 0x35, 0x2e, 0x210, 0x36, 0x2e, 0x210, 0x37, 0x2e, + 0x210, 0x38, 0x2e, 0x210, 0x39, 0x2e, 0x310, 0x31, + 0x30, 0x2e, 0x310, 0x31, 0x31, 0x2e, 0x310, 0x31, + 0x32, 0x2e, 0x310, 0x31, 0x33, 0x2e, 0x310, 0x31, + 0x34, 0x2e, 0x310, 0x31, 0x35, 0x2e, 0x310, 0x31, + 0x36, 0x2e, 0x310, 0x31, 0x37, 0x2e, 0x310, 0x31, + 0x38, 0x2e, 0x310, 0x31, 0x39, 0x2e, 0x310, 0x32, + 0x30, 0x2e, 0x310, 0x28, 0x61, 0x29, 0x310, 0x28, + 0x62, 0x29, 0x310, 0x28, 0x63, 0x29, 0x310, 0x28, + 0x64, 0x29, 0x310, 0x28, 0x65, 0x29, 0x310, 0x28, + 0x66, 0x29, 0x310, 0x28, 0x67, 0x29, 0x310, 0x28, + 0x68, 0x29, 0x310, 0x28, 0x69, 0x29, 0x310, 0x28, + 0x6a, 0x29, 0x310, 0x28, 0x6b, 0x29, 0x310, 0x28, + 0x6c, 0x29, 0x310, 0x28, 0x6d, 0x29, 0x310, 0x28, + 0x6e, 0x29, 0x310, 0x28, 0x6f, 0x29, 0x310, 0x28, + 0x70, 0x29, 0x310, 0x28, 0x71, 0x29, 0x310, 0x28, + 0x72, 0x29, 0x310, 0x28, 0x73, 0x29, 0x310, 0x28, + 0x74, 0x29, 0x310, 0x28, 0x75, 0x29, 0x310, 0x28, + 0x76, 0x29, 0x310, 0x28, 0x77, 0x29, 0x310, 0x28, + 0x78, 0x29, 0x310, 0x28, 0x79, 0x29, 0x310, 0x28, + 0x7a, 0x29, 0x108, 0x41, 0x108, 0x42, 0x108, 0x43, + 0x108, 0x44, 0x108, 0x45, 0x108, 0x46, 0x108, 0x47, + 0x108, 0x48, 0x108, 0x49, 0x108, 0x4a, 0x108, 0x4b, + 0x108, 0x4c, 0x108, 0x4d, 0x108, 0x4e, 0x108, 0x4f, + 0x108, 0x50, 0x108, 0x51, 0x108, 0x52, 0x108, 0x53, + 0x108, 0x54, 0x108, 0x55, 0x108, 0x56, 0x108, 0x57, + 0x108, 0x58, 0x108, 0x59, 0x108, 0x5a, 0x108, 0x61, + 0x108, 0x62, 0x108, 0x63, 0x108, 0x64, 0x108, 0x65, + 0x108, 0x66, 0x108, 0x67, 0x108, 0x68, 0x108, 0x69, + 0x108, 0x6a, 0x108, 0x6b, 0x108, 0x6c, 0x108, 0x6d, + 0x108, 0x6e, 0x108, 0x6f, 0x108, 0x70, 0x108, 0x71, + 0x108, 0x72, 0x108, 0x73, 0x108, 0x74, 0x108, 0x75, + 0x108, 0x76, 0x108, 0x77, 0x108, 0x78, 0x108, 0x79, + 0x108, 0x7a, 0x108, 0x30, 0x410, 0x222b, 0x222b, 0x222b, + 0x222b, 0x310, 0x3a, 0x3a, 0x3d, 0x210, 0x3d, 0x3d, + 0x310, 0x3d, 0x3d, 0x3d, 0x201, 0x2add, 0x338, 0x109, + 0x2d61, 0x110, 0x6bcd, 0x110, 0x9f9f, 0x110, 0x4e00, 0x110, + 0x4e28, 0x110, 0x4e36, 0x110, 0x4e3f, 0x110, 0x4e59, 0x110, + 0x4e85, 0x110, 0x4e8c, 0x110, 0x4ea0, 0x110, 0x4eba, 0x110, + 0x513f, 0x110, 0x5165, 0x110, 0x516b, 0x110, 0x5182, 0x110, + 0x5196, 0x110, 0x51ab, 0x110, 0x51e0, 0x110, 0x51f5, 0x110, + 0x5200, 0x110, 0x529b, 0x110, 0x52f9, 0x110, 0x5315, 0x110, + 0x531a, 0x110, 0x5338, 0x110, 0x5341, 0x110, 0x535c, 0x110, + 0x5369, 0x110, 0x5382, 0x110, 0x53b6, 0x110, 0x53c8, 0x110, + 0x53e3, 0x110, 0x56d7, 0x110, 0x571f, 0x110, 0x58eb, 0x110, + 0x5902, 0x110, 0x590a, 0x110, 0x5915, 0x110, 0x5927, 0x110, + 0x5973, 0x110, 0x5b50, 0x110, 0x5b80, 0x110, 0x5bf8, 0x110, + 0x5c0f, 0x110, 0x5c22, 0x110, 0x5c38, 0x110, 0x5c6e, 0x110, + 0x5c71, 0x110, 0x5ddb, 0x110, 0x5de5, 0x110, 0x5df1, 0x110, + 0x5dfe, 0x110, 0x5e72, 0x110, 0x5e7a, 0x110, 0x5e7f, 0x110, + 0x5ef4, 0x110, 0x5efe, 0x110, 0x5f0b, 0x110, 0x5f13, 0x110, + 0x5f50, 0x110, 0x5f61, 0x110, 0x5f73, 0x110, 0x5fc3, 0x110, + 0x6208, 0x110, 0x6236, 0x110, 0x624b, 0x110, 0x652f, 0x110, + 0x6534, 0x110, 0x6587, 0x110, 0x6597, 0x110, 0x65a4, 0x110, + 0x65b9, 0x110, 0x65e0, 0x110, 0x65e5, 0x110, 0x66f0, 0x110, + 0x6708, 0x110, 0x6728, 0x110, 0x6b20, 0x110, 0x6b62, 0x110, + 0x6b79, 0x110, 0x6bb3, 0x110, 0x6bcb, 0x110, 0x6bd4, 0x110, + 0x6bdb, 0x110, 0x6c0f, 0x110, 0x6c14, 0x110, 0x6c34, 0x110, + 0x706b, 0x110, 0x722a, 0x110, 0x7236, 0x110, 0x723b, 0x110, + 0x723f, 0x110, 0x7247, 0x110, 0x7259, 0x110, 0x725b, 0x110, + 0x72ac, 0x110, 0x7384, 0x110, 0x7389, 0x110, 0x74dc, 0x110, + 0x74e6, 0x110, 0x7518, 0x110, 0x751f, 0x110, 0x7528, 0x110, + 0x7530, 0x110, 0x758b, 0x110, 0x7592, 0x110, 0x7676, 0x110, + 0x767d, 0x110, 0x76ae, 0x110, 0x76bf, 0x110, 0x76ee, 0x110, + 0x77db, 0x110, 0x77e2, 0x110, 0x77f3, 0x110, 0x793a, 0x110, + 0x79b8, 0x110, 0x79be, 0x110, 0x7a74, 0x110, 0x7acb, 0x110, + 0x7af9, 0x110, 0x7c73, 0x110, 0x7cf8, 0x110, 0x7f36, 0x110, + 0x7f51, 0x110, 0x7f8a, 0x110, 0x7fbd, 0x110, 0x8001, 0x110, + 0x800c, 0x110, 0x8012, 0x110, 0x8033, 0x110, 0x807f, 0x110, + 0x8089, 0x110, 0x81e3, 0x110, 0x81ea, 0x110, 0x81f3, 0x110, + 0x81fc, 0x110, 0x820c, 0x110, 0x821b, 0x110, 0x821f, 0x110, + 0x826e, 0x110, 0x8272, 0x110, 0x8278, 0x110, 0x864d, 0x110, + 0x866b, 0x110, 0x8840, 0x110, 0x884c, 0x110, 0x8863, 0x110, + 0x897e, 0x110, 0x898b, 0x110, 0x89d2, 0x110, 0x8a00, 0x110, + 0x8c37, 0x110, 0x8c46, 0x110, 0x8c55, 0x110, 0x8c78, 0x110, + 0x8c9d, 0x110, 0x8d64, 0x110, 0x8d70, 0x110, 0x8db3, 0x110, + 0x8eab, 0x110, 0x8eca, 0x110, 0x8f9b, 0x110, 0x8fb0, 0x110, + 0x8fb5, 0x110, 0x9091, 0x110, 0x9149, 0x110, 0x91c6, 0x110, + 0x91cc, 0x110, 0x91d1, 0x110, 0x9577, 0x110, 0x9580, 0x110, + 0x961c, 0x110, 0x96b6, 0x110, 0x96b9, 0x110, 0x96e8, 0x110, + 0x9751, 0x110, 0x975e, 0x110, 0x9762, 0x110, 0x9769, 0x110, + 0x97cb, 0x110, 0x97ed, 0x110, 0x97f3, 0x110, 0x9801, 0x110, + 0x98a8, 0x110, 0x98db, 0x110, 0x98df, 0x110, 0x9996, 0x110, + 0x9999, 0x110, 0x99ac, 0x110, 0x9aa8, 0x110, 0x9ad8, 0x110, + 0x9adf, 0x110, 0x9b25, 0x110, 0x9b2f, 0x110, 0x9b32, 0x110, + 0x9b3c, 0x110, 0x9b5a, 0x110, 0x9ce5, 0x110, 0x9e75, 0x110, + 0x9e7f, 0x110, 0x9ea5, 0x110, 0x9ebb, 0x110, 0x9ec3, 0x110, + 0x9ecd, 0x110, 0x9ed1, 0x110, 0x9ef9, 0x110, 0x9efd, 0x110, + 0x9f0e, 0x110, 0x9f13, 0x110, 0x9f20, 0x110, 0x9f3b, 0x110, + 0x9f4a, 0x110, 0x9f52, 0x110, 0x9f8d, 0x110, 0x9f9c, 0x110, + 0x9fa0, 0x10c, 0x20, 0x110, 0x3012, 0x110, 0x5341, 0x110, + 0x5344, 0x110, 0x5345, 0x201, 0x304b, 0x3099, 0x201, 0x304d, + 0x3099, 0x201, 0x304f, 0x3099, 0x201, 0x3051, 0x3099, 0x201, + 0x3053, 0x3099, 0x201, 0x3055, 0x3099, 0x201, 0x3057, 0x3099, + 0x201, 0x3059, 0x3099, 0x201, 0x305b, 0x3099, 0x201, 0x305d, + 0x3099, 0x201, 0x305f, 0x3099, 0x201, 0x3061, 0x3099, 0x201, + 0x3064, 0x3099, 0x201, 0x3066, 0x3099, 0x201, 0x3068, 0x3099, + 0x201, 0x306f, 0x3099, 0x201, 0x306f, 0x309a, 0x201, 0x3072, + 0x3099, 0x201, 0x3072, 0x309a, 0x201, 0x3075, 0x3099, 0x201, + 0x3075, 0x309a, 0x201, 0x3078, 0x3099, 0x201, 0x3078, 0x309a, + 0x201, 0x307b, 0x3099, 0x201, 0x307b, 0x309a, 0x201, 0x3046, + 0x3099, 0x210, 0x20, 0x3099, 0x210, 0x20, 0x309a, 0x201, + 0x309d, 0x3099, 0x20b, 0x3088, 0x308a, 0x201, 0x30ab, 0x3099, + 0x201, 0x30ad, 0x3099, 0x201, 0x30af, 0x3099, 0x201, 0x30b1, + 0x3099, 0x201, 0x30b3, 0x3099, 0x201, 0x30b5, 0x3099, 0x201, + 0x30b7, 0x3099, 0x201, 0x30b9, 0x3099, 0x201, 0x30bb, 0x3099, + 0x201, 0x30bd, 0x3099, 0x201, 0x30bf, 0x3099, 0x201, 0x30c1, + 0x3099, 0x201, 0x30c4, 0x3099, 0x201, 0x30c6, 0x3099, 0x201, + 0x30c8, 0x3099, 0x201, 0x30cf, 0x3099, 0x201, 0x30cf, 0x309a, + 0x201, 0x30d2, 0x3099, 0x201, 0x30d2, 0x309a, 0x201, 0x30d5, + 0x3099, 0x201, 0x30d5, 0x309a, 0x201, 0x30d8, 0x3099, 0x201, + 0x30d8, 0x309a, 0x201, 0x30db, 0x3099, 0x201, 0x30db, 0x309a, + 0x201, 0x30a6, 0x3099, 0x201, 0x30ef, 0x3099, 0x201, 0x30f0, + 0x3099, 0x201, 0x30f1, 0x3099, 0x201, 0x30f2, 0x3099, 0x201, + 0x30fd, 0x3099, 0x20b, 0x30b3, 0x30c8, 0x110, 0x1100, 0x110, + 0x1101, 0x110, 0x11aa, 0x110, 0x1102, 0x110, 0x11ac, 0x110, + 0x11ad, 0x110, 0x1103, 0x110, 0x1104, 0x110, 0x1105, 0x110, + 0x11b0, 0x110, 0x11b1, 0x110, 0x11b2, 0x110, 0x11b3, 0x110, + 0x11b4, 0x110, 0x11b5, 0x110, 0x111a, 0x110, 0x1106, 0x110, + 0x1107, 0x110, 0x1108, 0x110, 0x1121, 0x110, 0x1109, 0x110, + 0x110a, 0x110, 0x110b, 0x110, 0x110c, 0x110, 0x110d, 0x110, + 0x110e, 0x110, 0x110f, 0x110, 0x1110, 0x110, 0x1111, 0x110, + 0x1112, 0x110, 0x1161, 0x110, 0x1162, 0x110, 0x1163, 0x110, + 0x1164, 0x110, 0x1165, 0x110, 0x1166, 0x110, 0x1167, 0x110, + 0x1168, 0x110, 0x1169, 0x110, 0x116a, 0x110, 0x116b, 0x110, + 0x116c, 0x110, 0x116d, 0x110, 0x116e, 0x110, 0x116f, 0x110, + 0x1170, 0x110, 0x1171, 0x110, 0x1172, 0x110, 0x1173, 0x110, + 0x1174, 0x110, 0x1175, 0x110, 0x1160, 0x110, 0x1114, 0x110, + 0x1115, 0x110, 0x11c7, 0x110, 0x11c8, 0x110, 0x11cc, 0x110, + 0x11ce, 0x110, 0x11d3, 0x110, 0x11d7, 0x110, 0x11d9, 0x110, + 0x111c, 0x110, 0x11dd, 0x110, 0x11df, 0x110, 0x111d, 0x110, + 0x111e, 0x110, 0x1120, 0x110, 0x1122, 0x110, 0x1123, 0x110, + 0x1127, 0x110, 0x1129, 0x110, 0x112b, 0x110, 0x112c, 0x110, + 0x112d, 0x110, 0x112e, 0x110, 0x112f, 0x110, 0x1132, 0x110, + 0x1136, 0x110, 0x1140, 0x110, 0x1147, 0x110, 0x114c, 0x110, + 0x11f1, 0x110, 0x11f2, 0x110, 0x1157, 0x110, 0x1158, 0x110, + 0x1159, 0x110, 0x1184, 0x110, 0x1185, 0x110, 0x1188, 0x110, + 0x1191, 0x110, 0x1192, 0x110, 0x1194, 0x110, 0x119e, 0x110, + 0x11a1, 0x109, 0x4e00, 0x109, 0x4e8c, 0x109, 0x4e09, 0x109, + 0x56db, 0x109, 0x4e0a, 0x109, 0x4e2d, 0x109, 0x4e0b, 0x109, + 0x7532, 0x109, 0x4e59, 0x109, 0x4e19, 0x109, 0x4e01, 0x109, + 0x5929, 0x109, 0x5730, 0x109, 0x4eba, 0x310, 0x28, 0x1100, + 0x29, 0x310, 0x28, 0x1102, 0x29, 0x310, 0x28, 0x1103, + 0x29, 0x310, 0x28, 0x1105, 0x29, 0x310, 0x28, 0x1106, + 0x29, 0x310, 0x28, 0x1107, 0x29, 0x310, 0x28, 0x1109, + 0x29, 0x310, 0x28, 0x110b, 0x29, 0x310, 0x28, 0x110c, + 0x29, 0x310, 0x28, 0x110e, 0x29, 0x310, 0x28, 0x110f, + 0x29, 0x310, 0x28, 0x1110, 0x29, 0x310, 0x28, 0x1111, + 0x29, 0x310, 0x28, 0x1112, 0x29, 0x410, 0x28, 0x1100, + 0x1161, 0x29, 0x410, 0x28, 0x1102, 0x1161, 0x29, 0x410, + 0x28, 0x1103, 0x1161, 0x29, 0x410, 0x28, 0x1105, 0x1161, + 0x29, 0x410, 0x28, 0x1106, 0x1161, 0x29, 0x410, 0x28, + 0x1107, 0x1161, 0x29, 0x410, 0x28, 0x1109, 0x1161, 0x29, + 0x410, 0x28, 0x110b, 0x1161, 0x29, 0x410, 0x28, 0x110c, + 0x1161, 0x29, 0x410, 0x28, 0x110e, 0x1161, 0x29, 0x410, + 0x28, 0x110f, 0x1161, 0x29, 0x410, 0x28, 0x1110, 0x1161, + 0x29, 0x410, 0x28, 0x1111, 0x1161, 0x29, 0x410, 0x28, + 0x1112, 0x1161, 0x29, 0x410, 0x28, 0x110c, 0x116e, 0x29, + 0x710, 0x28, 0x110b, 0x1169, 0x110c, 0x1165, 0x11ab, 0x29, + 0x610, 0x28, 0x110b, 0x1169, 0x1112, 0x116e, 0x29, 0x310, + 0x28, 0x4e00, 0x29, 0x310, 0x28, 0x4e8c, 0x29, 0x310, + 0x28, 0x4e09, 0x29, 0x310, 0x28, 0x56db, 0x29, 0x310, + 0x28, 0x4e94, 0x29, 0x310, 0x28, 0x516d, 0x29, 0x310, + 0x28, 0x4e03, 0x29, 0x310, 0x28, 0x516b, 0x29, 0x310, + 0x28, 0x4e5d, 0x29, 0x310, 0x28, 0x5341, 0x29, 0x310, + 0x28, 0x6708, 0x29, 0x310, 0x28, 0x706b, 0x29, 0x310, + 0x28, 0x6c34, 0x29, 0x310, 0x28, 0x6728, 0x29, 0x310, + 0x28, 0x91d1, 0x29, 0x310, 0x28, 0x571f, 0x29, 0x310, + 0x28, 0x65e5, 0x29, 0x310, 0x28, 0x682a, 0x29, 0x310, + 0x28, 0x6709, 0x29, 0x310, 0x28, 0x793e, 0x29, 0x310, + 0x28, 0x540d, 0x29, 0x310, 0x28, 0x7279, 0x29, 0x310, + 0x28, 0x8ca1, 0x29, 0x310, 0x28, 0x795d, 0x29, 0x310, + 0x28, 0x52b4, 0x29, 0x310, 0x28, 0x4ee3, 0x29, 0x310, + 0x28, 0x547c, 0x29, 0x310, 0x28, 0x5b66, 0x29, 0x310, + 0x28, 0x76e3, 0x29, 0x310, 0x28, 0x4f01, 0x29, 0x310, + 0x28, 0x8cc7, 0x29, 0x310, 0x28, 0x5354, 0x29, 0x310, + 0x28, 0x796d, 0x29, 0x310, 0x28, 0x4f11, 0x29, 0x310, + 0x28, 0x81ea, 0x29, 0x310, 0x28, 0x81f3, 0x29, 0x30f, + 0x50, 0x54, 0x45, 0x208, 0x32, 0x31, 0x208, 0x32, + 0x32, 0x208, 0x32, 0x33, 0x208, 0x32, 0x34, 0x208, + 0x32, 0x35, 0x208, 0x32, 0x36, 0x208, 0x32, 0x37, + 0x208, 0x32, 0x38, 0x208, 0x32, 0x39, 0x208, 0x33, + 0x30, 0x208, 0x33, 0x31, 0x208, 0x33, 0x32, 0x208, + 0x33, 0x33, 0x208, 0x33, 0x34, 0x208, 0x33, 0x35, + 0x108, 0x1100, 0x108, 0x1102, 0x108, 0x1103, 0x108, 0x1105, + 0x108, 0x1106, 0x108, 0x1107, 0x108, 0x1109, 0x108, 0x110b, + 0x108, 0x110c, 0x108, 0x110e, 0x108, 0x110f, 0x108, 0x1110, + 0x108, 0x1111, 0x108, 0x1112, 0x208, 0x1100, 0x1161, 0x208, + 0x1102, 0x1161, 0x208, 0x1103, 0x1161, 0x208, 0x1105, 0x1161, + 0x208, 0x1106, 0x1161, 0x208, 0x1107, 0x1161, 0x208, 0x1109, + 0x1161, 0x208, 0x110b, 0x1161, 0x208, 0x110c, 0x1161, 0x208, + 0x110e, 0x1161, 0x208, 0x110f, 0x1161, 0x208, 0x1110, 0x1161, + 0x208, 0x1111, 0x1161, 0x208, 0x1112, 0x1161, 0x508, 0x110e, + 0x1161, 0x11b7, 0x1100, 0x1169, 0x408, 0x110c, 0x116e, 0x110b, + 0x1174, 0x208, 0x110b, 0x116e, 0x108, 0x4e00, 0x108, 0x4e8c, + 0x108, 0x4e09, 0x108, 0x56db, 0x108, 0x4e94, 0x108, 0x516d, + 0x108, 0x4e03, 0x108, 0x516b, 0x108, 0x4e5d, 0x108, 0x5341, + 0x108, 0x6708, 0x108, 0x706b, 0x108, 0x6c34, 0x108, 0x6728, + 0x108, 0x91d1, 0x108, 0x571f, 0x108, 0x65e5, 0x108, 0x682a, + 0x108, 0x6709, 0x108, 0x793e, 0x108, 0x540d, 0x108, 0x7279, + 0x108, 0x8ca1, 0x108, 0x795d, 0x108, 0x52b4, 0x108, 0x79d8, + 0x108, 0x7537, 0x108, 0x5973, 0x108, 0x9069, 0x108, 0x512a, + 0x108, 0x5370, 0x108, 0x6ce8, 0x108, 0x9805, 0x108, 0x4f11, + 0x108, 0x5199, 0x108, 0x6b63, 0x108, 0x4e0a, 0x108, 0x4e2d, + 0x108, 0x4e0b, 0x108, 0x5de6, 0x108, 0x53f3, 0x108, 0x533b, + 0x108, 0x5b97, 0x108, 0x5b66, 0x108, 0x76e3, 0x108, 0x4f01, + 0x108, 0x8cc7, 0x108, 0x5354, 0x108, 0x591c, 0x208, 0x33, + 0x36, 0x208, 0x33, 0x37, 0x208, 0x33, 0x38, 0x208, + 0x33, 0x39, 0x208, 0x34, 0x30, 0x208, 0x34, 0x31, + 0x208, 0x34, 0x32, 0x208, 0x34, 0x33, 0x208, 0x34, + 0x34, 0x208, 0x34, 0x35, 0x208, 0x34, 0x36, 0x208, + 0x34, 0x37, 0x208, 0x34, 0x38, 0x208, 0x34, 0x39, + 0x208, 0x35, 0x30, 0x210, 0x31, 0x6708, 0x210, 0x32, + 0x6708, 0x210, 0x33, 0x6708, 0x210, 0x34, 0x6708, 0x210, + 0x35, 0x6708, 0x210, 0x36, 0x6708, 0x210, 0x37, 0x6708, + 0x210, 0x38, 0x6708, 0x210, 0x39, 0x6708, 0x310, 0x31, + 0x30, 0x6708, 0x310, 0x31, 0x31, 0x6708, 0x310, 0x31, + 0x32, 0x6708, 0x20f, 0x48, 0x67, 0x30f, 0x65, 0x72, + 0x67, 0x20f, 0x65, 0x56, 0x30f, 0x4c, 0x54, 0x44, + 0x108, 0x30a2, 0x108, 0x30a4, 0x108, 0x30a6, 0x108, 0x30a8, + 0x108, 0x30aa, 0x108, 0x30ab, 0x108, 0x30ad, 0x108, 0x30af, + 0x108, 0x30b1, 0x108, 0x30b3, 0x108, 0x30b5, 0x108, 0x30b7, + 0x108, 0x30b9, 0x108, 0x30bb, 0x108, 0x30bd, 0x108, 0x30bf, + 0x108, 0x30c1, 0x108, 0x30c4, 0x108, 0x30c6, 0x108, 0x30c8, + 0x108, 0x30ca, 0x108, 0x30cb, 0x108, 0x30cc, 0x108, 0x30cd, + 0x108, 0x30ce, 0x108, 0x30cf, 0x108, 0x30d2, 0x108, 0x30d5, + 0x108, 0x30d8, 0x108, 0x30db, 0x108, 0x30de, 0x108, 0x30df, + 0x108, 0x30e0, 0x108, 0x30e1, 0x108, 0x30e2, 0x108, 0x30e4, + 0x108, 0x30e6, 0x108, 0x30e8, 0x108, 0x30e9, 0x108, 0x30ea, + 0x108, 0x30eb, 0x108, 0x30ec, 0x108, 0x30ed, 0x108, 0x30ef, + 0x108, 0x30f0, 0x108, 0x30f1, 0x108, 0x30f2, 0x40f, 0x30a2, + 0x30d1, 0x30fc, 0x30c8, 0x40f, 0x30a2, 0x30eb, 0x30d5, 0x30a1, + 0x40f, 0x30a2, 0x30f3, 0x30da, 0x30a2, 0x30f, 0x30a2, 0x30fc, + 0x30eb, 0x40f, 0x30a4, 0x30cb, 0x30f3, 0x30b0, 0x30f, 0x30a4, + 0x30f3, 0x30c1, 0x30f, 0x30a6, 0x30a9, 0x30f3, 0x50f, 0x30a8, + 0x30b9, 0x30af, 0x30fc, 0x30c9, 0x40f, 0x30a8, 0x30fc, 0x30ab, + 0x30fc, 0x30f, 0x30aa, 0x30f3, 0x30b9, 0x30f, 0x30aa, 0x30fc, + 0x30e0, 0x30f, 0x30ab, 0x30a4, 0x30ea, 0x40f, 0x30ab, 0x30e9, + 0x30c3, 0x30c8, 0x40f, 0x30ab, 0x30ed, 0x30ea, 0x30fc, 0x30f, + 0x30ac, 0x30ed, 0x30f3, 0x30f, 0x30ac, 0x30f3, 0x30de, 0x20f, + 0x30ae, 0x30ac, 0x30f, 0x30ae, 0x30cb, 0x30fc, 0x40f, 0x30ad, + 0x30e5, 0x30ea, 0x30fc, 0x40f, 0x30ae, 0x30eb, 0x30c0, 0x30fc, + 0x20f, 0x30ad, 0x30ed, 0x50f, 0x30ad, 0x30ed, 0x30b0, 0x30e9, + 0x30e0, 0x60f, 0x30ad, 0x30ed, 0x30e1, 0x30fc, 0x30c8, 0x30eb, + 0x50f, 0x30ad, 0x30ed, 0x30ef, 0x30c3, 0x30c8, 0x30f, 0x30b0, + 0x30e9, 0x30e0, 0x50f, 0x30b0, 0x30e9, 0x30e0, 0x30c8, 0x30f3, + 0x50f, 0x30af, 0x30eb, 0x30bc, 0x30a4, 0x30ed, 0x40f, 0x30af, + 0x30ed, 0x30fc, 0x30cd, 0x30f, 0x30b1, 0x30fc, 0x30b9, 0x30f, + 0x30b3, 0x30eb, 0x30ca, 0x30f, 0x30b3, 0x30fc, 0x30dd, 0x40f, + 0x30b5, 0x30a4, 0x30af, 0x30eb, 0x50f, 0x30b5, 0x30f3, 0x30c1, + 0x30fc, 0x30e0, 0x40f, 0x30b7, 0x30ea, 0x30f3, 0x30b0, 0x30f, + 0x30bb, 0x30f3, 0x30c1, 0x30f, 0x30bb, 0x30f3, 0x30c8, 0x30f, + 0x30c0, 0x30fc, 0x30b9, 0x20f, 0x30c7, 0x30b7, 0x20f, 0x30c9, + 0x30eb, 0x20f, 0x30c8, 0x30f3, 0x20f, 0x30ca, 0x30ce, 0x30f, + 0x30ce, 0x30c3, 0x30c8, 0x30f, 0x30cf, 0x30a4, 0x30c4, 0x50f, + 0x30d1, 0x30fc, 0x30bb, 0x30f3, 0x30c8, 0x30f, 0x30d1, 0x30fc, + 0x30c4, 0x40f, 0x30d0, 0x30fc, 0x30ec, 0x30eb, 0x50f, 0x30d4, + 0x30a2, 0x30b9, 0x30c8, 0x30eb, 0x30f, 0x30d4, 0x30af, 0x30eb, + 0x20f, 0x30d4, 0x30b3, 0x20f, 0x30d3, 0x30eb, 0x50f, 0x30d5, + 0x30a1, 0x30e9, 0x30c3, 0x30c9, 0x40f, 0x30d5, 0x30a3, 0x30fc, + 0x30c8, 0x50f, 0x30d6, 0x30c3, 0x30b7, 0x30a7, 0x30eb, 0x30f, + 0x30d5, 0x30e9, 0x30f3, 0x50f, 0x30d8, 0x30af, 0x30bf, 0x30fc, + 0x30eb, 0x20f, 0x30da, 0x30bd, 0x30f, 0x30da, 0x30cb, 0x30d2, + 0x30f, 0x30d8, 0x30eb, 0x30c4, 0x30f, 0x30da, 0x30f3, 0x30b9, + 0x30f, 0x30da, 0x30fc, 0x30b8, 0x30f, 0x30d9, 0x30fc, 0x30bf, + 0x40f, 0x30dd, 0x30a4, 0x30f3, 0x30c8, 0x30f, 0x30dc, 0x30eb, + 0x30c8, 0x20f, 0x30db, 0x30f3, 0x30f, 0x30dd, 0x30f3, 0x30c9, + 0x30f, 0x30db, 0x30fc, 0x30eb, 0x30f, 0x30db, 0x30fc, 0x30f3, + 0x40f, 0x30de, 0x30a4, 0x30af, 0x30ed, 0x30f, 0x30de, 0x30a4, + 0x30eb, 0x30f, 0x30de, 0x30c3, 0x30cf, 0x30f, 0x30de, 0x30eb, + 0x30af, 0x50f, 0x30de, 0x30f3, 0x30b7, 0x30e7, 0x30f3, 0x40f, + 0x30df, 0x30af, 0x30ed, 0x30f3, 0x20f, 0x30df, 0x30ea, 0x50f, + 0x30df, 0x30ea, 0x30d0, 0x30fc, 0x30eb, 0x20f, 0x30e1, 0x30ac, + 0x40f, 0x30e1, 0x30ac, 0x30c8, 0x30f3, 0x40f, 0x30e1, 0x30fc, + 0x30c8, 0x30eb, 0x30f, 0x30e4, 0x30fc, 0x30c9, 0x30f, 0x30e4, + 0x30fc, 0x30eb, 0x30f, 0x30e6, 0x30a2, 0x30f3, 0x40f, 0x30ea, + 0x30c3, 0x30c8, 0x30eb, 0x20f, 0x30ea, 0x30e9, 0x30f, 0x30eb, + 0x30d4, 0x30fc, 0x40f, 0x30eb, 0x30fc, 0x30d6, 0x30eb, 0x20f, + 0x30ec, 0x30e0, 0x50f, 0x30ec, 0x30f3, 0x30c8, 0x30b2, 0x30f3, + 0x30f, 0x30ef, 0x30c3, 0x30c8, 0x210, 0x30, 0x70b9, 0x210, + 0x31, 0x70b9, 0x210, 0x32, 0x70b9, 0x210, 0x33, 0x70b9, + 0x210, 0x34, 0x70b9, 0x210, 0x35, 0x70b9, 0x210, 0x36, + 0x70b9, 0x210, 0x37, 0x70b9, 0x210, 0x38, 0x70b9, 0x210, + 0x39, 0x70b9, 0x310, 0x31, 0x30, 0x70b9, 0x310, 0x31, + 0x31, 0x70b9, 0x310, 0x31, 0x32, 0x70b9, 0x310, 0x31, + 0x33, 0x70b9, 0x310, 0x31, 0x34, 0x70b9, 0x310, 0x31, + 0x35, 0x70b9, 0x310, 0x31, 0x36, 0x70b9, 0x310, 0x31, + 0x37, 0x70b9, 0x310, 0x31, 0x38, 0x70b9, 0x310, 0x31, + 0x39, 0x70b9, 0x310, 0x32, 0x30, 0x70b9, 0x310, 0x32, + 0x31, 0x70b9, 0x310, 0x32, 0x32, 0x70b9, 0x310, 0x32, + 0x33, 0x70b9, 0x310, 0x32, 0x34, 0x70b9, 0x30f, 0x68, + 0x50, 0x61, 0x20f, 0x64, 0x61, 0x20f, 0x41, 0x55, + 0x30f, 0x62, 0x61, 0x72, 0x20f, 0x6f, 0x56, 0x20f, + 0x70, 0x63, 0x20f, 0x64, 0x6d, 0x30f, 0x64, 0x6d, + 0xb2, 0x30f, 0x64, 0x6d, 0xb3, 0x20f, 0x49, 0x55, + 0x20f, 0x5e73, 0x6210, 0x20f, 0x662d, 0x548c, 0x20f, 0x5927, + 0x6b63, 0x20f, 0x660e, 0x6cbb, 0x40f, 0x682a, 0x5f0f, 0x4f1a, + 0x793e, 0x20f, 0x70, 0x41, 0x20f, 0x6e, 0x41, 0x20f, + 0x3bc, 0x41, 0x20f, 0x6d, 0x41, 0x20f, 0x6b, 0x41, + 0x20f, 0x4b, 0x42, 0x20f, 0x4d, 0x42, 0x20f, 0x47, + 0x42, 0x30f, 0x63, 0x61, 0x6c, 0x40f, 0x6b, 0x63, + 0x61, 0x6c, 0x20f, 0x70, 0x46, 0x20f, 0x6e, 0x46, + 0x20f, 0x3bc, 0x46, 0x20f, 0x3bc, 0x67, 0x20f, 0x6d, + 0x67, 0x20f, 0x6b, 0x67, 0x20f, 0x48, 0x7a, 0x30f, + 0x6b, 0x48, 0x7a, 0x30f, 0x4d, 0x48, 0x7a, 0x30f, + 0x47, 0x48, 0x7a, 0x30f, 0x54, 0x48, 0x7a, 0x20f, + 0x3bc, 0x2113, 0x20f, 0x6d, 0x2113, 0x20f, 0x64, 0x2113, + 0x20f, 0x6b, 0x2113, 0x20f, 0x66, 0x6d, 0x20f, 0x6e, + 0x6d, 0x20f, 0x3bc, 0x6d, 0x20f, 0x6d, 0x6d, 0x20f, + 0x63, 0x6d, 0x20f, 0x6b, 0x6d, 0x30f, 0x6d, 0x6d, + 0xb2, 0x30f, 0x63, 0x6d, 0xb2, 0x20f, 0x6d, 0xb2, + 0x30f, 0x6b, 0x6d, 0xb2, 0x30f, 0x6d, 0x6d, 0xb3, + 0x30f, 0x63, 0x6d, 0xb3, 0x20f, 0x6d, 0xb3, 0x30f, + 0x6b, 0x6d, 0xb3, 0x30f, 0x6d, 0x2215, 0x73, 0x40f, + 0x6d, 0x2215, 0x73, 0xb2, 0x20f, 0x50, 0x61, 0x30f, + 0x6b, 0x50, 0x61, 0x30f, 0x4d, 0x50, 0x61, 0x30f, + 0x47, 0x50, 0x61, 0x30f, 0x72, 0x61, 0x64, 0x50f, + 0x72, 0x61, 0x64, 0x2215, 0x73, 0x60f, 0x72, 0x61, + 0x64, 0x2215, 0x73, 0xb2, 0x20f, 0x70, 0x73, 0x20f, + 0x6e, 0x73, 0x20f, 0x3bc, 0x73, 0x20f, 0x6d, 0x73, + 0x20f, 0x70, 0x56, 0x20f, 0x6e, 0x56, 0x20f, 0x3bc, + 0x56, 0x20f, 0x6d, 0x56, 0x20f, 0x6b, 0x56, 0x20f, + 0x4d, 0x56, 0x20f, 0x70, 0x57, 0x20f, 0x6e, 0x57, + 0x20f, 0x3bc, 0x57, 0x20f, 0x6d, 0x57, 0x20f, 0x6b, + 0x57, 0x20f, 0x4d, 0x57, 0x20f, 0x6b, 0x3a9, 0x20f, + 0x4d, 0x3a9, 0x40f, 0x61, 0x2e, 0x6d, 0x2e, 0x20f, + 0x42, 0x71, 0x20f, 0x63, 0x63, 0x20f, 0x63, 0x64, + 0x40f, 0x43, 0x2215, 0x6b, 0x67, 0x30f, 0x43, 0x6f, + 0x2e, 0x20f, 0x64, 0x42, 0x20f, 0x47, 0x79, 0x20f, + 0x68, 0x61, 0x20f, 0x48, 0x50, 0x20f, 0x69, 0x6e, + 0x20f, 0x4b, 0x4b, 0x20f, 0x4b, 0x4d, 0x20f, 0x6b, + 0x74, 0x20f, 0x6c, 0x6d, 0x20f, 0x6c, 0x6e, 0x30f, + 0x6c, 0x6f, 0x67, 0x20f, 0x6c, 0x78, 0x20f, 0x6d, + 0x62, 0x30f, 0x6d, 0x69, 0x6c, 0x30f, 0x6d, 0x6f, + 0x6c, 0x20f, 0x50, 0x48, 0x40f, 0x70, 0x2e, 0x6d, + 0x2e, 0x30f, 0x50, 0x50, 0x4d, 0x20f, 0x50, 0x52, + 0x20f, 0x73, 0x72, 0x20f, 0x53, 0x76, 0x20f, 0x57, + 0x62, 0x30f, 0x56, 0x2215, 0x6d, 0x30f, 0x41, 0x2215, + 0x6d, 0x210, 0x31, 0x65e5, 0x210, 0x32, 0x65e5, 0x210, + 0x33, 0x65e5, 0x210, 0x34, 0x65e5, 0x210, 0x35, 0x65e5, + 0x210, 0x36, 0x65e5, 0x210, 0x37, 0x65e5, 0x210, 0x38, + 0x65e5, 0x210, 0x39, 0x65e5, 0x310, 0x31, 0x30, 0x65e5, + 0x310, 0x31, 0x31, 0x65e5, 0x310, 0x31, 0x32, 0x65e5, + 0x310, 0x31, 0x33, 0x65e5, 0x310, 0x31, 0x34, 0x65e5, + 0x310, 0x31, 0x35, 0x65e5, 0x310, 0x31, 0x36, 0x65e5, + 0x310, 0x31, 0x37, 0x65e5, 0x310, 0x31, 0x38, 0x65e5, + 0x310, 0x31, 0x39, 0x65e5, 0x310, 0x32, 0x30, 0x65e5, + 0x310, 0x32, 0x31, 0x65e5, 0x310, 0x32, 0x32, 0x65e5, + 0x310, 0x32, 0x33, 0x65e5, 0x310, 0x32, 0x34, 0x65e5, + 0x310, 0x32, 0x35, 0x65e5, 0x310, 0x32, 0x36, 0x65e5, + 0x310, 0x32, 0x37, 0x65e5, 0x310, 0x32, 0x38, 0x65e5, + 0x310, 0x32, 0x39, 0x65e5, 0x310, 0x33, 0x30, 0x65e5, + 0x310, 0x33, 0x31, 0x65e5, 0x30f, 0x67, 0x61, 0x6c, + 0x101, 0x8c48, 0x101, 0x66f4, 0x101, 0x8eca, 0x101, 0x8cc8, + 0x101, 0x6ed1, 0x101, 0x4e32, 0x101, 0x53e5, 0x101, 0x9f9c, + 0x101, 0x9f9c, 0x101, 0x5951, 0x101, 0x91d1, 0x101, 0x5587, + 0x101, 0x5948, 0x101, 0x61f6, 0x101, 0x7669, 0x101, 0x7f85, + 0x101, 0x863f, 0x101, 0x87ba, 0x101, 0x88f8, 0x101, 0x908f, + 0x101, 0x6a02, 0x101, 0x6d1b, 0x101, 0x70d9, 0x101, 0x73de, + 0x101, 0x843d, 0x101, 0x916a, 0x101, 0x99f1, 0x101, 0x4e82, + 0x101, 0x5375, 0x101, 0x6b04, 0x101, 0x721b, 0x101, 0x862d, + 0x101, 0x9e1e, 0x101, 0x5d50, 0x101, 0x6feb, 0x101, 0x85cd, + 0x101, 0x8964, 0x101, 0x62c9, 0x101, 0x81d8, 0x101, 0x881f, + 0x101, 0x5eca, 0x101, 0x6717, 0x101, 0x6d6a, 0x101, 0x72fc, + 0x101, 0x90ce, 0x101, 0x4f86, 0x101, 0x51b7, 0x101, 0x52de, + 0x101, 0x64c4, 0x101, 0x6ad3, 0x101, 0x7210, 0x101, 0x76e7, + 0x101, 0x8001, 0x101, 0x8606, 0x101, 0x865c, 0x101, 0x8def, + 0x101, 0x9732, 0x101, 0x9b6f, 0x101, 0x9dfa, 0x101, 0x788c, + 0x101, 0x797f, 0x101, 0x7da0, 0x101, 0x83c9, 0x101, 0x9304, + 0x101, 0x9e7f, 0x101, 0x8ad6, 0x101, 0x58df, 0x101, 0x5f04, + 0x101, 0x7c60, 0x101, 0x807e, 0x101, 0x7262, 0x101, 0x78ca, + 0x101, 0x8cc2, 0x101, 0x96f7, 0x101, 0x58d8, 0x101, 0x5c62, + 0x101, 0x6a13, 0x101, 0x6dda, 0x101, 0x6f0f, 0x101, 0x7d2f, + 0x101, 0x7e37, 0x101, 0x964b, 0x101, 0x52d2, 0x101, 0x808b, + 0x101, 0x51dc, 0x101, 0x51cc, 0x101, 0x7a1c, 0x101, 0x7dbe, + 0x101, 0x83f1, 0x101, 0x9675, 0x101, 0x8b80, 0x101, 0x62cf, + 0x101, 0x6a02, 0x101, 0x8afe, 0x101, 0x4e39, 0x101, 0x5be7, + 0x101, 0x6012, 0x101, 0x7387, 0x101, 0x7570, 0x101, 0x5317, + 0x101, 0x78fb, 0x101, 0x4fbf, 0x101, 0x5fa9, 0x101, 0x4e0d, + 0x101, 0x6ccc, 0x101, 0x6578, 0x101, 0x7d22, 0x101, 0x53c3, + 0x101, 0x585e, 0x101, 0x7701, 0x101, 0x8449, 0x101, 0x8aaa, + 0x101, 0x6bba, 0x101, 0x8fb0, 0x101, 0x6c88, 0x101, 0x62fe, + 0x101, 0x82e5, 0x101, 0x63a0, 0x101, 0x7565, 0x101, 0x4eae, + 0x101, 0x5169, 0x101, 0x51c9, 0x101, 0x6881, 0x101, 0x7ce7, + 0x101, 0x826f, 0x101, 0x8ad2, 0x101, 0x91cf, 0x101, 0x52f5, + 0x101, 0x5442, 0x101, 0x5973, 0x101, 0x5eec, 0x101, 0x65c5, + 0x101, 0x6ffe, 0x101, 0x792a, 0x101, 0x95ad, 0x101, 0x9a6a, + 0x101, 0x9e97, 0x101, 0x9ece, 0x101, 0x529b, 0x101, 0x66c6, + 0x101, 0x6b77, 0x101, 0x8f62, 0x101, 0x5e74, 0x101, 0x6190, + 0x101, 0x6200, 0x101, 0x649a, 0x101, 0x6f23, 0x101, 0x7149, + 0x101, 0x7489, 0x101, 0x79ca, 0x101, 0x7df4, 0x101, 0x806f, + 0x101, 0x8f26, 0x101, 0x84ee, 0x101, 0x9023, 0x101, 0x934a, + 0x101, 0x5217, 0x101, 0x52a3, 0x101, 0x54bd, 0x101, 0x70c8, + 0x101, 0x88c2, 0x101, 0x8aaa, 0x101, 0x5ec9, 0x101, 0x5ff5, + 0x101, 0x637b, 0x101, 0x6bae, 0x101, 0x7c3e, 0x101, 0x7375, + 0x101, 0x4ee4, 0x101, 0x56f9, 0x101, 0x5be7, 0x101, 0x5dba, + 0x101, 0x601c, 0x101, 0x73b2, 0x101, 0x7469, 0x101, 0x7f9a, + 0x101, 0x8046, 0x101, 0x9234, 0x101, 0x96f6, 0x101, 0x9748, + 0x101, 0x9818, 0x101, 0x4f8b, 0x101, 0x79ae, 0x101, 0x91b4, + 0x101, 0x96b8, 0x101, 0x60e1, 0x101, 0x4e86, 0x101, 0x50da, + 0x101, 0x5bee, 0x101, 0x5c3f, 0x101, 0x6599, 0x101, 0x6a02, + 0x101, 0x71ce, 0x101, 0x7642, 0x101, 0x84fc, 0x101, 0x907c, + 0x101, 0x9f8d, 0x101, 0x6688, 0x101, 0x962e, 0x101, 0x5289, + 0x101, 0x677b, 0x101, 0x67f3, 0x101, 0x6d41, 0x101, 0x6e9c, + 0x101, 0x7409, 0x101, 0x7559, 0x101, 0x786b, 0x101, 0x7d10, + 0x101, 0x985e, 0x101, 0x516d, 0x101, 0x622e, 0x101, 0x9678, + 0x101, 0x502b, 0x101, 0x5d19, 0x101, 0x6dea, 0x101, 0x8f2a, + 0x101, 0x5f8b, 0x101, 0x6144, 0x101, 0x6817, 0x101, 0x7387, + 0x101, 0x9686, 0x101, 0x5229, 0x101, 0x540f, 0x101, 0x5c65, + 0x101, 0x6613, 0x101, 0x674e, 0x101, 0x68a8, 0x101, 0x6ce5, + 0x101, 0x7406, 0x101, 0x75e2, 0x101, 0x7f79, 0x101, 0x88cf, + 0x101, 0x88e1, 0x101, 0x91cc, 0x101, 0x96e2, 0x101, 0x533f, + 0x101, 0x6eba, 0x101, 0x541d, 0x101, 0x71d0, 0x101, 0x7498, + 0x101, 0x85fa, 0x101, 0x96a3, 0x101, 0x9c57, 0x101, 0x9e9f, + 0x101, 0x6797, 0x101, 0x6dcb, 0x101, 0x81e8, 0x101, 0x7acb, + 0x101, 0x7b20, 0x101, 0x7c92, 0x101, 0x72c0, 0x101, 0x7099, + 0x101, 0x8b58, 0x101, 0x4ec0, 0x101, 0x8336, 0x101, 0x523a, + 0x101, 0x5207, 0x101, 0x5ea6, 0x101, 0x62d3, 0x101, 0x7cd6, + 0x101, 0x5b85, 0x101, 0x6d1e, 0x101, 0x66b4, 0x101, 0x8f3b, + 0x101, 0x884c, 0x101, 0x964d, 0x101, 0x898b, 0x101, 0x5ed3, + 0x101, 0x5140, 0x101, 0x55c0, 0x101, 0x585a, 0x101, 0x6674, + 0x101, 0x51de, 0x101, 0x732a, 0x101, 0x76ca, 0x101, 0x793c, + 0x101, 0x795e, 0x101, 0x7965, 0x101, 0x798f, 0x101, 0x9756, + 0x101, 0x7cbe, 0x101, 0x7fbd, 0x101, 0x8612, 0x101, 0x8af8, + 0x101, 0x9038, 0x101, 0x90fd, 0x101, 0x98ef, 0x101, 0x98fc, + 0x101, 0x9928, 0x101, 0x9db4, 0x101, 0x4fae, 0x101, 0x50e7, + 0x101, 0x514d, 0x101, 0x52c9, 0x101, 0x52e4, 0x101, 0x5351, + 0x101, 0x559d, 0x101, 0x5606, 0x101, 0x5668, 0x101, 0x5840, + 0x101, 0x58a8, 0x101, 0x5c64, 0x101, 0x5c6e, 0x101, 0x6094, + 0x101, 0x6168, 0x101, 0x618e, 0x101, 0x61f2, 0x101, 0x654f, + 0x101, 0x65e2, 0x101, 0x6691, 0x101, 0x6885, 0x101, 0x6d77, + 0x101, 0x6e1a, 0x101, 0x6f22, 0x101, 0x716e, 0x101, 0x722b, + 0x101, 0x7422, 0x101, 0x7891, 0x101, 0x793e, 0x101, 0x7949, + 0x101, 0x7948, 0x101, 0x7950, 0x101, 0x7956, 0x101, 0x795d, + 0x101, 0x798d, 0x101, 0x798e, 0x101, 0x7a40, 0x101, 0x7a81, + 0x101, 0x7bc0, 0x101, 0x7df4, 0x101, 0x7e09, 0x101, 0x7e41, + 0x101, 0x7f72, 0x101, 0x8005, 0x101, 0x81ed, 0x101, 0x8279, + 0x101, 0x8279, 0x101, 0x8457, 0x101, 0x8910, 0x101, 0x8996, + 0x101, 0x8b01, 0x101, 0x8b39, 0x101, 0x8cd3, 0x101, 0x8d08, + 0x101, 0x8fb6, 0x101, 0x9038, 0x101, 0x96e3, 0x101, 0x97ff, + 0x101, 0x983b, 0x101, 0x4e26, 0x101, 0x51b5, 0x101, 0x5168, + 0x101, 0x4f80, 0x101, 0x5145, 0x101, 0x5180, 0x101, 0x52c7, + 0x101, 0x52fa, 0x101, 0x559d, 0x101, 0x5555, 0x101, 0x5599, + 0x101, 0x55e2, 0x101, 0x585a, 0x101, 0x58b3, 0x101, 0x5944, + 0x101, 0x5954, 0x101, 0x5a62, 0x101, 0x5b28, 0x101, 0x5ed2, + 0x101, 0x5ed9, 0x101, 0x5f69, 0x101, 0x5fad, 0x101, 0x60d8, + 0x101, 0x614e, 0x101, 0x6108, 0x101, 0x618e, 0x101, 0x6160, + 0x101, 0x61f2, 0x101, 0x6234, 0x101, 0x63c4, 0x101, 0x641c, + 0x101, 0x6452, 0x101, 0x6556, 0x101, 0x6674, 0x101, 0x6717, + 0x101, 0x671b, 0x101, 0x6756, 0x101, 0x6b79, 0x101, 0x6bba, + 0x101, 0x6d41, 0x101, 0x6edb, 0x101, 0x6ecb, 0x101, 0x6f22, + 0x101, 0x701e, 0x101, 0x716e, 0x101, 0x77a7, 0x101, 0x7235, + 0x101, 0x72af, 0x101, 0x732a, 0x101, 0x7471, 0x101, 0x7506, + 0x101, 0x753b, 0x101, 0x761d, 0x101, 0x761f, 0x101, 0x76ca, + 0x101, 0x76db, 0x101, 0x76f4, 0x101, 0x774a, 0x101, 0x7740, + 0x101, 0x78cc, 0x101, 0x7ab1, 0x101, 0x7bc0, 0x101, 0x7c7b, + 0x101, 0x7d5b, 0x101, 0x7df4, 0x101, 0x7f3e, 0x101, 0x8005, + 0x101, 0x8352, 0x101, 0x83ef, 0x101, 0x8779, 0x101, 0x8941, + 0x101, 0x8986, 0x101, 0x8996, 0x101, 0x8abf, 0x101, 0x8af8, + 0x101, 0x8acb, 0x101, 0x8b01, 0x101, 0x8afe, 0x101, 0x8aed, + 0x101, 0x8b39, 0x101, 0x8b8a, 0x101, 0x8d08, 0x101, 0x8f38, + 0x101, 0x9072, 0x101, 0x9199, 0x101, 0x9276, 0x101, 0x967c, + 0x101, 0x96e3, 0x101, 0x9756, 0x101, 0x97db, 0x101, 0x97ff, + 0x101, 0x980b, 0x101, 0x983b, 0x101, 0x9b12, 0x101, 0x9f9c, + 0x201, 0xd84a, 0xdc4a, 0x201, 0xd84a, 0xdc44, 0x201, 0xd84c, + 0xdfd5, 0x101, 0x3b9d, 0x101, 0x4018, 0x101, 0x4039, 0x201, + 0xd854, 0xde49, 0x201, 0xd857, 0xdcd0, 0x201, 0xd85f, 0xded3, + 0x101, 0x9f43, 0x101, 0x9f8e, 0x210, 0x66, 0x66, 0x210, + 0x66, 0x69, 0x210, 0x66, 0x6c, 0x310, 0x66, 0x66, + 0x69, 0x310, 0x66, 0x66, 0x6c, 0x210, 0x17f, 0x74, + 0x210, 0x73, 0x74, 0x210, 0x574, 0x576, 0x210, 0x574, + 0x565, 0x210, 0x574, 0x56b, 0x210, 0x57e, 0x576, 0x210, + 0x574, 0x56d, 0x201, 0x5d9, 0x5b4, 0x201, 0x5f2, 0x5b7, + 0x102, 0x5e2, 0x102, 0x5d0, 0x102, 0x5d3, 0x102, 0x5d4, + 0x102, 0x5db, 0x102, 0x5dc, 0x102, 0x5dd, 0x102, 0x5e8, + 0x102, 0x5ea, 0x102, 0x2b, 0x201, 0x5e9, 0x5c1, 0x201, + 0x5e9, 0x5c2, 0x201, 0xfb49, 0x5c1, 0x201, 0xfb49, 0x5c2, + 0x201, 0x5d0, 0x5b7, 0x201, 0x5d0, 0x5b8, 0x201, 0x5d0, + 0x5bc, 0x201, 0x5d1, 0x5bc, 0x201, 0x5d2, 0x5bc, 0x201, + 0x5d3, 0x5bc, 0x201, 0x5d4, 0x5bc, 0x201, 0x5d5, 0x5bc, + 0x201, 0x5d6, 0x5bc, 0x201, 0x5d8, 0x5bc, 0x201, 0x5d9, + 0x5bc, 0x201, 0x5da, 0x5bc, 0x201, 0x5db, 0x5bc, 0x201, + 0x5dc, 0x5bc, 0x201, 0x5de, 0x5bc, 0x201, 0x5e0, 0x5bc, + 0x201, 0x5e1, 0x5bc, 0x201, 0x5e3, 0x5bc, 0x201, 0x5e4, + 0x5bc, 0x201, 0x5e6, 0x5bc, 0x201, 0x5e7, 0x5bc, 0x201, + 0x5e8, 0x5bc, 0x201, 0x5e9, 0x5bc, 0x201, 0x5ea, 0x5bc, + 0x201, 0x5d5, 0x5b9, 0x201, 0x5d1, 0x5bf, 0x201, 0x5db, + 0x5bf, 0x201, 0x5e4, 0x5bf, 0x210, 0x5d0, 0x5dc, 0x107, + 0x671, 0x106, 0x671, 0x107, 0x67b, 0x106, 0x67b, 0x104, + 0x67b, 0x105, 0x67b, 0x107, 0x67e, 0x106, 0x67e, 0x104, + 0x67e, 0x105, 0x67e, 0x107, 0x680, 0x106, 0x680, 0x104, + 0x680, 0x105, 0x680, 0x107, 0x67a, 0x106, 0x67a, 0x104, + 0x67a, 0x105, 0x67a, 0x107, 0x67f, 0x106, 0x67f, 0x104, + 0x67f, 0x105, 0x67f, 0x107, 0x679, 0x106, 0x679, 0x104, + 0x679, 0x105, 0x679, 0x107, 0x6a4, 0x106, 0x6a4, 0x104, + 0x6a4, 0x105, 0x6a4, 0x107, 0x6a6, 0x106, 0x6a6, 0x104, + 0x6a6, 0x105, 0x6a6, 0x107, 0x684, 0x106, 0x684, 0x104, + 0x684, 0x105, 0x684, 0x107, 0x683, 0x106, 0x683, 0x104, + 0x683, 0x105, 0x683, 0x107, 0x686, 0x106, 0x686, 0x104, + 0x686, 0x105, 0x686, 0x107, 0x687, 0x106, 0x687, 0x104, + 0x687, 0x105, 0x687, 0x107, 0x68d, 0x106, 0x68d, 0x107, + 0x68c, 0x106, 0x68c, 0x107, 0x68e, 0x106, 0x68e, 0x107, + 0x688, 0x106, 0x688, 0x107, 0x698, 0x106, 0x698, 0x107, + 0x691, 0x106, 0x691, 0x107, 0x6a9, 0x106, 0x6a9, 0x104, + 0x6a9, 0x105, 0x6a9, 0x107, 0x6af, 0x106, 0x6af, 0x104, + 0x6af, 0x105, 0x6af, 0x107, 0x6b3, 0x106, 0x6b3, 0x104, + 0x6b3, 0x105, 0x6b3, 0x107, 0x6b1, 0x106, 0x6b1, 0x104, + 0x6b1, 0x105, 0x6b1, 0x107, 0x6ba, 0x106, 0x6ba, 0x107, + 0x6bb, 0x106, 0x6bb, 0x104, 0x6bb, 0x105, 0x6bb, 0x107, + 0x6c0, 0x106, 0x6c0, 0x107, 0x6c1, 0x106, 0x6c1, 0x104, + 0x6c1, 0x105, 0x6c1, 0x107, 0x6be, 0x106, 0x6be, 0x104, + 0x6be, 0x105, 0x6be, 0x107, 0x6d2, 0x106, 0x6d2, 0x107, + 0x6d3, 0x106, 0x6d3, 0x107, 0x6ad, 0x106, 0x6ad, 0x104, + 0x6ad, 0x105, 0x6ad, 0x107, 0x6c7, 0x106, 0x6c7, 0x107, + 0x6c6, 0x106, 0x6c6, 0x107, 0x6c8, 0x106, 0x6c8, 0x107, + 0x677, 0x107, 0x6cb, 0x106, 0x6cb, 0x107, 0x6c5, 0x106, + 0x6c5, 0x107, 0x6c9, 0x106, 0x6c9, 0x107, 0x6d0, 0x106, + 0x6d0, 0x104, 0x6d0, 0x105, 0x6d0, 0x104, 0x649, 0x105, + 0x649, 0x207, 0x626, 0x627, 0x206, 0x626, 0x627, 0x207, + 0x626, 0x6d5, 0x206, 0x626, 0x6d5, 0x207, 0x626, 0x648, + 0x206, 0x626, 0x648, 0x207, 0x626, 0x6c7, 0x206, 0x626, + 0x6c7, 0x207, 0x626, 0x6c6, 0x206, 0x626, 0x6c6, 0x207, + 0x626, 0x6c8, 0x206, 0x626, 0x6c8, 0x207, 0x626, 0x6d0, + 0x206, 0x626, 0x6d0, 0x204, 0x626, 0x6d0, 0x207, 0x626, + 0x649, 0x206, 0x626, 0x649, 0x204, 0x626, 0x649, 0x107, + 0x6cc, 0x106, 0x6cc, 0x104, 0x6cc, 0x105, 0x6cc, 0x207, + 0x626, 0x62c, 0x207, 0x626, 0x62d, 0x207, 0x626, 0x645, + 0x207, 0x626, 0x649, 0x207, 0x626, 0x64a, 0x207, 0x628, + 0x62c, 0x207, 0x628, 0x62d, 0x207, 0x628, 0x62e, 0x207, + 0x628, 0x645, 0x207, 0x628, 0x649, 0x207, 0x628, 0x64a, + 0x207, 0x62a, 0x62c, 0x207, 0x62a, 0x62d, 0x207, 0x62a, + 0x62e, 0x207, 0x62a, 0x645, 0x207, 0x62a, 0x649, 0x207, + 0x62a, 0x64a, 0x207, 0x62b, 0x62c, 0x207, 0x62b, 0x645, + 0x207, 0x62b, 0x649, 0x207, 0x62b, 0x64a, 0x207, 0x62c, + 0x62d, 0x207, 0x62c, 0x645, 0x207, 0x62d, 0x62c, 0x207, + 0x62d, 0x645, 0x207, 0x62e, 0x62c, 0x207, 0x62e, 0x62d, + 0x207, 0x62e, 0x645, 0x207, 0x633, 0x62c, 0x207, 0x633, + 0x62d, 0x207, 0x633, 0x62e, 0x207, 0x633, 0x645, 0x207, + 0x635, 0x62d, 0x207, 0x635, 0x645, 0x207, 0x636, 0x62c, + 0x207, 0x636, 0x62d, 0x207, 0x636, 0x62e, 0x207, 0x636, + 0x645, 0x207, 0x637, 0x62d, 0x207, 0x637, 0x645, 0x207, + 0x638, 0x645, 0x207, 0x639, 0x62c, 0x207, 0x639, 0x645, + 0x207, 0x63a, 0x62c, 0x207, 0x63a, 0x645, 0x207, 0x641, + 0x62c, 0x207, 0x641, 0x62d, 0x207, 0x641, 0x62e, 0x207, + 0x641, 0x645, 0x207, 0x641, 0x649, 0x207, 0x641, 0x64a, + 0x207, 0x642, 0x62d, 0x207, 0x642, 0x645, 0x207, 0x642, + 0x649, 0x207, 0x642, 0x64a, 0x207, 0x643, 0x627, 0x207, + 0x643, 0x62c, 0x207, 0x643, 0x62d, 0x207, 0x643, 0x62e, + 0x207, 0x643, 0x644, 0x207, 0x643, 0x645, 0x207, 0x643, + 0x649, 0x207, 0x643, 0x64a, 0x207, 0x644, 0x62c, 0x207, + 0x644, 0x62d, 0x207, 0x644, 0x62e, 0x207, 0x644, 0x645, + 0x207, 0x644, 0x649, 0x207, 0x644, 0x64a, 0x207, 0x645, + 0x62c, 0x207, 0x645, 0x62d, 0x207, 0x645, 0x62e, 0x207, + 0x645, 0x645, 0x207, 0x645, 0x649, 0x207, 0x645, 0x64a, + 0x207, 0x646, 0x62c, 0x207, 0x646, 0x62d, 0x207, 0x646, + 0x62e, 0x207, 0x646, 0x645, 0x207, 0x646, 0x649, 0x207, + 0x646, 0x64a, 0x207, 0x647, 0x62c, 0x207, 0x647, 0x645, + 0x207, 0x647, 0x649, 0x207, 0x647, 0x64a, 0x207, 0x64a, + 0x62c, 0x207, 0x64a, 0x62d, 0x207, 0x64a, 0x62e, 0x207, + 0x64a, 0x645, 0x207, 0x64a, 0x649, 0x207, 0x64a, 0x64a, + 0x207, 0x630, 0x670, 0x207, 0x631, 0x670, 0x207, 0x649, + 0x670, 0x307, 0x20, 0x64c, 0x651, 0x307, 0x20, 0x64d, + 0x651, 0x307, 0x20, 0x64e, 0x651, 0x307, 0x20, 0x64f, + 0x651, 0x307, 0x20, 0x650, 0x651, 0x307, 0x20, 0x651, + 0x670, 0x206, 0x626, 0x631, 0x206, 0x626, 0x632, 0x206, + 0x626, 0x645, 0x206, 0x626, 0x646, 0x206, 0x626, 0x649, + 0x206, 0x626, 0x64a, 0x206, 0x628, 0x631, 0x206, 0x628, + 0x632, 0x206, 0x628, 0x645, 0x206, 0x628, 0x646, 0x206, + 0x628, 0x649, 0x206, 0x628, 0x64a, 0x206, 0x62a, 0x631, + 0x206, 0x62a, 0x632, 0x206, 0x62a, 0x645, 0x206, 0x62a, + 0x646, 0x206, 0x62a, 0x649, 0x206, 0x62a, 0x64a, 0x206, + 0x62b, 0x631, 0x206, 0x62b, 0x632, 0x206, 0x62b, 0x645, + 0x206, 0x62b, 0x646, 0x206, 0x62b, 0x649, 0x206, 0x62b, + 0x64a, 0x206, 0x641, 0x649, 0x206, 0x641, 0x64a, 0x206, + 0x642, 0x649, 0x206, 0x642, 0x64a, 0x206, 0x643, 0x627, + 0x206, 0x643, 0x644, 0x206, 0x643, 0x645, 0x206, 0x643, + 0x649, 0x206, 0x643, 0x64a, 0x206, 0x644, 0x645, 0x206, + 0x644, 0x649, 0x206, 0x644, 0x64a, 0x206, 0x645, 0x627, + 0x206, 0x645, 0x645, 0x206, 0x646, 0x631, 0x206, 0x646, + 0x632, 0x206, 0x646, 0x645, 0x206, 0x646, 0x646, 0x206, + 0x646, 0x649, 0x206, 0x646, 0x64a, 0x206, 0x649, 0x670, + 0x206, 0x64a, 0x631, 0x206, 0x64a, 0x632, 0x206, 0x64a, + 0x645, 0x206, 0x64a, 0x646, 0x206, 0x64a, 0x649, 0x206, + 0x64a, 0x64a, 0x204, 0x626, 0x62c, 0x204, 0x626, 0x62d, + 0x204, 0x626, 0x62e, 0x204, 0x626, 0x645, 0x204, 0x626, + 0x647, 0x204, 0x628, 0x62c, 0x204, 0x628, 0x62d, 0x204, + 0x628, 0x62e, 0x204, 0x628, 0x645, 0x204, 0x628, 0x647, + 0x204, 0x62a, 0x62c, 0x204, 0x62a, 0x62d, 0x204, 0x62a, + 0x62e, 0x204, 0x62a, 0x645, 0x204, 0x62a, 0x647, 0x204, + 0x62b, 0x645, 0x204, 0x62c, 0x62d, 0x204, 0x62c, 0x645, + 0x204, 0x62d, 0x62c, 0x204, 0x62d, 0x645, 0x204, 0x62e, + 0x62c, 0x204, 0x62e, 0x645, 0x204, 0x633, 0x62c, 0x204, + 0x633, 0x62d, 0x204, 0x633, 0x62e, 0x204, 0x633, 0x645, + 0x204, 0x635, 0x62d, 0x204, 0x635, 0x62e, 0x204, 0x635, + 0x645, 0x204, 0x636, 0x62c, 0x204, 0x636, 0x62d, 0x204, + 0x636, 0x62e, 0x204, 0x636, 0x645, 0x204, 0x637, 0x62d, + 0x204, 0x638, 0x645, 0x204, 0x639, 0x62c, 0x204, 0x639, + 0x645, 0x204, 0x63a, 0x62c, 0x204, 0x63a, 0x645, 0x204, + 0x641, 0x62c, 0x204, 0x641, 0x62d, 0x204, 0x641, 0x62e, + 0x204, 0x641, 0x645, 0x204, 0x642, 0x62d, 0x204, 0x642, + 0x645, 0x204, 0x643, 0x62c, 0x204, 0x643, 0x62d, 0x204, + 0x643, 0x62e, 0x204, 0x643, 0x644, 0x204, 0x643, 0x645, + 0x204, 0x644, 0x62c, 0x204, 0x644, 0x62d, 0x204, 0x644, + 0x62e, 0x204, 0x644, 0x645, 0x204, 0x644, 0x647, 0x204, + 0x645, 0x62c, 0x204, 0x645, 0x62d, 0x204, 0x645, 0x62e, + 0x204, 0x645, 0x645, 0x204, 0x646, 0x62c, 0x204, 0x646, + 0x62d, 0x204, 0x646, 0x62e, 0x204, 0x646, 0x645, 0x204, + 0x646, 0x647, 0x204, 0x647, 0x62c, 0x204, 0x647, 0x645, + 0x204, 0x647, 0x670, 0x204, 0x64a, 0x62c, 0x204, 0x64a, + 0x62d, 0x204, 0x64a, 0x62e, 0x204, 0x64a, 0x645, 0x204, + 0x64a, 0x647, 0x205, 0x626, 0x645, 0x205, 0x626, 0x647, + 0x205, 0x628, 0x645, 0x205, 0x628, 0x647, 0x205, 0x62a, + 0x645, 0x205, 0x62a, 0x647, 0x205, 0x62b, 0x645, 0x205, + 0x62b, 0x647, 0x205, 0x633, 0x645, 0x205, 0x633, 0x647, + 0x205, 0x634, 0x645, 0x205, 0x634, 0x647, 0x205, 0x643, + 0x644, 0x205, 0x643, 0x645, 0x205, 0x644, 0x645, 0x205, + 0x646, 0x645, 0x205, 0x646, 0x647, 0x205, 0x64a, 0x645, + 0x205, 0x64a, 0x647, 0x305, 0x640, 0x64e, 0x651, 0x305, + 0x640, 0x64f, 0x651, 0x305, 0x640, 0x650, 0x651, 0x207, + 0x637, 0x649, 0x207, 0x637, 0x64a, 0x207, 0x639, 0x649, + 0x207, 0x639, 0x64a, 0x207, 0x63a, 0x649, 0x207, 0x63a, + 0x64a, 0x207, 0x633, 0x649, 0x207, 0x633, 0x64a, 0x207, + 0x634, 0x649, 0x207, 0x634, 0x64a, 0x207, 0x62d, 0x649, + 0x207, 0x62d, 0x64a, 0x207, 0x62c, 0x649, 0x207, 0x62c, + 0x64a, 0x207, 0x62e, 0x649, 0x207, 0x62e, 0x64a, 0x207, + 0x635, 0x649, 0x207, 0x635, 0x64a, 0x207, 0x636, 0x649, + 0x207, 0x636, 0x64a, 0x207, 0x634, 0x62c, 0x207, 0x634, + 0x62d, 0x207, 0x634, 0x62e, 0x207, 0x634, 0x645, 0x207, + 0x634, 0x631, 0x207, 0x633, 0x631, 0x207, 0x635, 0x631, + 0x207, 0x636, 0x631, 0x206, 0x637, 0x649, 0x206, 0x637, + 0x64a, 0x206, 0x639, 0x649, 0x206, 0x639, 0x64a, 0x206, + 0x63a, 0x649, 0x206, 0x63a, 0x64a, 0x206, 0x633, 0x649, + 0x206, 0x633, 0x64a, 0x206, 0x634, 0x649, 0x206, 0x634, + 0x64a, 0x206, 0x62d, 0x649, 0x206, 0x62d, 0x64a, 0x206, + 0x62c, 0x649, 0x206, 0x62c, 0x64a, 0x206, 0x62e, 0x649, + 0x206, 0x62e, 0x64a, 0x206, 0x635, 0x649, 0x206, 0x635, + 0x64a, 0x206, 0x636, 0x649, 0x206, 0x636, 0x64a, 0x206, + 0x634, 0x62c, 0x206, 0x634, 0x62d, 0x206, 0x634, 0x62e, + 0x206, 0x634, 0x645, 0x206, 0x634, 0x631, 0x206, 0x633, + 0x631, 0x206, 0x635, 0x631, 0x206, 0x636, 0x631, 0x204, + 0x634, 0x62c, 0x204, 0x634, 0x62d, 0x204, 0x634, 0x62e, + 0x204, 0x634, 0x645, 0x204, 0x633, 0x647, 0x204, 0x634, + 0x647, 0x204, 0x637, 0x645, 0x205, 0x633, 0x62c, 0x205, + 0x633, 0x62d, 0x205, 0x633, 0x62e, 0x205, 0x634, 0x62c, + 0x205, 0x634, 0x62d, 0x205, 0x634, 0x62e, 0x205, 0x637, + 0x645, 0x205, 0x638, 0x645, 0x206, 0x627, 0x64b, 0x207, + 0x627, 0x64b, 0x304, 0x62a, 0x62c, 0x645, 0x306, 0x62a, + 0x62d, 0x62c, 0x304, 0x62a, 0x62d, 0x62c, 0x304, 0x62a, + 0x62d, 0x645, 0x304, 0x62a, 0x62e, 0x645, 0x304, 0x62a, + 0x645, 0x62c, 0x304, 0x62a, 0x645, 0x62d, 0x304, 0x62a, + 0x645, 0x62e, 0x306, 0x62c, 0x645, 0x62d, 0x304, 0x62c, + 0x645, 0x62d, 0x306, 0x62d, 0x645, 0x64a, 0x306, 0x62d, + 0x645, 0x649, 0x304, 0x633, 0x62d, 0x62c, 0x304, 0x633, + 0x62c, 0x62d, 0x306, 0x633, 0x62c, 0x649, 0x306, 0x633, + 0x645, 0x62d, 0x304, 0x633, 0x645, 0x62d, 0x304, 0x633, + 0x645, 0x62c, 0x306, 0x633, 0x645, 0x645, 0x304, 0x633, + 0x645, 0x645, 0x306, 0x635, 0x62d, 0x62d, 0x304, 0x635, + 0x62d, 0x62d, 0x306, 0x635, 0x645, 0x645, 0x306, 0x634, + 0x62d, 0x645, 0x304, 0x634, 0x62d, 0x645, 0x306, 0x634, + 0x62c, 0x64a, 0x306, 0x634, 0x645, 0x62e, 0x304, 0x634, + 0x645, 0x62e, 0x306, 0x634, 0x645, 0x645, 0x304, 0x634, + 0x645, 0x645, 0x306, 0x636, 0x62d, 0x649, 0x306, 0x636, + 0x62e, 0x645, 0x304, 0x636, 0x62e, 0x645, 0x306, 0x637, + 0x645, 0x62d, 0x304, 0x637, 0x645, 0x62d, 0x304, 0x637, + 0x645, 0x645, 0x306, 0x637, 0x645, 0x64a, 0x306, 0x639, + 0x62c, 0x645, 0x306, 0x639, 0x645, 0x645, 0x304, 0x639, + 0x645, 0x645, 0x306, 0x639, 0x645, 0x649, 0x306, 0x63a, + 0x645, 0x645, 0x306, 0x63a, 0x645, 0x64a, 0x306, 0x63a, + 0x645, 0x649, 0x306, 0x641, 0x62e, 0x645, 0x304, 0x641, + 0x62e, 0x645, 0x306, 0x642, 0x645, 0x62d, 0x306, 0x642, + 0x645, 0x645, 0x306, 0x644, 0x62d, 0x645, 0x306, 0x644, + 0x62d, 0x64a, 0x306, 0x644, 0x62d, 0x649, 0x304, 0x644, + 0x62c, 0x62c, 0x306, 0x644, 0x62c, 0x62c, 0x306, 0x644, + 0x62e, 0x645, 0x304, 0x644, 0x62e, 0x645, 0x306, 0x644, + 0x645, 0x62d, 0x304, 0x644, 0x645, 0x62d, 0x304, 0x645, + 0x62d, 0x62c, 0x304, 0x645, 0x62d, 0x645, 0x306, 0x645, + 0x62d, 0x64a, 0x304, 0x645, 0x62c, 0x62d, 0x304, 0x645, + 0x62c, 0x645, 0x304, 0x645, 0x62e, 0x62c, 0x304, 0x645, + 0x62e, 0x645, 0x304, 0x645, 0x62c, 0x62e, 0x304, 0x647, + 0x645, 0x62c, 0x304, 0x647, 0x645, 0x645, 0x304, 0x646, + 0x62d, 0x645, 0x306, 0x646, 0x62d, 0x649, 0x306, 0x646, + 0x62c, 0x645, 0x304, 0x646, 0x62c, 0x645, 0x306, 0x646, + 0x62c, 0x649, 0x306, 0x646, 0x645, 0x64a, 0x306, 0x646, + 0x645, 0x649, 0x306, 0x64a, 0x645, 0x645, 0x304, 0x64a, + 0x645, 0x645, 0x306, 0x628, 0x62e, 0x64a, 0x306, 0x62a, + 0x62c, 0x64a, 0x306, 0x62a, 0x62c, 0x649, 0x306, 0x62a, + 0x62e, 0x64a, 0x306, 0x62a, 0x62e, 0x649, 0x306, 0x62a, + 0x645, 0x64a, 0x306, 0x62a, 0x645, 0x649, 0x306, 0x62c, + 0x645, 0x64a, 0x306, 0x62c, 0x62d, 0x649, 0x306, 0x62c, + 0x645, 0x649, 0x306, 0x633, 0x62e, 0x649, 0x306, 0x635, + 0x62d, 0x64a, 0x306, 0x634, 0x62d, 0x64a, 0x306, 0x636, + 0x62d, 0x64a, 0x306, 0x644, 0x62c, 0x64a, 0x306, 0x644, + 0x645, 0x64a, 0x306, 0x64a, 0x62d, 0x64a, 0x306, 0x64a, + 0x62c, 0x64a, 0x306, 0x64a, 0x645, 0x64a, 0x306, 0x645, + 0x645, 0x64a, 0x306, 0x642, 0x645, 0x64a, 0x306, 0x646, + 0x62d, 0x64a, 0x304, 0x642, 0x645, 0x62d, 0x304, 0x644, + 0x62d, 0x645, 0x306, 0x639, 0x645, 0x64a, 0x306, 0x643, + 0x645, 0x64a, 0x304, 0x646, 0x62c, 0x62d, 0x306, 0x645, + 0x62e, 0x64a, 0x304, 0x644, 0x62c, 0x645, 0x306, 0x643, + 0x645, 0x645, 0x306, 0x644, 0x62c, 0x645, 0x306, 0x646, + 0x62c, 0x62d, 0x306, 0x62c, 0x62d, 0x64a, 0x306, 0x62d, + 0x62c, 0x64a, 0x306, 0x645, 0x62c, 0x64a, 0x306, 0x641, + 0x645, 0x64a, 0x306, 0x628, 0x62d, 0x64a, 0x304, 0x643, + 0x645, 0x645, 0x304, 0x639, 0x62c, 0x645, 0x304, 0x635, + 0x645, 0x645, 0x306, 0x633, 0x62e, 0x64a, 0x306, 0x646, + 0x62c, 0x64a, 0x307, 0x635, 0x644, 0x6d2, 0x307, 0x642, + 0x644, 0x6d2, 0x407, 0x627, 0x644, 0x644, 0x647, 0x407, + 0x627, 0x643, 0x628, 0x631, 0x407, 0x645, 0x62d, 0x645, + 0x62f, 0x407, 0x635, 0x644, 0x639, 0x645, 0x407, 0x631, + 0x633, 0x648, 0x644, 0x407, 0x639, 0x644, 0x64a, 0x647, + 0x407, 0x648, 0x633, 0x644, 0x645, 0x307, 0x635, 0x644, + 0x649, 0x1207, 0x635, 0x644, 0x649, 0x20, 0x627, 0x644, + 0x644, 0x647, 0x20, 0x639, 0x644, 0x64a, 0x647, 0x20, + 0x648, 0x633, 0x644, 0x645, 0x807, 0x62c, 0x644, 0x20, + 0x62c, 0x644, 0x627, 0x644, 0x647, 0x407, 0x631, 0x6cc, + 0x627, 0x644, 0x10b, 0x2c, 0x10b, 0x3001, 0x10b, 0x3002, + 0x10b, 0x3a, 0x10b, 0x3b, 0x10b, 0x21, 0x10b, 0x3f, + 0x10b, 0x3016, 0x10b, 0x3017, 0x10b, 0x2026, 0x10b, 0x2025, + 0x10b, 0x2014, 0x10b, 0x2013, 0x10b, 0x5f, 0x10b, 0x5f, + 0x10b, 0x28, 0x10b, 0x29, 0x10b, 0x7b, 0x10b, 0x7d, + 0x10b, 0x3014, 0x10b, 0x3015, 0x10b, 0x3010, 0x10b, 0x3011, + 0x10b, 0x300a, 0x10b, 0x300b, 0x10b, 0x3008, 0x10b, 0x3009, + 0x10b, 0x300c, 0x10b, 0x300d, 0x10b, 0x300e, 0x10b, 0x300f, + 0x10b, 0x5b, 0x10b, 0x5d, 0x110, 0x203e, 0x110, 0x203e, + 0x110, 0x203e, 0x110, 0x203e, 0x110, 0x5f, 0x110, 0x5f, + 0x110, 0x5f, 0x10e, 0x2c, 0x10e, 0x3001, 0x10e, 0x2e, + 0x10e, 0x3b, 0x10e, 0x3a, 0x10e, 0x3f, 0x10e, 0x21, + 0x10e, 0x2014, 0x10e, 0x28, 0x10e, 0x29, 0x10e, 0x7b, + 0x10e, 0x7d, 0x10e, 0x3014, 0x10e, 0x3015, 0x10e, 0x23, + 0x10e, 0x26, 0x10e, 0x2a, 0x10e, 0x2b, 0x10e, 0x2d, + 0x10e, 0x3c, 0x10e, 0x3e, 0x10e, 0x3d, 0x10e, 0x5c, + 0x10e, 0x24, 0x10e, 0x25, 0x10e, 0x40, 0x207, 0x20, + 0x64b, 0x205, 0x640, 0x64b, 0x207, 0x20, 0x64c, 0x207, + 0x20, 0x64d, 0x207, 0x20, 0x64e, 0x205, 0x640, 0x64e, + 0x207, 0x20, 0x64f, 0x205, 0x640, 0x64f, 0x207, 0x20, + 0x650, 0x205, 0x640, 0x650, 0x207, 0x20, 0x651, 0x205, + 0x640, 0x651, 0x207, 0x20, 0x652, 0x205, 0x640, 0x652, + 0x107, 0x621, 0x107, 0x622, 0x106, 0x622, 0x107, 0x623, + 0x106, 0x623, 0x107, 0x624, 0x106, 0x624, 0x107, 0x625, + 0x106, 0x625, 0x107, 0x626, 0x106, 0x626, 0x104, 0x626, + 0x105, 0x626, 0x107, 0x627, 0x106, 0x627, 0x107, 0x628, + 0x106, 0x628, 0x104, 0x628, 0x105, 0x628, 0x107, 0x629, + 0x106, 0x629, 0x107, 0x62a, 0x106, 0x62a, 0x104, 0x62a, + 0x105, 0x62a, 0x107, 0x62b, 0x106, 0x62b, 0x104, 0x62b, + 0x105, 0x62b, 0x107, 0x62c, 0x106, 0x62c, 0x104, 0x62c, + 0x105, 0x62c, 0x107, 0x62d, 0x106, 0x62d, 0x104, 0x62d, + 0x105, 0x62d, 0x107, 0x62e, 0x106, 0x62e, 0x104, 0x62e, + 0x105, 0x62e, 0x107, 0x62f, 0x106, 0x62f, 0x107, 0x630, + 0x106, 0x630, 0x107, 0x631, 0x106, 0x631, 0x107, 0x632, + 0x106, 0x632, 0x107, 0x633, 0x106, 0x633, 0x104, 0x633, + 0x105, 0x633, 0x107, 0x634, 0x106, 0x634, 0x104, 0x634, + 0x105, 0x634, 0x107, 0x635, 0x106, 0x635, 0x104, 0x635, + 0x105, 0x635, 0x107, 0x636, 0x106, 0x636, 0x104, 0x636, + 0x105, 0x636, 0x107, 0x637, 0x106, 0x637, 0x104, 0x637, + 0x105, 0x637, 0x107, 0x638, 0x106, 0x638, 0x104, 0x638, + 0x105, 0x638, 0x107, 0x639, 0x106, 0x639, 0x104, 0x639, + 0x105, 0x639, 0x107, 0x63a, 0x106, 0x63a, 0x104, 0x63a, + 0x105, 0x63a, 0x107, 0x641, 0x106, 0x641, 0x104, 0x641, + 0x105, 0x641, 0x107, 0x642, 0x106, 0x642, 0x104, 0x642, + 0x105, 0x642, 0x107, 0x643, 0x106, 0x643, 0x104, 0x643, + 0x105, 0x643, 0x107, 0x644, 0x106, 0x644, 0x104, 0x644, + 0x105, 0x644, 0x107, 0x645, 0x106, 0x645, 0x104, 0x645, + 0x105, 0x645, 0x107, 0x646, 0x106, 0x646, 0x104, 0x646, + 0x105, 0x646, 0x107, 0x647, 0x106, 0x647, 0x104, 0x647, + 0x105, 0x647, 0x107, 0x648, 0x106, 0x648, 0x107, 0x649, + 0x106, 0x649, 0x107, 0x64a, 0x106, 0x64a, 0x104, 0x64a, + 0x105, 0x64a, 0x207, 0x644, 0x622, 0x206, 0x644, 0x622, + 0x207, 0x644, 0x623, 0x206, 0x644, 0x623, 0x207, 0x644, + 0x625, 0x206, 0x644, 0x625, 0x207, 0x644, 0x627, 0x206, + 0x644, 0x627, 0x10c, 0x21, 0x10c, 0x22, 0x10c, 0x23, + 0x10c, 0x24, 0x10c, 0x25, 0x10c, 0x26, 0x10c, 0x27, + 0x10c, 0x28, 0x10c, 0x29, 0x10c, 0x2a, 0x10c, 0x2b, + 0x10c, 0x2c, 0x10c, 0x2d, 0x10c, 0x2e, 0x10c, 0x2f, + 0x10c, 0x30, 0x10c, 0x31, 0x10c, 0x32, 0x10c, 0x33, + 0x10c, 0x34, 0x10c, 0x35, 0x10c, 0x36, 0x10c, 0x37, + 0x10c, 0x38, 0x10c, 0x39, 0x10c, 0x3a, 0x10c, 0x3b, + 0x10c, 0x3c, 0x10c, 0x3d, 0x10c, 0x3e, 0x10c, 0x3f, + 0x10c, 0x40, 0x10c, 0x41, 0x10c, 0x42, 0x10c, 0x43, + 0x10c, 0x44, 0x10c, 0x45, 0x10c, 0x46, 0x10c, 0x47, + 0x10c, 0x48, 0x10c, 0x49, 0x10c, 0x4a, 0x10c, 0x4b, + 0x10c, 0x4c, 0x10c, 0x4d, 0x10c, 0x4e, 0x10c, 0x4f, + 0x10c, 0x50, 0x10c, 0x51, 0x10c, 0x52, 0x10c, 0x53, + 0x10c, 0x54, 0x10c, 0x55, 0x10c, 0x56, 0x10c, 0x57, + 0x10c, 0x58, 0x10c, 0x59, 0x10c, 0x5a, 0x10c, 0x5b, + 0x10c, 0x5c, 0x10c, 0x5d, 0x10c, 0x5e, 0x10c, 0x5f, + 0x10c, 0x60, 0x10c, 0x61, 0x10c, 0x62, 0x10c, 0x63, + 0x10c, 0x64, 0x10c, 0x65, 0x10c, 0x66, 0x10c, 0x67, + 0x10c, 0x68, 0x10c, 0x69, 0x10c, 0x6a, 0x10c, 0x6b, + 0x10c, 0x6c, 0x10c, 0x6d, 0x10c, 0x6e, 0x10c, 0x6f, + 0x10c, 0x70, 0x10c, 0x71, 0x10c, 0x72, 0x10c, 0x73, + 0x10c, 0x74, 0x10c, 0x75, 0x10c, 0x76, 0x10c, 0x77, + 0x10c, 0x78, 0x10c, 0x79, 0x10c, 0x7a, 0x10c, 0x7b, + 0x10c, 0x7c, 0x10c, 0x7d, 0x10c, 0x7e, 0x10c, 0x2985, + 0x10c, 0x2986, 0x10d, 0x3002, 0x10d, 0x300c, 0x10d, 0x300d, + 0x10d, 0x3001, 0x10d, 0x30fb, 0x10d, 0x30f2, 0x10d, 0x30a1, + 0x10d, 0x30a3, 0x10d, 0x30a5, 0x10d, 0x30a7, 0x10d, 0x30a9, + 0x10d, 0x30e3, 0x10d, 0x30e5, 0x10d, 0x30e7, 0x10d, 0x30c3, + 0x10d, 0x30fc, 0x10d, 0x30a2, 0x10d, 0x30a4, 0x10d, 0x30a6, + 0x10d, 0x30a8, 0x10d, 0x30aa, 0x10d, 0x30ab, 0x10d, 0x30ad, + 0x10d, 0x30af, 0x10d, 0x30b1, 0x10d, 0x30b3, 0x10d, 0x30b5, + 0x10d, 0x30b7, 0x10d, 0x30b9, 0x10d, 0x30bb, 0x10d, 0x30bd, + 0x10d, 0x30bf, 0x10d, 0x30c1, 0x10d, 0x30c4, 0x10d, 0x30c6, + 0x10d, 0x30c8, 0x10d, 0x30ca, 0x10d, 0x30cb, 0x10d, 0x30cc, + 0x10d, 0x30cd, 0x10d, 0x30ce, 0x10d, 0x30cf, 0x10d, 0x30d2, + 0x10d, 0x30d5, 0x10d, 0x30d8, 0x10d, 0x30db, 0x10d, 0x30de, + 0x10d, 0x30df, 0x10d, 0x30e0, 0x10d, 0x30e1, 0x10d, 0x30e2, + 0x10d, 0x30e4, 0x10d, 0x30e6, 0x10d, 0x30e8, 0x10d, 0x30e9, + 0x10d, 0x30ea, 0x10d, 0x30eb, 0x10d, 0x30ec, 0x10d, 0x30ed, + 0x10d, 0x30ef, 0x10d, 0x30f3, 0x10d, 0x3099, 0x10d, 0x309a, + 0x10d, 0x3164, 0x10d, 0x3131, 0x10d, 0x3132, 0x10d, 0x3133, + 0x10d, 0x3134, 0x10d, 0x3135, 0x10d, 0x3136, 0x10d, 0x3137, + 0x10d, 0x3138, 0x10d, 0x3139, 0x10d, 0x313a, 0x10d, 0x313b, + 0x10d, 0x313c, 0x10d, 0x313d, 0x10d, 0x313e, 0x10d, 0x313f, + 0x10d, 0x3140, 0x10d, 0x3141, 0x10d, 0x3142, 0x10d, 0x3143, + 0x10d, 0x3144, 0x10d, 0x3145, 0x10d, 0x3146, 0x10d, 0x3147, + 0x10d, 0x3148, 0x10d, 0x3149, 0x10d, 0x314a, 0x10d, 0x314b, + 0x10d, 0x314c, 0x10d, 0x314d, 0x10d, 0x314e, 0x10d, 0x314f, + 0x10d, 0x3150, 0x10d, 0x3151, 0x10d, 0x3152, 0x10d, 0x3153, + 0x10d, 0x3154, 0x10d, 0x3155, 0x10d, 0x3156, 0x10d, 0x3157, + 0x10d, 0x3158, 0x10d, 0x3159, 0x10d, 0x315a, 0x10d, 0x315b, + 0x10d, 0x315c, 0x10d, 0x315d, 0x10d, 0x315e, 0x10d, 0x315f, + 0x10d, 0x3160, 0x10d, 0x3161, 0x10d, 0x3162, 0x10d, 0x3163, + 0x10c, 0xa2, 0x10c, 0xa3, 0x10c, 0xac, 0x10c, 0xaf, + 0x10c, 0xa6, 0x10c, 0xa5, 0x10c, 0x20a9, 0x10d, 0x2502, + 0x10d, 0x2190, 0x10d, 0x2191, 0x10d, 0x2192, 0x10d, 0x2193, + 0x10d, 0x25a0, 0x10d, 0x25cb, 0x401, 0xd834, 0xdd57, 0xd834, + 0xdd65, 0x401, 0xd834, 0xdd58, 0xd834, 0xdd65, 0x401, 0xd834, + 0xdd5f, 0xd834, 0xdd6e, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd6f, + 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd70, 0x401, 0xd834, 0xdd5f, + 0xd834, 0xdd71, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd72, 0x401, + 0xd834, 0xddb9, 0xd834, 0xdd65, 0x401, 0xd834, 0xddba, 0xd834, + 0xdd65, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6e, 0x401, 0xd834, + 0xddbc, 0xd834, 0xdd6e, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6f, + 0x401, 0xd834, 0xddbc, 0xd834, 0xdd6f, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, + 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, + 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, + 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, + 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102, + 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, + 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, 0x4a, 0x102, + 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, 0x4e, 0x102, + 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52, 0x102, + 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102, + 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102, + 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, + 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102, + 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, + 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, + 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, + 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, + 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x43, 0x102, + 0x44, 0x102, 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102, + 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102, + 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, + 0x66, 0x102, 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, + 0x6b, 0x102, 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, + 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, + 0x4d, 0x102, 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, + 0x51, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, + 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102, + 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, + 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, + 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, + 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, + 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102, + 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, 0x47, 0x102, + 0x49, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, + 0x4d, 0x102, 0x4f, 0x102, 0x53, 0x102, 0x54, 0x102, + 0x55, 0x102, 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, + 0x59, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x131, 0x102, + 0x237, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, + 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, + 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, + 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, + 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, + 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, + 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, + 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, + 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, + 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, + 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, + 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, + 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, + 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, + 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102, + 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102, + 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102, + 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102, + 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102, + 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102, + 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102, + 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102, + 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102, + 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102, + 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102, + 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102, + 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102, + 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102, + 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102, + 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, + 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, + 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, + 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, + 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, + 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, + 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, + 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, + 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, + 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, + 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, + 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, + 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, + 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, + 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102, + 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102, + 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102, + 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102, + 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102, + 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102, + 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102, + 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102, + 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102, + 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102, + 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102, + 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102, + 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102, + 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102, + 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102, + 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, + 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, + 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, + 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, + 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, + 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, + 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, + 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, + 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, + 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, + 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, + 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, + 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, + 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, + 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x3dc, 0x102, + 0x3dd, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, + 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, + 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102, + 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102, + 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102, + 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, + 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, + 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102, + 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102, + 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102, + 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, + 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, + 0x37, 0x102, 0x38, 0x102, 0x39, 0x101, 0x4e3d, 0x101, + 0x4e38, 0x101, 0x4e41, 0x201, 0xd840, 0xdd22, 0x101, 0x4f60, + 0x101, 0x4fae, 0x101, 0x4fbb, 0x101, 0x5002, 0x101, 0x507a, + 0x101, 0x5099, 0x101, 0x50e7, 0x101, 0x50cf, 0x101, 0x349e, + 0x201, 0xd841, 0xde3a, 0x101, 0x514d, 0x101, 0x5154, 0x101, + 0x5164, 0x101, 0x5177, 0x201, 0xd841, 0xdd1c, 0x101, 0x34b9, + 0x101, 0x5167, 0x101, 0x518d, 0x201, 0xd841, 0xdd4b, 0x101, + 0x5197, 0x101, 0x51a4, 0x101, 0x4ecc, 0x101, 0x51ac, 0x101, + 0x51b5, 0x201, 0xd864, 0xdddf, 0x101, 0x51f5, 0x101, 0x5203, + 0x101, 0x34df, 0x101, 0x523b, 0x101, 0x5246, 0x101, 0x5272, + 0x101, 0x5277, 0x101, 0x3515, 0x101, 0x52c7, 0x101, 0x52c9, + 0x101, 0x52e4, 0x101, 0x52fa, 0x101, 0x5305, 0x101, 0x5306, + 0x101, 0x5317, 0x101, 0x5349, 0x101, 0x5351, 0x101, 0x535a, + 0x101, 0x5373, 0x101, 0x537d, 0x101, 0x537f, 0x101, 0x537f, + 0x101, 0x537f, 0x201, 0xd842, 0xde2c, 0x101, 0x7070, 0x101, + 0x53ca, 0x101, 0x53df, 0x201, 0xd842, 0xdf63, 0x101, 0x53eb, + 0x101, 0x53f1, 0x101, 0x5406, 0x101, 0x549e, 0x101, 0x5438, + 0x101, 0x5448, 0x101, 0x5468, 0x101, 0x54a2, 0x101, 0x54f6, + 0x101, 0x5510, 0x101, 0x5553, 0x101, 0x5563, 0x101, 0x5584, + 0x101, 0x5584, 0x101, 0x5599, 0x101, 0x55ab, 0x101, 0x55b3, + 0x101, 0x55c2, 0x101, 0x5716, 0x101, 0x5606, 0x101, 0x5717, + 0x101, 0x5651, 0x101, 0x5674, 0x101, 0x5207, 0x101, 0x58ee, + 0x101, 0x57ce, 0x101, 0x57f4, 0x101, 0x580d, 0x101, 0x578b, + 0x101, 0x5832, 0x101, 0x5831, 0x101, 0x58ac, 0x201, 0xd845, + 0xdce4, 0x101, 0x58f2, 0x101, 0x58f7, 0x101, 0x5906, 0x101, + 0x591a, 0x101, 0x5922, 0x101, 0x5962, 0x201, 0xd845, 0xdea8, + 0x201, 0xd845, 0xdeea, 0x101, 0x59ec, 0x101, 0x5a1b, 0x101, + 0x5a27, 0x101, 0x59d8, 0x101, 0x5a66, 0x101, 0x36ee, 0x101, + 0x36fc, 0x101, 0x5b08, 0x101, 0x5b3e, 0x101, 0x5b3e, 0x201, + 0xd846, 0xddc8, 0x101, 0x5bc3, 0x101, 0x5bd8, 0x101, 0x5be7, + 0x101, 0x5bf3, 0x201, 0xd846, 0xdf18, 0x101, 0x5bff, 0x101, + 0x5c06, 0x101, 0x5f53, 0x101, 0x5c22, 0x101, 0x3781, 0x101, + 0x5c60, 0x101, 0x5c6e, 0x101, 0x5cc0, 0x101, 0x5c8d, 0x201, + 0xd847, 0xdde4, 0x101, 0x5d43, 0x201, 0xd847, 0xdde6, 0x101, + 0x5d6e, 0x101, 0x5d6b, 0x101, 0x5d7c, 0x101, 0x5de1, 0x101, + 0x5de2, 0x101, 0x382f, 0x101, 0x5dfd, 0x101, 0x5e28, 0x101, + 0x5e3d, 0x101, 0x5e69, 0x101, 0x3862, 0x201, 0xd848, 0xdd83, + 0x101, 0x387c, 0x101, 0x5eb0, 0x101, 0x5eb3, 0x101, 0x5eb6, + 0x101, 0x5eca, 0x201, 0xd868, 0xdf92, 0x101, 0x5efe, 0x201, + 0xd848, 0xdf31, 0x201, 0xd848, 0xdf31, 0x101, 0x8201, 0x101, + 0x5f22, 0x101, 0x5f22, 0x101, 0x38c7, 0x201, 0xd84c, 0xdeb8, + 0x201, 0xd858, 0xddda, 0x101, 0x5f62, 0x101, 0x5f6b, 0x101, + 0x38e3, 0x101, 0x5f9a, 0x101, 0x5fcd, 0x101, 0x5fd7, 0x101, + 0x5ff9, 0x101, 0x6081, 0x101, 0x393a, 0x101, 0x391c, 0x101, + 0x6094, 0x201, 0xd849, 0xded4, 0x101, 0x60c7, 0x101, 0x6148, + 0x101, 0x614c, 0x101, 0x614e, 0x101, 0x614c, 0x101, 0x617a, + 0x101, 0x618e, 0x101, 0x61b2, 0x101, 0x61a4, 0x101, 0x61af, + 0x101, 0x61de, 0x101, 0x61f2, 0x101, 0x61f6, 0x101, 0x6210, + 0x101, 0x621b, 0x101, 0x625d, 0x101, 0x62b1, 0x101, 0x62d4, + 0x101, 0x6350, 0x201, 0xd84a, 0xdf0c, 0x101, 0x633d, 0x101, + 0x62fc, 0x101, 0x6368, 0x101, 0x6383, 0x101, 0x63e4, 0x201, + 0xd84a, 0xdff1, 0x101, 0x6422, 0x101, 0x63c5, 0x101, 0x63a9, + 0x101, 0x3a2e, 0x101, 0x6469, 0x101, 0x647e, 0x101, 0x649d, + 0x101, 0x6477, 0x101, 0x3a6c, 0x101, 0x654f, 0x101, 0x656c, + 0x201, 0xd84c, 0xdc0a, 0x101, 0x65e3, 0x101, 0x66f8, 0x101, + 0x6649, 0x101, 0x3b19, 0x101, 0x6691, 0x101, 0x3b08, 0x101, + 0x3ae4, 0x101, 0x5192, 0x101, 0x5195, 0x101, 0x6700, 0x101, + 0x669c, 0x101, 0x80ad, 0x101, 0x43d9, 0x101, 0x6717, 0x101, + 0x671b, 0x101, 0x6721, 0x101, 0x675e, 0x101, 0x6753, 0x201, + 0xd84c, 0xdfc3, 0x101, 0x3b49, 0x101, 0x67fa, 0x101, 0x6785, + 0x101, 0x6852, 0x101, 0x6885, 0x201, 0xd84d, 0xdc6d, 0x101, + 0x688e, 0x101, 0x681f, 0x101, 0x6914, 0x101, 0x3b9d, 0x101, + 0x6942, 0x101, 0x69a3, 0x101, 0x69ea, 0x101, 0x6aa8, 0x201, + 0xd84d, 0xdea3, 0x101, 0x6adb, 0x101, 0x3c18, 0x101, 0x6b21, + 0x201, 0xd84e, 0xdca7, 0x101, 0x6b54, 0x101, 0x3c4e, 0x101, + 0x6b72, 0x101, 0x6b9f, 0x101, 0x6bba, 0x101, 0x6bbb, 0x201, + 0xd84e, 0xde8d, 0x201, 0xd847, 0xdd0b, 0x201, 0xd84e, 0xdefa, + 0x101, 0x6c4e, 0x201, 0xd84f, 0xdcbc, 0x101, 0x6cbf, 0x101, + 0x6ccd, 0x101, 0x6c67, 0x101, 0x6d16, 0x101, 0x6d3e, 0x101, + 0x6d77, 0x101, 0x6d41, 0x101, 0x6d69, 0x101, 0x6d78, 0x101, + 0x6d85, 0x201, 0xd84f, 0xdd1e, 0x101, 0x6d34, 0x101, 0x6e2f, + 0x101, 0x6e6e, 0x101, 0x3d33, 0x101, 0x6ecb, 0x101, 0x6ec7, + 0x201, 0xd84f, 0xded1, 0x101, 0x6df9, 0x101, 0x6f6e, 0x201, + 0xd84f, 0xdf5e, 0x201, 0xd84f, 0xdf8e, 0x101, 0x6fc6, 0x101, + 0x7039, 0x101, 0x701e, 0x101, 0x701b, 0x101, 0x3d96, 0x101, + 0x704a, 0x101, 0x707d, 0x101, 0x7077, 0x101, 0x70ad, 0x201, + 0xd841, 0xdd25, 0x101, 0x7145, 0x201, 0xd850, 0xde63, 0x101, + 0x719c, 0x201, 0xd850, 0xdfab, 0x101, 0x7228, 0x101, 0x7235, + 0x101, 0x7250, 0x201, 0xd851, 0xde08, 0x101, 0x7280, 0x101, + 0x7295, 0x201, 0xd851, 0xdf35, 0x201, 0xd852, 0xdc14, 0x101, + 0x737a, 0x101, 0x738b, 0x101, 0x3eac, 0x101, 0x73a5, 0x101, + 0x3eb8, 0x101, 0x3eb8, 0x101, 0x7447, 0x101, 0x745c, 0x101, + 0x7471, 0x101, 0x7485, 0x101, 0x74ca, 0x101, 0x3f1b, 0x101, + 0x7524, 0x201, 0xd853, 0xdc36, 0x101, 0x753e, 0x201, 0xd853, + 0xdc92, 0x101, 0x7570, 0x201, 0xd848, 0xdd9f, 0x101, 0x7610, + 0x201, 0xd853, 0xdfa1, 0x201, 0xd853, 0xdfb8, 0x201, 0xd854, + 0xdc44, 0x101, 0x3ffc, 0x101, 0x4008, 0x101, 0x76f4, 0x201, + 0xd854, 0xdcf3, 0x201, 0xd854, 0xdcf2, 0x201, 0xd854, 0xdd19, + 0x201, 0xd854, 0xdd33, 0x101, 0x771e, 0x101, 0x771f, 0x101, + 0x771f, 0x101, 0x774a, 0x101, 0x4039, 0x101, 0x778b, 0x101, + 0x4046, 0x101, 0x4096, 0x201, 0xd855, 0xdc1d, 0x101, 0x784e, + 0x101, 0x788c, 0x101, 0x78cc, 0x101, 0x40e3, 0x201, 0xd855, + 0xde26, 0x101, 0x7956, 0x201, 0xd855, 0xde9a, 0x201, 0xd855, + 0xdec5, 0x101, 0x798f, 0x101, 0x79eb, 0x101, 0x412f, 0x101, + 0x7a40, 0x101, 0x7a4a, 0x101, 0x7a4f, 0x201, 0xd856, 0xdd7c, + 0x201, 0xd856, 0xdea7, 0x201, 0xd856, 0xdea7, 0x101, 0x7aee, + 0x101, 0x4202, 0x201, 0xd856, 0xdfab, 0x101, 0x7bc6, 0x101, + 0x7bc9, 0x101, 0x4227, 0x201, 0xd857, 0xdc80, 0x101, 0x7cd2, + 0x101, 0x42a0, 0x101, 0x7ce8, 0x101, 0x7ce3, 0x101, 0x7d00, + 0x201, 0xd857, 0xdf86, 0x101, 0x7d63, 0x101, 0x4301, 0x101, + 0x7dc7, 0x101, 0x7e02, 0x101, 0x7e45, 0x101, 0x4334, 0x201, + 0xd858, 0xde28, 0x201, 0xd858, 0xde47, 0x101, 0x4359, 0x201, + 0xd858, 0xded9, 0x101, 0x7f7a, 0x201, 0xd858, 0xdf3e, 0x101, + 0x7f95, 0x101, 0x7ffa, 0x101, 0x8005, 0x201, 0xd859, 0xdcda, + 0x201, 0xd859, 0xdd23, 0x101, 0x8060, 0x201, 0xd859, 0xdda8, + 0x101, 0x8070, 0x201, 0xd84c, 0xdf5f, 0x101, 0x43d5, 0x101, + 0x80b2, 0x101, 0x8103, 0x101, 0x440b, 0x101, 0x813e, 0x101, + 0x5ab5, 0x201, 0xd859, 0xdfa7, 0x201, 0xd859, 0xdfb5, 0x201, + 0xd84c, 0xdf93, 0x201, 0xd84c, 0xdf9c, 0x101, 0x8201, 0x101, + 0x8204, 0x101, 0x8f9e, 0x101, 0x446b, 0x101, 0x8291, 0x101, + 0x828b, 0x101, 0x829d, 0x101, 0x52b3, 0x101, 0x82b1, 0x101, + 0x82b3, 0x101, 0x82bd, 0x101, 0x82e6, 0x201, 0xd85a, 0xdf3c, + 0x101, 0x82e5, 0x101, 0x831d, 0x101, 0x8363, 0x101, 0x83ad, + 0x101, 0x8323, 0x101, 0x83bd, 0x101, 0x83e7, 0x101, 0x8457, + 0x101, 0x8353, 0x101, 0x83ca, 0x101, 0x83cc, 0x101, 0x83dc, + 0x201, 0xd85b, 0xdc36, 0x201, 0xd85b, 0xdd6b, 0x201, 0xd85b, + 0xdcd5, 0x101, 0x452b, 0x101, 0x84f1, 0x101, 0x84f3, 0x101, + 0x8516, 0x201, 0xd85c, 0xdfca, 0x101, 0x8564, 0x201, 0xd85b, + 0xdf2c, 0x101, 0x455d, 0x101, 0x4561, 0x201, 0xd85b, 0xdfb1, + 0x201, 0xd85c, 0xdcd2, 0x101, 0x456b, 0x101, 0x8650, 0x101, + 0x865c, 0x101, 0x8667, 0x101, 0x8669, 0x101, 0x86a9, 0x101, + 0x8688, 0x101, 0x870e, 0x101, 0x86e2, 0x101, 0x8779, 0x101, + 0x8728, 0x101, 0x876b, 0x101, 0x8786, 0x101, 0x45d7, 0x101, + 0x87e1, 0x101, 0x8801, 0x101, 0x45f9, 0x101, 0x8860, 0x101, + 0x8863, 0x201, 0xd85d, 0xde67, 0x101, 0x88d7, 0x101, 0x88de, + 0x101, 0x4635, 0x101, 0x88fa, 0x101, 0x34bb, 0x201, 0xd85e, + 0xdcae, 0x201, 0xd85e, 0xdd66, 0x101, 0x46be, 0x101, 0x46c7, + 0x101, 0x8aa0, 0x101, 0x8aed, 0x101, 0x8b8a, 0x101, 0x8c55, + 0x201, 0xd85f, 0xdca8, 0x101, 0x8cab, 0x101, 0x8cc1, 0x101, + 0x8d1b, 0x101, 0x8d77, 0x201, 0xd85f, 0xdf2f, 0x201, 0xd842, + 0xdc04, 0x101, 0x8dcb, 0x101, 0x8dbc, 0x101, 0x8df0, 0x201, + 0xd842, 0xdcde, 0x101, 0x8ed4, 0x101, 0x8f38, 0x201, 0xd861, + 0xddd2, 0x201, 0xd861, 0xdded, 0x101, 0x9094, 0x101, 0x90f1, + 0x101, 0x9111, 0x201, 0xd861, 0xdf2e, 0x101, 0x911b, 0x101, + 0x9238, 0x101, 0x92d7, 0x101, 0x92d8, 0x101, 0x927c, 0x101, + 0x93f9, 0x101, 0x9415, 0x201, 0xd862, 0xdffa, 0x101, 0x958b, + 0x101, 0x4995, 0x101, 0x95b7, 0x201, 0xd863, 0xdd77, 0x101, + 0x49e6, 0x101, 0x96c3, 0x101, 0x5db2, 0x101, 0x9723, 0x201, + 0xd864, 0xdd45, 0x201, 0xd864, 0xde1a, 0x101, 0x4a6e, 0x101, + 0x4a76, 0x101, 0x97e0, 0x201, 0xd865, 0xdc0a, 0x101, 0x4ab2, + 0x201, 0xd865, 0xdc96, 0x101, 0x980b, 0x101, 0x980b, 0x101, + 0x9829, 0x201, 0xd865, 0xddb6, 0x101, 0x98e2, 0x101, 0x4b33, + 0x101, 0x9929, 0x101, 0x99a7, 0x101, 0x99c2, 0x101, 0x99fe, + 0x101, 0x4bce, 0x201, 0xd866, 0xdf30, 0x101, 0x9b12, 0x101, + 0x9c40, 0x101, 0x9cfd, 0x101, 0x4cce, 0x101, 0x4ced, 0x101, + 0x9d67, 0x201, 0xd868, 0xdcce, 0x101, 0x4cf8, 0x201, 0xd868, + 0xdd05, 0x201, 0xd868, 0xde0e, 0x201, 0xd868, 0xde91, 0x101, + 0x9ebb, 0x101, 0x4d56, 0x101, 0x9ef9, 0x101, 0x9efe, 0x101, + 0x9f05, 0x101, 0x9f0f, 0x101, 0x9f16, 0x101, 0x9f3b, 0x201, + 0xd869, 0xde00, }; static const unsigned short uc_ligature_trie[] = { // 0 - 0x3100 - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 424, 456, 488, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 520, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 552, 392, 392, 392, 584, 616, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 648, 680, 392, 392, 712, 744, 392, - 392, 392, 776, 392, 392, 392, 808, 392, - 392, 840, 872, 392, 392, 392, 904, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - - 392, 936, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 968, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - - 392, 392, 392, 392, 1000, 392, 392, 392, - - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x0, 0xa9, 0x194, 0x1d5, 0x20e, 0xffff, 0x267, 0x2a8, - 0x305, 0x372, 0x3a3, 0x3b0, 0x3bd, 0xffff, 0xffff, 0x408, - 0xffff, 0x425, 0xffff, 0x43e, 0x45b, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x47c, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0x485, 0x4da, 0x4df, 0x4e4, 0x4ed, - 0x51a, 0xffff, 0xffff, 0xffff, 0xffff, 0x52f, 0x548, 0xffff, - 0x54d, 0x55a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x57d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0x5d6, 0xffff, 0xffff, 0x611, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x690, 0x693, 0x6a0, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x6a3, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6aa, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6ad, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b0, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b3, 0x6b6, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b9, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6be, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c3, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0x6c6, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c9, 0x6d0, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d3, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d8, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x6db, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e0, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e3, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e6, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e9, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x700, 0x761, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 424, 456, 488, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 520, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 552, 392, 392, 392, 584, 616, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 648, 680, 392, 392, 712, 744, 392, + 392, 392, 776, 392, 392, 392, 808, 392, + 392, 840, 872, 392, 392, 392, 904, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + + 392, 936, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 968, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + + 392, 392, 392, 392, 1000, 392, 392, 392, + + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x0, 0xa9, 0x194, 0x1d5, 0x20e, 0xffff, 0x267, 0x2a8, + 0x305, 0x372, 0x3a3, 0x3b0, 0x3bd, 0xffff, 0xffff, 0x408, + 0xffff, 0x425, 0xffff, 0x43e, 0x45b, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x47c, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0x485, 0x4da, 0x4df, 0x4e4, 0x4ed, + 0x51a, 0xffff, 0xffff, 0xffff, 0xffff, 0x52f, 0x548, 0xffff, + 0x54d, 0x55a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x57d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0x5d6, 0xffff, 0xffff, 0x611, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x690, 0x693, 0x6a0, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x6a3, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6aa, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6ad, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b0, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b3, 0x6b6, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b9, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6be, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c3, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0x6c6, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c9, 0x6d0, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d3, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d8, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x6db, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e0, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e3, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e6, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e9, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x700, 0x761, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, }; #define GET_LIGATURE_INDEX(u2) (u2 < 0x3100 ? uc_ligature_trie[uc_ligature_trie[u2>>5] + (u2 & 0x1f)] : 0xffff); static const unsigned short uc_ligature_map [] = { - 0x54, 0x41, 0xc0, 0x45, 0xc8, 0x49, 0xcc, 0x4e, - 0x1f8, 0x4f, 0xd2, 0x55, 0xd9, 0x57, 0x1e80, 0x59, - 0x1ef2, 0x61, 0xe0, 0x65, 0xe8, 0x69, 0xec, 0x6e, - 0x1f9, 0x6f, 0xf2, 0x75, 0xf9, 0x77, 0x1e81, 0x79, - 0x1ef3, 0xa8, 0x1fed, 0xc2, 0x1ea6, 0xca, 0x1ec0, 0xd4, - 0x1ed2, 0xdc, 0x1db, 0xe2, 0x1ea7, 0xea, 0x1ec1, 0xf4, - 0x1ed3, 0xfc, 0x1dc, 0x102, 0x1eb0, 0x103, 0x1eb1, 0x112, - 0x1e14, 0x113, 0x1e15, 0x14c, 0x1e50, 0x14d, 0x1e51, 0x1a0, - 0x1edc, 0x1a1, 0x1edd, 0x1af, 0x1eea, 0x1b0, 0x1eeb, 0x391, - 0x1fba, 0x395, 0x1fc8, 0x397, 0x1fca, 0x399, 0x1fda, 0x39f, - 0x1ff8, 0x3a5, 0x1fea, 0x3a9, 0x1ffa, 0x3b1, 0x1f70, 0x3b5, - 0x1f72, 0x3b7, 0x1f74, 0x3b9, 0x1f76, 0x3bf, 0x1f78, 0x3c5, - 0x1f7a, 0x3c9, 0x1f7c, 0x3ca, 0x1fd2, 0x3cb, 0x1fe2, 0x415, - 0x400, 0x418, 0x40d, 0x435, 0x450, 0x438, 0x45d, 0x1f00, - 0x1f02, 0x1f01, 0x1f03, 0x1f08, 0x1f0a, 0x1f09, 0x1f0b, 0x1f10, - 0x1f12, 0x1f11, 0x1f13, 0x1f18, 0x1f1a, 0x1f19, 0x1f1b, 0x1f20, - 0x1f22, 0x1f21, 0x1f23, 0x1f28, 0x1f2a, 0x1f29, 0x1f2b, 0x1f30, - 0x1f32, 0x1f31, 0x1f33, 0x1f38, 0x1f3a, 0x1f39, 0x1f3b, 0x1f40, - 0x1f42, 0x1f41, 0x1f43, 0x1f48, 0x1f4a, 0x1f49, 0x1f4b, 0x1f50, - 0x1f52, 0x1f51, 0x1f53, 0x1f59, 0x1f5b, 0x1f60, 0x1f62, 0x1f61, - 0x1f63, 0x1f68, 0x1f6a, 0x1f69, 0x1f6b, 0x1fbf, 0x1fcd, 0x1ffe, - 0x1fdd, 0x75, 0x41, 0xc1, 0x43, 0x106, 0x45, 0xc9, - 0x47, 0x1f4, 0x49, 0xcd, 0x4b, 0x1e30, 0x4c, 0x139, - 0x4d, 0x1e3e, 0x4e, 0x143, 0x4f, 0xd3, 0x50, 0x1e54, - 0x52, 0x154, 0x53, 0x15a, 0x55, 0xda, 0x57, 0x1e82, - 0x59, 0xdd, 0x5a, 0x179, 0x61, 0xe1, 0x63, 0x107, - 0x65, 0xe9, 0x67, 0x1f5, 0x69, 0xed, 0x6b, 0x1e31, - 0x6c, 0x13a, 0x6d, 0x1e3f, 0x6e, 0x144, 0x6f, 0xf3, - 0x70, 0x1e55, 0x72, 0x155, 0x73, 0x15b, 0x75, 0xfa, - 0x77, 0x1e83, 0x79, 0xfd, 0x7a, 0x17a, 0xa8, 0x385, - 0xc2, 0x1ea4, 0xc5, 0x1fa, 0xc6, 0x1fc, 0xc7, 0x1e08, - 0xca, 0x1ebe, 0xcf, 0x1e2e, 0xd4, 0x1ed0, 0xd5, 0x1e4c, - 0xd8, 0x1fe, 0xdc, 0x1d7, 0xe2, 0x1ea5, 0xe5, 0x1fb, - 0xe6, 0x1fd, 0xe7, 0x1e09, 0xea, 0x1ebf, 0xef, 0x1e2f, - 0xf4, 0x1ed1, 0xf5, 0x1e4d, 0xf8, 0x1ff, 0xfc, 0x1d8, - 0x102, 0x1eae, 0x103, 0x1eaf, 0x112, 0x1e16, 0x113, 0x1e17, - 0x14c, 0x1e52, 0x14d, 0x1e53, 0x168, 0x1e78, 0x169, 0x1e79, - 0x1a0, 0x1eda, 0x1a1, 0x1edb, 0x1af, 0x1ee8, 0x1b0, 0x1ee9, - 0x391, 0x386, 0x395, 0x388, 0x397, 0x389, 0x399, 0x38a, - 0x39f, 0x38c, 0x3a5, 0x38e, 0x3a9, 0x38f, 0x3b1, 0x3ac, - 0x3b5, 0x3ad, 0x3b7, 0x3ae, 0x3b9, 0x3af, 0x3bf, 0x3cc, - 0x3c5, 0x3cd, 0x3c9, 0x3ce, 0x3ca, 0x390, 0x3cb, 0x3b0, - 0x3d2, 0x3d3, 0x413, 0x403, 0x41a, 0x40c, 0x433, 0x453, - 0x43a, 0x45c, 0x1f00, 0x1f04, 0x1f01, 0x1f05, 0x1f08, 0x1f0c, - 0x1f09, 0x1f0d, 0x1f10, 0x1f14, 0x1f11, 0x1f15, 0x1f18, 0x1f1c, - 0x1f19, 0x1f1d, 0x1f20, 0x1f24, 0x1f21, 0x1f25, 0x1f28, 0x1f2c, - 0x1f29, 0x1f2d, 0x1f30, 0x1f34, 0x1f31, 0x1f35, 0x1f38, 0x1f3c, - 0x1f39, 0x1f3d, 0x1f40, 0x1f44, 0x1f41, 0x1f45, 0x1f48, 0x1f4c, - 0x1f49, 0x1f4d, 0x1f50, 0x1f54, 0x1f51, 0x1f55, 0x1f59, 0x1f5d, - 0x1f60, 0x1f64, 0x1f61, 0x1f65, 0x1f68, 0x1f6c, 0x1f69, 0x1f6d, - 0x1fbf, 0x1fce, 0x1ffe, 0x1fde, 0x20, 0x41, 0xc2, 0x43, - 0x108, 0x45, 0xca, 0x47, 0x11c, 0x48, 0x124, 0x49, - 0xce, 0x4a, 0x134, 0x4f, 0xd4, 0x53, 0x15c, 0x55, - 0xdb, 0x57, 0x174, 0x59, 0x176, 0x5a, 0x1e90, 0x61, - 0xe2, 0x63, 0x109, 0x65, 0xea, 0x67, 0x11d, 0x68, - 0x125, 0x69, 0xee, 0x6a, 0x135, 0x6f, 0xf4, 0x73, - 0x15d, 0x75, 0xfb, 0x77, 0x175, 0x79, 0x177, 0x7a, - 0x1e91, 0x1ea0, 0x1eac, 0x1ea1, 0x1ead, 0x1eb8, 0x1ec6, 0x1eb9, - 0x1ec7, 0x1ecc, 0x1ed8, 0x1ecd, 0x1ed9, 0x1c, 0x41, 0xc3, - 0x45, 0x1ebc, 0x49, 0x128, 0x4e, 0xd1, 0x4f, 0xd5, - 0x55, 0x168, 0x56, 0x1e7c, 0x59, 0x1ef8, 0x61, 0xe3, - 0x65, 0x1ebd, 0x69, 0x129, 0x6e, 0xf1, 0x6f, 0xf5, - 0x75, 0x169, 0x76, 0x1e7d, 0x79, 0x1ef9, 0xc2, 0x1eaa, - 0xca, 0x1ec4, 0xd4, 0x1ed6, 0xe2, 0x1eab, 0xea, 0x1ec5, - 0xf4, 0x1ed7, 0x102, 0x1eb4, 0x103, 0x1eb5, 0x1a0, 0x1ee0, - 0x1a1, 0x1ee1, 0x1af, 0x1eee, 0x1b0, 0x1eef, 0x2c, 0x41, - 0x100, 0x45, 0x112, 0x47, 0x1e20, 0x49, 0x12a, 0x4f, - 0x14c, 0x55, 0x16a, 0x59, 0x232, 0x61, 0x101, 0x65, - 0x113, 0x67, 0x1e21, 0x69, 0x12b, 0x6f, 0x14d, 0x75, - 0x16b, 0x79, 0x233, 0xc4, 0x1de, 0xc6, 0x1e2, 0xd5, - 0x22c, 0xd6, 0x22a, 0xdc, 0x1d5, 0xe4, 0x1df, 0xe6, - 0x1e3, 0xf5, 0x22d, 0xf6, 0x22b, 0xfc, 0x1d6, 0x1ea, - 0x1ec, 0x1eb, 0x1ed, 0x226, 0x1e0, 0x227, 0x1e1, 0x22e, - 0x230, 0x22f, 0x231, 0x391, 0x1fb9, 0x399, 0x1fd9, 0x3a5, - 0x1fe9, 0x3b1, 0x1fb1, 0x3b9, 0x1fd1, 0x3c5, 0x1fe1, 0x418, - 0x4e2, 0x423, 0x4ee, 0x438, 0x4e3, 0x443, 0x4ef, 0x1e36, - 0x1e38, 0x1e37, 0x1e39, 0x1e5a, 0x1e5c, 0x1e5b, 0x1e5d, 0x20, - 0x41, 0x102, 0x45, 0x114, 0x47, 0x11e, 0x49, 0x12c, - 0x4f, 0x14e, 0x55, 0x16c, 0x61, 0x103, 0x65, 0x115, - 0x67, 0x11f, 0x69, 0x12d, 0x6f, 0x14f, 0x75, 0x16d, - 0x228, 0x1e1c, 0x229, 0x1e1d, 0x391, 0x1fb8, 0x399, 0x1fd8, - 0x3a5, 0x1fe8, 0x3b1, 0x1fb0, 0x3b9, 0x1fd0, 0x3c5, 0x1fe0, - 0x410, 0x4d0, 0x415, 0x4d6, 0x416, 0x4c1, 0x418, 0x419, - 0x423, 0x40e, 0x430, 0x4d1, 0x435, 0x4d7, 0x436, 0x4c2, - 0x438, 0x439, 0x443, 0x45e, 0x1ea0, 0x1eb6, 0x1ea1, 0x1eb7, - 0x2e, 0x41, 0x226, 0x42, 0x1e02, 0x43, 0x10a, 0x44, - 0x1e0a, 0x45, 0x116, 0x46, 0x1e1e, 0x47, 0x120, 0x48, - 0x1e22, 0x49, 0x130, 0x4d, 0x1e40, 0x4e, 0x1e44, 0x4f, - 0x22e, 0x50, 0x1e56, 0x52, 0x1e58, 0x53, 0x1e60, 0x54, - 0x1e6a, 0x57, 0x1e86, 0x58, 0x1e8a, 0x59, 0x1e8e, 0x5a, - 0x17b, 0x61, 0x227, 0x62, 0x1e03, 0x63, 0x10b, 0x64, - 0x1e0b, 0x65, 0x117, 0x66, 0x1e1f, 0x67, 0x121, 0x68, - 0x1e23, 0x6d, 0x1e41, 0x6e, 0x1e45, 0x6f, 0x22f, 0x70, - 0x1e57, 0x72, 0x1e59, 0x73, 0x1e61, 0x74, 0x1e6b, 0x77, - 0x1e87, 0x78, 0x1e8b, 0x79, 0x1e8f, 0x7a, 0x17c, 0x15a, - 0x1e64, 0x15b, 0x1e65, 0x160, 0x1e66, 0x161, 0x1e67, 0x17f, - 0x1e9b, 0x1e62, 0x1e68, 0x1e63, 0x1e69, 0x36, 0x41, 0xc4, - 0x45, 0xcb, 0x48, 0x1e26, 0x49, 0xcf, 0x4f, 0xd6, - 0x55, 0xdc, 0x57, 0x1e84, 0x58, 0x1e8c, 0x59, 0x178, - 0x61, 0xe4, 0x65, 0xeb, 0x68, 0x1e27, 0x69, 0xef, - 0x6f, 0xf6, 0x74, 0x1e97, 0x75, 0xfc, 0x77, 0x1e85, - 0x78, 0x1e8d, 0x79, 0xff, 0xd5, 0x1e4e, 0xf5, 0x1e4f, - 0x16a, 0x1e7a, 0x16b, 0x1e7b, 0x399, 0x3aa, 0x3a5, 0x3ab, - 0x3b9, 0x3ca, 0x3c5, 0x3cb, 0x3d2, 0x3d4, 0x406, 0x407, - 0x410, 0x4d2, 0x415, 0x401, 0x416, 0x4dc, 0x417, 0x4de, - 0x418, 0x4e4, 0x41e, 0x4e6, 0x423, 0x4f0, 0x427, 0x4f4, - 0x42b, 0x4f8, 0x42d, 0x4ec, 0x430, 0x4d3, 0x435, 0x451, - 0x436, 0x4dd, 0x437, 0x4df, 0x438, 0x4e5, 0x43e, 0x4e7, - 0x443, 0x4f1, 0x447, 0x4f5, 0x44b, 0x4f9, 0x44d, 0x4ed, - 0x456, 0x457, 0x4d8, 0x4da, 0x4d9, 0x4db, 0x4e8, 0x4ea, - 0x4e9, 0x4eb, 0x18, 0x41, 0x1ea2, 0x45, 0x1eba, 0x49, - 0x1ec8, 0x4f, 0x1ece, 0x55, 0x1ee6, 0x59, 0x1ef6, 0x61, - 0x1ea3, 0x65, 0x1ebb, 0x69, 0x1ec9, 0x6f, 0x1ecf, 0x75, - 0x1ee7, 0x79, 0x1ef7, 0xc2, 0x1ea8, 0xca, 0x1ec2, 0xd4, - 0x1ed4, 0xe2, 0x1ea9, 0xea, 0x1ec3, 0xf4, 0x1ed5, 0x102, - 0x1eb2, 0x103, 0x1eb3, 0x1a0, 0x1ede, 0x1a1, 0x1edf, 0x1af, - 0x1eec, 0x1b0, 0x1eed, 0x6, 0x41, 0xc5, 0x55, 0x16e, - 0x61, 0xe5, 0x75, 0x16f, 0x77, 0x1e98, 0x79, 0x1e99, - 0x6, 0x4f, 0x150, 0x55, 0x170, 0x6f, 0x151, 0x75, - 0x171, 0x423, 0x4f2, 0x443, 0x4f3, 0x25, 0x41, 0x1cd, - 0x43, 0x10c, 0x44, 0x10e, 0x45, 0x11a, 0x47, 0x1e6, - 0x48, 0x21e, 0x49, 0x1cf, 0x4b, 0x1e8, 0x4c, 0x13d, - 0x4e, 0x147, 0x4f, 0x1d1, 0x52, 0x158, 0x53, 0x160, - 0x54, 0x164, 0x55, 0x1d3, 0x5a, 0x17d, 0x61, 0x1ce, - 0x63, 0x10d, 0x64, 0x10f, 0x65, 0x11b, 0x67, 0x1e7, - 0x68, 0x21f, 0x69, 0x1d0, 0x6a, 0x1f0, 0x6b, 0x1e9, - 0x6c, 0x13e, 0x6e, 0x148, 0x6f, 0x1d2, 0x72, 0x159, - 0x73, 0x161, 0x74, 0x165, 0x75, 0x1d4, 0x7a, 0x17e, - 0xdc, 0x1d9, 0xfc, 0x1da, 0x1b7, 0x1ee, 0x292, 0x1ef, - 0xe, 0x41, 0x200, 0x45, 0x204, 0x49, 0x208, 0x4f, - 0x20c, 0x52, 0x210, 0x55, 0x214, 0x61, 0x201, 0x65, - 0x205, 0x69, 0x209, 0x6f, 0x20d, 0x72, 0x211, 0x75, - 0x215, 0x474, 0x476, 0x475, 0x477, 0xc, 0x41, 0x202, - 0x45, 0x206, 0x49, 0x20a, 0x4f, 0x20e, 0x52, 0x212, - 0x55, 0x216, 0x61, 0x203, 0x65, 0x207, 0x69, 0x20b, - 0x6f, 0x20f, 0x72, 0x213, 0x75, 0x217, 0xe, 0x391, - 0x1f08, 0x395, 0x1f18, 0x397, 0x1f28, 0x399, 0x1f38, 0x39f, - 0x1f48, 0x3a9, 0x1f68, 0x3b1, 0x1f00, 0x3b5, 0x1f10, 0x3b7, - 0x1f20, 0x3b9, 0x1f30, 0x3bf, 0x1f40, 0x3c1, 0x1fe4, 0x3c5, - 0x1f50, 0x3c9, 0x1f60, 0x10, 0x391, 0x1f09, 0x395, 0x1f19, - 0x397, 0x1f29, 0x399, 0x1f39, 0x39f, 0x1f49, 0x3a1, 0x1fec, - 0x3a5, 0x1f59, 0x3a9, 0x1f69, 0x3b1, 0x1f01, 0x3b5, 0x1f11, - 0x3b7, 0x1f21, 0x3b9, 0x1f31, 0x3bf, 0x1f41, 0x3c1, 0x1fe5, - 0x3c5, 0x1f51, 0x3c9, 0x1f61, 0x4, 0x4f, 0x1a0, 0x55, - 0x1af, 0x6f, 0x1a1, 0x75, 0x1b0, 0x2a, 0x41, 0x1ea0, - 0x42, 0x1e04, 0x44, 0x1e0c, 0x45, 0x1eb8, 0x48, 0x1e24, - 0x49, 0x1eca, 0x4b, 0x1e32, 0x4c, 0x1e36, 0x4d, 0x1e42, - 0x4e, 0x1e46, 0x4f, 0x1ecc, 0x52, 0x1e5a, 0x53, 0x1e62, - 0x54, 0x1e6c, 0x55, 0x1ee4, 0x56, 0x1e7e, 0x57, 0x1e88, - 0x59, 0x1ef4, 0x5a, 0x1e92, 0x61, 0x1ea1, 0x62, 0x1e05, - 0x64, 0x1e0d, 0x65, 0x1eb9, 0x68, 0x1e25, 0x69, 0x1ecb, - 0x6b, 0x1e33, 0x6c, 0x1e37, 0x6d, 0x1e43, 0x6e, 0x1e47, - 0x6f, 0x1ecd, 0x72, 0x1e5b, 0x73, 0x1e63, 0x74, 0x1e6d, - 0x75, 0x1ee5, 0x76, 0x1e7f, 0x77, 0x1e89, 0x79, 0x1ef5, - 0x7a, 0x1e93, 0x1a0, 0x1ee2, 0x1a1, 0x1ee3, 0x1af, 0x1ef0, - 0x1b0, 0x1ef1, 0x2, 0x55, 0x1e72, 0x75, 0x1e73, 0x2, - 0x41, 0x1e00, 0x61, 0x1e01, 0x4, 0x53, 0x218, 0x54, - 0x21a, 0x73, 0x219, 0x74, 0x21b, 0x16, 0x43, 0xc7, - 0x44, 0x1e10, 0x45, 0x228, 0x47, 0x122, 0x48, 0x1e28, - 0x4b, 0x136, 0x4c, 0x13b, 0x4e, 0x145, 0x52, 0x156, - 0x53, 0x15e, 0x54, 0x162, 0x63, 0xe7, 0x64, 0x1e11, - 0x65, 0x229, 0x67, 0x123, 0x68, 0x1e29, 0x6b, 0x137, - 0x6c, 0x13c, 0x6e, 0x146, 0x72, 0x157, 0x73, 0x15f, - 0x74, 0x163, 0xa, 0x41, 0x104, 0x45, 0x118, 0x49, - 0x12e, 0x4f, 0x1ea, 0x55, 0x172, 0x61, 0x105, 0x65, - 0x119, 0x69, 0x12f, 0x6f, 0x1eb, 0x75, 0x173, 0xc, - 0x44, 0x1e12, 0x45, 0x1e18, 0x4c, 0x1e3c, 0x4e, 0x1e4a, - 0x54, 0x1e70, 0x55, 0x1e76, 0x64, 0x1e13, 0x65, 0x1e19, - 0x6c, 0x1e3d, 0x6e, 0x1e4b, 0x74, 0x1e71, 0x75, 0x1e77, - 0x2, 0x48, 0x1e2a, 0x68, 0x1e2b, 0x6, 0x45, 0x1e1a, - 0x49, 0x1e2c, 0x55, 0x1e74, 0x65, 0x1e1b, 0x69, 0x1e2d, - 0x75, 0x1e75, 0x11, 0x42, 0x1e06, 0x44, 0x1e0e, 0x4b, - 0x1e34, 0x4c, 0x1e3a, 0x4e, 0x1e48, 0x52, 0x1e5e, 0x54, - 0x1e6e, 0x5a, 0x1e94, 0x62, 0x1e07, 0x64, 0x1e0f, 0x68, - 0x1e96, 0x6b, 0x1e35, 0x6c, 0x1e3b, 0x6e, 0x1e49, 0x72, - 0x1e5f, 0x74, 0x1e6f, 0x7a, 0x1e95, 0x2c, 0x3c, 0x226e, - 0x3d, 0x2260, 0x3e, 0x226f, 0x2190, 0x219a, 0x2192, 0x219b, - 0x2194, 0x21ae, 0x21d0, 0x21cd, 0x21d2, 0x21cf, 0x21d4, 0x21ce, - 0x2203, 0x2204, 0x2208, 0x2209, 0x220b, 0x220c, 0x2223, 0x2224, - 0x2225, 0x2226, 0x223c, 0x2241, 0x2243, 0x2244, 0x2245, 0x2247, - 0x2248, 0x2249, 0x224d, 0x226d, 0x2261, 0x2262, 0x2264, 0x2270, - 0x2265, 0x2271, 0x2272, 0x2274, 0x2273, 0x2275, 0x2276, 0x2278, - 0x2277, 0x2279, 0x227a, 0x2280, 0x227b, 0x2281, 0x227c, 0x22e0, - 0x227d, 0x22e1, 0x2282, 0x2284, 0x2283, 0x2285, 0x2286, 0x2288, - 0x2287, 0x2289, 0x2291, 0x22e2, 0x2292, 0x22e3, 0x22a2, 0x22ac, - 0x22a8, 0x22ad, 0x22a9, 0x22ae, 0x22ab, 0x22af, 0x22b2, 0x22ea, - 0x22b3, 0x22eb, 0x22b4, 0x22ec, 0x22b5, 0x22ed, 0x1d, 0xa8, - 0x1fc1, 0x3b1, 0x1fb6, 0x3b7, 0x1fc6, 0x3b9, 0x1fd6, 0x3c5, - 0x1fe6, 0x3c9, 0x1ff6, 0x3ca, 0x1fd7, 0x3cb, 0x1fe7, 0x1f00, - 0x1f06, 0x1f01, 0x1f07, 0x1f08, 0x1f0e, 0x1f09, 0x1f0f, 0x1f20, - 0x1f26, 0x1f21, 0x1f27, 0x1f28, 0x1f2e, 0x1f29, 0x1f2f, 0x1f30, - 0x1f36, 0x1f31, 0x1f37, 0x1f38, 0x1f3e, 0x1f39, 0x1f3f, 0x1f50, - 0x1f56, 0x1f51, 0x1f57, 0x1f59, 0x1f5f, 0x1f60, 0x1f66, 0x1f61, - 0x1f67, 0x1f68, 0x1f6e, 0x1f69, 0x1f6f, 0x1fbf, 0x1fcf, 0x1ffe, - 0x1fdf, 0x3f, 0x391, 0x1fbc, 0x397, 0x1fcc, 0x3a9, 0x1ffc, - 0x3ac, 0x1fb4, 0x3ae, 0x1fc4, 0x3b1, 0x1fb3, 0x3b7, 0x1fc3, - 0x3c9, 0x1ff3, 0x3ce, 0x1ff4, 0x1f00, 0x1f80, 0x1f01, 0x1f81, - 0x1f02, 0x1f82, 0x1f03, 0x1f83, 0x1f04, 0x1f84, 0x1f05, 0x1f85, - 0x1f06, 0x1f86, 0x1f07, 0x1f87, 0x1f08, 0x1f88, 0x1f09, 0x1f89, - 0x1f0a, 0x1f8a, 0x1f0b, 0x1f8b, 0x1f0c, 0x1f8c, 0x1f0d, 0x1f8d, - 0x1f0e, 0x1f8e, 0x1f0f, 0x1f8f, 0x1f20, 0x1f90, 0x1f21, 0x1f91, - 0x1f22, 0x1f92, 0x1f23, 0x1f93, 0x1f24, 0x1f94, 0x1f25, 0x1f95, - 0x1f26, 0x1f96, 0x1f27, 0x1f97, 0x1f28, 0x1f98, 0x1f29, 0x1f99, - 0x1f2a, 0x1f9a, 0x1f2b, 0x1f9b, 0x1f2c, 0x1f9c, 0x1f2d, 0x1f9d, - 0x1f2e, 0x1f9e, 0x1f2f, 0x1f9f, 0x1f60, 0x1fa0, 0x1f61, 0x1fa1, - 0x1f62, 0x1fa2, 0x1f63, 0x1fa3, 0x1f64, 0x1fa4, 0x1f65, 0x1fa5, - 0x1f66, 0x1fa6, 0x1f67, 0x1fa7, 0x1f68, 0x1fa8, 0x1f69, 0x1fa9, - 0x1f6a, 0x1faa, 0x1f6b, 0x1fab, 0x1f6c, 0x1fac, 0x1f6d, 0x1fad, - 0x1f6e, 0x1fae, 0x1f6f, 0x1faf, 0x1f70, 0x1fb2, 0x1f74, 0x1fc2, - 0x1f7c, 0x1ff2, 0x1fb6, 0x1fb7, 0x1fc6, 0x1fc7, 0x1ff6, 0x1ff7, - 0x1, 0x627, 0x622, 0x6, 0x627, 0x623, 0x648, 0x624, - 0x64a, 0x626, 0x6c1, 0x6c2, 0x6d2, 0x6d3, 0x6d5, 0x6c0, - 0x1, 0x627, 0x625, 0x3, 0x928, 0x929, 0x930, 0x931, - 0x933, 0x934, 0x1, 0x9c7, 0x9cb, 0x1, 0x9c7, 0x9cc, - 0x1, 0xb47, 0xb4b, 0x1, 0xb47, 0xb48, 0x1, 0xb47, - 0xb4c, 0x2, 0xbc6, 0xbca, 0xbc7, 0xbcb, 0x2, 0xb92, - 0xb94, 0xbc6, 0xbcc, 0x1, 0xc46, 0xc48, 0x1, 0xcc6, - 0xcca, 0x3, 0xcbf, 0xcc0, 0xcc6, 0xcc7, 0xcca, 0xccb, - 0x1, 0xcc6, 0xcc8, 0x2, 0xd46, 0xd4a, 0xd47, 0xd4b, - 0x1, 0xd46, 0xd4c, 0x2, 0xdd9, 0xdda, 0xddc, 0xddd, - 0x1, 0xdd9, 0xddc, 0x1, 0xdd9, 0xdde, 0x1, 0x1025, - 0x1026, 0xb, 0x1b05, 0x1b06, 0x1b07, 0x1b08, 0x1b09, 0x1b0a, - 0x1b0b, 0x1b0c, 0x1b0d, 0x1b0e, 0x1b11, 0x1b12, 0x1b3a, 0x1b3b, - 0x1b3c, 0x1b3d, 0x1b3e, 0x1b40, 0x1b3f, 0x1b41, 0x1b42, 0x1b43, - 0x30, 0x3046, 0x3094, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, - 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, - 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, - 0x3060, 0x3061, 0x3062, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, - 0x3069, 0x306f, 0x3070, 0x3072, 0x3073, 0x3075, 0x3076, 0x3078, - 0x3079, 0x307b, 0x307c, 0x309d, 0x309e, 0x30a6, 0x30f4, 0x30ab, - 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, 0x30b1, 0x30b2, 0x30b3, - 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, 0x30b9, 0x30ba, 0x30bb, - 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, 0x30c1, 0x30c2, 0x30c4, - 0x30c5, 0x30c6, 0x30c7, 0x30c8, 0x30c9, 0x30cf, 0x30d0, 0x30d2, - 0x30d3, 0x30d5, 0x30d6, 0x30d8, 0x30d9, 0x30db, 0x30dc, 0x30ef, - 0x30f7, 0x30f0, 0x30f8, 0x30f1, 0x30f9, 0x30f2, 0x30fa, 0x30fd, - 0x30fe, 0xa, 0x306f, 0x3071, 0x3072, 0x3074, 0x3075, 0x3077, - 0x3078, 0x307a, 0x307b, 0x307d, 0x30cf, 0x30d1, 0x30d2, 0x30d4, - 0x30d5, 0x30d7, 0x30d8, 0x30da, 0x30db, 0x30dd, + 0x54, 0x41, 0xc0, 0x45, 0xc8, 0x49, 0xcc, 0x4e, + 0x1f8, 0x4f, 0xd2, 0x55, 0xd9, 0x57, 0x1e80, 0x59, + 0x1ef2, 0x61, 0xe0, 0x65, 0xe8, 0x69, 0xec, 0x6e, + 0x1f9, 0x6f, 0xf2, 0x75, 0xf9, 0x77, 0x1e81, 0x79, + 0x1ef3, 0xa8, 0x1fed, 0xc2, 0x1ea6, 0xca, 0x1ec0, 0xd4, + 0x1ed2, 0xdc, 0x1db, 0xe2, 0x1ea7, 0xea, 0x1ec1, 0xf4, + 0x1ed3, 0xfc, 0x1dc, 0x102, 0x1eb0, 0x103, 0x1eb1, 0x112, + 0x1e14, 0x113, 0x1e15, 0x14c, 0x1e50, 0x14d, 0x1e51, 0x1a0, + 0x1edc, 0x1a1, 0x1edd, 0x1af, 0x1eea, 0x1b0, 0x1eeb, 0x391, + 0x1fba, 0x395, 0x1fc8, 0x397, 0x1fca, 0x399, 0x1fda, 0x39f, + 0x1ff8, 0x3a5, 0x1fea, 0x3a9, 0x1ffa, 0x3b1, 0x1f70, 0x3b5, + 0x1f72, 0x3b7, 0x1f74, 0x3b9, 0x1f76, 0x3bf, 0x1f78, 0x3c5, + 0x1f7a, 0x3c9, 0x1f7c, 0x3ca, 0x1fd2, 0x3cb, 0x1fe2, 0x415, + 0x400, 0x418, 0x40d, 0x435, 0x450, 0x438, 0x45d, 0x1f00, + 0x1f02, 0x1f01, 0x1f03, 0x1f08, 0x1f0a, 0x1f09, 0x1f0b, 0x1f10, + 0x1f12, 0x1f11, 0x1f13, 0x1f18, 0x1f1a, 0x1f19, 0x1f1b, 0x1f20, + 0x1f22, 0x1f21, 0x1f23, 0x1f28, 0x1f2a, 0x1f29, 0x1f2b, 0x1f30, + 0x1f32, 0x1f31, 0x1f33, 0x1f38, 0x1f3a, 0x1f39, 0x1f3b, 0x1f40, + 0x1f42, 0x1f41, 0x1f43, 0x1f48, 0x1f4a, 0x1f49, 0x1f4b, 0x1f50, + 0x1f52, 0x1f51, 0x1f53, 0x1f59, 0x1f5b, 0x1f60, 0x1f62, 0x1f61, + 0x1f63, 0x1f68, 0x1f6a, 0x1f69, 0x1f6b, 0x1fbf, 0x1fcd, 0x1ffe, + 0x1fdd, 0x75, 0x41, 0xc1, 0x43, 0x106, 0x45, 0xc9, + 0x47, 0x1f4, 0x49, 0xcd, 0x4b, 0x1e30, 0x4c, 0x139, + 0x4d, 0x1e3e, 0x4e, 0x143, 0x4f, 0xd3, 0x50, 0x1e54, + 0x52, 0x154, 0x53, 0x15a, 0x55, 0xda, 0x57, 0x1e82, + 0x59, 0xdd, 0x5a, 0x179, 0x61, 0xe1, 0x63, 0x107, + 0x65, 0xe9, 0x67, 0x1f5, 0x69, 0xed, 0x6b, 0x1e31, + 0x6c, 0x13a, 0x6d, 0x1e3f, 0x6e, 0x144, 0x6f, 0xf3, + 0x70, 0x1e55, 0x72, 0x155, 0x73, 0x15b, 0x75, 0xfa, + 0x77, 0x1e83, 0x79, 0xfd, 0x7a, 0x17a, 0xa8, 0x385, + 0xc2, 0x1ea4, 0xc5, 0x1fa, 0xc6, 0x1fc, 0xc7, 0x1e08, + 0xca, 0x1ebe, 0xcf, 0x1e2e, 0xd4, 0x1ed0, 0xd5, 0x1e4c, + 0xd8, 0x1fe, 0xdc, 0x1d7, 0xe2, 0x1ea5, 0xe5, 0x1fb, + 0xe6, 0x1fd, 0xe7, 0x1e09, 0xea, 0x1ebf, 0xef, 0x1e2f, + 0xf4, 0x1ed1, 0xf5, 0x1e4d, 0xf8, 0x1ff, 0xfc, 0x1d8, + 0x102, 0x1eae, 0x103, 0x1eaf, 0x112, 0x1e16, 0x113, 0x1e17, + 0x14c, 0x1e52, 0x14d, 0x1e53, 0x168, 0x1e78, 0x169, 0x1e79, + 0x1a0, 0x1eda, 0x1a1, 0x1edb, 0x1af, 0x1ee8, 0x1b0, 0x1ee9, + 0x391, 0x386, 0x395, 0x388, 0x397, 0x389, 0x399, 0x38a, + 0x39f, 0x38c, 0x3a5, 0x38e, 0x3a9, 0x38f, 0x3b1, 0x3ac, + 0x3b5, 0x3ad, 0x3b7, 0x3ae, 0x3b9, 0x3af, 0x3bf, 0x3cc, + 0x3c5, 0x3cd, 0x3c9, 0x3ce, 0x3ca, 0x390, 0x3cb, 0x3b0, + 0x3d2, 0x3d3, 0x413, 0x403, 0x41a, 0x40c, 0x433, 0x453, + 0x43a, 0x45c, 0x1f00, 0x1f04, 0x1f01, 0x1f05, 0x1f08, 0x1f0c, + 0x1f09, 0x1f0d, 0x1f10, 0x1f14, 0x1f11, 0x1f15, 0x1f18, 0x1f1c, + 0x1f19, 0x1f1d, 0x1f20, 0x1f24, 0x1f21, 0x1f25, 0x1f28, 0x1f2c, + 0x1f29, 0x1f2d, 0x1f30, 0x1f34, 0x1f31, 0x1f35, 0x1f38, 0x1f3c, + 0x1f39, 0x1f3d, 0x1f40, 0x1f44, 0x1f41, 0x1f45, 0x1f48, 0x1f4c, + 0x1f49, 0x1f4d, 0x1f50, 0x1f54, 0x1f51, 0x1f55, 0x1f59, 0x1f5d, + 0x1f60, 0x1f64, 0x1f61, 0x1f65, 0x1f68, 0x1f6c, 0x1f69, 0x1f6d, + 0x1fbf, 0x1fce, 0x1ffe, 0x1fde, 0x20, 0x41, 0xc2, 0x43, + 0x108, 0x45, 0xca, 0x47, 0x11c, 0x48, 0x124, 0x49, + 0xce, 0x4a, 0x134, 0x4f, 0xd4, 0x53, 0x15c, 0x55, + 0xdb, 0x57, 0x174, 0x59, 0x176, 0x5a, 0x1e90, 0x61, + 0xe2, 0x63, 0x109, 0x65, 0xea, 0x67, 0x11d, 0x68, + 0x125, 0x69, 0xee, 0x6a, 0x135, 0x6f, 0xf4, 0x73, + 0x15d, 0x75, 0xfb, 0x77, 0x175, 0x79, 0x177, 0x7a, + 0x1e91, 0x1ea0, 0x1eac, 0x1ea1, 0x1ead, 0x1eb8, 0x1ec6, 0x1eb9, + 0x1ec7, 0x1ecc, 0x1ed8, 0x1ecd, 0x1ed9, 0x1c, 0x41, 0xc3, + 0x45, 0x1ebc, 0x49, 0x128, 0x4e, 0xd1, 0x4f, 0xd5, + 0x55, 0x168, 0x56, 0x1e7c, 0x59, 0x1ef8, 0x61, 0xe3, + 0x65, 0x1ebd, 0x69, 0x129, 0x6e, 0xf1, 0x6f, 0xf5, + 0x75, 0x169, 0x76, 0x1e7d, 0x79, 0x1ef9, 0xc2, 0x1eaa, + 0xca, 0x1ec4, 0xd4, 0x1ed6, 0xe2, 0x1eab, 0xea, 0x1ec5, + 0xf4, 0x1ed7, 0x102, 0x1eb4, 0x103, 0x1eb5, 0x1a0, 0x1ee0, + 0x1a1, 0x1ee1, 0x1af, 0x1eee, 0x1b0, 0x1eef, 0x2c, 0x41, + 0x100, 0x45, 0x112, 0x47, 0x1e20, 0x49, 0x12a, 0x4f, + 0x14c, 0x55, 0x16a, 0x59, 0x232, 0x61, 0x101, 0x65, + 0x113, 0x67, 0x1e21, 0x69, 0x12b, 0x6f, 0x14d, 0x75, + 0x16b, 0x79, 0x233, 0xc4, 0x1de, 0xc6, 0x1e2, 0xd5, + 0x22c, 0xd6, 0x22a, 0xdc, 0x1d5, 0xe4, 0x1df, 0xe6, + 0x1e3, 0xf5, 0x22d, 0xf6, 0x22b, 0xfc, 0x1d6, 0x1ea, + 0x1ec, 0x1eb, 0x1ed, 0x226, 0x1e0, 0x227, 0x1e1, 0x22e, + 0x230, 0x22f, 0x231, 0x391, 0x1fb9, 0x399, 0x1fd9, 0x3a5, + 0x1fe9, 0x3b1, 0x1fb1, 0x3b9, 0x1fd1, 0x3c5, 0x1fe1, 0x418, + 0x4e2, 0x423, 0x4ee, 0x438, 0x4e3, 0x443, 0x4ef, 0x1e36, + 0x1e38, 0x1e37, 0x1e39, 0x1e5a, 0x1e5c, 0x1e5b, 0x1e5d, 0x20, + 0x41, 0x102, 0x45, 0x114, 0x47, 0x11e, 0x49, 0x12c, + 0x4f, 0x14e, 0x55, 0x16c, 0x61, 0x103, 0x65, 0x115, + 0x67, 0x11f, 0x69, 0x12d, 0x6f, 0x14f, 0x75, 0x16d, + 0x228, 0x1e1c, 0x229, 0x1e1d, 0x391, 0x1fb8, 0x399, 0x1fd8, + 0x3a5, 0x1fe8, 0x3b1, 0x1fb0, 0x3b9, 0x1fd0, 0x3c5, 0x1fe0, + 0x410, 0x4d0, 0x415, 0x4d6, 0x416, 0x4c1, 0x418, 0x419, + 0x423, 0x40e, 0x430, 0x4d1, 0x435, 0x4d7, 0x436, 0x4c2, + 0x438, 0x439, 0x443, 0x45e, 0x1ea0, 0x1eb6, 0x1ea1, 0x1eb7, + 0x2e, 0x41, 0x226, 0x42, 0x1e02, 0x43, 0x10a, 0x44, + 0x1e0a, 0x45, 0x116, 0x46, 0x1e1e, 0x47, 0x120, 0x48, + 0x1e22, 0x49, 0x130, 0x4d, 0x1e40, 0x4e, 0x1e44, 0x4f, + 0x22e, 0x50, 0x1e56, 0x52, 0x1e58, 0x53, 0x1e60, 0x54, + 0x1e6a, 0x57, 0x1e86, 0x58, 0x1e8a, 0x59, 0x1e8e, 0x5a, + 0x17b, 0x61, 0x227, 0x62, 0x1e03, 0x63, 0x10b, 0x64, + 0x1e0b, 0x65, 0x117, 0x66, 0x1e1f, 0x67, 0x121, 0x68, + 0x1e23, 0x6d, 0x1e41, 0x6e, 0x1e45, 0x6f, 0x22f, 0x70, + 0x1e57, 0x72, 0x1e59, 0x73, 0x1e61, 0x74, 0x1e6b, 0x77, + 0x1e87, 0x78, 0x1e8b, 0x79, 0x1e8f, 0x7a, 0x17c, 0x15a, + 0x1e64, 0x15b, 0x1e65, 0x160, 0x1e66, 0x161, 0x1e67, 0x17f, + 0x1e9b, 0x1e62, 0x1e68, 0x1e63, 0x1e69, 0x36, 0x41, 0xc4, + 0x45, 0xcb, 0x48, 0x1e26, 0x49, 0xcf, 0x4f, 0xd6, + 0x55, 0xdc, 0x57, 0x1e84, 0x58, 0x1e8c, 0x59, 0x178, + 0x61, 0xe4, 0x65, 0xeb, 0x68, 0x1e27, 0x69, 0xef, + 0x6f, 0xf6, 0x74, 0x1e97, 0x75, 0xfc, 0x77, 0x1e85, + 0x78, 0x1e8d, 0x79, 0xff, 0xd5, 0x1e4e, 0xf5, 0x1e4f, + 0x16a, 0x1e7a, 0x16b, 0x1e7b, 0x399, 0x3aa, 0x3a5, 0x3ab, + 0x3b9, 0x3ca, 0x3c5, 0x3cb, 0x3d2, 0x3d4, 0x406, 0x407, + 0x410, 0x4d2, 0x415, 0x401, 0x416, 0x4dc, 0x417, 0x4de, + 0x418, 0x4e4, 0x41e, 0x4e6, 0x423, 0x4f0, 0x427, 0x4f4, + 0x42b, 0x4f8, 0x42d, 0x4ec, 0x430, 0x4d3, 0x435, 0x451, + 0x436, 0x4dd, 0x437, 0x4df, 0x438, 0x4e5, 0x43e, 0x4e7, + 0x443, 0x4f1, 0x447, 0x4f5, 0x44b, 0x4f9, 0x44d, 0x4ed, + 0x456, 0x457, 0x4d8, 0x4da, 0x4d9, 0x4db, 0x4e8, 0x4ea, + 0x4e9, 0x4eb, 0x18, 0x41, 0x1ea2, 0x45, 0x1eba, 0x49, + 0x1ec8, 0x4f, 0x1ece, 0x55, 0x1ee6, 0x59, 0x1ef6, 0x61, + 0x1ea3, 0x65, 0x1ebb, 0x69, 0x1ec9, 0x6f, 0x1ecf, 0x75, + 0x1ee7, 0x79, 0x1ef7, 0xc2, 0x1ea8, 0xca, 0x1ec2, 0xd4, + 0x1ed4, 0xe2, 0x1ea9, 0xea, 0x1ec3, 0xf4, 0x1ed5, 0x102, + 0x1eb2, 0x103, 0x1eb3, 0x1a0, 0x1ede, 0x1a1, 0x1edf, 0x1af, + 0x1eec, 0x1b0, 0x1eed, 0x6, 0x41, 0xc5, 0x55, 0x16e, + 0x61, 0xe5, 0x75, 0x16f, 0x77, 0x1e98, 0x79, 0x1e99, + 0x6, 0x4f, 0x150, 0x55, 0x170, 0x6f, 0x151, 0x75, + 0x171, 0x423, 0x4f2, 0x443, 0x4f3, 0x25, 0x41, 0x1cd, + 0x43, 0x10c, 0x44, 0x10e, 0x45, 0x11a, 0x47, 0x1e6, + 0x48, 0x21e, 0x49, 0x1cf, 0x4b, 0x1e8, 0x4c, 0x13d, + 0x4e, 0x147, 0x4f, 0x1d1, 0x52, 0x158, 0x53, 0x160, + 0x54, 0x164, 0x55, 0x1d3, 0x5a, 0x17d, 0x61, 0x1ce, + 0x63, 0x10d, 0x64, 0x10f, 0x65, 0x11b, 0x67, 0x1e7, + 0x68, 0x21f, 0x69, 0x1d0, 0x6a, 0x1f0, 0x6b, 0x1e9, + 0x6c, 0x13e, 0x6e, 0x148, 0x6f, 0x1d2, 0x72, 0x159, + 0x73, 0x161, 0x74, 0x165, 0x75, 0x1d4, 0x7a, 0x17e, + 0xdc, 0x1d9, 0xfc, 0x1da, 0x1b7, 0x1ee, 0x292, 0x1ef, + 0xe, 0x41, 0x200, 0x45, 0x204, 0x49, 0x208, 0x4f, + 0x20c, 0x52, 0x210, 0x55, 0x214, 0x61, 0x201, 0x65, + 0x205, 0x69, 0x209, 0x6f, 0x20d, 0x72, 0x211, 0x75, + 0x215, 0x474, 0x476, 0x475, 0x477, 0xc, 0x41, 0x202, + 0x45, 0x206, 0x49, 0x20a, 0x4f, 0x20e, 0x52, 0x212, + 0x55, 0x216, 0x61, 0x203, 0x65, 0x207, 0x69, 0x20b, + 0x6f, 0x20f, 0x72, 0x213, 0x75, 0x217, 0xe, 0x391, + 0x1f08, 0x395, 0x1f18, 0x397, 0x1f28, 0x399, 0x1f38, 0x39f, + 0x1f48, 0x3a9, 0x1f68, 0x3b1, 0x1f00, 0x3b5, 0x1f10, 0x3b7, + 0x1f20, 0x3b9, 0x1f30, 0x3bf, 0x1f40, 0x3c1, 0x1fe4, 0x3c5, + 0x1f50, 0x3c9, 0x1f60, 0x10, 0x391, 0x1f09, 0x395, 0x1f19, + 0x397, 0x1f29, 0x399, 0x1f39, 0x39f, 0x1f49, 0x3a1, 0x1fec, + 0x3a5, 0x1f59, 0x3a9, 0x1f69, 0x3b1, 0x1f01, 0x3b5, 0x1f11, + 0x3b7, 0x1f21, 0x3b9, 0x1f31, 0x3bf, 0x1f41, 0x3c1, 0x1fe5, + 0x3c5, 0x1f51, 0x3c9, 0x1f61, 0x4, 0x4f, 0x1a0, 0x55, + 0x1af, 0x6f, 0x1a1, 0x75, 0x1b0, 0x2a, 0x41, 0x1ea0, + 0x42, 0x1e04, 0x44, 0x1e0c, 0x45, 0x1eb8, 0x48, 0x1e24, + 0x49, 0x1eca, 0x4b, 0x1e32, 0x4c, 0x1e36, 0x4d, 0x1e42, + 0x4e, 0x1e46, 0x4f, 0x1ecc, 0x52, 0x1e5a, 0x53, 0x1e62, + 0x54, 0x1e6c, 0x55, 0x1ee4, 0x56, 0x1e7e, 0x57, 0x1e88, + 0x59, 0x1ef4, 0x5a, 0x1e92, 0x61, 0x1ea1, 0x62, 0x1e05, + 0x64, 0x1e0d, 0x65, 0x1eb9, 0x68, 0x1e25, 0x69, 0x1ecb, + 0x6b, 0x1e33, 0x6c, 0x1e37, 0x6d, 0x1e43, 0x6e, 0x1e47, + 0x6f, 0x1ecd, 0x72, 0x1e5b, 0x73, 0x1e63, 0x74, 0x1e6d, + 0x75, 0x1ee5, 0x76, 0x1e7f, 0x77, 0x1e89, 0x79, 0x1ef5, + 0x7a, 0x1e93, 0x1a0, 0x1ee2, 0x1a1, 0x1ee3, 0x1af, 0x1ef0, + 0x1b0, 0x1ef1, 0x2, 0x55, 0x1e72, 0x75, 0x1e73, 0x2, + 0x41, 0x1e00, 0x61, 0x1e01, 0x4, 0x53, 0x218, 0x54, + 0x21a, 0x73, 0x219, 0x74, 0x21b, 0x16, 0x43, 0xc7, + 0x44, 0x1e10, 0x45, 0x228, 0x47, 0x122, 0x48, 0x1e28, + 0x4b, 0x136, 0x4c, 0x13b, 0x4e, 0x145, 0x52, 0x156, + 0x53, 0x15e, 0x54, 0x162, 0x63, 0xe7, 0x64, 0x1e11, + 0x65, 0x229, 0x67, 0x123, 0x68, 0x1e29, 0x6b, 0x137, + 0x6c, 0x13c, 0x6e, 0x146, 0x72, 0x157, 0x73, 0x15f, + 0x74, 0x163, 0xa, 0x41, 0x104, 0x45, 0x118, 0x49, + 0x12e, 0x4f, 0x1ea, 0x55, 0x172, 0x61, 0x105, 0x65, + 0x119, 0x69, 0x12f, 0x6f, 0x1eb, 0x75, 0x173, 0xc, + 0x44, 0x1e12, 0x45, 0x1e18, 0x4c, 0x1e3c, 0x4e, 0x1e4a, + 0x54, 0x1e70, 0x55, 0x1e76, 0x64, 0x1e13, 0x65, 0x1e19, + 0x6c, 0x1e3d, 0x6e, 0x1e4b, 0x74, 0x1e71, 0x75, 0x1e77, + 0x2, 0x48, 0x1e2a, 0x68, 0x1e2b, 0x6, 0x45, 0x1e1a, + 0x49, 0x1e2c, 0x55, 0x1e74, 0x65, 0x1e1b, 0x69, 0x1e2d, + 0x75, 0x1e75, 0x11, 0x42, 0x1e06, 0x44, 0x1e0e, 0x4b, + 0x1e34, 0x4c, 0x1e3a, 0x4e, 0x1e48, 0x52, 0x1e5e, 0x54, + 0x1e6e, 0x5a, 0x1e94, 0x62, 0x1e07, 0x64, 0x1e0f, 0x68, + 0x1e96, 0x6b, 0x1e35, 0x6c, 0x1e3b, 0x6e, 0x1e49, 0x72, + 0x1e5f, 0x74, 0x1e6f, 0x7a, 0x1e95, 0x2c, 0x3c, 0x226e, + 0x3d, 0x2260, 0x3e, 0x226f, 0x2190, 0x219a, 0x2192, 0x219b, + 0x2194, 0x21ae, 0x21d0, 0x21cd, 0x21d2, 0x21cf, 0x21d4, 0x21ce, + 0x2203, 0x2204, 0x2208, 0x2209, 0x220b, 0x220c, 0x2223, 0x2224, + 0x2225, 0x2226, 0x223c, 0x2241, 0x2243, 0x2244, 0x2245, 0x2247, + 0x2248, 0x2249, 0x224d, 0x226d, 0x2261, 0x2262, 0x2264, 0x2270, + 0x2265, 0x2271, 0x2272, 0x2274, 0x2273, 0x2275, 0x2276, 0x2278, + 0x2277, 0x2279, 0x227a, 0x2280, 0x227b, 0x2281, 0x227c, 0x22e0, + 0x227d, 0x22e1, 0x2282, 0x2284, 0x2283, 0x2285, 0x2286, 0x2288, + 0x2287, 0x2289, 0x2291, 0x22e2, 0x2292, 0x22e3, 0x22a2, 0x22ac, + 0x22a8, 0x22ad, 0x22a9, 0x22ae, 0x22ab, 0x22af, 0x22b2, 0x22ea, + 0x22b3, 0x22eb, 0x22b4, 0x22ec, 0x22b5, 0x22ed, 0x1d, 0xa8, + 0x1fc1, 0x3b1, 0x1fb6, 0x3b7, 0x1fc6, 0x3b9, 0x1fd6, 0x3c5, + 0x1fe6, 0x3c9, 0x1ff6, 0x3ca, 0x1fd7, 0x3cb, 0x1fe7, 0x1f00, + 0x1f06, 0x1f01, 0x1f07, 0x1f08, 0x1f0e, 0x1f09, 0x1f0f, 0x1f20, + 0x1f26, 0x1f21, 0x1f27, 0x1f28, 0x1f2e, 0x1f29, 0x1f2f, 0x1f30, + 0x1f36, 0x1f31, 0x1f37, 0x1f38, 0x1f3e, 0x1f39, 0x1f3f, 0x1f50, + 0x1f56, 0x1f51, 0x1f57, 0x1f59, 0x1f5f, 0x1f60, 0x1f66, 0x1f61, + 0x1f67, 0x1f68, 0x1f6e, 0x1f69, 0x1f6f, 0x1fbf, 0x1fcf, 0x1ffe, + 0x1fdf, 0x3f, 0x391, 0x1fbc, 0x397, 0x1fcc, 0x3a9, 0x1ffc, + 0x3ac, 0x1fb4, 0x3ae, 0x1fc4, 0x3b1, 0x1fb3, 0x3b7, 0x1fc3, + 0x3c9, 0x1ff3, 0x3ce, 0x1ff4, 0x1f00, 0x1f80, 0x1f01, 0x1f81, + 0x1f02, 0x1f82, 0x1f03, 0x1f83, 0x1f04, 0x1f84, 0x1f05, 0x1f85, + 0x1f06, 0x1f86, 0x1f07, 0x1f87, 0x1f08, 0x1f88, 0x1f09, 0x1f89, + 0x1f0a, 0x1f8a, 0x1f0b, 0x1f8b, 0x1f0c, 0x1f8c, 0x1f0d, 0x1f8d, + 0x1f0e, 0x1f8e, 0x1f0f, 0x1f8f, 0x1f20, 0x1f90, 0x1f21, 0x1f91, + 0x1f22, 0x1f92, 0x1f23, 0x1f93, 0x1f24, 0x1f94, 0x1f25, 0x1f95, + 0x1f26, 0x1f96, 0x1f27, 0x1f97, 0x1f28, 0x1f98, 0x1f29, 0x1f99, + 0x1f2a, 0x1f9a, 0x1f2b, 0x1f9b, 0x1f2c, 0x1f9c, 0x1f2d, 0x1f9d, + 0x1f2e, 0x1f9e, 0x1f2f, 0x1f9f, 0x1f60, 0x1fa0, 0x1f61, 0x1fa1, + 0x1f62, 0x1fa2, 0x1f63, 0x1fa3, 0x1f64, 0x1fa4, 0x1f65, 0x1fa5, + 0x1f66, 0x1fa6, 0x1f67, 0x1fa7, 0x1f68, 0x1fa8, 0x1f69, 0x1fa9, + 0x1f6a, 0x1faa, 0x1f6b, 0x1fab, 0x1f6c, 0x1fac, 0x1f6d, 0x1fad, + 0x1f6e, 0x1fae, 0x1f6f, 0x1faf, 0x1f70, 0x1fb2, 0x1f74, 0x1fc2, + 0x1f7c, 0x1ff2, 0x1fb6, 0x1fb7, 0x1fc6, 0x1fc7, 0x1ff6, 0x1ff7, + 0x1, 0x627, 0x622, 0x6, 0x627, 0x623, 0x648, 0x624, + 0x64a, 0x626, 0x6c1, 0x6c2, 0x6d2, 0x6d3, 0x6d5, 0x6c0, + 0x1, 0x627, 0x625, 0x3, 0x928, 0x929, 0x930, 0x931, + 0x933, 0x934, 0x1, 0x9c7, 0x9cb, 0x1, 0x9c7, 0x9cc, + 0x1, 0xb47, 0xb4b, 0x1, 0xb47, 0xb48, 0x1, 0xb47, + 0xb4c, 0x2, 0xbc6, 0xbca, 0xbc7, 0xbcb, 0x2, 0xb92, + 0xb94, 0xbc6, 0xbcc, 0x1, 0xc46, 0xc48, 0x1, 0xcc6, + 0xcca, 0x3, 0xcbf, 0xcc0, 0xcc6, 0xcc7, 0xcca, 0xccb, + 0x1, 0xcc6, 0xcc8, 0x2, 0xd46, 0xd4a, 0xd47, 0xd4b, + 0x1, 0xd46, 0xd4c, 0x2, 0xdd9, 0xdda, 0xddc, 0xddd, + 0x1, 0xdd9, 0xddc, 0x1, 0xdd9, 0xdde, 0x1, 0x1025, + 0x1026, 0xb, 0x1b05, 0x1b06, 0x1b07, 0x1b08, 0x1b09, 0x1b0a, + 0x1b0b, 0x1b0c, 0x1b0d, 0x1b0e, 0x1b11, 0x1b12, 0x1b3a, 0x1b3b, + 0x1b3c, 0x1b3d, 0x1b3e, 0x1b40, 0x1b3f, 0x1b41, 0x1b42, 0x1b43, + 0x30, 0x3046, 0x3094, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, + 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, + 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, + 0x3060, 0x3061, 0x3062, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306f, 0x3070, 0x3072, 0x3073, 0x3075, 0x3076, 0x3078, + 0x3079, 0x307b, 0x307c, 0x309d, 0x309e, 0x30a6, 0x30f4, 0x30ab, + 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, 0x30b1, 0x30b2, 0x30b3, + 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, 0x30b9, 0x30ba, 0x30bb, + 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, 0x30c1, 0x30c2, 0x30c4, + 0x30c5, 0x30c6, 0x30c7, 0x30c8, 0x30c9, 0x30cf, 0x30d0, 0x30d2, + 0x30d3, 0x30d5, 0x30d6, 0x30d8, 0x30d9, 0x30db, 0x30dc, 0x30ef, + 0x30f7, 0x30f0, 0x30f8, 0x30f1, 0x30f9, 0x30f2, 0x30fa, 0x30fd, + 0x30fe, 0xa, 0x306f, 0x3071, 0x3072, 0x3074, 0x3075, 0x3077, + 0x3078, 0x307a, 0x307b, 0x307d, 0x30cf, 0x30d1, 0x30d2, 0x30d4, + 0x30d5, 0x30d7, 0x30d8, 0x30da, 0x30db, 0x30dd, }; struct NormalizationCorrection { diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/tools/qunicodetables_p.h index ce426e7..625dee7 100644 --- a/src/corelib/tools/qunicodetables_p.h +++ b/src/corelib/tools/qunicodetables_p.h @@ -81,8 +81,8 @@ namespace QUnicodeTables { ushort wordBreak : 8; ushort sentenceBreak : 8; }; - Q_CORE_EXPORT const Properties* QT_FASTCALL properties(uint ucs4); - Q_CORE_EXPORT const Properties* QT_FASTCALL properties(ushort ucs2); + Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4); + Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2); // See http://www.unicode.org/reports/tr24/tr24-5.html -- cgit v0.12 From 9da6a1d34f1d06879ba9d72e9ad15bf261aea8c9 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Wed, 1 Jul 2009 13:29:58 +0200 Subject: Doc: correcting typo Correcting typos Task-number: 257225 --- src/gui/itemviews/qitemdelegate.cpp | 2 +- src/gui/itemviews/qstyleditemdelegate.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 264fa37..2dd5540 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -574,7 +574,7 @@ void QItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) con } /*! - Gets data drom the \a editor widget and stores it in the specified + Gets data from the \a editor widget and stores it in the specified \a model at the item \a index. The default implementation gets the value to be stored in the data diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index e528e58..edca724 100644 --- a/src/gui/itemviews/qstyleditemdelegate.cpp +++ b/src/gui/itemviews/qstyleditemdelegate.cpp @@ -508,7 +508,7 @@ void QStyledItemDelegate::setEditorData(QWidget *editor, const QModelIndex &inde } /*! - Gets data drom the \a editor widget and stores it in the specified + Gets data from the \a editor widget and stores it in the specified \a model at the item \a index. The default implementation gets the value to be stored in the data -- cgit v0.12 From f3a6f4dc01f9d6c5c167a94ae49acff35ccc0c11 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 1 Jul 2009 13:53:28 +0200 Subject: Fixed the build on Windows after regenerating the unicode tables. Reviewed-by: trustme --- src/corelib/tools/qunicodetables.cpp | 4 ++-- util/unicode/main.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp index 0387181..c103016 100644 --- a/src/corelib/tools/qunicodetables.cpp +++ b/src/corelib/tools/qunicodetables.cpp @@ -4336,13 +4336,13 @@ static inline const QUnicodeTables::Properties *qGetProp(ushort ucs2) return uc_properties + index; } -Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(uint ucs4) +Q_CORE_EXPORT const QUnicodeTables::Properties * QT_FASTCALL QUnicodeTables::properties(uint ucs4) { int index = GET_PROP_INDEX(ucs4); return uc_properties + index; } -Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(ushort ucs2) +Q_CORE_EXPORT const QUnicodeTables::Properties * QT_FASTCALL QUnicodeTables::properties(ushort ucs2) { int index = GET_PROP_INDEX_UCS2(ucs2); return uc_properties + index; diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index 3c32e6d..c24486b 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -2052,13 +2052,13 @@ static QByteArray createPropertyInfo() " return uc_properties + index;\n" "}\n" "\n" - "Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(uint ucs4)\n" + "Q_CORE_EXPORT const QUnicodeTables::Properties * QT_FASTCALL QUnicodeTables::properties(uint ucs4)\n" "{\n" " int index = GET_PROP_INDEX(ucs4);\n" " return uc_properties + index;\n" "}\n" "\n" - "Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(ushort ucs2)\n" + "Q_CORE_EXPORT const QUnicodeTables::Properties * QT_FASTCALL QUnicodeTables::properties(ushort ucs2)\n" "{\n" " int index = GET_PROP_INDEX_UCS2(ucs2);\n" " return uc_properties + index;\n" -- cgit v0.12 From fe889557bcf3f4744205ba65b330276b5dc41c61 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Wed, 1 Jul 2009 13:57:46 +0200 Subject: Doc: clearifying docs - QProgressDialog Clearifying details on a warning about a function call (setValue()) Task-number: qtp 4.5Workarea --- src/gui/dialogs/qprogressdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/dialogs/qprogressdialog.cpp b/src/gui/dialogs/qprogressdialog.cpp index 959cdbc..580794b 100644 --- a/src/gui/dialogs/qprogressdialog.cpp +++ b/src/gui/dialogs/qprogressdialog.cpp @@ -626,7 +626,7 @@ int QProgressDialog::value() const \warning If the progress dialog is modal (see QProgressDialog::QProgressDialog()), - this function calls QApplication::processEvents(), so take care that + setValue() calls QApplication::processEvents(), so take care that this does not cause undesirable re-entrancy in your code. For example, don't use a QProgressDialog inside a paintEvent()! -- cgit v0.12 From f6872e6b7a18b946c7428916c7096b82560a9cc6 Mon Sep 17 00:00:00 2001 From: kh Date: Wed, 1 Jul 2009 14:18:57 +0200 Subject: Do not start Assistant without at least an empty page. Noticed while looking into task 256903, since in case there are no recent shown pages,we would start Assistant only showning the search. Task-number: 256903 Reviewed-by: kh --- tools/assistant/tools/assistant/centralwidget.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 385f0bb..64c2a80 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -427,8 +427,11 @@ void CentralWidget::setLastShownPages() QString::SkipEmptyParts); const int pageCount = lastShownPageList.count(); - if (pageCount == 0 && usesDefaultCollection) { - setSource(QUrl(QLatin1String("help"))); + if (pageCount == 0) { + if (usesDefaultCollection) + setSource(QUrl(QLatin1String("help"))); + else + setSource(QUrl(QLatin1String("about:blank"))); return; } -- cgit v0.12 From 1813a6d2bc0ba611cecd2d74dea75cd4644a9f95 Mon Sep 17 00:00:00 2001 From: kh Date: Wed, 1 Jul 2009 14:49:10 +0200 Subject: Sync with QtCreator. --- tools/assistant/tools/assistant/centralwidget.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 64c2a80..a384544 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -286,6 +286,10 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent) CentralWidget::~CentralWidget() { +#ifndef QT_NO_PRINTER + delete printer; +#endif + QHelpEngineCore engine(collectionFile, 0); if (!engine.setupData()) return; @@ -357,10 +361,10 @@ void CentralWidget::findNext() void CentralWidget::nextPage() { - if(tabWidget->currentIndex() < tabWidget->count() -1) - tabWidget->setCurrentIndex(tabWidget->currentIndex() +1); - else - tabWidget->setCurrentIndex(0); + int index = tabWidget->currentIndex() + 1; + if (index >= tabWidget->count()) + index = 0; + tabWidget->setCurrentIndex(index); } void CentralWidget::resetZoom() @@ -376,10 +380,9 @@ void CentralWidget::resetZoom() void CentralWidget::previousPage() { int index = tabWidget->currentIndex() -1; - if(index >= 0) - tabWidget->setCurrentIndex(index); - else - tabWidget->setCurrentIndex(tabWidget->count() -1); + if (index < 0) + index = tabWidget->count() -1; + tabWidget->setCurrentIndex(index); } void CentralWidget::findPrevious() @@ -400,7 +403,8 @@ void CentralWidget::closeTab() void CentralWidget::setSource(const QUrl &url) { HelpViewer *viewer = currentHelpViewer(); - HelpViewer *lastViewer = qobject_cast(tabWidget->widget(lastTabPage)); + HelpViewer *lastViewer = + qobject_cast(tabWidget->widget(lastTabPage)); if (!viewer && !lastViewer) { viewer = new HelpViewer(helpEngine, this); -- cgit v0.12 From 7c6ae7d93b2fe7fb3054798ad77b411608801388 Mon Sep 17 00:00:00 2001 From: kh Date: Wed, 1 Jul 2009 15:05:49 +0200 Subject: Sync with QtCreator. Reviewed-by: kh --- .../assistant/tools/assistant/bookmarkmanager.cpp | 54 +++++++++++++++++++--- tools/assistant/tools/assistant/bookmarkmanager.h | 8 ++++ tools/assistant/tools/assistant/mainwindow.cpp | 37 +++++++++++++-- tools/assistant/tools/assistant/mainwindow.h | 5 ++ 4 files changed, 94 insertions(+), 10 deletions(-) diff --git a/tools/assistant/tools/assistant/bookmarkmanager.cpp b/tools/assistant/tools/assistant/bookmarkmanager.cpp index 3bca573..250262e 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.cpp +++ b/tools/assistant/tools/assistant/bookmarkmanager.cpp @@ -347,7 +347,7 @@ void BookmarkWidget::filterChanged() filterBookmarkModel->setFilterRegExp(regExp); - QModelIndex index = treeView->indexAt(QPoint(1, 1)); + const QModelIndex &index = treeView->indexAt(QPoint(1, 1)); if (index.isValid()) treeView->setCurrentIndex(index); @@ -445,9 +445,10 @@ void BookmarkWidget::setup(bool showButtons) treeView = new TreeView(this); vlayout->addWidget(treeView); - QString system = QLatin1String("win"); #ifdef Q_OS_MAC - system = QLatin1String("mac"); +# define SYSTEM "mac" +#else +# define SYSTEM "win" #endif if (showButtons) { @@ -458,8 +459,8 @@ void BookmarkWidget::setup(bool showButtons) addButton = new QToolButton(this); addButton->setText(tr("Add")); - addButton->setIcon(QIcon(QString::fromUtf8( - ":/trolltech/assistant/images/%1/addtab.png").arg(system))); + addButton->setIcon(QIcon(QLatin1String(":/trolltech/assistant/images/" + SYSTEM "/addtab.png"))); addButton->setAutoRaise(true); addButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); hlayout->addWidget(addButton); @@ -467,8 +468,8 @@ void BookmarkWidget::setup(bool showButtons) removeButton = new QToolButton(this); removeButton->setText(tr("Remove")); - removeButton->setIcon(QIcon(QString::fromUtf8( - ":/trolltech/assistant/images/%1/closetab.png").arg(system))); + removeButton->setIcon(QIcon(QLatin1String(":/trolltech/assistant/images/" + SYSTEM "/closetab.png"))); removeButton->setAutoRaise(true); removeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); hlayout->addWidget(removeButton); @@ -626,6 +627,10 @@ BookmarkManager::BookmarkManager(QHelpEngineCore *_helpEngine) connect(treeModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(itemChanged(QStandardItem*))); + connect(treeModel, SIGNAL(itemChanged(QStandardItem*)), this, + SIGNAL(bookmarksChanged())); + connect(treeModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SIGNAL(bookmarksChanged())); } BookmarkManager::~BookmarkManager() @@ -736,6 +741,41 @@ void BookmarkManager::addNewBookmark(const QModelIndex &index, else treeModel->appendRow(item); listModel->appendRow(item->clone()); + emit bookmarksChanged(); +} + +void BookmarkManager::fillBookmarkMenu(QMenu *menu) +{ + if (!menu || !treeModel) + return; + + map.clear(); + fillBookmarkMenu(menu, treeModel->invisibleRootItem()); +} + +void BookmarkManager::fillBookmarkMenu(QMenu *menu, QStandardItem *root) +{ + for (int i = 0; i < root->rowCount(); ++i) { + QStandardItem *item = root->child(i); + if (item && item->data(Qt::UserRole + 10) + .toString() == QLatin1String("Folder")) { + QMenu* newMenu = menu->addMenu(folderIcon, item->text()); + if (item->rowCount() > 0) + fillBookmarkMenu(newMenu, item); + } else { + map.insert(menu->addAction(item->text()), item->index()); + } + } +} + +QUrl BookmarkManager::urlForAction(QAction* action) const +{ + if (map.contains(action)) { + const QModelIndex &index = map.value(action); + if (QStandardItem* item = treeModel->itemFromIndex(index)) + return QUrl(item->data(Qt::UserRole + 10).toString()); + } + return QUrl(); } void BookmarkManager::itemChanged(QStandardItem *item) diff --git a/tools/assistant/tools/assistant/bookmarkmanager.h b/tools/assistant/tools/assistant/bookmarkmanager.h index bf7af41..33db5b6 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.h +++ b/tools/assistant/tools/assistant/bookmarkmanager.h @@ -183,6 +183,12 @@ public: const QString &url); void setupBookmarkModels(); + void fillBookmarkMenu(QMenu *menu); + QUrl urlForAction(QAction* action) const; + +signals: + void bookmarksChanged(); + private slots: void itemChanged(QStandardItem *item); @@ -191,6 +197,7 @@ private: void removeBookmarkFolderItems(QStandardItem *item); void readBookmarksRecursive(const QStandardItem *item, QDataStream &stream, const qint32 depth) const; + void fillBookmarkMenu(QMenu *menu, QStandardItem *root); private: QString oldText; @@ -200,6 +207,7 @@ private: BookmarkModel *listModel; QStandardItem *renameItem; QHelpEngineCore *helpEngine; + QMap map; }; QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index 5b3e731..0340297 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -137,7 +137,14 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent) if (initHelpDB()) { setupFilterToolbar(); setupAddressToolbar(); + m_bookmarkManager->setupBookmarkModels(); + m_bookmarkMenu->addSeparator(); + m_bookmarkManager->fillBookmarkMenu(m_bookmarkMenu); + connect(m_bookmarkMenu, SIGNAL(triggered(QAction*)), this, + SLOT(showBookmark(QAction*))); + connect(m_bookmarkManager, SIGNAL(bookmarksChanged()), this, + SLOT(updateBookmarkMenu())); setWindowTitle(m_helpEngine->customValue(QLatin1String("WindowTitle"), defWindowTitle).toString()); @@ -370,6 +377,29 @@ void MainWindow::checkInitState() } } +void MainWindow::updateBookmarkMenu() +{ + if (m_bookmarkManager) { + m_bookmarkMenu->removeAction(m_bookmarkMenuAction); + + m_bookmarkMenu->clear(); + + m_bookmarkMenu->addAction(m_bookmarkMenuAction); + m_bookmarkMenu->addSeparator(); + + m_bookmarkManager->fillBookmarkMenu(m_bookmarkMenu); + } +} + +void MainWindow::showBookmark(QAction *action) +{ + if (m_bookmarkManager) { + const QUrl &url = m_bookmarkManager->urlForAction(action); + if (url.isValid()) + m_centralWidget->setSource(url); + } +} + void MainWindow::insertLastPages() { if (m_cmdLine->url().isValid()) @@ -495,9 +525,10 @@ void MainWindow::setupActions() tmp->setShortcuts(QList() << QKeySequence(tr("Ctrl+Alt+Left")) << QKeySequence(Qt::CTRL + Qt::Key_PageUp)); - menu = menuBar()->addMenu(tr("&Bookmarks")); - tmp = menu->addAction(tr("Add Bookmark..."), this, SLOT(addBookmark())); - tmp->setShortcut(tr("CTRL+D")); + m_bookmarkMenu = menuBar()->addMenu(tr("&Bookmarks")); + m_bookmarkMenuAction = m_bookmarkMenu->addAction(tr("Add Bookmark..."), + this, SLOT(addBookmark())); + m_bookmarkMenuAction->setShortcut(tr("CTRL+D")); menu = menuBar()->addMenu(tr("&Help")); m_aboutAction = menu->addAction(tr("About..."), this, SLOT(showAboutDialog())); diff --git a/tools/assistant/tools/assistant/mainwindow.h b/tools/assistant/tools/assistant/mainwindow.h index 9ab3185..f7df724 100644 --- a/tools/assistant/tools/assistant/mainwindow.h +++ b/tools/assistant/tools/assistant/mainwindow.h @@ -119,6 +119,9 @@ private slots: void qtDocumentationInstalled(bool newDocsInstalled); void checkInitState(); + void updateBookmarkMenu(); + void showBookmark(QAction *action); + private: bool initHelpDB(); void setupActions(); @@ -157,6 +160,8 @@ private: QMenu *m_viewMenu; QMenu *m_toolBarMenu; + QMenu *m_bookmarkMenu; + QAction *m_bookmarkMenuAction; CmdLineParser *m_cmdLine; -- cgit v0.12 From 3e303b195a79d555b907a6badbe4df5d4b8686b4 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 1 Jul 2009 16:07:01 -0700 Subject: Code cleanup Move the code from QDirectFBPaintEnginePrivate::(end|begin) into QDirectFBPaintEngine::(end|begin) Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 84 ++++++++++------------ 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 40bec0e..bac9f09 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -244,9 +244,6 @@ public: inline void updateClip(); void systemStateChanged(); - void begin(QPaintDevice *device); - void end(); - static IDirectFBSurface *getSurface(const QImage &img, bool *release); #ifdef QT_DIRECTFB_IMAGECACHE @@ -299,7 +296,34 @@ QDirectFBPaintEngine::~QDirectFBPaintEngine() bool QDirectFBPaintEngine::begin(QPaintDevice *device) { Q_D(QDirectFBPaintEngine); - d->begin(device); + d->lastLockedHeight = -1; + if (device->devType() == QInternal::CustomRaster) { + d->dfbDevice = static_cast(device); + } else if (d->device->devType() == QInternal::Pixmap) { + QPixmapData *data = static_cast(device)->pixmapData(); + Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); + QDirectFBPixmapData *dfbPixmapData = static_cast(data); + d->dfbDevice = static_cast(dfbPixmapData); + } + + if (d->dfbDevice) + d->surface = d->dfbDevice->directFBSurface(); + + if (!d->surface) { + qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", + device->devType()); + } + d->lockedMemory = 0; + + d->surface->GetSize(d->surface, &d->fbWidth, &d->fbHeight); + + d->setTransform(QTransform()); + d->antialiased = false; + d->setOpacity(255); + d->setCompositionMode(state()->compositionMode()); + d->dirtyClip = true; + d->setPen(state()->pen); + const bool status = QRasterPaintEngine::begin(device); // XXX: QRasterPaintEngine::begin() resets the capabilities @@ -311,8 +335,14 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device) bool QDirectFBPaintEngine::end() { Q_D(QDirectFBPaintEngine); - d->end(); - return QRasterPaintEngine::end(); + d->unlock(); + d->dfbDevice = 0; +#if (Q_DIRECTFB_VERSION >= 0x010000) + d->surface->ReleaseSource(d->surface); +#endif + d->surface->SetClip(d->surface, NULL); + d->surface = 0; + return true; } void QDirectFBPaintEngine::clipEnabledChanged() @@ -873,48 +903,6 @@ void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m) } } -void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) -{ - lastLockedHeight = -1; - if (device->devType() == QInternal::CustomRaster) - dfbDevice = static_cast(device); - else if (device->devType() == QInternal::Pixmap) { - QPixmapData *data = static_cast(device)->pixmapData(); - Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); - QDirectFBPixmapData* dfbPixmapData = static_cast(data); - dfbDevice = static_cast(dfbPixmapData); - } - - if (dfbDevice) - surface = dfbDevice->directFBSurface(); - - if (!surface) { - qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", - device->devType()); - } - lockedMemory = 0; - - surface->GetSize(surface, &fbWidth, &fbHeight); - - setTransform(QTransform()); - antialiased = false; - setOpacity(255); - setCompositionMode(q->state()->compositionMode()); - dirtyClip = true; - setPen(q->state()->pen); -} - -void QDirectFBPaintEnginePrivate::end() -{ - lockedMemory = 0; - dfbDevice = 0; -#if (Q_DIRECTFB_VERSION >= 0x010000) - surface->ReleaseSource(surface); -#endif - surface->SetClip(surface, NULL); - surface = 0; -} - void QDirectFBPaintEnginePrivate::setPen(const QPen &p) { pen = p; -- cgit v0.12 From 765a6676e04b19a9af298096f9d4f0a6e571ccbd Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 1 Jul 2009 16:11:50 -0700 Subject: Make sure we check the right device Also. Make sure to call QRasterPaintEngine::end() Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index bac9f09..e4ce230 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -299,7 +299,7 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device) d->lastLockedHeight = -1; if (device->devType() == QInternal::CustomRaster) { d->dfbDevice = static_cast(device); - } else if (d->device->devType() == QInternal::Pixmap) { + } else if (device->devType() == QInternal::Pixmap) { QPixmapData *data = static_cast(device)->pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbPixmapData = static_cast(data); @@ -342,7 +342,7 @@ bool QDirectFBPaintEngine::end() #endif d->surface->SetClip(d->surface, NULL); d->surface = 0; - return true; + return QRasterPaintEngine::end(); } void QDirectFBPaintEngine::clipEnabledChanged() -- cgit v0.12 From 35a4141f01ab9db910c85ccb89e76058aa3ac5cf Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 1 Jul 2009 17:58:49 -0700 Subject: We still need to Flip in NO_WM mode This ifdef was simply in the wrong place. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index 71e1fde..86ee62c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -364,6 +364,7 @@ void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, if (winOpacity != opacity) dfbWindow->SetOpacity(dfbWindow, winOpacity); } +#endif if (!(flipFlags & DSFLIP_BLIT)) { dfbSurface->Flip(dfbSurface, 0, flipFlags); } else { @@ -385,7 +386,6 @@ void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags); } } -#endif #ifdef QT_DIRECTFB_TIMING enum { Secs = 3 }; ++frames; -- cgit v0.12 From a24b8166631a9b1d80f8205cd0e450824166a25d Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 2 Jul 2009 14:59:14 +1000 Subject: Get more autotests passing/fixed up. --- src/sql/drivers/oci/qsql_oci.cpp | 7 +++++-- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 4 ++++ tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index bbbbc22..8d34dd8 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -1588,9 +1588,12 @@ void QOCICols::getValues(QVector &v, int index) } else if ((d->precisionPolicy == QSql::LowPrecisionInt64) && (fld.typ == QVariant::LongLong)) { qint64 qll = 0; - OCINumberToInt(d->err, reinterpret_cast(fld.data), sizeof(qint64), + int r = OCINumberToInt(d->err, reinterpret_cast(fld.data), sizeof(qint64), OCI_NUMBER_SIGNED, &qll); - v[index + i] = qll; + if(r == OCI_SUCCESS) + v[index + i] = qll; + else + v[index + i] = QVariant(); break; } else if ((d->precisionPolicy == QSql::LowPrecisionInt32) && (fld.typ == QVariant::Int)) { diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index a2f4a66..91533dd 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -132,6 +132,10 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase db ) if ( !db.isValid() ) return; QSqlQuery q( db ); + if (tst_Databases::isSqlServer(db)) { + QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON")); + QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF")); + } // please never ever change this table; otherwise fix all tests ;) if ( tst_Databases::isMSAccess( db ) ) { QVERIFY_SQL(q, exec( "create table " + qTableName( "qtest" ) + " ( id int not null, t_varchar varchar(40) not null," diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index a286fb9..28a2191 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -298,6 +298,7 @@ void tst_QSqlDatabase::createTestTables(QSqlDatabase db) q.exec("set table_type=innodb"); if (tst_Databases::isSqlServer(db)) { QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON")); + QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF")); } // please never ever change this table; otherwise fix all tests ;) @@ -1244,7 +1245,7 @@ void tst_QSqlDatabase::recordSQLServer() FieldDef("varchar(20)", QVariant::String, QString("Blah1")), FieldDef("bigint", QVariant::LongLong, 12345), FieldDef("int", QVariant::Int, 123456), - FieldDef("tinyint", QVariant::Int, 255), + FieldDef("tinyint", QVariant::UInt, 255), #ifdef QT3_SUPPORT FieldDef("image", QVariant::ByteArray, Q3CString("Blah1")), #endif @@ -1359,11 +1360,13 @@ void tst_QSqlDatabase::bigIntField() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + QString drvName = db.driverName(); QSqlQuery q(db); q.setForwardOnly(true); + if (drvName.startsWith("QOCI")) + q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64); - QString drvName = db.driverName(); if (drvName.startsWith("QMYSQL")) { QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bigint") + " (id int, t_s64bit bigint, t_u64bit bigint unsigned)")); } else if (drvName.startsWith("QPSQL") @@ -1372,6 +1375,8 @@ void tst_QSqlDatabase::bigIntField() QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bigint") + "(id int, t_s64bit bigint, t_u64bit bigint)")); } else if (drvName.startsWith("QOCI")) { QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bigint") + " (id int, t_s64bit int, t_u64bit int)")); + //} else if (drvName.startsWith("QIBASE")) { + // QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bigint") + " (id int, t_s64bit int64, t_u64bit int64)")); } else { QSKIP("no 64 bit integer support", SkipAll); } @@ -1401,10 +1406,15 @@ void tst_QSqlDatabase::bigIntField() } QVERIFY(q.exec("select * from " + qTableName("qtest_bigint") + " order by id")); QVERIFY(q.next()); + QCOMPARE(q.value(1).toDouble(), (double)ll); QCOMPARE(q.value(1).toLongLong(), ll); + if(drvName.startsWith("QOCI")) + QEXPECT_FAIL("", "Oracle driver lacks support for unsigned int64 types", Continue); QCOMPARE(q.value(2).toULongLong(), ull); QVERIFY(q.next()); QCOMPARE(q.value(1).toLongLong(), -ll); + if(drvName.startsWith("QOCI")) + QEXPECT_FAIL("", "Oracle driver lacks support for unsigned int64 types", Continue); QCOMPARE(q.value(2).toULongLong(), ull); } -- cgit v0.12 From 18055b3c3fe50337ee1af819839694674bdfb3ff Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 2 Jul 2009 15:00:03 +1000 Subject: Tinyint is unsigned, force it to such. Tinyint only supports 0-255, so mark it as unsigned despite sign flag, which have the time is inverted/wrong. --- src/sql/drivers/odbc/qsql_odbc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index e18a9eb..4f358ec 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -252,9 +252,11 @@ static QVariant::Type qDecodeODBCType(SQLSMALLINT sqltype, const T* p, bool isSi case SQL_SMALLINT: case SQL_INTEGER: case SQL_BIT: - case SQL_TINYINT: type = isSigned ? QVariant::Int : QVariant::UInt; break; + case SQL_TINYINT: + type = QVariant::UInt; + break; case SQL_BIGINT: type = isSigned ? QVariant::LongLong : QVariant::ULongLong; break; -- cgit v0.12 From cdfb2ed5096053314c0e23482609a1a491636ac1 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 10:16:20 +1000 Subject: Improve cetest error reporting. Reviewed-by: Michael Goddard --- .../qtestlib/wince/cetest/activesyncconnection.cpp | 6 ++-- tools/qtestlib/wince/cetest/remoteconnection.cpp | 32 ++++++++++++++++++++++ tools/qtestlib/wince/cetest/remoteconnection.h | 2 ++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index e8ca8f2..76e4a41 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -113,6 +113,8 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS CeCloseHandle(deviceHandle); return true; } + } else { + qWarning("Could not open %s: %s", qPrintable(localSource), qPrintable(file.errorString())); } return false; } @@ -120,7 +122,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS deleteFile(deviceDest); HANDLE deviceHandle = CeCreateFile(deviceDest.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (deviceHandle == INVALID_HANDLE_VALUE) { - debugOutput(QString::fromLatin1(" Could not create target file"), 2); + qWarning("Could not create %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData()); return false; } @@ -144,7 +146,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS if (toWrite == 0) break; if (!CeWriteFile(deviceHandle, data.data() , toWrite, &written, NULL)) { - debugOutput(QString::fromLatin1(" Could not write File"), 2); + qWarning("Could not write to %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData()); return false; } currentPos += written; diff --git a/tools/qtestlib/wince/cetest/remoteconnection.cpp b/tools/qtestlib/wince/cetest/remoteconnection.cpp index 547b211..75788e2 100644 --- a/tools/qtestlib/wince/cetest/remoteconnection.cpp +++ b/tools/qtestlib/wince/cetest/remoteconnection.cpp @@ -41,6 +41,38 @@ #include "remoteconnection.h" +QByteArray strwinerror(DWORD errorcode) +{ + QByteArray out(512, 0); + + DWORD ok = FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM, + 0, + errorcode, + 0, + out.data(), + out.size(), + 0 + ); + + if (!ok) { + qsnprintf(out.data(), out.size(), + "(error %d; additionally, error %d while looking up error string)", + (int)errorcode, (int)GetLastError()); + } + else { + out.resize(qstrlen(out.constData())); + if (out.endsWith("\r\n")) + out.chop(2); + + /* Append error number to error message for good measure */ + out.append(" ("); + out.append(QByteArray::number((int)errorcode)); + out.append(")"); + } + return out; +} + AbstractRemoteConnection::AbstractRemoteConnection() { } diff --git a/tools/qtestlib/wince/cetest/remoteconnection.h b/tools/qtestlib/wince/cetest/remoteconnection.h index 9c3e63d..f517009 100644 --- a/tools/qtestlib/wince/cetest/remoteconnection.h +++ b/tools/qtestlib/wince/cetest/remoteconnection.h @@ -79,4 +79,6 @@ public: virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0; }; +QByteArray strwinerror(DWORD); + #endif -- cgit v0.12 From fb1fa68ae8555deeaeaf6f193c678269c85ffc4d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 11:42:25 +1000 Subject: Let QtRemote report the error code to cetest when creating the test process fails. This gives some hint to the user in the case of problems like missing DLLs, as opposed to silent failure. Reviewed-by: Michael Goddard --- tools/qtestlib/wince/cetest/activesyncconnection.cpp | 14 ++++++++++++-- tools/qtestlib/wince/remotelib/commands.cpp | 10 ++++++++-- tools/qtestlib/wince/remotelib/commands.h | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 76e4a41..99fac2c 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -382,6 +382,7 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo BYTE* output; IRAPIStream *stream; int returned = 0; + DWORD error = 0; HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); if (S_OK != res) { if (S_OK != CeGetLastError()) @@ -416,9 +417,18 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { qWarning(" Could not access return value of process"); } - result = true; - } + if (S_OK != stream->Read(&error, sizeof(error), &written)) { + qWarning(" Could not access error code"); + } + if (error) { + qWarning() << "Error on target:" << strwinerror(error); + result = false; + } + else { + result = true; + } + } if (returnValue) *returnValue = returned; diff --git a/tools/qtestlib/wince/remotelib/commands.cpp b/tools/qtestlib/wince/remotelib/commands.cpp index 3aed2d6..f2176dd 100644 --- a/tools/qtestlib/wince/remotelib/commands.cpp +++ b/tools/qtestlib/wince/remotelib/commands.cpp @@ -56,6 +56,7 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) wchar_t* arguments = 0; int timeout = -1; int returnValue = -2; + DWORD error = 0; if (S_OK != stream->Read(&appLength, sizeof(appLength), &bytesRead)) CLEAN_FAIL(-2); @@ -74,11 +75,13 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) if (S_OK != stream->Read(&timeout, sizeof(timeout), &bytesRead)) CLEAN_FAIL(-2); - bool result = qRemoteExecute(appName, arguments, &returnValue, timeout); + bool result = qRemoteExecute(appName, arguments, &returnValue, &error, timeout); if (timeout != 0) { if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) CLEAN_FAIL(-4); + if (S_OK != stream->Write(&error, sizeof(error), &bytesRead)) + CLEAN_FAIL(-5); } delete appName; delete arguments; @@ -90,13 +93,16 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) } -bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, int timeout) +bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, DWORD* error, int timeout) { + *error = 0; + if (!program) return false; PROCESS_INFORMATION pid; if (!CreateProcess(program, arguments, NULL, NULL, false, 0, NULL, NULL, NULL, &pid)) { + *error = GetLastError(); wprintf(L"Could not launch: %s\n", program); return false; } diff --git a/tools/qtestlib/wince/remotelib/commands.h b/tools/qtestlib/wince/remotelib/commands.h index 9f0b2e3..5275f2c 100644 --- a/tools/qtestlib/wince/remotelib/commands.h +++ b/tools/qtestlib/wince/remotelib/commands.h @@ -45,7 +45,7 @@ extern "C" { int __declspec(dllexport) qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream*); - bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , int timeout = -1); + bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , DWORD* error = NULL, int timeout = -1); } #endif -- cgit v0.12 From f126b8cc5733d2cd37dd2aad9119e482b0d4a0e6 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 2 Jul 2009 08:39:57 +0200 Subject: doc: Corrected several qdoc warnings. --- src/gui/graphicsview/qgraphicssceneevent.cpp | 35 ++++++++++++++-------------- src/gui/itemviews/qheaderview.h | 2 +- src/gui/kernel/qapplication.cpp | 2 +- src/qt3support/widgets/q3datetimeedit.cpp | 7 +++--- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 7906fb8..338f12a 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -1875,12 +1875,12 @@ void QGraphicsSceneGestureEvent::setGestures(const QSet &gestures) } /*! - Sets the accept flag of the all gestures inside the event object, - the equivalent of calling \l{QEvent::accept()}{accept()} or - \l{QEvent::setAccepted()}{setAccepted(true)}. + Sets the accept flag of the all gestures for the event object. + This is the equivalent of calling \l{QEvent::accept()} {accept()} + or \l{QEvent::setAccepted()}{setAccepted(true)}. - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent + Setting the accept flag indicates that the event receiver wants + the gesture. Unwanted gestures might be propagated to the parent widget. */ void QGraphicsSceneGestureEvent::acceptAll() @@ -1893,13 +1893,14 @@ void QGraphicsSceneGestureEvent::acceptAll() } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. + Sets the accept flag of the gesture specified by \a type. This is + equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> + \l{QGesture::accept()}{accept()} + + Setting the accept flag indicates that the event receiver + wants the gesture. Unwanted gestures might be propagated to the parent + widget. */ void QGraphicsSceneGestureEvent::accept(Qt::GestureType type) { @@ -1908,13 +1909,13 @@ void QGraphicsSceneGestureEvent::accept(Qt::GestureType type) } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. + Sets the accept flag of the gesture specified by \a type. This is + equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> + \l{QGesture::accept()}{accept()} + + Setting the accept flag indicates that the event receiver wants the + gesture. Unwanted gestures might be propagated to the parent widget. */ void QGraphicsSceneGestureEvent::accept(const QString &type) { diff --git a/src/gui/itemviews/qheaderview.h b/src/gui/itemviews/qheaderview.h index f752ae2..bf92667 100644 --- a/src/gui/itemviews/qheaderview.h +++ b/src/gui/itemviews/qheaderview.h @@ -221,7 +221,7 @@ protected: bool isIndexHidden(const QModelIndex &index) const; QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers); - void setSelection(const QRect&, QItemSelectionModel::SelectionFlags); + void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags); QRegion visualRegionForSelection(const QItemSelection &selection) const; void initStyleOption(QStyleOptionHeader *option) const; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 15ddce8..60c69cc 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5096,7 +5096,7 @@ void QApplication::removeGestureRecognizer(QGestureRecognizer *recognizer) The delay allows to postpone widget's input event handling until gestures framework can successfully recognize a gesture. - \sa QWidget::grabGesture + \sa QWidget::grabGesture() */ void QApplication::setEventDeliveryDelayForGestures(int delay) { diff --git a/src/qt3support/widgets/q3datetimeedit.cpp b/src/qt3support/widgets/q3datetimeedit.cpp index 4872642..9c2f289 100644 --- a/src/qt3support/widgets/q3datetimeedit.cpp +++ b/src/qt3support/widgets/q3datetimeedit.cpp @@ -2648,13 +2648,12 @@ Q3DateTimeEdit::~Q3DateTimeEdit() } -/*! +/*! \fn void Q3DateTimeEdit::resizeEvent(QResizeEvent *event) \reimp - Intercepts and handles resize events which have special meaning - for the Q3DateTimeEdit. + Intercepts and handles the resize \a event, which hase a + special meaning for the Q3DateTimeEdit. */ - void Q3DateTimeEdit::resizeEvent(QResizeEvent *) { int dw = de->sizeHint().width(); -- cgit v0.12 From 058c4f1cfd0536779ec99f3d89bdd90bf52ae20e Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 12:58:51 +1000 Subject: Let cetest deploy libraries other than for Qt to make it usable for running unit tests for projects outside of Qt. Let cetest look in the paths given with `-L' in LIBS, and to deploy libraries whose names don't start with `Qt'. This also fixes deployment of Qt autotests which link against phonon (the only Qt library whose name doesn't start with `Qt'). Reviewed-by: mauricek --- tools/qtestlib/wince/cetest/deployment.cpp | 34 +++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/tools/qtestlib/wince/cetest/deployment.cpp b/tools/qtestlib/wince/cetest/deployment.cpp index fec2735..68f0197 100644 --- a/tools/qtestlib/wince/cetest/deployment.cpp +++ b/tools/qtestlib/wince/cetest/deployment.cpp @@ -125,13 +125,37 @@ void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &depl if (!project->values("QMAKE_QT_DLL").isEmpty() && !project->values("QMAKE_LIBDIR").isEmpty()) { QStringList libs = project->values("LIBS"); QStringList qtLibs; + QStringList libPaths; foreach (QString item, libs) { - if (item.startsWith("-lQt")) { - qtLibs += project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + item.mid(2) + QLatin1String("4.dll"); + + if (item.startsWith("-L")) { + // -L -> a directory containing DLLs + libPaths << item.mid(2); + continue; + } + + QStringList libCandidates; + + if (item.startsWith("-l")) { + // -l -> a library located within one of the standard library paths + QString lib = item.mid(2); + + // Check if it's a Qt library first, then check in all paths given with -L. + // Note Qt libraries get a `4' appended to them, others don't. + libCandidates << project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + lib + QLatin1String("4.dll"); + foreach (QString const& libPath, libPaths) { + libCandidates << libPath + QDir::separator() + lib + QLatin1String(".dll"); + } } else { - QFileInfo info(item); - if (info.exists() && info.isAbsolute() && info.fileName().startsWith(QLatin1String("Qt"))) - qtLibs += info.dir().absoluteFilePath(info.fileName().replace(QLatin1String(".lib"), QLatin1String(".dll"))); + libCandidates << item.replace(".lib",".dll"); + } + + foreach (QString const& file, libCandidates) { + QFileInfo info(file); + if (info.exists()) { + qtLibs += info.dir().absoluteFilePath(info.fileName()); + break; + } } } for (QStringList::ConstIterator it = qtLibs.constBegin(); it != qtLibs.constEnd(); ++it) { -- cgit v0.12 From b4028f5a2195a432059ff26c288d772af47bc14d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 17:03:31 +1000 Subject: Fixed cetest compile. --- tools/qtestlib/wince/cetest/activesyncconnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 99fac2c..0f98619 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -422,7 +422,7 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo } if (error) { - qWarning() << "Error on target:" << strwinerror(error); + qWarning("Error on target: %s", strwinerror(error).constData()); result = false; } else { -- cgit v0.12 From 69083610b09aaabbff5e8a177fac713a6a6d46ba Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 2 Jul 2009 10:38:08 +0200 Subject: doc: Corrected several qdoc warnings. --- src/gui/graphicsview/qgraphicssceneevent.cpp | 5 ++++- src/gui/kernel/qevent.cpp | 4 ++++ src/gui/kernel/qgesturerecognizer.cpp | 7 ++++--- src/qt3support/sql/q3datatable.cpp | 2 -- tools/qdoc3/test/qt-cpp-ignore.qdocconf | 3 ++- tools/qdoc3/test/qt-inc.qdocconf | 3 ++- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 338f12a..27a2d7e 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -1892,8 +1892,11 @@ void QGraphicsSceneGestureEvent::acceptAll() setAccepted(true); } -/*! +/*! \fn void QGraphicsSceneGestureEvent::accept() + Calls QEvent::accept(). +*/ +/*! Sets the accept flag of the gesture specified by \a type. This is equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> \l{QGesture::accept()}{accept()} diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index e40ad9d..a7a7f2d 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3628,6 +3628,10 @@ QSet QGestureEvent::cancelledGestures() const return m_cancelledGestures; } +/*! \fn void QGestureEvent::accept() + Calls QEvent::accept(). +*/ + /*! Sets the accept flag of the all gestures inside the event object, the equivalent of calling \l{QEvent::accept()}{accept()} or diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp index c330663..30889d7 100644 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -97,8 +97,8 @@ QString qt_getStandardGestureTypeName(Qt::GestureType gestureType); This is a pure virtual function that needs to be implemented in subclasses. - Parses input \a event and returns the result, which specifies if - the event sequence is a gesture or not. + Parses input \a event and returns the result, which specifies + whether the event sequence is a gesture or not. */ /*! \fn QGesture* QGestureRecognizer::getGesture() @@ -123,7 +123,8 @@ QString qt_getStandardGestureTypeName(Qt::GestureType gestureType); The gesture recognizer might emit the stateChanged() signal when the gesture state changes asynchronously, i.e. without any event - being filtered through filterEvent(). + being filtered through filterEvent(). \a result specifies whether + the event sequence is a gesture or not. */ QGestureRecognizerPrivate::QGestureRecognizerPrivate() diff --git a/src/qt3support/sql/q3datatable.cpp b/src/qt3support/sql/q3datatable.cpp index 638aff8..d8d3c2b 100644 --- a/src/qt3support/sql/q3datatable.cpp +++ b/src/qt3support/sql/q3datatable.cpp @@ -1726,8 +1726,6 @@ void Q3DataTable::repaintCell( int row, int col ) the content coordinate system. If \a selected is true the cell has been selected and would normally be rendered differently than an unselected cell. - - \sa QSql::isNull() */ void Q3DataTable::paintCell( QPainter * p, int row, int col, const QRect & cr, diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf index 9a18abe..709e336 100644 --- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf +++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf @@ -68,7 +68,8 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \ QT_END_NAMESPACE \ QT_END_INCLUDE_NAMESPACE \ PHONON_EXPORT \ - Q_GADGET + Q_GADGET \ + QWEBKIT_EXPORT Cpp.ignoredirectives = Q_DECLARE_HANDLE \ Q_DECLARE_INTERFACE \ Q_DECLARE_METATYPE \ diff --git a/tools/qdoc3/test/qt-inc.qdocconf b/tools/qdoc3/test/qt-inc.qdocconf index 01b07b3..542c7ca 100644 --- a/tools/qdoc3/test/qt-inc.qdocconf +++ b/tools/qdoc3/test/qt-inc.qdocconf @@ -100,7 +100,8 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \ Q_TYPENAME \ Q_XML_EXPORT \ QDBUS_EXPORT \ - Q_GADGET + Q_GADGET \ + QWEBKIT_EXPORT Cpp.ignoredirectives = Q_DECLARE_HANDLE \ Q_DECLARE_INTERFACE \ Q_DECLARE_METATYPE \ -- cgit v0.12 From ad84039a4cb0d0057d2fc260e90f20cdd9761f46 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Thu, 2 Jul 2009 10:54:44 +0200 Subject: Doc: adding details to qmake docs Added documentation about the create_prl and link_prl to the CONFIG variable in the qmake manual Task-number: 165165 Rev-by: Geir Vattekar Rev-by: Volker Hilsheimer --- doc/src/qmake-manual.qdoc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index d840c71..afd881f 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -1019,6 +1019,25 @@ \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 24 + When linking a library, \c qmake relies on the underlying platform to know + what other libraries this library links against. However, if linking + statically, \c qmake will not get this information unless we use the following + \c CONFIG options: + + \table 95% + \header \o Option \o Description + \row \o create_prl \o This option enables \c qmake to track these + dependencies. When this option is enabled, \c qmake will create a file + ending in \c .prl which will save meta-information about the library + (see \l{LibDepend}{Library Dependencies} for more info). + \row \o link_prl \o When this is enabled, \c qmake will process all + libraries linked to by the application and find their meta-information + (see \l{LibDepend}{Library Dependencies} for more info). + \endtable + + Please note that \c create_prl is required when \i {building} a static library, + while \c link_prl is required when \i {using} a static library. + On Windows (or if Qt is configured with \c{-debug_and_release}, adding the \c build_all option to the \c CONFIG variable makes this rule the default when building the project, and installation targets will be created for -- cgit v0.12 From 353dacb5e4c45e860ae8be228df9647c5a71093e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 2 Jul 2009 10:54:09 +0200 Subject: add license headers --- tests/auto/linguist/lconvert/tst_lconvert.cpp | 41 +++++++++++++++++++++++++++ tests/auto/linguist/lrelease/tst_lrelease.cpp | 41 +++++++++++++++++++++++++++ tests/auto/linguist/lupdate/testlupdate.cpp | 41 +++++++++++++++++++++++++++ tests/auto/linguist/lupdate/testlupdate.h | 41 +++++++++++++++++++++++++++ tests/auto/linguist/lupdate/tst_lupdate.cpp | 41 +++++++++++++++++++++++++++ 5 files changed, 205 insertions(+) diff --git a/tests/auto/linguist/lconvert/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp index 3df2a19..40be55a 100644 --- a/tests/auto/linguist/lconvert/tst_lconvert.cpp +++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include #include diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp index 6f65dbc..512987d 100644 --- a/tests/auto/linguist/lrelease/tst_lrelease.cpp +++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include #include #include diff --git a/tests/auto/linguist/lupdate/testlupdate.cpp b/tests/auto/linguist/lupdate/testlupdate.cpp index c80dd54..8abc2b0 100644 --- a/tests/auto/linguist/lupdate/testlupdate.cpp +++ b/tests/auto/linguist/lupdate/testlupdate.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "testlupdate.h" #include #include diff --git a/tests/auto/linguist/lupdate/testlupdate.h b/tests/auto/linguist/lupdate/testlupdate.h index 3fd7dcb..efe9d85 100644 --- a/tests/auto/linguist/lupdate/testlupdate.h +++ b/tests/auto/linguist/lupdate/testlupdate.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef TESTLUPDATE_H #define TESTLUPDATE_H diff --git a/tests/auto/linguist/lupdate/tst_lupdate.cpp b/tests/auto/linguist/lupdate/tst_lupdate.cpp index 1beae73..fcf8582 100644 --- a/tests/auto/linguist/lupdate/tst_lupdate.cpp +++ b/tests/auto/linguist/lupdate/tst_lupdate.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "testlupdate.h" #if CHECK_SIMTEXTH #include "../shared/simtexth.h" -- cgit v0.12 From ad637177fa62f6ac92b653735bc2f743d7af2851 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 2 Jul 2009 11:10:36 +0200 Subject: add a few QObject binding tests --- tests/auto/qscriptqobject/tst_qscriptqobject.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp index 14d3283..ee914ab 100644 --- a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp +++ b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp @@ -605,6 +605,12 @@ void tst_QScriptExtQObject::getSetStaticProperty() QVERIFY(!(mobj.propertyFlags("mySlot") & QScriptValue::Undeletable)); QVERIFY(!(mobj.propertyFlags("mySlot") & QScriptValue::SkipInEnumeration)); QVERIFY(mobj.propertyFlags("mySlot") & QScriptValue::QObjectMember); + + // signature-based property + QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::ReadOnly)); + QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::Undeletable)); + QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::SkipInEnumeration)); + QVERIFY(mobj.propertyFlags("mySlot()") & QScriptValue::QObjectMember); } // property change in C++ should be reflected in script @@ -847,6 +853,9 @@ void tst_QScriptExtQObject::getSetStaticProperty() QVERIFY(slot.isFunction()); QScriptValue sameSlot = m_engine->evaluate("myObject.mySlot"); QVERIFY(sameSlot.strictlyEquals(slot)); + sameSlot = m_engine->evaluate("myObject['mySlot()']"); + QEXPECT_FAIL("", "Signature-based method lookup creates new function wrapper object", Continue); + QVERIFY(sameSlot.strictlyEquals(slot)); } } @@ -897,6 +906,20 @@ void tst_QScriptExtQObject::getSetChildren() QCOMPARE(m_engine->evaluate("myObject.hasOwnProperty('child')") .strictlyEquals(QScriptValue(m_engine, true)), true); + QScriptValue mobj = m_engine->evaluate("myObject"); + QVERIFY(mobj.propertyFlags("child") & QScriptValue::ReadOnly); + QVERIFY(mobj.propertyFlags("child") & QScriptValue::Undeletable); + QVERIFY(mobj.propertyFlags("child") & QScriptValue::SkipInEnumeration); + QVERIFY(!(mobj.propertyFlags("child") & QScriptValue::QObjectMember)); + + { + QScriptValue scriptChild = m_engine->evaluate("myObject.child"); + QVERIFY(scriptChild.isQObject()); + QCOMPARE(scriptChild.toQObject(), (QObject*)child); + QScriptValue sameChild = m_engine->evaluate("myObject.child"); + QVERIFY(sameChild.strictlyEquals(scriptChild)); + } + // add a grandchild MyQObject *grandChild = new MyQObject(child); grandChild->setObjectName("grandChild"); -- cgit v0.12 From cd4901b1e3a545d025628e881a143b8f240d2690 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 2 Jul 2009 11:37:53 +0200 Subject: doc: Corrected several qdoc warnings. --- doc/src/qnamespace.qdoc | 3 +++ src/gui/kernel/qapplication.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index 805855a..e77cc7e 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -1208,6 +1208,9 @@ handle touch events. Without this attribute set, events from a touch device will be sent as mouse events. + \value WA_TouchPadAcceptSingleTouchEvents Allows touchpad single + touch events to be sent to the widget. + \omitvalue WA_SetLayoutDirection \omitvalue WA_InputMethodTransparent \omitvalue WA_WState_CompressKeys diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 60c69cc..a7b7a0a 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5064,7 +5064,7 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy) Qt takes ownership of the provided \a recognizer. - \sa Qt::AA_EnableGestures, QGestureEvent + \sa QGestureEvent */ void QApplication::addGestureRecognizer(QGestureRecognizer *recognizer) { @@ -5076,7 +5076,7 @@ void QApplication::addGestureRecognizer(QGestureRecognizer *recognizer) Removes custom gesture \a recognizer object. - \sa Qt::AA_EnableGestures, QGestureEvent + \sa QGestureEvent */ void QApplication::removeGestureRecognizer(QGestureRecognizer *recognizer) { -- cgit v0.12 From 11ef1b9bae383c46f7893db0d26c99d354642609 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 20:50:32 +0200 Subject: Add a function to check if an interface is implemented by an object. Also reorganise a bit, moving the function to create the interface name from an object's class name to qdbusmisc.cpp too. Reviewed-By: Trust Me --- src/dbus/qdbusconnection_p.h | 5 ++--- src/dbus/qdbusintegrator.cpp | 8 ++----- src/dbus/qdbusmisc.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++ src/dbus/qdbusxmlgenerator.cpp | 37 --------------------------------- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 5c37509..a156a71 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -300,6 +300,8 @@ public: extern int qDBusParametersForMethod(const QMetaMethod &mm, QList& metaTypes); extern int qDBusNameToTypeId(const char *name); extern bool qDBusCheckAsyncTag(const char *tag); +extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name); +extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo); // in qdbusinternalfilters.cpp extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node); @@ -310,9 +312,6 @@ extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNod extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg); -// in qdbusxmlgenerator.cpp -extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo); - QT_END_NAMESPACE #endif diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 0578bf1..76179c9 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1359,12 +1359,8 @@ void QDBusConnectionPrivate::activateObject(ObjectTreeNode &node, const QDBusMes // try the object itself: if (node.flags & (QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportNonScriptableSlots)) { bool interfaceFound = true; - if (!msg.interface().isEmpty()) { - // check if the interface name matches anything in the class hierarchy - const QMetaObject *mo = node.obj->metaObject(); - for ( ; !interfaceFound && mo != &QObject::staticMetaObject; mo = mo->superClass()) - interfaceFound = msg.interface() == qDBusInterfaceFromMetaObject(mo); - } + if (!msg.interface().isEmpty()) + interfaceFound = qDBusInterfaceInObject(node.obj, msg.interface()); if (interfaceFound) { if (!activateCall(node.obj, node.flags, msg)) diff --git a/src/dbus/qdbusmisc.cpp b/src/dbus/qdbusmisc.cpp index e5c1da6..1b77a9b 100644 --- a/src/dbus/qdbusmisc.cpp +++ b/src/dbus/qdbusmisc.cpp @@ -41,12 +41,14 @@ #include +#include #include #include #include "qdbusutil_p.h" #include "qdbusconnection_p.h" #include "qdbusmetatype_p.h" +#include "qdbusabstractadaptor_p.h" // for QCLASSINFO_DBUS_* QT_BEGIN_NAMESPACE @@ -73,6 +75,51 @@ int qDBusNameToTypeId(const char *name) return id; } +QString qDBusInterfaceFromMetaObject(const QMetaObject *mo) +{ + QString interface; + + int idx = mo->indexOfClassInfo(QCLASSINFO_DBUS_INTERFACE); + if (idx >= mo->classInfoOffset()) { + interface = QLatin1String(mo->classInfo(idx).value()); + } else { + interface = QLatin1String(mo->className()); + interface.replace(QLatin1String("::"), QLatin1String(".")); + + if (interface.startsWith(QLatin1String("QDBus"))) { + interface.prepend(QLatin1String("com.trolltech.QtDBus.")); + } else if (interface.startsWith(QLatin1Char('Q')) && + interface.length() >= 2 && interface.at(1).isUpper()) { + // assume it's Qt + interface.prepend(QLatin1String("com.trolltech.Qt.")); + } else if (!QCoreApplication::instance()|| + QCoreApplication::instance()->applicationName().isEmpty()) { + interface.prepend(QLatin1String("local.")); + } else { + interface.prepend(QLatin1Char('.')).prepend(QCoreApplication::instance()->applicationName()); + QStringList domainName = + QCoreApplication::instance()->organizationDomain().split(QLatin1Char('.'), + QString::SkipEmptyParts); + if (domainName.isEmpty()) + interface.prepend(QLatin1String("local.")); + else + for (int i = 0; i < domainName.count(); ++i) + interface.prepend(QLatin1Char('.')).prepend(domainName.at(i)); + } + } + + return interface; +} + +bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name) +{ + const QMetaObject *mo = obj->metaObject(); + for ( ; mo != &QObject::staticMetaObject; mo = mo->superClass()) + if (interface_name == qDBusInterfaceFromMetaObject(mo)) + return true; + return false; +} + // calculates the metatypes for the method // the slot must have the parameters in the following form: // - zero or more value or const-ref parameters of any kind diff --git a/src/dbus/qdbusxmlgenerator.cpp b/src/dbus/qdbusxmlgenerator.cpp index 82bd762..b426abd 100644 --- a/src/dbus/qdbusxmlgenerator.cpp +++ b/src/dbus/qdbusxmlgenerator.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ -#include #include #include @@ -232,42 +231,6 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method return retval; } -QString qDBusInterfaceFromMetaObject(const QMetaObject *mo) -{ - QString interface; - - int idx = mo->indexOfClassInfo(QCLASSINFO_DBUS_INTERFACE); - if (idx >= mo->classInfoOffset()) { - interface = QLatin1String(mo->classInfo(idx).value()); - } else { - interface = QLatin1String(mo->className()); - interface.replace(QLatin1String("::"), QLatin1String(".")); - - if (interface.startsWith(QLatin1String("QDBus"))) { - interface.prepend(QLatin1String("com.trolltech.QtDBus.")); - } else if (interface.startsWith(QLatin1Char('Q')) && - interface.length() >= 2 && interface.at(1).isUpper()) { - // assume it's Qt - interface.prepend(QLatin1String("com.trolltech.Qt.")); - } else if (!QCoreApplication::instance()|| - QCoreApplication::instance()->applicationName().isEmpty()) { - interface.prepend(QLatin1String("local.")); - } else { - interface.prepend(QLatin1Char('.')).prepend(QCoreApplication::instance()->applicationName()); - QStringList domainName = - QCoreApplication::instance()->organizationDomain().split(QLatin1Char('.'), - QString::SkipEmptyParts); - if (domainName.isEmpty()) - interface.prepend(QLatin1String("local.")); - else - for (int i = 0; i < domainName.count(); ++i) - interface.prepend(QLatin1Char('.')).prepend(domainName.at(i)); - } - } - - return interface; - } - QString qDBusGenerateMetaObjectXml(QString interface, const QMetaObject *mo, const QMetaObject *base, int flags) { -- cgit v0.12 From 6bd18f891b4bbc265e5ddd18ba57095886b36e38 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 15:32:26 +0200 Subject: Add some new error codes for indicating invalid D-Bus parameters. I'm wondering if I should be adding com.trolltech.QtDBus stuff now. But since there's already one there, I don't see why not... Reviewed-By: Harald Fernengel --- src/dbus/qdbuserror.cpp | 11 ++++++++++- src/dbus/qdbuserror.h | 6 +++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/dbus/qdbuserror.cpp b/src/dbus/qdbuserror.cpp index 817356d..7509ded 100644 --- a/src/dbus/qdbuserror.cpp +++ b/src/dbus/qdbuserror.cpp @@ -91,6 +91,10 @@ org.freedesktop.DBus.Error.InvalidSignature org.freedesktop.DBus.Error.UnknownInterface com.trolltech.QtDBus.Error.InternalError org.freedesktop.DBus.Error.UnknownObject +com.trolltech.QtDBus.Error.InvalidService +com.trolltech.QtDBus.Error.InvalidObjectPath +com.trolltech.QtDBus.Error.InvalidInterface +com.trolltech.QtDBus.Error.InvalidMember */ // in the same order as KnownErrors! @@ -116,12 +120,17 @@ static const char errorMessages_string[] = "org.freedesktop.DBus.Error.UnknownInterface\0" "com.trolltech.QtDBus.Error.InternalError\0" "org.freedesktop.DBus.Error.UnknownObject\0" + "com.trolltech.QtDBus.Error.InvalidService\0" + "com.trolltech.QtDBus.Error.InvalidObjectPath\0" + "com.trolltech.QtDBus.Error.InvalidInterface\0" + "com.trolltech.QtDBus.Error.InvalidMember\0" "\0"; static const int errorMessages_indices[] = { 0, 6, 40, 76, 118, 153, 191, 231, 273, 313, 349, 384, 421, 461, 501, 540, - 581, 617, 661, 705, 746, 0 + 581, 617, 661, 705, 746, 787, 829, 874, + 918, 0 }; static const int errorMessages_count = sizeof errorMessages_indices / diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h index 7b77fd5..4e348dd 100644 --- a/src/dbus/qdbuserror.h +++ b/src/dbus/qdbuserror.h @@ -81,10 +81,14 @@ public: UnknownInterface, InternalError, UnknownObject, + InvalidService, + InvalidObjectPath, + InvalidInterface, + InvalidMember, #ifndef Q_QDOC // don't use this one! - LastErrorType = UnknownObject + LastErrorType = InvalidMember #endif }; -- cgit v0.12 From 96152ee50dfca7adf47b81b14015355260564a22 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 17:52:33 +0200 Subject: Add central validation code to QDBusUtil. These tests are useful in QDBusMessage and QDBusAbstractInterface. It avoids having the same messages all over the place. Reviewed-By: Harald Fernengel --- src/dbus/qdbusutil_p.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h index 13031fd..5c1e4cd 100644 --- a/src/dbus/qdbusutil_p.h +++ b/src/dbus/qdbusutil_p.h @@ -57,6 +57,7 @@ #include #include +#include QT_BEGIN_HEADER @@ -83,6 +84,73 @@ namespace QDBusUtil QDBUS_EXPORT bool isValidSingleSignature(const QString &signature); QDBUS_EXPORT QString argumentToString(const QVariant &variant); + + enum AllowEmptyFlag { + EmptyAllowed, + EmptyNotAllowed + }; + + inline bool checkInterfaceName(const QString &name, AllowEmptyFlag empty, QDBusError *error) + { + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidInterface, QLatin1String("Interface name cannot be empty")); + return false; + } + if (isValidInterfaceName(name)) return true; + *error = QDBusError(QDBusError::InvalidInterface, QString::fromLatin1("Invalid interface class: %1").arg(name)); + return false; + } + + inline bool checkBusName(const QString &name, AllowEmptyFlag empty, QDBusError *error) + { + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidService, QLatin1String("Service name cannot be empty")); + return false; + } + if (isValidBusName(name)) return true; + *error = QDBusError(QDBusError::InvalidService, QString::fromLatin1("Invalid service name: %1").arg(name)); + return false; + } + + inline bool checkObjectPath(const QString &path, AllowEmptyFlag empty, QDBusError *error) + { + if (path.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidObjectPath, QLatin1String("Object path cannot be empty")); + return false; + } + if (isValidObjectPath(path)) return true; + *error = QDBusError(QDBusError::InvalidObjectPath, QString::fromLatin1("Invalid object path: %1").arg(path)); + return false; + } + + inline bool checkMemberName(const QString &name, AllowEmptyFlag empty, QDBusError *error, const char *nameType = 0) + { + if (!nameType) nameType = "member"; + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidMember, QLatin1String(nameType) + QLatin1String(" name cannot be empty")); + return false; + } + if (isValidMemberName(name)) return true; + *error = QDBusError(QDBusError::InvalidMember, QString::fromLatin1("Invalid %1 name: %2") + .arg(QString::fromLatin1(nameType), name)); + return false; + } + + inline bool checkErrorName(const QString &name, AllowEmptyFlag empty, QDBusError *error) + { + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidInterface, QLatin1String("Error name cannot be empty")); + return false; + } + if (isValidErrorName(name)) return true; + *error = QDBusError(QDBusError::InvalidInterface, QString::fromLatin1("Invalid error name: %1").arg(name)); + return false; + } } QT_END_NAMESPACE -- cgit v0.12 From bda9c20a556aa6ab6ccba978f7fc1ffe02c50813 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 16:31:09 +0200 Subject: Add support for error messages in the D-Bus marshaller. Reviewed-By: Harald Fernengel --- src/dbus/qdbusargument_p.h | 3 ++- src/dbus/qdbusmarshaller.cpp | 35 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/dbus/qdbusargument_p.h b/src/dbus/qdbusargument_p.h index b49a517..78bc683 100644 --- a/src/dbus/qdbusargument_p.h +++ b/src/dbus/qdbusargument_p.h @@ -130,7 +130,7 @@ public: QDBusMarshaller *endCommon(); void open(QDBusMarshaller &sub, int code, const char *signature); void close(); - void error(); + void error(const QString &message); bool appendVariantInternal(const QVariant &arg); bool appendRegisteredType(const QVariant &arg); @@ -140,6 +140,7 @@ public: DBusMessageIter iterator; QDBusMarshaller *parent; QByteArray *ba; + QString errorString; char closeCode; bool ok; diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index 7ada1ed..bb7fa6b 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -121,7 +121,7 @@ inline void QDBusMarshaller::append(const QDBusObjectPath &arg) { QByteArray data = arg.path().toUtf8(); if (!ba && data.isEmpty()) - error(); + error(QLatin1String("Invalid object path passed in arguments")); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_OBJECT_PATH, &cdata); } @@ -130,7 +130,7 @@ inline void QDBusMarshaller::append(const QDBusSignature &arg) { QByteArray data = arg.signature().toUtf8(); if (!ba && data.isEmpty()) - error(); + error(QLatin1String("Invalid signature passed in arguments")); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_SIGNATURE, &cdata); } @@ -161,7 +161,7 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg) QVariant::Type id = QVariant::Type(value.userType()); if (id == QVariant::Invalid) { qWarning("QDBusMarshaller: cannot add a null QDBusVariant"); - error(); + error(QLatin1String("Variant containing QVariant::Invalid passed in arguments")); return false; } @@ -180,7 +180,8 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( id ), id); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(id)))); return false; } @@ -220,7 +221,8 @@ inline QDBusMarshaller *QDBusMarshaller::beginArray(int id) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( QVariant::Type(id) ), id); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(id))))); return this; } @@ -234,22 +236,26 @@ inline QDBusMarshaller *QDBusMarshaller::beginMap(int kid, int vid) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( QVariant::Type(kid) ), kid); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(kid))))); return this; } if (ksignature[1] != 0 || !q_dbus_type_is_basic(*ksignature)) { qWarning("QDBusMarshaller: type '%s' (%d) cannot be used as the key type in a D-BUS map.", QVariant::typeToName( QVariant::Type(kid) ), kid); - error(); + error(QString::fromLatin1("Type %1 passed in arguments cannot be used as a key in a map") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(kid))))); return this; } const char *vsignature = QDBusMetaType::typeToSignature( QVariant::Type(vid) ); if (!vsignature) { + const char *typeName = QVariant::typeToName(QVariant::Type(vid)); qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", - QVariant::typeToName( QVariant::Type(vid) ), vid); - error(); + typeName, vid); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(typeName))); return this; } @@ -328,11 +334,13 @@ void QDBusMarshaller::close() } } -void QDBusMarshaller::error() +void QDBusMarshaller::error(const QString &msg) { ok = false; if (parent) - parent->error(); + parent->error(msg); + else + errorString = msg; } bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) @@ -340,7 +348,7 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) int id = arg.userType(); if (id == QVariant::Invalid) { qWarning("QDBusMarshaller: cannot add an invalid QVariant"); - error(); + error(QLatin1String("Variant containing QVariant::Invalid passed in arguments")); return false; } @@ -371,7 +379,8 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( QVariant::Type(id) ), id); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(id))))); return false; } -- cgit v0.12 From 6b0b1a3eefe60dbeed3f56770fb58d487852e45b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 11:47:46 +0200 Subject: Adapt the message-sending code to return error messages from the marshalling code. Reviewed-By: Harald Fernengel --- src/dbus/qdbusintegrator.cpp | 89 +++++++++++++++----------- src/dbus/qdbusmessage.cpp | 48 ++++++++++---- src/dbus/qdbusmessage_p.h | 2 +- tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 16 ++++- 4 files changed, 104 insertions(+), 51 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 76179c9..704d2e3 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1144,9 +1144,12 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), interface, QLatin1String(memberName)); message.setArguments(args); - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + QDBusError error; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); if (!msg) { - qWarning("QDBusConnection: Could not emit signal %s.%s", qPrintable(interface), memberName.constData()); + qWarning("QDBusConnection: Could not emit signal %s.%s: %s", qPrintable(interface), memberName.constData(), + qPrintable(error.message())); + lastError = error; return; } @@ -1698,21 +1701,26 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message) return -1; // don't send; the reply will be retrieved by the caller // through the d_ptr->localReply link - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + QDBusError error; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); if (!msg) { if (message.type() == QDBusMessage::MethodCallMessage) - qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.service()), qPrintable(message.path()), - qPrintable(message.interface()), qPrintable(message.member())); + qPrintable(message.interface()), qPrintable(message.member()), + qPrintable(error.message())); else if (message.type() == QDBusMessage::SignalMessage) - qWarning("QDBusConnection: error: could not send signal path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send signal path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.path()), qPrintable(message.interface()), - qPrintable(message.member())); + qPrintable(message.member()), + qPrintable(error.message())); else - qWarning("QDBusConnection: error: could not send %s message to service \"%s\"", + qWarning("QDBusConnection: error: could not send %s message to service \"%s\": %s", message.type() == QDBusMessage::ReplyMessage ? "reply" : message.type() == QDBusMessage::ErrorMessage ? "error" : - "invalid", qPrintable(message.service())); + "invalid", qPrintable(message.service()), + qPrintable(error.message())); + lastError = error; return 0; } @@ -1739,12 +1747,15 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, return sendWithReplyLocal(message); if (!QCoreApplication::instance() || sendMode == QDBus::Block) { - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + QDBusError err; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &err); if (!msg) { - qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.service()), qPrintable(message.path()), - qPrintable(message.interface()), qPrintable(message.member())); - return QDBusMessage(); + qPrintable(message.interface()), qPrintable(message.member()), + qPrintable(err.message())); + lastError = err; + return QDBusMessage::createError(err); } qDBusDebug() << QThread::currentThread() << "sending message (blocking):" << message; @@ -1754,9 +1765,8 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, q_dbus_message_unref(msg); if (!!error) { - QDBusError qe = error; - lastError = qe; - return QDBusMessage::createError(qe); + lastError = err = error; + return QDBusMessage::createError(err); } QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(reply); @@ -1766,16 +1776,17 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, return amsg; } else { // use the event loop QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, timeout); - if (!pcall) - return QDBusMessage(); + Q_ASSERT(pcall); - pcall->watcherHelper = new QDBusPendingCallWatcherHelper; - QEventLoop loop; - loop.connect(pcall->watcherHelper, SIGNAL(reply(QDBusMessage)), SLOT(quit())); - loop.connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), SLOT(quit())); + if (pcall->replyMessage.type() != QDBusMessage::InvalidMessage) { + pcall->watcherHelper = new QDBusPendingCallWatcherHelper; + QEventLoop loop; + loop.connect(pcall->watcherHelper, SIGNAL(reply(QDBusMessage)), SLOT(quit())); + loop.connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), SLOT(quit())); - // enter the event loop and wait for a reply - loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); + // enter the event loop and wait for a reply + loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); + } QDBusMessage reply = pcall->replyMessage; lastError = reply; // set or clear error @@ -1831,20 +1842,25 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM return pcall; } - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + checkThread(); + QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; + pcall->sentMessage = message; + pcall->ref = 0; + + QDBusError error; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); if (!msg) { - qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.service()), qPrintable(message.path()), - qPrintable(message.interface()), qPrintable(message.member())); - return 0; + qPrintable(message.interface()), qPrintable(message.member()), + qPrintable(error.message())); + pcall->replyMessage = QDBusMessage::createError(error); + lastError = error; + return pcall; } - checkThread(); qDBusDebug() << QThread::currentThread() << "sending message (async):" << message; DBusPendingCall *pending = 0; - QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; - pcall->sentMessage = message; - pcall->ref = 0; QDBusDispatchLocker locker(SendWithReplyAsyncAction, this); if (q_dbus_connection_send_with_reply(connection, msg, &pending, timeout)) { @@ -1858,14 +1874,14 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM return pcall; } else { // we're probably disconnected at this point - lastError = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to server")); + lastError = error = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to server")); } } else { - lastError = QDBusError(QDBusError::NoMemory, QLatin1String("Out of memory")); + lastError = error = QDBusError(QDBusError::NoMemory, QLatin1String("Out of memory")); } q_dbus_message_unref(msg); - pcall->replyMessage = QDBusMessage::createError(lastError); + pcall->replyMessage = QDBusMessage::createError(error); return pcall; } @@ -1874,8 +1890,7 @@ int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObj int timeout) { QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, timeout); - if (!pcall) - return 0; + Q_ASSERT(pcall); // has it already finished (dispatched locally)? if (pcall->replyMessage.type() == QDBusMessage::ReplyMessage) { diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index 9150295..eb09de9 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -94,11 +94,17 @@ QString QDBusMessage::errorMessage() const \internal Constructs a DBusMessage object from this object. The returned value must be de-referenced with q_dbus_message_unref. + + The \a error object is set to indicate the error if anything went wrong with the + marshalling. Usually, this error message will be placed in the reply, as if the call failed. + The \a error pointer must not be null. */ -DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) +DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusError *error) { - if (!qdbus_loadLibDBus()) + if (!qdbus_loadLibDBus()) { + *error = QDBusError(QDBusError::Failed, QLatin1String("Could not open lidbus-1 library")); return 0; + } DBusMessage *msg = 0; const QDBusMessagePrivate *d_ptr = message.d_ptr; @@ -108,10 +114,17 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) //qDebug() << "QDBusMessagePrivate::toDBusMessage" << "message is invalid"; break; case DBUS_MESSAGE_TYPE_METHOD_CALL: - // only interface can be empty - if (d_ptr->service.isEmpty() || d_ptr->path.isEmpty() || d_ptr->name.isEmpty()) - break; - msg = q_dbus_message_new_method_call(d_ptr->service.toUtf8(), d_ptr->path.toUtf8(), + // only service and interface can be empty -> path and name must not be empty + if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + + msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(), data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8()); break; case DBUS_MESSAGE_TYPE_METHOD_RETURN: @@ -123,8 +136,9 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) break; case DBUS_MESSAGE_TYPE_ERROR: // error name can't be empty - if (d_ptr->name.isEmpty()) - break; + if (!QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) + return 0; + msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8()); if (!d_ptr->localMessage) { @@ -134,8 +148,13 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) break; case DBUS_MESSAGE_TYPE_SIGNAL: // nothing can be empty here - if (d_ptr->path.isEmpty() || d_ptr->interface.isEmpty() || d_ptr->name.isEmpty()) - break; + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(), d_ptr->name.toUtf8()); break; @@ -170,6 +189,7 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) // not ok; q_dbus_message_unref(msg); + *error = QDBusError(QDBusError::Failed, QLatin1String("Marshalling failed: ") + marshaller.errorString); return 0; } @@ -247,7 +267,13 @@ QDBusMessage QDBusMessagePrivate::makeLocal(const QDBusConnectionPrivate &conn, // yes, we are // we must marshall and demarshall again so as to create QDBusArgument // entries for the complex types - DBusMessage *message = toDBusMessage(asSent); + QDBusError error; + DBusMessage *message = toDBusMessage(asSent, &error); + if (!message) { + // failed to marshall, so it's a call error + return QDBusMessage::createError(error); + } + q_dbus_message_set_sender(message, conn.baseService.toUtf8()); QDBusMessage retval = fromDBusMessage(message); diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h index 12a9500..a0a681f 100644 --- a/src/dbus/qdbusmessage_p.h +++ b/src/dbus/qdbusmessage_p.h @@ -80,7 +80,7 @@ public: mutable uint delayedReply : 1; uint localMessage : 1; - static DBusMessage *toDBusMessage(const QDBusMessage &message); + static DBusMessage *toDBusMessage(const QDBusMessage &message, QDBusError *error); static QDBusMessage fromDBusMessage(DBusMessage *dmsg); static bool isLocal(const QDBusMessage &msg); diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index e5b2ebb..3ba789a 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -793,7 +793,7 @@ void tst_QDBusMarshall::sendErrors() "signalName"); msg << qVariantFromValue(QDBusObjectPath()); - QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\""); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid object path passed in arguments"); QVERIFY(!con.send(msg)); msg.setArguments(QVariantList()); @@ -803,7 +803,19 @@ void tst_QDBusMarshall::sendErrors() path.setPath("abc"); msg << qVariantFromValue(path); - QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\""); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid object path passed in arguments"); + QVERIFY(!con.send(msg)); + + QDBusSignature sig; + msg.setArguments(QVariantList() << qVariantFromValue(sig)); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid signature passed in arguments"); + QVERIFY(!con.send(msg)); + + QTest::ignoreMessage(QtWarningMsg, "QDBusSignature: invalid signature \"a\""); + sig.setSignature("a"); + msg.setArguments(QVariantList()); + msg << qVariantFromValue(sig); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid signature passed in arguments"); QVERIFY(!con.send(msg)); } -- cgit v0.12 From 8d4657764b0c4362dc25aa79a6e2853b8c98f0ad Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 15:20:33 +0200 Subject: Keep creation failure errors for QDBusAbstractInterface. In case the object creation fails, set isValid to false. This will prevent any outgoing calls to be made with invalid information. In that case, lastError will never change either. This required adding a method to QDBusPendingCall, to be able to create one such object from an existing QDBusError. Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusabstractinterface.cpp | 140 ++++++++++++++++++------------------ src/dbus/qdbusabstractinterface_p.h | 4 ++ src/dbus/qdbuspendingcall.cpp | 36 ++++++++++ src/dbus/qdbuspendingcall.h | 3 + src/dbus/qdbuspendingcall_p.h | 3 + 5 files changed, 116 insertions(+), 70 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 85c3274..a4097c6 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -52,82 +52,66 @@ QT_BEGIN_NAMESPACE +static QDBusError checkIfValid(const QString &service, const QString &path, + const QString &interface, bool isDynamic) +{ + // We should be throwing exceptions here... oh well + QDBusError error; + + // dynamic interfaces (QDBusInterface) can have empty interfaces, but not service and object paths + // non-dynamic is the opposite: service and object paths can be empty, but not the interface + if (!isDynamic) { + // use assertion here because this should never happen, at all + Q_ASSERT_X(!interface.isEmpty(), "QDBusAbstractInterface", "Interface name cannot be empty"); + } + if (!QDBusUtil::checkBusName(service, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error)) + return error; + if (!QDBusUtil::checkObjectPath(path, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error)) + return error; + if (!QDBusUtil::checkInterfaceName(interface, QDBusUtil::EmptyAllowed, &error)) + return error; + + // no error + return QDBusError(); +} + QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection& con, bool isDynamic) - : connection(con), service(serv), path(p), interface(iface), isValid(true) + : connection(con), service(serv), path(p), interface(iface), + lastError(checkIfValid(serv, p, iface, isDynamic)), + isValid(!lastError.isValid()) { - if (isDynamic) { - // QDBusInterface: service and object path can't be empty, but interface can -#if 0 - Q_ASSERT_X(QDBusUtil::isValidBusName(service), - "QDBusInterface::QDBusInterface", "Invalid service name"); - Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), - "QDBusInterface::QDBusInterface", "Invalid object path given"); - Q_ASSERT_X(interface.isEmpty() || QDBusUtil::isValidInterfaceName(interface), - "QDBusInterface::QDBusInterface", "Invalid interface name"); -#else - if (!QDBusUtil::isValidBusName(service)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid service name")); - isValid = false; - } else if (!QDBusUtil::isValidObjectPath(path)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid object name given")); - isValid = false; - } else if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid interface name")); - isValid = false; - } -#endif - } else { - // all others: service and path can be empty here, but interface can't -#if 0 - Q_ASSERT_X(service.isEmpty() || QDBusUtil::isValidBusName(service), - "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid service name"); - Q_ASSERT_X(path.isEmpty() || QDBusUtil::isValidObjectPath(path), - "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid object path given"); - Q_ASSERT_X(QDBusUtil::isValidInterfaceName(interface), - "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid interface class!"); -#else - if (!service.isEmpty() && !QDBusUtil::isValidBusName(service)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid service name")); - isValid = false; - } else if (!path.isEmpty() && !QDBusUtil::isValidObjectPath(path)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid object path given")); - isValid = false; - } else if (!QDBusUtil::isValidInterfaceName(interface)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid interface class")); - isValid = false; - } -#endif - } - if (!isValid) return; if (!connection.isConnected()) { lastError = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to D-Bus server")); - isValid = false; } else if (!service.isEmpty()) { currentOwner = connectionPrivate()->getNameOwner(service); // verify the name owner if (currentOwner.isEmpty()) { - isValid = false; lastError = connectionPrivate()->lastError; } } } +bool QDBusAbstractInterfacePrivate::canMakeCalls() const +{ + // recheck only if we have a wildcard (i.e. empty) service or path + // if any are empty, set the error message according to QDBusUtil + if (service.isEmpty()) + return QDBusUtil::checkBusName(service, QDBusUtil::EmptyNotAllowed, &lastError); + if (path.isEmpty()) + return QDBusUtil::checkObjectPath(path, QDBusUtil::EmptyNotAllowed, &lastError); + return true; +} + QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const { - if (!connection.isConnected()) // not connected + if (!isValid || !canMakeCalls()) // can't make calls return QVariant(); // is this metatype registered? @@ -144,6 +128,9 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be " "used to read property %s.%s", mp.typeName(), qPrintable(interface), mp.name()); + lastError = QDBusError(QDBusError::Failed, + QString::fromLatin1("Unregistered type %1 cannot be handled") + .arg(QLatin1String(mp.typeName()))); return QVariant(); } } @@ -208,7 +195,7 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) { - if (!connection.isConnected()) // not connected + if (!isValid || !canMakeCalls()) // can't make calls return; // send the value @@ -230,7 +217,6 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner; if (name == service) { currentOwner = newOwner; - isValid = !newOwner.isEmpty(); } } @@ -261,7 +247,7 @@ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, : QObject(d, parent) { // keep track of the service owner - if (d_func()->isValid) + if (!d_func()->currentOwner.isEmpty()) QObject::connect(d_func()->connectionPrivate(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } @@ -300,7 +286,7 @@ QDBusAbstractInterface::~QDBusAbstractInterface() */ bool QDBusAbstractInterface::isValid() const { - return d_func()->isValid; + return !d_func()->currentOwner.isEmpty(); } /*! @@ -367,6 +353,9 @@ QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode, { Q_D(QDBusAbstractInterface); + if (!d->isValid || !d->canMakeCalls()) + return QDBusMessage::createError(d->lastError); + QString m = method; // split out the signature from the method int pos = method.indexOf(QLatin1Char('.')); @@ -425,6 +414,9 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString { Q_D(QDBusAbstractInterface); + if (!d->isValid || !d->canMakeCalls()) + return QDBusPendingCall::fromError(d->lastError); + QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method); msg.setArguments(args); return d->connection.asyncCall(msg); @@ -440,7 +432,8 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString This function returns true if the queueing succeeds. It does not indicate that the executed call succeeded. If it fails, - the \a errorMethod is called. + the \a errorMethod is called. If the queueing failed, this + function returns false and no slot will be called. The \a returnMethod must have as its parameters the types returned by the function call. Optionally, it may have a QDBusMessage @@ -453,22 +446,25 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString bool QDBusAbstractInterface::callWithCallback(const QString &method, const QList &args, QObject *receiver, - const char *returnMethod, + const char *returnMethod, const char *errorMethod) { Q_D(QDBusAbstractInterface); + if (!d->isValid || !d->canMakeCalls()) + return false; + QDBusMessage msg = QDBusMessage::createMethodCall(service(), - path(), - interface(), - method); + path(), + interface(), + method); msg.setArguments(args); d->lastError = 0; return d->connection.callWithCallback(msg, - receiver, - returnMethod, - errorMethod); + receiver, + returnMethod, + errorMethod); } /*! @@ -492,7 +488,7 @@ bool QDBusAbstractInterface::callWithCallback(const QString &method, bool QDBusAbstractInterface::callWithCallback(const QString &method, const QList &args, QObject *receiver, - const char *slot) + const char *slot) { return callWithCallback(method, args, receiver, slot, 0); } @@ -503,13 +499,15 @@ bool QDBusAbstractInterface::callWithCallback(const QString &method, */ void QDBusAbstractInterface::connectNotify(const char *signal) { + // someone connecting to one of our signals + Q_D(QDBusAbstractInterface); + if (!d->isValid) + return; + // we end up recursing here, so optimise away if (qstrcmp(signal + 1, "destroyed(QObject*)") == 0) return; - // someone connecting to one of our signals - Q_D(QDBusAbstractInterface); - QDBusConnectionPrivate *conn = d->connectionPrivate(); if (conn) conn->connectRelay(d->service, d->currentOwner, d->path, d->interface, @@ -524,6 +522,8 @@ void QDBusAbstractInterface::disconnectNotify(const char *signal) { // someone disconnecting from one of our signals Q_D(QDBusAbstractInterface); + if (!d->isValid) + return; QDBusConnectionPrivate *conn = d->connectionPrivate(); if (conn) diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h index e2ea058..e5822b3 100644 --- a/src/dbus/qdbusabstractinterface_p.h +++ b/src/dbus/qdbusabstractinterface_p.h @@ -75,11 +75,15 @@ public: QString path; QString interface; mutable QDBusError lastError; + + // this is set during creation and never changed + // it can't be const because QDBusInterfacePrivate has one more check bool isValid; QDBusAbstractInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection& con, bool dynamic); virtual ~QDBusAbstractInterfacePrivate() { } + bool canMakeCalls() const; // these functions do not check if the property is valid QVariant property(const QMetaProperty &mp) const; diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 1797ed0..7807543 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -409,6 +409,42 @@ bool QDBusPendingCall::setReplyCallback(QObject *target, const char *member) } #endif +/*! + Creates a QDBusPendingCall object based on the error condition + \a error. The resulting pending call object will be in the + "finished" state and QDBusPendingReply::isError() will return true. + + \sa fromCompletedCall() +*/ +QDBusPendingCall QDBusPendingCall::fromError(const QDBusError &error) +{ + return fromCompletedCall(QDBusMessage::createError(error)); +} + +/*! + Creates a QDBusPendingCall object based on the message \a msg. + The message must be of type QDBusMessage::ErrorMessage or + QDBusMessage::ReplyMessage (that is, a message that is typical + of a completed call). + + This function is useful for code that requires simulating a pending + call, but that has already finished. + + \sa fromError() +*/ +QDBusPendingCall QDBusPendingCall::fromCompletedCall(const QDBusMessage &msg) +{ + QDBusPendingCallPrivate *d = 0; + if (msg.type() == QDBusMessage::ErrorMessage || + msg.type() == QDBusMessage::ReplyMessage) { + d = new QDBusPendingCallPrivate; + d->replyMessage = msg; + d->connection = 0; + } + + return QDBusPendingCall(d); +} + class QDBusPendingCallWatcherPrivate: public QObjectPrivate { diff --git a/src/dbus/qdbuspendingcall.h b/src/dbus/qdbuspendingcall.h index 8881920..8dbbb3c 100644 --- a/src/dbus/qdbuspendingcall.h +++ b/src/dbus/qdbuspendingcall.h @@ -78,6 +78,9 @@ public: QDBusMessage reply() const; #endif + static QDBusPendingCall fromError(const QDBusError &error); + static QDBusPendingCall fromCompletedCall(const QDBusMessage &message); + protected: QExplicitlySharedDataPointer d; friend class QDBusPendingCallPrivate; diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h index 7136f67..5577451 100644 --- a/src/dbus/qdbuspendingcall_p.h +++ b/src/dbus/qdbuspendingcall_p.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE +class QDBusPendingCall; class QDBusPendingCallWatcher; class QDBusPendingCallWatcherHelper; class QDBusConnectionPrivate; @@ -94,6 +95,8 @@ public: void waitForFinished(); void setMetaTypes(int count, const int *types); void checkReceivedSignature(); + + static QDBusPendingCall fromMessage(const QDBusMessage &msg); }; class QDBusPendingCallWatcherHelper: public QObject -- cgit v0.12 From e7ca74ed8a41eb4c05f436007417d160b6cf94f7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 11:13:47 +0200 Subject: Avoid revalidating message parameters. This is a small performance improvement when making a call: we don't need to validate what we already know to be valid because we either designed it to be so or because we've already validated. The D-Bus library unfortunately validates again and there's nothing we can do about it. But we can avoid doing it twice in our own code. Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusabstractinterface.cpp | 6 ++++ src/dbus/qdbusintegrator.cpp | 3 ++ src/dbus/qdbusinternalfilters.cpp | 2 +- src/dbus/qdbusmessage.cpp | 60 +++++++++++++++++++++---------------- src/dbus/qdbusmessage.h | 6 ++-- src/dbus/qdbusmessage_p.h | 9 ++++++ 6 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index a4097c6..08da997 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -44,6 +44,7 @@ #include "qdbusargument.h" #include "qdbuspendingcall.h" +#include "qdbusmessage_p.h" #include "qdbusmetaobject_p.h" #include "qdbusmetatype_p.h" #include "qdbusutil_p.h" @@ -139,6 +140,7 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Get")); + QDBusMessagePrivate::setParametersValidated(msg, true); msg << interface << QString::fromUtf8(mp.name()); QDBusMessage reply = connection.call(msg, QDBus::Block); @@ -202,6 +204,7 @@ void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const Q QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Set")); + QDBusMessagePrivate::setParametersValidated(msg, true); msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value)); QDBusMessage reply = connection.call(msg, QDBus::Block); @@ -386,6 +389,7 @@ QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode, // qDebug() << "QDBusAbstractInterface" << "Service" << service() << "Path:" << path(); QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), m); + QDBusMessagePrivate::setParametersValidated(msg, true); msg.setArguments(args); QDBusMessage reply = d->connection.call(msg, mode); @@ -418,6 +422,7 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString return QDBusPendingCall::fromError(d->lastError); QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method); + QDBusMessagePrivate::setParametersValidated(msg, true); msg.setArguments(args); return d->connection.asyncCall(msg); } @@ -458,6 +463,7 @@ bool QDBusAbstractInterface::callWithCallback(const QString &method, path(), interface(), method); + QDBusMessagePrivate::setParametersValidated(msg, true); msg.setArguments(args); d->lastError = 0; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 704d2e3..a0903ed 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1143,6 +1143,7 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in QDBusReadLocker locker(RelaySignalAction, this); QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), interface, QLatin1String(memberName)); + QDBusMessagePrivate::setParametersValidated(message, true); message.setArguments(args); QDBusError error; DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); @@ -2092,6 +2093,7 @@ QString QDBusConnectionPrivate::getNameOwner(const QString& serviceName) QDBusMessage msg = QDBusMessage::createMethodCall(QLatin1String(DBUS_SERVICE_DBUS), QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS), QLatin1String("GetNameOwner")); + QDBusMessagePrivate::setParametersValidated(msg, true); msg << serviceName; QDBusMessage reply = sendWithReply(msg, QDBus::Block); if (reply.type() == QDBusMessage::ReplyMessage) @@ -2115,6 +2117,7 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_INTROSPECTABLE), QLatin1String("Introspect")); + QDBusMessagePrivate::setParametersValidated(msg, true); QDBusMessage reply = sendWithReply(msg, QDBus::Block); diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index 416144d..762a49b 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -179,7 +179,7 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node static QDBusMessage qDBusPropertyError(const QDBusMessage &msg, const QString &interface_name) { - return msg.createErrorReply(QLatin1String(DBUS_ERROR_INVALID_ARGS), + return msg.createErrorReply(QDBusError::InvalidArgs, QString::fromLatin1("Interface %1 was not found in object %2") .arg(interface_name) .arg(msg.path())); diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index eb09de9..78de6d9 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -62,7 +62,8 @@ static inline const char *data(const QByteArray &arr) QDBusMessagePrivate::QDBusMessagePrivate() : msg(0), reply(0), type(DBUS_MESSAGE_TYPE_INVALID), - timeout(-1), localReply(0), ref(1), delayedReply(false), localMessage(false) + timeout(-1), localReply(0), ref(1), delayedReply(false), localMessage(false), + parametersValidated(false) { } @@ -115,14 +116,16 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB break; case DBUS_MESSAGE_TYPE_METHOD_CALL: // only service and interface can be empty -> path and name must not be empty - if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) - return 0; - if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) - return 0; - if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) - return 0; - if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) - return 0; + if (!d_ptr->parametersValidated) { + if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + } msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(), data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8()); @@ -136,7 +139,8 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB break; case DBUS_MESSAGE_TYPE_ERROR: // error name can't be empty - if (!QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) + if (!d_ptr->parametersValidated + && !QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) return 0; msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); @@ -148,12 +152,14 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB break; case DBUS_MESSAGE_TYPE_SIGNAL: // nothing can be empty here - if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) - return 0; - if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) - return 0; - if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) - return 0; + if (!d_ptr->parametersValidated) { + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + } msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(), d_ptr->name.toUtf8()); @@ -162,16 +168,11 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB Q_ASSERT(false); break; } -#if 0 - DBusError err; - q_dbus_error_init(&err); - if (q_dbus_error_is_set(&err)) { - QDBusError qe(&err); - qDebug() << "QDBusMessagePrivate::toDBusMessage" << qe; - } -#endif - if (!msg) - return 0; + + // if we got here, the parameters validated + // and since the message parameters cannot be changed once the message is created + // we can record this fact + d_ptr->parametersValidated = true; QDBusMarshaller marshaller; QVariantList::ConstIterator it = d_ptr->arguments.constBegin(); @@ -492,6 +493,13 @@ QDBusMessage QDBusMessage::createErrorReply(const QString name, const QString &m Constructs a new DBus reply message for the error type \a type using the message \a msg. Returns the DBus message. */ +QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType atype, const QString &amsg) const +{ + QDBusMessage msg = createErrorReply(QDBusError::errorString(atype), amsg); + msg.d_ptr->parametersValidated = true; + return msg; +} + /*! Constructs an empty, invalid QDBusMessage object. diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h index 55f388a..34b1635 100644 --- a/src/dbus/qdbusmessage.h +++ b/src/dbus/qdbusmessage.h @@ -87,8 +87,9 @@ public: QDBusMessage createErrorReply(const QString name, const QString &msg) const; inline QDBusMessage createErrorReply(const QDBusError &err) const { return createErrorReply(err.name(), err.message()); } - inline QDBusMessage createErrorReply(QDBusError::ErrorType type, const QString &msg) const; + QDBusMessage createErrorReply(QDBusError::ErrorType type, const QString &msg) const; + // there are no setters; if this changes, see qdbusmessage_p.h QString service() const; QString path() const; QString interface() const; @@ -113,9 +114,6 @@ private: QDBusMessagePrivate *d_ptr; }; -inline QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType atype, const QString &amsg) const -{ return createErrorReply(QDBusError::errorString(atype), amsg); } - #ifndef QT_NO_DEBUG_STREAM QDBUS_EXPORT QDebug operator<<(QDebug, const QDBusMessage &); #endif diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h index a0a681f..b8f23dc 100644 --- a/src/dbus/qdbusmessage_p.h +++ b/src/dbus/qdbusmessage_p.h @@ -55,6 +55,7 @@ #include #include +#include struct DBusMessage; @@ -69,7 +70,11 @@ public: ~QDBusMessagePrivate(); QList arguments; + + // the following parameters are "const": they are not changed after the constructors + // the parametersValidated member below controls whether they've been validated already QString service, path, interface, name, message, signature; + DBusMessage *msg; DBusMessage *reply; int type; @@ -79,6 +84,10 @@ public: mutable uint delayedReply : 1; uint localMessage : 1; + mutable uint parametersValidated : 1; + + static void setParametersValidated(QDBusMessage &msg, bool enable) + { msg.d_ptr->parametersValidated = enable; } static DBusMessage *toDBusMessage(const QDBusMessage &message, QDBusError *error); static QDBusMessage fromDBusMessage(DBusMessage *dmsg); -- cgit v0.12 From 485b2afb790444a0c6c2b32fbac65421e652dbe4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 18:27:11 +0200 Subject: Use an "int status" extra parameter in property reading/writing. When calling qt_metacall with the ReadProperty or WriteProperty, the data is on argv[0] like it was before, but now the QVariant itself is on argv[1] and there's an extra parameter in argv[2] which the meta code can use to indicate result. This allows QtDBus to process properties much more easily. In the case of property reading, we need to be able to modify the variant itself, because copying types when we don't have the data isn't very easy. As for setting, we need to be able to tell setProperty to return true or false depending on whether we succeeded in setting the property or not. Reviewed-By: Kent Hansen Reviewed-By: Marius Bugge Monsen --- src/corelib/kernel/qmetaobject.cpp | 23 ++++++++++++++++----- src/dbus/qdbusabstractinterface.cpp | 40 ++++++++++++++++++++++++++++++++----- src/dbus/qdbusabstractinterface.h | 18 ++++++++++++++++- src/dbus/qdbusabstractinterface_p.h | 2 +- src/dbus/qdbusinterface.cpp | 20 ------------------- 5 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 71dd5ff..34f580b 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2131,8 +2131,15 @@ QVariant QMetaProperty::read(const QObject *object) const return QVariant(); } } + + // the status variable is changed by qt_metacall to indicate what it did + // this feature is currently only used by QtDBus and should not be depended + // upon. Don't change it without looking into QDBusAbstractInterface first + // -1 (unchanged): normal qt_metacall, result stored in argv[0] + // changed: result stored directly in value + int status = -1; QVariant value; - void *argv[2] = { 0, &value }; + void *argv[] = { 0, &value, &status }; if (t == QVariant::LastType) { argv[0] = &value; } else { @@ -2142,8 +2149,8 @@ QVariant QMetaProperty::read(const QObject *object) const const_cast(object)->qt_metacall(QMetaObject::ReadProperty, idx + mobj->propertyOffset(), argv); - if (argv[1] == 0) - // "value" was changed + + if (status != -1) return value; if (t != QVariant::LastType && argv[0] != value.data()) // pointer or reference @@ -2201,13 +2208,19 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const return false; } - void *argv[2] = { 0, &v }; + // the status variable is changed by qt_metacall to indicate what it did + // this feature is currently only used by QtDBus and should not be depended + // upon. Don't change it without looking into QDBusAbstractInterface first + // -1 (unchanged): normal qt_metacall, result stored in argv[0] + // changed: result stored directly in value, return the value of status + int status = -1; + void *argv[] = { 0, &v, &status }; if (t == QVariant::LastType) argv[0] = &v; else argv[0] = v.data(); object->qt_metacall(QMetaObject::WriteProperty, idx + mobj->propertyOffset(), argv); - return true; + return status; } /*! diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 08da997..9bef2dd 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -195,10 +195,10 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const return QVariant(); } -void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) +bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) { if (!isValid || !canMakeCalls()) // can't make calls - return; + return false; // send the value QDBusMessage msg = QDBusMessage::createMethodCall(service, path, @@ -208,8 +208,11 @@ void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const Q msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value)); QDBusMessage reply = connection.call(msg, QDBus::Block); - if (reply.type() != QDBusMessage::ReplyMessage) + if (reply.type() != QDBusMessage::ReplyMessage) { lastError = reply; + return false; + } + return true; } void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, @@ -223,6 +226,33 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, } } +QDBusAbstractInterfaceBase::QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &d, QObject *parent) + : QObject(d, parent) +{ +} + +int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + int saved_id = _id; + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + + if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty) { + QMetaProperty mp = metaObject()->property(saved_id); + int &status = *reinterpret_cast(_a[2]); + QVariant &variant = *reinterpret_cast(_a[1]); + + if (_c == QMetaObject::WriteProperty) { + status = d_func()->setProperty(mp, variant) ? 1 : 0; + } else { + variant = d_func()->property(mp); + status = variant.isValid() ? 1 : 0; + } + _id = -1; + } + return _id; +} /*! \class QDBusAbstractInterface @@ -247,7 +277,7 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, This is the constructor called from QDBusInterface::QDBusInterface. */ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QObject *parent) - : QObject(d, parent) + : QDBusAbstractInterfaceBase(d, parent) { // keep track of the service owner if (!d_func()->currentOwner.isEmpty()) @@ -263,7 +293,7 @@ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QDBusAbstractInterface::QDBusAbstractInterface(const QString &service, const QString &path, const char *interface, const QDBusConnection &con, QObject *parent) - : QObject(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface), + : QDBusAbstractInterfaceBase(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface), con, false), parent) { // keep track of the service owner diff --git a/src/dbus/qdbusabstractinterface.h b/src/dbus/qdbusabstractinterface.h index 6400b26..e525f77 100644 --- a/src/dbus/qdbusabstractinterface.h +++ b/src/dbus/qdbusabstractinterface.h @@ -61,7 +61,23 @@ class QDBusError; class QDBusPendingCall; class QDBusAbstractInterfacePrivate; -class QDBUS_EXPORT QDBusAbstractInterface: public QObject + +class QDBUS_EXPORT QDBusAbstractInterfaceBase: public QObject +{ +public: + int qt_metacall(QMetaObject::Call, int, void**); +protected: + QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &dd, QObject *parent); +private: + Q_DECLARE_PRIVATE(QDBusAbstractInterface) +}; + +class QDBUS_EXPORT QDBusAbstractInterface: +#ifdef Q_QDOC + public QObject +#else + public QDBusAbstractInterfaceBase +#endif { Q_OBJECT diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h index e5822b3..e577898 100644 --- a/src/dbus/qdbusabstractinterface_p.h +++ b/src/dbus/qdbusabstractinterface_p.h @@ -87,7 +87,7 @@ public: // these functions do not check if the property is valid QVariant property(const QMetaProperty &mp) const; - void setProperty(const QMetaProperty &mp, const QVariant &value); + bool setProperty(const QMetaProperty &mp, const QVariant &value); // return conn's d pointer inline QDBusConnectionPrivate *connectionPrivate() const diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp index 211b717..6f61847 100644 --- a/src/dbus/qdbusinterface.cpp +++ b/src/dbus/qdbusinterface.cpp @@ -205,26 +205,6 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) // done return -1; } - } else if (c == QMetaObject::ReadProperty) { - // Qt doesn't support non-readable properties - // we have to re-check - QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset()); - if (!mp.isReadable()) - return -1; // don't read - - QVariant *value = reinterpret_cast(argv[1]); - argv[1] = 0; - *value = property(mp); - - return -1; // handled, error or not - } else if (c == QMetaObject::WriteProperty) { - // QMetaProperty::write has already checked that we're writable - // it has also checked that the type is right - QVariant *value = reinterpret_cast(argv[1]); - QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset()); - - setProperty(mp, *value); - return -1; } return id; } -- cgit v0.12 From c4fa498f447bd569ee91e16f07bdb7954b5adc76 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 20:52:35 +0200 Subject: Fix setting of complex/custom properties and error messages. Complex properties require demarshalling before passing on to QMetaProperty::write(). We can't pass on a QVariant containing an un-demarshalled QDBusArgument. So add a new function that does the decoding properly, as well as error checking. Also take the opportunity to properly check the interface name in the case of setting a property exported from the object itself (not an adaptor). Task-number: 240608 Reviewed-by: Marius Bugge Monsen --- src/dbus/qdbusinternalfilters.cpp | 167 +++++++++++++++++++++++++++++++------- 1 file changed, 136 insertions(+), 31 deletions(-) diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index 762a49b..45cbbb0 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -53,6 +53,7 @@ #include "qdbusextratypes.h" #include "qdbusmessage.h" #include "qdbusmetatype.h" +#include "qdbusmetatype_p.h" #include "qdbusmessage_p.h" #include "qdbusutil_p.h" @@ -177,14 +178,25 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node // implement the D-Bus interface org.freedesktop.DBus.Properties -static QDBusMessage qDBusPropertyError(const QDBusMessage &msg, const QString &interface_name) +static inline QDBusMessage interfaceNotFoundError(const QDBusMessage &msg, const QString &interface_name) { - return msg.createErrorReply(QDBusError::InvalidArgs, + return msg.createErrorReply(QDBusError::UnknownInterface, QString::fromLatin1("Interface %1 was not found in object %2") .arg(interface_name) .arg(msg.path())); } +static inline QDBusMessage +propertyNotFoundError(const QDBusMessage &msg, const QString &interface_name, const QByteArray &property_name) +{ + return msg.createErrorReply(QDBusError::InvalidArgs, + QString::fromLatin1("Property %1%2%3 was not found in object %4") + .arg(interface_name, + QString::fromLatin1(interface_name.isEmpty() ? "" : "."), + QString::fromLatin1(property_name), + msg.path())); +} + QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg) { @@ -198,6 +210,7 @@ QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node QDBusAdaptorConnector *connector; QVariant value; + bool interfaceFound = false; if (node.flags & QDBusConnection::ExportAdaptors && (connector = qDBusFindAdaptorConnector(node.obj))) { @@ -217,31 +230,122 @@ QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node QDBusAdaptorConnector::AdaptorMap::ConstIterator it; it = qLowerBound(connector->adaptors.constBegin(), connector->adaptors.constEnd(), interface_name); - if (it != connector->adaptors.constEnd() && interface_name == QLatin1String(it->interface)) + if (it != connector->adaptors.constEnd() && interface_name == QLatin1String(it->interface)) { + interfaceFound = true; value = it->adaptor->property(property_name); + } } } - if (!value.isValid() && node.flags & (QDBusConnection::ExportAllProperties | - QDBusConnection::ExportNonScriptableProperties)) { + if (!interfaceFound && !value.isValid() + && node.flags & (QDBusConnection::ExportAllProperties | + QDBusConnection::ExportNonScriptableProperties)) { // try the object itself - int pidx = node.obj->metaObject()->indexOfProperty(property_name); - if (pidx != -1) { - QMetaProperty mp = node.obj->metaObject()->property(pidx); - if ((mp.isScriptable() && (node.flags & QDBusConnection::ExportScriptableProperties)) || - (!mp.isScriptable() && (node.flags & QDBusConnection::ExportNonScriptableProperties))) - value = mp.read(node.obj); + if (!interface_name.isEmpty()) + interfaceFound = qDBusInterfaceInObject(node.obj, interface_name); + + if (interfaceFound) { + int pidx = node.obj->metaObject()->indexOfProperty(property_name); + if (pidx != -1) { + QMetaProperty mp = node.obj->metaObject()->property(pidx); + if ((mp.isScriptable() && (node.flags & QDBusConnection::ExportScriptableProperties)) || + (!mp.isScriptable() && (node.flags & QDBusConnection::ExportNonScriptableProperties))) + value = mp.read(node.obj); + } } } if (!value.isValid()) { // the property was not found - return qDBusPropertyError(msg, interface_name); + if (!interfaceFound) + return interfaceNotFoundError(msg, interface_name); + return propertyNotFoundError(msg, interface_name, property_name); } return msg.createReply(qVariantFromValue(QDBusVariant(value))); } +enum PropertyWriteResult { + PropertyWriteSuccess = 0, + PropertyNotFound, + PropertyTypeMismatch, + PropertyWriteFailed +}; + +static QDBusMessage propertyWriteReply(const QDBusMessage &msg, const QString &interface_name, + const QByteArray &property_name, int status) +{ + switch (status) { + case PropertyNotFound: + return propertyNotFoundError(msg, interface_name, property_name); + case PropertyTypeMismatch: + return msg.createErrorReply(QDBusError::InvalidArgs, + QString::fromLatin1("Invalid arguments for writing to property %1%2%3") + .arg(interface_name, + QString::fromLatin1(interface_name.isEmpty() ? "" : "."), + QString::fromLatin1(property_name))); + case PropertyWriteFailed: + return msg.createErrorReply(QDBusError::InternalError, + QString::fromLatin1("Internal error")); + + case PropertyWriteSuccess: + return msg.createReply(); + } + Q_ASSERT_X(false, "", "Should not be reached"); + return QDBusMessage(); +} + +static int writeProperty(QObject *obj, const QByteArray &property_name, QVariant value, + int propFlags = QDBusConnection::ExportAllProperties) +{ + const QMetaObject *mo = obj->metaObject(); + int pidx = mo->indexOfProperty(property_name); + if (pidx == -1) { + // this object has no property by that name + return PropertyNotFound; + } + + QMetaProperty mp = mo->property(pidx); + + // check if this property is exported + bool isScriptable = mp.isScriptable(); + if (!(propFlags & QDBusConnection::ExportScriptableProperties) && isScriptable) + return PropertyNotFound; + if (!(propFlags & QDBusConnection::ExportNonScriptableProperties) && !isScriptable) + return PropertyNotFound; + + // we found our property + // do we have the right type? + int id = mp.type(); + if (id == QVariant::UserType) { + // dynamic type + id = qDBusNameToTypeId(mp.typeName()); + if (id == -1) { + // type not registered? + qWarning("QDBusConnection: Unable to handle unregistered datatype '%s' for property '%s::%s'", + mp.typeName(), mo->className(), property_name.constData()); + return PropertyWriteFailed; + } + } + + if (id != 0xff && value.userType() == QDBusMetaTypeId::argument) { + // we have to demarshall before writing + void *null = 0; + QVariant other(id, null); + if (!QDBusMetaType::demarshall(qVariantValue(value), id, other.data())) { + qWarning("QDBusConnection: type `%s' (%d) is not registered with QtDBus. " + "Use qDBusRegisterMetaType to register it", + mp.typeName(), id); + return PropertyWriteFailed; + } + + value = other; + } + + // the property type here should match + return mp.write(obj, value) ? PropertyWriteSuccess : PropertyWriteFailed; +} + QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg) { @@ -263,38 +367,39 @@ QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node if (interface_name.isEmpty()) { for (QDBusAdaptorConnector::AdaptorMap::ConstIterator it = connector->adaptors.constBegin(), end = connector->adaptors.constEnd(); it != end; ++it) { - const QMetaObject *mo = it->adaptor->metaObject(); - int pidx = mo->indexOfProperty(property_name); - if (pidx != -1) { - mo->property(pidx).write(it->adaptor, value); - return msg.createReply(); - } + int status = writeProperty(it->adaptor, property_name, value); + if (status == PropertyNotFound) + continue; + return propertyWriteReply(msg, interface_name, property_name, status); } } else { QDBusAdaptorConnector::AdaptorMap::ConstIterator it; it = qLowerBound(connector->adaptors.constBegin(), connector->adaptors.constEnd(), interface_name); - if (it != connector->adaptors.end() && interface_name == QLatin1String(it->interface)) - if (it->adaptor->setProperty(property_name, value)) - return msg.createReply(); + if (it != connector->adaptors.end() && interface_name == QLatin1String(it->interface)) { + return propertyWriteReply(msg, interface_name, property_name, + writeProperty(it->adaptor, property_name, value)); + } } } if (node.flags & (QDBusConnection::ExportScriptableProperties | QDBusConnection::ExportNonScriptableProperties)) { // try the object itself - int pidx = node.obj->metaObject()->indexOfProperty(property_name); - if (pidx != -1) { - QMetaProperty mp = node.obj->metaObject()->property(pidx); - if ((mp.isScriptable() && (node.flags & QDBusConnection::ExportScriptableProperties)) || - (!mp.isScriptable() && (node.flags & QDBusConnection::ExportNonScriptableProperties))) - if (mp.write(node.obj, value)) - return msg.createReply(); + bool interfaceFound = true; + if (!interface_name.isEmpty()) + interfaceFound = qDBusInterfaceInObject(node.obj, interface_name); + + if (interfaceFound) { + return propertyWriteReply(msg, interface_name, property_name, + writeProperty(node.obj, property_name, value, node.flags)); } } - // the property was not found or not written to - return qDBusPropertyError(msg, interface_name); + // the property was not found + if (!interface_name.isEmpty()) + return interfaceNotFoundError(msg, interface_name); + return propertyWriteReply(msg, interface_name, property_name, PropertyNotFound); } // unite two QVariantMaps, but don't generate duplicate keys @@ -385,7 +490,7 @@ QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &n if (!interfaceFound && !interface_name.isEmpty()) { // the interface was not found - return qDBusPropertyError(msg, interface_name); + return interfaceNotFoundError(msg, interface_name); } return msg.createReply(qVariantFromValue(result)); -- cgit v0.12 From a80d8f015f68cb2b6d5f4cc8b2893543122c5d2b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 16:16:57 +0200 Subject: Autotest: make sure we create the QDBusInterface after the object exists. The current code allows making calls to QDBusInterface objects that failed to introspect. It's technically a valid condition. You won't be able to connect to signals, get or set properties, but making calls was possible. I don't know if I want to keep this change in behaviour. --- .../tst_qdbusabstractadaptor.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp index c70c619..5d08c63 100644 --- a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp +++ b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp @@ -609,19 +609,22 @@ void tst_QDBusAbstractAdaptor::methodCalls() QVERIFY(con.isConnected()); //QDBusInterface emptycon.baseService(), "/", QString()); - QDBusInterface if1(con.baseService(), "/", "local.Interface1", con); - QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); - QDBusInterface if3(con.baseService(), "/", "local.Interface3", con); - QDBusInterface if4(con.baseService(), "/", "local.Interface4", con); - // must fail: no object - //QCOMPARE(empty->call("method").type(), QDBusMessage::ErrorMessage); - QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); + { + // must fail: no object + QDBusInterface if1(con.baseService(), "/", "local.Interface1", con); + QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); + } QFETCH(int, nInterfaces); MyObject obj(nInterfaces); con.registerObject("/", &obj); + QDBusInterface if1(con.baseService(), "/", "local.Interface1", con); + QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); + QDBusInterface if3(con.baseService(), "/", "local.Interface3", con); + QDBusInterface if4(con.baseService(), "/", "local.Interface4", con); + // must fail: no such method QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); if (!nInterfaces--) @@ -670,11 +673,11 @@ void tst_QDBusAbstractAdaptor::methodCallScriptable() QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); - QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); - MyObject obj(2); con.registerObject("/", &obj); + QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); + QCOMPARE(if2.call(QDBus::BlockWithGui,"scriptableMethod").type(), QDBusMessage::ReplyMessage); QCOMPARE(slotSpy, "void Interface2::scriptableMethod()"); } -- cgit v0.12 From d675a1f752f6acb57c66082b9b25e1b8aa337f8a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 11:15:22 +0200 Subject: Autotest: add tests for method call errors --- tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 105 ++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index 3ba789a..e304712 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -84,12 +84,17 @@ private slots: void sendArgument_data(); void sendArgument(); - void sendErrors(); + void sendSignalErrors(); + void sendCallErrors_data(); + void sendCallErrors(); private: QProcess proc; }; +struct UnregisteredType { }; +Q_DECLARE_METATYPE(UnregisteredType) + class WaitForQPong: public QObject { Q_OBJECT @@ -784,7 +789,7 @@ void tst_QDBusMarshall::sendArgument() QCOMPARE(extracted, value); } -void tst_QDBusMarshall::sendErrors() +void tst_QDBusMarshall::sendSignalErrors() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -819,5 +824,101 @@ void tst_QDBusMarshall::sendErrors() QVERIFY(!con.send(msg)); } +void tst_QDBusMarshall::sendCallErrors_data() +{ + QTest::addColumn("service"); + QTest::addColumn("path"); + QTest::addColumn("interface"); + QTest::addColumn("method"); + QTest::addColumn("arguments"); + QTest::addColumn("errorName"); + QTest::addColumn("errorMsg"); + QTest::addColumn("ignoreMsg"); + + // this error comes from the bus server + QTest::newRow("empty-service") << "" << objectPath << interfaceName << "ping" << QVariantList() + << "org.freedesktop.DBus.Error.UnknownMethod" + << "Method \"ping\" with signature \"\" on interface \"com.trolltech.autotests.qpong\" doesn't exist\n" << (const char*)0; + + QTest::newRow("invalid-service") << "this isn't valid" << objectPath << interfaceName << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidService" + << "Invalid service name: this isn't valid" << ""; + + QTest::newRow("empty-path") << serviceName << "" << interfaceName << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidObjectPath" + << "Object path cannot be empty" << ""; + QTest::newRow("invalid-path") << serviceName << "//" << interfaceName << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidObjectPath" + << "Invalid object path: //" << ""; + + // empty interfaces are valid + QTest::newRow("invalid-interface") << serviceName << objectPath << "this isn't valid" << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidInterface" + << "Invalid interface class: this isn't valid" << ""; + + QTest::newRow("empty-method") << serviceName << objectPath << interfaceName << "" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidMember" + << "method name cannot be empty" << ""; + QTest::newRow("invalid-method") << serviceName << objectPath << interfaceName << "this isn't valid" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidMember" + << "Invalid method name: this isn't valid" << ""; + + QTest::newRow("invalid-variant1") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << QVariant()) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Variant containing QVariant::Invalid passed in arguments" + << "QDBusMarshaller: cannot add an invalid QVariant"; + QTest::newRow("invalid-variant1") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(QDBusVariant())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Variant containing QVariant::Invalid passed in arguments" + << "QDBusMarshaller: cannot add a null QDBusVariant"; + + QTest::newRow("builtin-unregistered") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << QLocale::c()) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Unregistered type QLocale passed in arguments" + << "QDBusMarshaller: type `QLocale' (18) is not registered with D-BUS. Use qDBusRegisterMetaType to register it"; + + // this type is known to the meta type system, but not registered with D-Bus + qRegisterMetaType(); + QTest::newRow("extra-unregistered") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(UnregisteredType())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Unregistered type UnregisteredType passed in arguments" + << QString("QDBusMarshaller: type `UnregisteredType' (%1) is not registered with D-BUS. Use qDBusRegisterMetaType to register it") + .arg(qMetaTypeId()); +} + +void tst_QDBusMarshall::sendCallErrors() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QFETCH(QString, service); + QFETCH(QString, path); + QFETCH(QString, interface); + QFETCH(QString, method); + QFETCH(QVariantList, arguments); + QFETCH(QString, errorMsg); + + QFETCH(QString, ignoreMsg); + if (!ignoreMsg.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, ignoreMsg.toLatin1()); + if (!ignoreMsg.isNull()) + QTest::ignoreMessage(QtWarningMsg, + QString("QDBusConnection: error: could not send message to service \"%1\" path \"%2\" interface \"%3\" member \"%4\": %5") + .arg(service, path, interface, method, errorMsg) + .toLatin1()); + + QDBusMessage msg = QDBusMessage::createMethodCall(service, path, interface, method); + msg.setArguments(arguments); + + QDBusMessage reply = con.call(msg, QDBus::Block); + QCOMPARE(reply.type(), QDBusMessage::ErrorMessage); + QTEST(reply.errorName(), "errorName"); + QCOMPARE(reply.errorMessage(), errorMsg); +} + QTEST_MAIN(tst_QDBusMarshall) #include "tst_qdbusmarshall.moc" -- cgit v0.12 From 202167643206bbfb50cce605fdfbd4cfef843bad Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 16:21:44 +0200 Subject: Autotest: Add testing of QDBusAbstractInterface --- tests/auto/auto.pro | 1 + .../com.trolltech.QtDBus.Pinger.xml | 29 ++ tests/auto/qdbusabstractinterface/interface.cpp | 48 ++ tests/auto/qdbusabstractinterface/interface.h | 109 +++++ tests/auto/qdbusabstractinterface/pinger.cpp | 67 +++ tests/auto/qdbusabstractinterface/pinger.h | 139 ++++++ .../qdbusabstractinterface.pro | 15 + .../tst_qdbusabstractinterface.cpp | 529 +++++++++++++++++++++ 8 files changed, 937 insertions(+) create mode 100644 tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml create mode 100644 tests/auto/qdbusabstractinterface/interface.cpp create mode 100644 tests/auto/qdbusabstractinterface/interface.h create mode 100644 tests/auto/qdbusabstractinterface/pinger.cpp create mode 100644 tests/auto/qdbusabstractinterface/pinger.h create mode 100644 tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro create mode 100644 tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index fd887fd..8bc2ed9 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -419,6 +419,7 @@ xmlpatternsxslts.depends = xmlpatternsxqts unix:!embedded:contains(QT_CONFIG, dbus):SUBDIRS += \ qdbusabstractadaptor \ + qdbusabstractinterface \ qdbusconnection \ qdbusinterface \ qdbuslocalcalls \ diff --git a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml new file mode 100644 index 0000000..8909675 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/qdbusabstractinterface/interface.cpp b/tests/auto/qdbusabstractinterface/interface.cpp new file mode 100644 index 0000000..1c391ce --- /dev/null +++ b/tests/auto/qdbusabstractinterface/interface.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "interface.h" + +Interface::Interface() +{ +} + +#include "moc_interface.cpp" diff --git a/tests/auto/qdbusabstractinterface/interface.h b/tests/auto/qdbusabstractinterface/interface.h new file mode 100644 index 0000000..86e0dc4 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/interface.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INTERFACE_H +#define INTERFACE_H + +#include +#include + +struct RegisteredType +{ + inline RegisteredType(const QString &str = QString()) : s(str) {} + inline bool operator==(const RegisteredType &other) const { return s == other.s; } + QString s; +}; +Q_DECLARE_METATYPE(RegisteredType) + +inline QDBusArgument &operator<<(QDBusArgument &s, const RegisteredType &data) +{ + s.beginStructure(); + s << data.s; + s.endStructure(); + return s; +} + +inline const QDBusArgument &operator>>(const QDBusArgument &s, RegisteredType &data) +{ + s.beginStructure(); + s >> data.s; + s.endStructure(); + return s; +} + +struct UnregisteredType +{ + QString s; +}; +Q_DECLARE_METATYPE(UnregisteredType) + +class Interface: public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.Pinger") + Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp SCRIPTABLE true) + Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp SCRIPTABLE true) + + friend class tst_QDBusAbstractInterface; + QString m_stringProp; + RegisteredType m_complexProp; + +public: + Interface(); + + QString stringProp() const { return m_stringProp; } + void setStringProp(const QString &s) { m_stringProp = s; } + RegisteredType complexProp() const { return m_complexProp; } + void setComplexProp(const RegisteredType &r) { m_complexProp = r; } + +public slots: + Q_SCRIPTABLE void voidMethod() {} + Q_SCRIPTABLE QString stringMethod() { return "Hello, world"; } + Q_SCRIPTABLE RegisteredType complexMethod() { return RegisteredType("Hello, world"); } + Q_SCRIPTABLE QString multiOutMethod(int &value) { value = 42; return "Hello, world"; } + +signals: + Q_SCRIPTABLE void voidSignal(); + Q_SCRIPTABLE void stringSignal(const QString &); + Q_SCRIPTABLE void complexSignal(RegisteredType); +}; + +#endif // INTERFACE_H diff --git a/tests/auto/qdbusabstractinterface/pinger.cpp b/tests/auto/qdbusabstractinterface/pinger.cpp new file mode 100644 index 0000000..4fcb89a --- /dev/null +++ b/tests/auto/qdbusabstractinterface/pinger.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDBus module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -i interface.h -p pinger com.trolltech.QtDBus.Pinger.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "pinger.h" + +/* + * Implementation of interface class ComTrolltechQtDBusPingerInterface + */ + +ComTrolltechQtDBusPingerInterface::ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +ComTrolltechQtDBusPingerInterface::~ComTrolltechQtDBusPingerInterface() +{ +} + diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h new file mode 100644 index 0000000..3ff218c --- /dev/null +++ b/tests/auto/qdbusabstractinterface/pinger.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDBus module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -i interface.h -p pinger com.trolltech.QtDBus.Pinger.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef PINGER_H_1246371899 +#define PINGER_H_1246371899 + +#include +#include +#include +#include +#include +#include +#include +#include +#include "interface.h" + +/* + * Proxy class for interface com.trolltech.QtDBus.Pinger + */ +class ComTrolltechQtDBusPingerInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.trolltech.QtDBus.Pinger"; } + +public: + ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~ComTrolltechQtDBusPingerInterface(); + + Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp) + inline RegisteredType complexProp() const + { return qvariant_cast< RegisteredType >(internalPropGet("complexProp")); } + inline void setComplexProp(RegisteredType value) + { internalPropSet("complexProp", qVariantFromValue(value)); } + + Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp) + inline QString stringProp() const + { return qvariant_cast< QString >(internalPropGet("stringProp")); } + inline void setStringProp(const QString &value) + { internalPropSet("stringProp", qVariantFromValue(value)); } + +public Q_SLOTS: // METHODS + inline QDBusPendingReply complexMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("complexMethod"), argumentList); + } + + inline QDBusPendingReply multiOutMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("multiOutMethod"), argumentList); + } + inline QDBusReply multiOutMethod(int &out1) + { + QList argumentList; + QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("multiOutMethod"), argumentList); + if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) { + out1 = qdbus_cast(reply.arguments().at(1)); + } + return reply; + } + + inline QDBusPendingReply stringMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("stringMethod"), argumentList); + } + + inline QDBusPendingReply<> voidMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("voidMethod"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void complexSignal(RegisteredType in0); + void stringSignal(const QString &in0); + void voidSignal(); +}; + +namespace com { + namespace trolltech { + namespace QtDBus { + typedef ::ComTrolltechQtDBusPingerInterface Pinger; + } + } +} +#endif diff --git a/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro b/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro new file mode 100644 index 0000000..a4853b8 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro @@ -0,0 +1,15 @@ +load(qttest_p4) +QT = core +contains(QT_CONFIG,dbus): { + SOURCES += tst_qdbusabstractinterface.cpp interface.cpp + HEADERS += interface.h + QT += dbus + + # These are generated sources + # To regenerate, see the command-line at the top of the files + SOURCES += pinger.cpp + HEADERS += pinger.h +} +else:SOURCES += ../qdbusmarshall/dummy.cpp + +OTHER_FILES += com.trolltech.QtDBus.Pinger.xml diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp new file mode 100644 index 0000000..4aee089 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -0,0 +1,529 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include + +#include + +#include + +#include "interface.h" +#include "pinger.h" + +typedef QSharedPointer Pinger; + +class tst_QDBusAbstractInterface: public QObject +{ + Q_OBJECT + Interface targetObj; + + Pinger getPinger(QString service = "", const QString &path = "/") + { + QDBusConnection con = QDBusConnection::sessionBus(); + if (!con.isConnected()) + return Pinger(); + if (service.isEmpty() && !service.isNull()) + service = con.baseService(); + return Pinger(new com::trolltech::QtDBus::Pinger(service, path, con)); + } + +public: + tst_QDBusAbstractInterface(); + +private slots: + void initTestCase(); + + void makeVoidCall(); + void makeStringCall(); + void makeComplexCall(); + void makeMultiOutCall(); + + void makeAsyncVoidCall(); + void makeAsyncStringCall(); + void makeAsyncComplexCall(); + void makeAsyncMultiOutCall(); + + void stringPropRead(); + void stringPropWrite(); + void complexPropRead(); + void complexPropWrite(); + + void stringPropDirectRead(); + void stringPropDirectWrite(); + void complexPropDirectRead(); + void complexPropDirectWrite(); + + void getVoidSignal_data(); + void getVoidSignal(); + void getStringSignal_data(); + void getStringSignal(); + void getComplexSignal_data(); + void getComplexSignal(); + + void createErrors_data(); + void createErrors(); + + void callErrors_data(); + void callErrors(); + void asyncCallErrors_data(); + void asyncCallErrors(); + + void propertyReadErrors_data(); + void propertyReadErrors(); + void propertyWriteErrors_data(); + void propertyWriteErrors(); + void directPropertyReadErrors_data(); + void directPropertyReadErrors(); + void directPropertyWriteErrors_data(); + void directPropertyWriteErrors(); +}; + +tst_QDBusAbstractInterface::tst_QDBusAbstractInterface() +{ + // register the meta types + qDBusRegisterMetaType(); + qRegisterMetaType(); +} + +void tst_QDBusAbstractInterface::initTestCase() +{ + // register the object + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + con.registerObject("/", &targetObj, QDBusConnection::ExportScriptableContents); +} + +void tst_QDBusAbstractInterface::makeVoidCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply r = p->voidMethod(); + QVERIFY(r.isValid()); +} + +void tst_QDBusAbstractInterface::makeStringCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply r = p->stringMethod(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.stringMethod()); +} + +void tst_QDBusAbstractInterface::makeComplexCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply r = p->complexMethod(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.complexMethod()); +} + +void tst_QDBusAbstractInterface::makeMultiOutCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + int value; + QDBusReply r = p->multiOutMethod(value); + QVERIFY(r.isValid()); + + int expectedValue; + QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); + QCOMPARE(value, expectedValue); +} + +void tst_QDBusAbstractInterface::makeAsyncVoidCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->voidMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); +} + +void tst_QDBusAbstractInterface::makeAsyncStringCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->stringMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.stringMethod()); +} + +void tst_QDBusAbstractInterface::makeAsyncComplexCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->complexMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.complexMethod()); +} + +void tst_QDBusAbstractInterface::makeAsyncMultiOutCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->multiOutMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + + int expectedValue; + QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); + QCOMPARE(r.argumentAt<1>(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = targetObj.m_stringProp = "This is a test"; + QVariant v = p->property("stringProp"); + QVERIFY(v.isValid()); + QCOMPARE(v.toString(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = "This is a value"; + QVERIFY(p->setProperty("stringProp", expectedValue)); + QCOMPARE(targetObj.m_stringProp, expectedValue); +} + +void tst_QDBusAbstractInterface::complexPropRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = targetObj.m_complexProp = RegisteredType("This is a test"); + QVariant v = p->property("complexProp"); + QVERIFY(v.userType() == qMetaTypeId()); + QCOMPARE(v.value(), targetObj.m_complexProp); +} + +void tst_QDBusAbstractInterface::complexPropWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = RegisteredType("This is a value"); + QVERIFY(p->setProperty("complexProp", qVariantFromValue(expectedValue))); + QCOMPARE(targetObj.m_complexProp, expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropDirectRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = targetObj.m_stringProp = "This is a test"; + QCOMPARE(p->stringProp(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropDirectWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = "This is a value"; + p->setStringProp(expectedValue); + QCOMPARE(targetObj.m_stringProp, expectedValue); +} + +void tst_QDBusAbstractInterface::complexPropDirectRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = targetObj.m_complexProp = RegisteredType("This is a test"); + QCOMPARE(p->complexProp(), targetObj.m_complexProp); +} + +void tst_QDBusAbstractInterface::complexPropDirectWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = RegisteredType("This is a value"); + p->setComplexProp(expectedValue); + QCOMPARE(targetObj.m_complexProp, expectedValue); +} + +void tst_QDBusAbstractInterface::getVoidSignal_data() +{ + QTest::addColumn("service"); + QTest::addColumn("path"); + + QTest::newRow("specific") << QDBusConnection::sessionBus().baseService() << "/"; + QTest::newRow("service-wildcard") << QString() << "/"; + QTest::newRow("path-wildcard") << QDBusConnection::sessionBus().baseService() << QString(); + QTest::newRow("full-wildcard") << QString() << QString(); +} + +void tst_QDBusAbstractInterface::getVoidSignal() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(voidSignal()), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(voidSignal())); + + emit targetObj.voidSignal(); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s.at(0).size() == 0); +} + +void tst_QDBusAbstractInterface::getStringSignal_data() +{ + getVoidSignal_data(); +} + +void tst_QDBusAbstractInterface::getStringSignal() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(stringSignal(QString)), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(stringSignal(QString))); + + QString expectedValue = "Good morning"; + emit targetObj.stringSignal(expectedValue); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s[0].size() == 1); + QCOMPARE(s[0][0].userType(), int(QVariant::String)); + QCOMPARE(s[0][0].toString(), expectedValue); +} + +void tst_QDBusAbstractInterface::getComplexSignal_data() +{ + getVoidSignal_data(); +} + +void tst_QDBusAbstractInterface::getComplexSignal() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(complexSignal(RegisteredType)), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(complexSignal(RegisteredType))); + + RegisteredType expectedValue("Good evening"); + emit targetObj.complexSignal(expectedValue); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s[0].size() == 1); + QCOMPARE(s[0][0].userType(), qMetaTypeId()); + QCOMPARE(s[0][0].value(), expectedValue); +} + +void tst_QDBusAbstractInterface::createErrors_data() +{ + QTest::addColumn("service"); + QTest::addColumn("path"); + QTest::addColumn("errorName"); + + QTest::newRow("invalid-service") << "this isn't valid" << "/" << "com.trolltech.QtDBus.Error.InvalidService"; + QTest::newRow("invalid-path") << QDBusConnection::sessionBus().baseService() << "this isn't valid" + << "com.trolltech.QtDBus.Error.InvalidObjectPath"; +} + +void tst_QDBusAbstractInterface::createErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + QVERIFY(!p->isValid()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::callErrors_data() +{ + createErrors_data(); + QTest::newRow("service-wildcard") << QString() << "/" << "com.trolltech.QtDBus.Error.InvalidService"; + QTest::newRow("path-wildcard") << QDBusConnection::sessionBus().baseService() << QString() + << "com.trolltech.QtDBus.Error.InvalidObjectPath"; + QTest::newRow("full-wildcard") << QString() << QString() << "com.trolltech.QtDBus.Error.InvalidService"; +} + +void tst_QDBusAbstractInterface::callErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to make this call: + QDBusReply r = p->stringMethod(); + QVERIFY(!r.isValid()); + QTEST(r.error().name(), "errorName"); + QCOMPARE(p->lastError().name(), r.error().name()); +} + +void tst_QDBusAbstractInterface::asyncCallErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::asyncCallErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to make this call: + QDBusPendingReply r = p->stringMethod(); + QVERIFY(r.isError()); + QTEST(r.error().name(), "errorName"); + QCOMPARE(p->lastError().name(), r.error().name()); +} + +void tst_QDBusAbstractInterface::propertyReadErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::propertyReadErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + QVariant v = p->property("stringProp"); + QVERIFY(v.isNull()); + QVERIFY(!v.isValid()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::propertyWriteErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::propertyWriteErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + if (p->isValid()) + QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); + QVERIFY(!p->setProperty("stringProp", "")); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::directPropertyReadErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::directPropertyReadErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + QString v = p->stringProp(); + QVERIFY(v.isNull()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::directPropertyWriteErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::directPropertyWriteErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + // but there's no direct way of verifying that the setting failed + if (p->isValid()) + QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); + p->setStringProp(""); + QTEST(p->lastError().name(), "errorName"); +} + +QTEST_MAIN(tst_QDBusAbstractInterface) +#include "tst_qdbusabstractinterface.moc" -- cgit v0.12 From 826c03c1c010a9d612007aa85ce3a5188edb0cb8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 19:27:16 +0200 Subject: Autotest: Add property-setting and getting tests to QDBusInterface --- tests/auto/qdbusinterface/tst_qdbusinterface.cpp | 102 ++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index c4d4b08..718ba18 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -60,6 +60,9 @@ class MyObject: public QObject Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" +" \n" +" \n" +" \n" " \n" " \n" " \n" @@ -75,6 +78,9 @@ class MyObject: public QObject " \n" " \n" "") + Q_PROPERTY(int prop1 READ prop1 WRITE setProp1) + Q_PROPERTY(QList complexProp READ complexProp WRITE setComplexProp) + public: static int callCount; static QVariantList callArgs; @@ -84,6 +90,30 @@ public: subObject->setObjectName("subObject"); } + int m_prop1; + int prop1() const + { + ++callCount; + return m_prop1; + } + void setProp1(int value) + { + ++callCount; + m_prop1 = value; + } + + QList m_complexProp; + QList complexProp() const + { + ++callCount; + return m_complexProp; + } + void setComplexProp(const QList &value) + { + ++callCount; + m_complexProp = value; + } + public slots: void ping(QDBusMessage msg) @@ -146,6 +176,11 @@ private slots: void invokeMethod(); void signal(); + + void propertyRead(); + void propertyWrite(); + void complexPropertyRead(); + void complexPropertyWrite(); }; void tst_QDBusInterface::initTestCase() @@ -154,7 +189,7 @@ void tst_QDBusInterface::initTestCase() QVERIFY(con.isConnected()); QTest::qWait(500); - con.registerObject("/", &obj, QDBusConnection::ExportAdaptors + con.registerObject("/", &obj, QDBusConnection::ExportAllProperties | QDBusConnection::ExportAllSlots | QDBusConnection::ExportChildObjects); } @@ -231,8 +266,9 @@ void tst_QDBusInterface::introspect() QCOMPARE(mo->methodCount() - mo->methodOffset(), 3); QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1); - QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 1); + QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2); QVERIFY(mo->indexOfProperty("prop1") != -1); + QVERIFY(mo->indexOfProperty("complexProp") != -1); } void tst_QDBusInterface::callMethod() @@ -322,6 +358,68 @@ void tst_QDBusInterface::signal() } } +void tst_QDBusInterface::propertyRead() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + int arg = obj.m_prop1 = 42; + MyObject::callCount = 0; + + QVariant v = iface.property("prop1"); + QVERIFY(v.isValid()); + QCOMPARE(v.userType(), int(QVariant::Int)); + QCOMPARE(v.toInt(), arg); + QCOMPARE(MyObject::callCount, 1); +} + +void tst_QDBusInterface::propertyWrite() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + int arg = 42; + obj.m_prop1 = 0; + MyObject::callCount = 0; + + QVERIFY(iface.setProperty("prop1", arg)); + QCOMPARE(MyObject::callCount, 1); + QCOMPARE(obj.m_prop1, arg); +} + +void tst_QDBusInterface::complexPropertyRead() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + QList arg = obj.m_complexProp = QList() << 42 << -47; + MyObject::callCount = 0; + + QVariant v = iface.property("complexProp"); + QVERIFY(v.isValid()); + QCOMPARE(v.userType(), qMetaTypeId >()); + QCOMPARE(v.value >(), arg); + QCOMPARE(MyObject::callCount, 1); +} + +void tst_QDBusInterface::complexPropertyWrite() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + QList arg = QList() << -47 << 42; + obj.m_complexProp.clear(); + MyObject::callCount = 0; + + QVERIFY(iface.setProperty("complexProp", qVariantFromValue(arg))); + QCOMPARE(MyObject::callCount, 1); + QCOMPARE(obj.m_complexProp, arg); +} + QTEST_MAIN(tst_QDBusInterface) #include "tst_qdbusinterface.moc" -- cgit v0.12 From 962b7fde5194a08a83609b9b4367425e52f76614 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 17:44:56 +0200 Subject: Improve the code a bit more by using the variant that QMetaProperty creates. This works for the case of complex types that have to be demarshalled. We don't need to instantiate a new type because QMetaProperty has already done that for us. Also, fix the handling of properties of type variant. I have verified as well that the sending of those properties on the wire use a double-variant encoding (i.e., a variant containing a variant containing some data, the same that Qt 4.5 uses). It's a bit pedantic and it's hard to use when reading stuff, because you get a QVariant containing a QDBusVariant which contains data, but I can't change this anymore. Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusabstractinterface.cpp | 70 +++++++++++++++---------------------- src/dbus/qdbusabstractinterface_p.h | 2 +- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 9bef2dd..7c520df 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -110,21 +110,17 @@ bool QDBusAbstractInterfacePrivate::canMakeCalls() const return true; } -QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const +void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &where) const { - if (!isValid || !canMakeCalls()) // can't make calls - return QVariant(); + if (!isValid || !canMakeCalls()) { // can't make calls + where.clear(); + return; + } // is this metatype registered? - int mid; - const char *expectedSignature; - if (mp.type() == QVariant::LastType) { - // We're asking to read a QVariant - mid = qMetaTypeId(); - expectedSignature = "v"; - } else { - mid = QMetaType::type(mp.typeName()); - expectedSignature = QDBusMetaType::typeToSignature(mid); + const char *expectedSignature = ""; + if (mp.type() != 0xff) { + expectedSignature = QDBusMetaType::typeToSignature(where.userType()); if (expectedSignature == 0) { qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be " "used to read property %s.%s", @@ -132,7 +128,8 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const lastError = QDBusError(QDBusError::Failed, QString::fromLatin1("Unregistered type %1 cannot be handled") .arg(QLatin1String(mp.typeName()))); - return QVariant(); + where.clear(); + return; } } @@ -146,21 +143,27 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const if (reply.type() != QDBusMessage::ReplyMessage) { lastError = reply; - return QVariant(); + where.clear(); + return; } if (reply.signature() != QLatin1String("v")) { QString errmsg = QLatin1String("Invalid signature `%1' in return from call to " DBUS_INTERFACE_PROPERTIES); lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature())); - return QVariant(); + where.clear(); + return; } QByteArray foundSignature; const char *foundType = 0; QVariant value = qvariant_cast(reply.arguments().at(0)).variant(); - if (value.userType() == mid) - return value; // simple match + if (value.userType() == where.userType() || mp.type() == 0xff + || (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) { + // simple match + where = value; + return; + } if (value.userType() == qMetaTypeId()) { QDBusArgument arg = qvariant_cast(value); @@ -168,14 +171,9 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const foundType = "user type"; foundSignature = arg.currentSignature().toLatin1(); if (foundSignature == expectedSignature) { - void *null = 0; - QVariant result(mid, null); - QDBusMetaType::demarshall(arg, mid, result.data()); - - if (mp.type() == QVariant::LastType) - // special case: QVariant - return qvariant_cast(result).variant(); - return result; + // signatures match, we can demarshall + QDBusMetaType::demarshall(arg, where.userType(), where.data()); + return; } } else { foundType = value.typeName(); @@ -192,7 +190,8 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const QString::fromUtf8(mp.name()), QString::fromLatin1(mp.typeName()), QString::fromLatin1(expectedSignature))); - return QVariant(); + where.clear(); + return; } bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) @@ -246,7 +245,7 @@ int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void if (_c == QMetaObject::WriteProperty) { status = d_func()->setProperty(mp, variant) ? 1 : 0; } else { - variant = d_func()->property(mp); + d_func()->property(mp, variant); status = variant.isValid() ? 1 : 0; } _id = -1; @@ -576,11 +575,7 @@ QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const // assume this property exists and is readable // we're only called from generated code anyways - int idx = metaObject()->indexOfProperty(propname); - if (idx != -1) - return d_func()->property(metaObject()->property(idx)); - qWarning("QDBusAbstractInterface::internalPropGet called with unknown property '%s'", propname); - return QVariant(); // error + return property(propname); } /*! @@ -589,16 +584,7 @@ QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const */ void QDBusAbstractInterface::internalPropSet(const char *propname, const QVariant &value) { - Q_D(QDBusAbstractInterface); - - // assume this property exists and is writeable - // we're only called from generated code anyways - - int idx = metaObject()->indexOfProperty(propname); - if (idx != -1) - d->setProperty(metaObject()->property(idx), value); - else - qWarning("QDBusAbstractInterface::internalPropGet called with unknown property '%s'", propname); + setProperty(propname, value); } /*! diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h index e577898..65df902 100644 --- a/src/dbus/qdbusabstractinterface_p.h +++ b/src/dbus/qdbusabstractinterface_p.h @@ -86,7 +86,7 @@ public: bool canMakeCalls() const; // these functions do not check if the property is valid - QVariant property(const QMetaProperty &mp) const; + void property(const QMetaProperty &mp, QVariant &where) const; bool setProperty(const QMetaProperty &mp, const QVariant &value); // return conn's d pointer -- cgit v0.12 From 43a760280edd49382d01eb1e23ae2a08933b6bf7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 17:45:17 +0200 Subject: Autotest: add tests for checking variant properties --- .../com.trolltech.QtDBus.Pinger.xml | 1 + tests/auto/qdbusabstractinterface/interface.h | 4 ++ tests/auto/qdbusabstractinterface/pinger.h | 10 ++++- .../tst_qdbusabstractinterface.cpp | 47 ++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml index 8909675..fb2aab8 100644 --- a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml +++ b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml @@ -2,6 +2,7 @@ + diff --git a/tests/auto/qdbusabstractinterface/interface.h b/tests/auto/qdbusabstractinterface/interface.h index 86e0dc4..f6d34a7 100644 --- a/tests/auto/qdbusabstractinterface/interface.h +++ b/tests/auto/qdbusabstractinterface/interface.h @@ -80,10 +80,12 @@ class Interface: public QObject Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.Pinger") Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp SCRIPTABLE true) + Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp SCRIPTABLE true) Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp SCRIPTABLE true) friend class tst_QDBusAbstractInterface; QString m_stringProp; + QDBusVariant m_variantProp; RegisteredType m_complexProp; public: @@ -91,6 +93,8 @@ public: QString stringProp() const { return m_stringProp; } void setStringProp(const QString &s) { m_stringProp = s; } + QDBusVariant variantProp() const { return m_variantProp; } + void setVariantProp(const QDBusVariant &v) { m_variantProp = v; } RegisteredType complexProp() const { return m_complexProp; } void setComplexProp(const RegisteredType &r) { m_complexProp = r; } diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h index 3ff218c..6e92e65 100644 --- a/tests/auto/qdbusabstractinterface/pinger.h +++ b/tests/auto/qdbusabstractinterface/pinger.h @@ -49,8 +49,8 @@ * Do not edit! All changes made to it will be lost. */ -#ifndef PINGER_H_1246371899 -#define PINGER_H_1246371899 +#ifndef PINGER_H_1246460303 +#define PINGER_H_1246460303 #include #include @@ -89,6 +89,12 @@ public: inline void setStringProp(const QString &value) { internalPropSet("stringProp", qVariantFromValue(value)); } + Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp) + inline QDBusVariant variantProp() const + { return qvariant_cast< QDBusVariant >(internalPropGet("variantProp")); } + inline void setVariantProp(const QDBusVariant &value) + { internalPropSet("variantProp", qVariantFromValue(value)); } + public Q_SLOTS: // METHODS inline QDBusPendingReply complexMethod() { diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index 4aee089..fa5e332 100644 --- a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -84,11 +84,15 @@ private slots: void stringPropRead(); void stringPropWrite(); + void variantPropRead(); + void variantPropWrite(); void complexPropRead(); void complexPropWrite(); void stringPropDirectRead(); void stringPropDirectWrite(); + void variantPropDirectRead(); + void variantPropDirectWrite(); void complexPropDirectRead(); void complexPropDirectWrite(); @@ -242,6 +246,29 @@ void tst_QDBusAbstractInterface::stringPropWrite() QCOMPARE(targetObj.m_stringProp, expectedValue); } +void tst_QDBusAbstractInterface::variantPropRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = targetObj.m_variantProp = QDBusVariant(QVariant(42)); + QVariant v = p->property("variantProp"); + QVERIFY(v.isValid()); + QDBusVariant value = v.value(); + QCOMPARE(value.variant().userType(), expectedValue.variant().userType()); + QCOMPARE(value.variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::variantPropWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); + QVERIFY(p->setProperty("variantProp", qVariantFromValue(expectedValue))); + QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); +} + void tst_QDBusAbstractInterface::complexPropRead() { Pinger p = getPinger(); @@ -282,6 +309,26 @@ void tst_QDBusAbstractInterface::stringPropDirectWrite() QCOMPARE(targetObj.m_stringProp, expectedValue); } +void tst_QDBusAbstractInterface::variantPropDirectRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = targetObj.m_variantProp = QDBusVariant(42); + QCOMPARE(p->variantProp().variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::variantPropDirectWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); + p->setVariantProp(expectedValue); + QCOMPARE(targetObj.m_variantProp.variant().userType(), expectedValue.variant().userType()); + QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); +} + void tst_QDBusAbstractInterface::complexPropDirectRead() { Pinger p = getPinger(); -- cgit v0.12 From 232f7af78d152518ccdcaaf1f42f89abb048ae5f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 17:52:48 +0200 Subject: Replace internalPropGet and internalPropSet with the QObject versions in QDBusAbstractInterface. They're now good enough and as fast. Reviewed-By: Marius Bugge Monsen --- tests/auto/qdbusabstractinterface/pinger.h | 16 ++++++++-------- tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp | 11 ++++------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h index 6e92e65..fb8adda 100644 --- a/tests/auto/qdbusabstractinterface/pinger.h +++ b/tests/auto/qdbusabstractinterface/pinger.h @@ -49,8 +49,8 @@ * Do not edit! All changes made to it will be lost. */ -#ifndef PINGER_H_1246460303 -#define PINGER_H_1246460303 +#ifndef PINGER_H_1246463415 +#define PINGER_H_1246463415 #include #include @@ -79,21 +79,21 @@ public: Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp) inline RegisteredType complexProp() const - { return qvariant_cast< RegisteredType >(internalPropGet("complexProp")); } + { return qvariant_cast< RegisteredType >(property("complexProp")); } inline void setComplexProp(RegisteredType value) - { internalPropSet("complexProp", qVariantFromValue(value)); } + { setProperty("complexProp", qVariantFromValue(value)); } Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp) inline QString stringProp() const - { return qvariant_cast< QString >(internalPropGet("stringProp")); } + { return qvariant_cast< QString >(property("stringProp")); } inline void setStringProp(const QString &value) - { internalPropSet("stringProp", qVariantFromValue(value)); } + { setProperty("stringProp", qVariantFromValue(value)); } Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp) inline QDBusVariant variantProp() const - { return qvariant_cast< QDBusVariant >(internalPropGet("variantProp")); } + { return qvariant_cast< QDBusVariant >(property("variantProp")); } inline void setVariantProp(const QDBusVariant &value) - { internalPropSet("variantProp", qVariantFromValue(value)); } + { setProperty("variantProp", qVariantFromValue(value)); } public Q_SLOTS: // METHODS inline QDBusPendingReply complexMethod() diff --git a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp index 5d1ac32..b8b9338 100644 --- a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -613,18 +613,15 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf // getter: if (property.access != QDBusIntrospection::Property::Write) { - hs << " inline " << type << " " << getter << "() const" << endl; - if (type != "QVariant") - hs << " { return qvariant_cast< " << type << " >(internalPropGet(\"" - << property.name << "\")); }" << endl; - else - hs << " { return internalPropGet(\"" << property.name << "\"); }" << endl; + hs << " inline " << type << " " << getter << "() const" << endl + << " { return qvariant_cast< " << type << " >(property(\"" + << property.name << "\")); }" << endl; } // setter: if (property.access != QDBusIntrospection::Property::Read) { hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << endl - << " { internalPropSet(\"" << property.name + << " { setProperty(\"" << property.name << "\", qVariantFromValue(value)); }" << endl; } -- cgit v0.12 From 200286b8e83918e785b61e4695443a3b77ebeaea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 18:24:56 +0200 Subject: Implement a support for getting return arguments out of invokeMethod with QDBusInterface. The problem was that I didn't know how to implement the operator= for all types. But it turns out that this was possible all along: the only types I have to implement the operator= for are the basic types, which are already demarshalled. The complex types are left in QDBusArgument semi-demarshalling, but we have QDBusMetaType::demarshall, which takes a void* to an already-constructed type and demarshalls into it. That's exactly what the doctor ordered. Task-number: 206765 Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusinterface.cpp | 126 +++++++++++++++++++++-- tests/auto/qdbusinterface/tst_qdbusinterface.cpp | 92 ++++++++++++++++- 2 files changed, 209 insertions(+), 9 deletions(-) diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp index 6f61847..5f6df0a 100644 --- a/src/dbus/qdbusinterface.cpp +++ b/src/dbus/qdbusinterface.cpp @@ -51,6 +51,102 @@ QT_BEGIN_NAMESPACE +static void copyArgument(void *to, int id, const QVariant &arg) +{ + if (id == arg.userType()) { + switch (id) { + case QVariant::Bool: + *reinterpret_cast(to) = arg.toBool(); + return; + + case QMetaType::UChar: + *reinterpret_cast(to) = arg.value(); + return; + + case QMetaType::Short: + *reinterpret_cast(to) = arg.value(); + return; + + case QMetaType::UShort: + *reinterpret_cast(to) = arg.value(); + return; + + case QVariant::Int: + *reinterpret_cast(to) = arg.toInt(); + return; + + case QVariant::UInt: + *reinterpret_cast(to) = arg.toUInt(); + return; + + case QVariant::LongLong: + *reinterpret_cast(to) = arg.toLongLong(); + return; + + case QVariant::ULongLong: + *reinterpret_cast(to) = arg.toULongLong(); + return; + + case QVariant::Double: + *reinterpret_cast(to) = arg.toDouble(); + return; + + case QVariant::String: + *reinterpret_cast(to) = arg.toString(); + return; + + case QVariant::ByteArray: + *reinterpret_cast(to) = arg.toByteArray(); + return; + + case QVariant::StringList: + *reinterpret_cast(to) = arg.toStringList(); + return; + } + + if (id == QDBusMetaTypeId::variant) { + *reinterpret_cast(to) = arg.value(); + return; + } else if (id == QDBusMetaTypeId::objectpath) { + *reinterpret_cast(to) = arg.value(); + return; + } else if (id == QDBusMetaTypeId::signature) { + *reinterpret_cast(to) = arg.value(); + return; + } + + // those above are the only types possible + // the demarshaller code doesn't demarshall anything else + qFatal("Found a decoded basic type in a D-Bus reply that shouldn't be there"); + } + + // if we got here, it's either an un-dermarshalled type or a mismatch + if (arg.userType() != QDBusMetaTypeId::argument) { + // it's a mismatch + //qWarning? + return; + } + + // is this type registered? + const char *userSignature = QDBusMetaType::typeToSignature(id); + if (!userSignature || !*userSignature) { + // type not registered + //qWarning? + return; + } + + // is it the same signature? + QDBusArgument dbarg = arg.value(); + if (dbarg.currentSignature() != QLatin1String(userSignature)) { + // not the same signature, another mismatch + //qWarning? + return; + } + + // we can demarshall + QDBusMetaType::demarshall(dbarg, id, to); +} + QDBusInterfacePrivate::QDBusInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection &con) : QDBusAbstractInterfacePrivate(serv, p, iface, con, true), metaObject(0) @@ -186,23 +282,37 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) // we will assume that the input arguments were passed correctly QVariantList args; - for (int i = 1; i <= inputTypesCount; ++i) + int i = 1; + for ( ; i <= inputTypesCount; ++i) args << QVariant(inputTypes[i], argv[i]); // make the call - QPointer qq = q; QDBusMessage reply = q->callWithArgumentList(QDBus::Block, methodName, args); - args.clear(); - // we ignore return values + if (reply.type() == QDBusMessage::ReplyMessage) { + // attempt to demarshall the return values + args = reply.arguments(); + QVariantList::ConstIterator it = args.constBegin(); + const int *outputTypes = metaObject->outputTypesForMethod(id); + int outputTypesCount = *outputTypes++; + + if (*mm.typeName()) { + // this method has a return type + if (argv[0] && it != args.constEnd()) + copyArgument(argv[0], *outputTypes++, *it); - // access to "this" or to "q" below this point must check for "qq" - // we may have been deleted! + // skip this argument even if we didn't copy it + --outputTypesCount; + ++it; + } - if (!qq.isNull()) - lastError = reply; + for (int j = 0; j < outputTypesCount && it != args.constEnd(); ++i, ++j, ++it) { + copyArgument(argv[i], outputTypes[j], *it); + } + } // done + lastError = reply; return -1; } } diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index 718ba18..60afe4e 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -76,6 +76,12 @@ class MyObject: public QObject " \n" " \n" " \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" "") Q_PROPERTY(int prop1 READ prop1 WRITE setProp1) @@ -174,6 +180,9 @@ private slots: void introspect(); void callMethod(); void invokeMethod(); + void invokeMethodWithReturn(); + void invokeMethodWithMultiReturn(); + void invokeMethodWithComplexReturn(); void signal(); @@ -263,7 +272,7 @@ void tst_QDBusInterface::introspect() const QMetaObject *mo = iface.metaObject(); - QCOMPARE(mo->methodCount() - mo->methodOffset(), 3); + QCOMPARE(mo->methodCount() - mo->methodOffset(), 4); QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1); QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2); @@ -317,6 +326,87 @@ void tst_QDBusInterface::invokeMethod() QCOMPARE(dv.variant().toString(), QString("foo")); } +void tst_QDBusInterface::invokeMethodWithReturn() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + // make the call without a return type + MyObject::callCount = 0; + QDBusVariant arg("foo"); + QDBusVariant retArg; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg))); + QCOMPARE(MyObject::callCount, 1); + + // verify what the callee received + QCOMPARE(MyObject::callArgs.count(), 1); + QVariant v = MyObject::callArgs.at(0); + QDBusVariant dv = qdbus_cast(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg.variant().toString()); + + // verify that we got the reply as expected + QCOMPARE(retArg.variant(), arg.variant()); +} + +void tst_QDBusInterface::invokeMethodWithMultiReturn() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + // make the call without a return type + MyObject::callCount = 0; + QDBusVariant arg("foo"), arg2("bar"); + QDBusVariant retArg, retArg2; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", + Q_RETURN_ARG(QDBusVariant, retArg), + Q_ARG(QDBusVariant, arg), + Q_ARG(QDBusVariant, arg2), + Q_ARG(QDBusVariant&, retArg2))); + QCOMPARE(MyObject::callCount, 1); + + // verify what the callee received + QCOMPARE(MyObject::callArgs.count(), 2); + QVariant v = MyObject::callArgs.at(0); + QDBusVariant dv = qdbus_cast(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg.variant().toString()); + + v = MyObject::callArgs.at(1); + dv = qdbus_cast(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg2.variant().toString()); + + // verify that we got the replies as expected + QCOMPARE(retArg.variant(), arg.variant()); + QCOMPARE(retArg2.variant(), arg2.variant()); +} + +void tst_QDBusInterface::invokeMethodWithComplexReturn() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + // make the call without a return type + MyObject::callCount = 0; + QList arg = QList() << 42 << -47; + QList retArg; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList, retArg), Q_ARG(QList, arg))); + QCOMPARE(MyObject::callCount, 1); + + // verify what the callee received + QCOMPARE(MyObject::callArgs.count(), 1); + QVariant v = MyObject::callArgs.at(0); + QCOMPARE(v.userType(), qMetaTypeId()); + QCOMPARE(qdbus_cast >(v), arg); + + // verify that we got the reply as expected + QCOMPARE(retArg, arg); +} + void tst_QDBusInterface::signal() { QDBusConnection con = QDBusConnection::sessionBus(); -- cgit v0.12 From 9a90dab23bd1bd37bd4a7aace588896d2ae7e9d9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 1 Jul 2009 10:53:23 +0200 Subject: add support for attaching meta data to translatable messages Requirement: QT-457 --- .../snippets/code/src_corelib_kernel_qobject.cpp | 9 ++++++ src/corelib/kernel/qobject.cpp | 28 +++++++++++++++++ .../lupdate/testdata/good/parsecpp/main.cpp | 19 ++++++++++++ .../testdata/good/parsecpp/project.ts.result | 21 +++++++++++++ tools/linguist/lupdate/cpp.cpp | 35 ++++++++++++++++++---- 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_kernel_qobject.cpp b/doc/src/snippets/code/src_corelib_kernel_qobject.cpp index 5a7c5a7..5c0f80c 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qobject.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qobject.cpp @@ -376,6 +376,15 @@ hostNameLabel->setText(tr("Name:")); QString example = tr("Example"); //! [40] +//! [meta data] +//: This is a comment for the translator. +//= qtn_foo_bar +//~ loc-layout_id foo_dialog +//~ loc-blank False +//~ magic-stuff This might mean something magic. +QString text = MyMagicClass::tr("Sim sala bim."); +//! [meta data] + //! [explicit tr context] QString text = QScrollBar::tr("Page up"); //! [explicit tr context] diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 9dc25c7..9e87b3b 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2086,6 +2086,34 @@ void QObject::deleteLater() \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17 + \section1 Meta Data + + Additional data can be attached to each translatable message. + The syntax: + + \tt{//= } + + can be used to give the message a unique identifier to support tools + which need it. + The syntax: + + \tt{//~ } + + can be used to attach meta data to the message. The field name should consist + of a domain prefix (possibly the conventional file extension of the file format + the field is inspired by), a hyphen and the actual field name in + underscore-delimited notation. For storage in TS files, the field name together + with the prefix "extra-" will form an XML element name. The field contents will + be XML-escaped, but otherwise appear verbatim as the element's contents. + Any number of unique fields can be added to each message. + + Example: + + \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp meta data + + Meta data appearing right in front of a magic TRANSLATOR comment applies to the + whole TS file. + \section1 Character Encodings You can set the encoding for \a sourceText by calling QTextCodec::setCodecForTr(). diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp index df75baf..9fb43fe 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp @@ -156,3 +156,22 @@ QT_TRANSLATE_NOOP3_UTF8("scope", "string", "comment") // 4.4 doesn't see this QT_TRANSLATE_NOOP("scope", "string " // this is an interleaved comment "continuation on next line") + + +class TestingTake17 : QObject { + Q_OBJECT + + int function(void) + { + //: random comment + //= this_is_an_id + //~ loc-layout_id fooish_bar + //~ po-ignore_me totally foo-barred nonsense + tr("something cool"); + + tr("less cool"); + + //= another_id + tr("even more cool"); + } +}; diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result index 9386c19..5bd7525 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result @@ -239,6 +239,27 @@ + TestingTake17 + + + something cool + random comment + + totally foo-barred nonsense + fooish_bar + + + + less cool + + + + + even more cool + + + + scope diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 09148e7..b1d2d01 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -180,7 +180,8 @@ private: QString transcode(const QString &str, bool utf8); void recordMessage( int line, const QString &context, const QString &text, const QString &comment, - const QString &extracomment, bool utf8, bool plural); + const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, + bool utf8, bool plural); void processInclude(const QString &file, ConversionData &cd, QSet &inclusions); @@ -1299,13 +1300,16 @@ QString CppParser::transcode(const QString &str, bool utf8) void CppParser::recordMessage( int line, const QString &context, const QString &text, const QString &comment, - const QString &extracomment, bool utf8, bool plural) + const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, + bool utf8, bool plural) { TranslatorMessage msg( transcode(context, utf8), transcode(text, utf8), transcode(comment, utf8), QString(), yyFileName, line, QStringList(), TranslatorMessage::Unfinished, plural); msg.setExtraComment(transcode(extracomment.simplified(), utf8)); + msg.setId(msgid); + msg.setExtras(extra); if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit()) msg.setUtf8(true); results->tor->append(msg); @@ -1332,6 +1336,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) QString text; QString comment; QString extracomment; + QString msgid; + TranslatorMessage::ExtraData extra; QString prefix; #ifdef DIAGNOSE_RETRANSLATABILITY QString functionName; @@ -1604,9 +1610,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) prefix.clear(); } - recordMessage(line, context, text, comment, extracomment, utf8, plural); + recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural); } extracomment.clear(); + msgid.clear(); + extra.clear(); break; case Tok_translateUtf8: case Tok_translate: @@ -1655,9 +1663,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; } } - recordMessage(line, context, text, comment, extracomment, utf8, plural); + recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural); } extracomment.clear(); + msgid.clear(); + extra.clear(); break; case Tok_Q_DECLARE_TR_FUNCTIONS: case Tok_Q_OBJECT: @@ -1679,6 +1689,15 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) if (yyComment.startsWith(QLatin1Char(':'))) { yyComment.remove(0, 1); extracomment.append(yyComment); + } else if (yyComment.startsWith(QLatin1Char('='))) { + yyComment.remove(0, 1); + msgid = yyComment.simplified(); + } else if (yyComment.startsWith(QLatin1Char('~'))) { + yyComment.remove(0, 1); + yyComment = yyComment.trimmed(); + int k = yyComment.indexOf(QLatin1Char(' ')); + if (k > -1) + extra.insert(yyComment.left(k), yyComment.mid(k + 1).trimmed()); } else { comment = yyComment.simplified(); if (comment.startsWith(QLatin1String(MagicComment))) { @@ -1689,7 +1708,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } else { context = comment.left(k); comment.remove(0, k + 1); - recordMessage(yyLineNo, context, QString(), comment, extracomment, false, false); + recordMessage(yyLineNo, context, QString(), comment, extracomment, + QString(), TranslatorMessage::ExtraData(), false, false); + extracomment.clear(); + results->tor->setExtras(extra); + extra.clear(); } } } @@ -1739,6 +1762,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) prospectiveContext.clear(); prefix.clear(); extracomment.clear(); + msgid.clear(); + extra.clear(); yyTokColonSeen = false; yyTok = getToken(); break; -- cgit v0.12 From ebfdbff7712e230c19fc2a990632038e3fc79ef2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 13:27:21 +0200 Subject: Doc: indicate that these methods are added in 4.6 --- src/dbus/qdbuspendingcall.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 7807543..0ec1a26 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -410,6 +410,7 @@ bool QDBusPendingCall::setReplyCallback(QObject *target, const char *member) #endif /*! + \since 4.6 Creates a QDBusPendingCall object based on the error condition \a error. The resulting pending call object will be in the "finished" state and QDBusPendingReply::isError() will return true. @@ -422,6 +423,7 @@ QDBusPendingCall QDBusPendingCall::fromError(const QDBusError &error) } /*! + \since 4.6 Creates a QDBusPendingCall object based on the message \a msg. The message must be of type QDBusMessage::ErrorMessage or QDBusMessage::ReplyMessage (that is, a message that is typical -- cgit v0.12 From bd3c9e428af5a804fd4631c941fb642c99f6430b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 13:28:17 +0200 Subject: Add a note about this method not being safe in multithreaded contexts --- src/dbus/qdbusconnection.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 6777aa5..14cadd9 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -973,8 +973,15 @@ QDBusConnection QDBusConnection::systemBus() } /*! + \nonreentrant + Returns the connection that sent the signal, if called in a slot activated by QDBus; otherwise it returns 0. + + \note Please avoid this function. This function is not thread-safe, so if + there's any other thread delivering a D-Bus call, this function may return + the wrong connection. In new code, please use QDBusContext::connection() + (see that class for a description on how to use it). */ QDBusConnection QDBusConnection::sender() { -- cgit v0.12 From c5f83fbd89d6bb950fb012c285879f6c88b5bdf3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 16:47:12 +0200 Subject: Add qcore_unix_p.h containing mostly safe versions of Unix functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of these functions are from unistd.h and need to have a loop around the actual call because the calls can be interrupted by a signal delivery. Some special calls (open, dup2, pipe) require an extra flag to support thread-safe execution: the file descriptor must be created from the operating system with the FD_CLOEXEC flag already set. The O_CLOEXEC flag is specified in POSIX.1-2008, but the rest is Linux-specific. Reviewed-By: João Abecasis --- src/corelib/kernel/kernel.pri | 1 + src/corelib/kernel/qcore_unix_p.h | 246 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 src/corelib/kernel/qcore_unix_p.h diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index ecef555..6f28029 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -92,6 +92,7 @@ unix { kernel/qsharedmemory_unix.cpp \ kernel/qsystemsemaphore_unix.cpp HEADERS += \ + kernel/qcore_unix_p.h \ kernel/qcrashhandler_p.h contains(QT_CONFIG, glib) { diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h new file mode 100644 index 0000000..4e3158a --- /dev/null +++ b/src/corelib/kernel/qcore_unix_p.h @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCORE_UNIX_P_H +#define QCORE_UNIX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt code on Unix. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qplatformdefs.h" + +#ifndef Q_OS_UNIX +# error "qcore_unix_p.h included on a non-Unix system" +#endif + +#include +#include +#include + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0209 +# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 +#else +# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0 +#endif + +#define EINTR_LOOP(var, cmd) \ + do { \ + var = cmd; \ + } while (var == -1 && errno == EINTR) + + +// don't call QT_OPEN or ::open +// call qt_safe_open +static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 0777) +{ +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + register int fd; + EINTR_LOOP(fd, QT_OPEN(pathname, flags, mode)); + + // unknown flags are ignored, so we have no way of verifying if + // O_CLOEXEC was accepted + if (fd != -1) + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + return fd; +} +#undef QT_OPEN +#define QT_OPEN qt_safe_open + +// don't call ::pipe +// call qt_safe_pipe +static inline int qt_safe_pipe(int pipefd[2], int flags = 0) +{ +#ifdef O_CLOEXEC + Q_ASSERT((flags & ~(O_CLOEXEC | O_NONBLOCK)) == 0); +#else + Q_ASSERT((flags & ~O_NONBLOCK) == 0); +#endif + + register int ret; +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC + // use pipe2 + flags |= O_CLOEXEC; + ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR + if (ret == 0 || errno != ENOSYS) + return ret; +#endif + + ret = ::pipe(pipefd); + if (ret == -1) + return -1; + + ::fcntl(pipefd[0], F_SETFD, FD_CLOEXEC); + ::fcntl(pipefd[1], F_SETFD, FD_CLOEXEC); + + // set non-block too? + if (flags & O_NONBLOCK) { + ::fcntl(pipefd[0], F_SETFL, ::fcntl(pipefd[0], F_GETFL) | O_NONBLOCK); + ::fcntl(pipefd[1], F_SETFL, ::fcntl(pipefd[1], F_GETFL) | O_NONBLOCK); + } + + return 0; +} + +// don't call dup or fcntl(F_DUPFD) +static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC) +{ + Q_ASSERT(flags == FD_CLOEXEC || flags == 0); + + register int ret; +#ifdef F_DUPFD_CLOEXEC + // use this fcntl + if (flags & FD_CLOEXEC) { + ret = ::fcntl(oldfd, F_DUPFD_CLOEXEC, atleast); + if (ret != -1 || errno != EINVAL) + return ret; + } +#endif + + // use F_DUPFD + ret = ::fcntl(oldfd, F_DUPFD, atleast); + + if (flags && ret != -1) + ::fcntl(ret, F_SETFD, flags); + return ret; +} + +// don't call dup2 +// call qt_safe_dup2 +static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) +{ + Q_ASSERT(flags == FD_CLOEXEC || flags == 0); + + register int ret; +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC + // use dup3 + if (flags & FD_CLOEXEC) { + EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC)); + if (ret == 0 || errno != ENOSYS) + return ret; + } +#endif + EINTR_LOOP(ret, ::dup2(oldfd, newfd)); + if (ret == -1) + return -1; + + if (flags) + ::fcntl(newfd, F_SETFD, flags); + return 0; +} + +static inline qint64 qt_safe_read(int fd, char *data, qint64 maxlen) +{ + qint64 ret = 0; + EINTR_LOOP(ret, QT_READ(fd, data, maxlen)); + return ret; +} +#undef QT_READ +#define QT_READ qt_safe_read + +static inline qint64 qt_safe_write(int fd, const char *data, qint64 len) +{ + qint64 ret = 0; + EINTR_LOOP(ret, QT_WRITE(fd, data, len)); + return ret; +} +#undef QT_WRITE +#define QT_WRITE qt_safe_write + +static inline int qt_safe_close(int fd) +{ + register int ret; + EINTR_LOOP(ret, QT_CLOSE(fd)); + return ret; +} +#undef QT_CLOSE +#define QT_CLOSE qt_safe_close + +static inline int qt_safe_execve(const char *filename, char *const argv[], + char *const envp[]) +{ + register int ret; + EINTR_LOOP(ret, ::execve(filename, argv, envp)); + return ret; +} + +static inline int qt_safe_execv(const char *path, char *const argv[]) +{ + register int ret; + EINTR_LOOP(ret, ::execv(path, argv)); + return ret; +} + +static inline int qt_safe_execvp(const char *file, char *const argv[]) +{ + register int ret; + EINTR_LOOP(ret, ::execvp(file, argv)); + return ret; +} + +static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) +{ + register int ret; + EINTR_LOOP(ret, ::waitpid(pid, status, options)); + return ret; +} + +Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + const struct timeval *tv); + +QT_END_NAMESPACE + +#endif -- cgit v0.12 From 29302d2429ed81f4396155383b602e7bde4edd3b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 17:30:51 +0200 Subject: Port most uses of ::open and QT_OPEN to the safe version. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures that we're calling the open64 version of this function as well as handling the O_CLOEXEC flag and EINTR errors. Reviewed-By: João Abecasis --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 5 +++-- src/corelib/io/qfsfileengine_unix.cpp | 18 +++++++----------- src/corelib/io/qresource.cpp | 4 ++++ src/corelib/io/qtemporaryfile.cpp | 17 ++++++----------- src/corelib/kernel/qsharedmemory_unix.cpp | 4 +++- src/corelib/kernel/qtranslator.cpp | 1 + 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index ed42c34..721f52c 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -43,6 +43,7 @@ #include "qfilesystemwatcher.h" #include "qfilesystemwatcher_kqueue_p.h" +#include "qcore_unix_p.h" #include #include @@ -124,9 +125,9 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths, QString path = it.next(); int fd; #if defined(O_EVTONLY) - fd = ::open(QFile::encodeName(path), O_EVTONLY); + fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY); #else - fd = ::open(QFile::encodeName(path), O_RDONLY); + fd = qt_safe_open(QFile::encodeName(path), O_RDONLY); #endif if (fd == -1) { perror("QKqueueFileSystemWatcherEngine::addPaths: open"); diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 4743a47..5708e9f 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -42,6 +42,7 @@ #include "qplatformdefs.h" #include "qabstractfileengine.h" #include "private/qfsfileengine_p.h" +#include "private/qcore_unix_p.h" #ifndef QT_NO_FSFILEENGINE @@ -90,6 +91,12 @@ static QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString & if (flags & QIODevice::ReadOnly) mode += '+'; } + +#if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0207 + // must be glibc >= 2.7 + mode += 'e'; +#endif + return mode; } @@ -118,12 +125,6 @@ static int openModeToOpenFlags(QIODevice::OpenMode mode) oflags |= QT_OPEN_TRUNC; } -#ifdef O_CLOEXEC - // supported on Linux >= 2.6.23; avoids one extra system call - // and avoids a race condition: if another thread forks, we could - // end up leaking a file descriptor... - oflags |= O_CLOEXEC; -#endif return oflags; } @@ -177,11 +178,6 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) } } -#ifndef O_CLOEXEC - // not needed on Linux >= 2.6.23 - setCloseOnExec(fd); // ignore failure -#endif - // Seek to the end when in Append mode. if (flags & QFile::Append) { int ret; diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index fe8764d..a70b92f 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -56,6 +56,10 @@ #include #include "private/qabstractfileengine_p.h" +#ifdef Q_OS_UNIX +# include "private/qcore_unix_p.h" +#endif + //#define DEBUG_RESOURCE_MATCH QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 62ab0c4..2ae4611 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -60,6 +60,10 @@ #include #include +#if defined(Q_OS_UNIX) +# include "private/qcore_unix_p.h" +#endif + #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) # include # if defined(_MSC_VER) && _MSC_VER >= 1400 @@ -72,7 +76,6 @@ # include "qfunctions_wince.h" #endif - QT_BEGIN_NAMESPACE /* @@ -208,8 +211,9 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) if ((*doopen = QT_OPEN(targetPath.toLocal8Bit(), O_CREAT|O_EXCL|O_RDWR # else // CE + // this is Unix if ((*doopen = - open(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR + qt_safe_open(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR # endif # ifdef QT_LARGEFILE_SUPPORT |QT_OPEN_LARGEFILE @@ -219,18 +223,9 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) # elif defined(Q_OS_WIN) |O_BINARY # endif -# ifdef O_CLOEXEC - // supported on Linux >= 2.6.23; avoids one extra system call - // and avoids a race condition: if another thread forks, we could - // end up leaking a file descriptor... - |O_CLOEXEC -# endif , 0600)) >= 0) #endif // WIN && !CE { -#if defined(Q_OS_UNIX) && !defined(O_CLOEXEC) - fcntl(*doopen, F_SETFD, FD_CLOEXEC); -#endif return 1; } if (errno != EEXIST) diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp index 5299972..04739ff 100644 --- a/src/corelib/kernel/qsharedmemory_unix.cpp +++ b/src/corelib/kernel/qsharedmemory_unix.cpp @@ -59,6 +59,8 @@ #include #include +#include "private/qcore_unix_p.h" + QT_BEGIN_NAMESPACE QSharedMemoryPrivate::QSharedMemoryPrivate() @@ -153,7 +155,7 @@ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName) if (QFile::exists(fileName)) return 0; - int fd = open(QFile::encodeName(fileName).constData(), + int fd = qt_safe_open(QFile::encodeName(fileName).constData(), O_EXCL | O_CREAT | O_RDWR, 0640); if (-1 == fd) { if (errno == EEXIST) diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 64cf16e..4aed2b2 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -58,6 +58,7 @@ #if defined(Q_OS_UNIX) #define QT_USE_MMAP +#include "private/qcore_unix_p.h" #endif // most of the headers below are already included in qplatformdefs.h -- cgit v0.12 From 557258e8f944f0003e9b71e5fe11fcb458db71d8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 18:01:05 +0200 Subject: Make the inotify_init call also use FD_CLOEXEC-safe version of the system call Reviewed-By: ossi --- src/corelib/io/qfilesystemwatcher_inotify.cpp | 40 +++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index 401e545..9d08228 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -44,6 +44,8 @@ #ifndef QT_NO_FILESYSTEMWATCHER +#include "private/qcore_unix_p.h" + #include #include #include @@ -62,62 +64,80 @@ # define __NR_inotify_init 291 # define __NR_inotify_add_watch 292 # define __NR_inotify_rm_watch 293 +# define __NR_inotify_init1 332 #elif defined(__x86_64__) # define __NR_inotify_init 253 # define __NR_inotify_add_watch 254 # define __NR_inotify_rm_watch 255 +# define __NR_inotify_init1 294 #elif defined(__powerpc__) || defined(__powerpc64__) # define __NR_inotify_init 275 # define __NR_inotify_add_watch 276 # define __NR_inotify_rm_watch 277 +# define __NR_inotify_init1 318 #elif defined (__ia64__) # define __NR_inotify_init 1277 # define __NR_inotify_add_watch 1278 # define __NR_inotify_rm_watch 1279 +# define __NR_inotify_init1 1318 #elif defined (__s390__) || defined (__s390x__) # define __NR_inotify_init 284 # define __NR_inotify_add_watch 285 # define __NR_inotify_rm_watch 286 +# define __NR_inotify_init1 324 #elif defined (__alpha__) # define __NR_inotify_init 444 # define __NR_inotify_add_watch 445 # define __NR_inotify_rm_watch 446 +// no inotify_init1 for the Alpha #elif defined (__sparc__) || defined (__sparc64__) # define __NR_inotify_init 151 # define __NR_inotify_add_watch 152 # define __NR_inotify_rm_watch 156 +# define __NR_inotify_init1 322 #elif defined (__arm__) # define __NR_inotify_init 316 # define __NR_inotify_add_watch 317 # define __NR_inotify_rm_watch 318 +# define __NR_inotify_init1 360 #elif defined (__sh__) # define __NR_inotify_init 290 # define __NR_inotify_add_watch 291 # define __NR_inotify_rm_watch 292 +# define __NR_inotify_init1 332 #elif defined (__sh64__) # define __NR_inotify_init 318 # define __NR_inotify_add_watch 319 # define __NR_inotify_rm_watch 320 +# define __NR_inotify_init1 360 #elif defined (__mips__) # define __NR_inotify_init 284 # define __NR_inotify_add_watch 285 # define __NR_inotify_rm_watch 286 +# define __NR_inotify_init1 329 #elif defined (__hppa__) # define __NR_inotify_init 269 # define __NR_inotify_add_watch 270 # define __NR_inotify_rm_watch 271 +# define __NR_inotify_init1 314 #elif defined (__avr32__) # define __NR_inotify_init 240 # define __NR_inotify_add_watch 241 # define __NR_inotify_rm_watch 242 +// no inotify_init1 for AVR32 #elif defined (__mc68000__) # define __NR_inotify_init 284 # define __NR_inotify_add_watch 285 # define __NR_inotify_rm_watch 286 +# define __NR_inotify_init1 328 #else # error "This architecture is not supported. Please talk to qt-bugs@trolltech.com" #endif +#if !defined(IN_CLOEXEC) && defined(O_CLOEXEC) && defined(__NR_inotify_init1) +# define IN_CLOEXEC O_CLOEXEC +#endif + QT_BEGIN_NAMESPACE #ifdef QT_LINUXBASE @@ -140,6 +160,13 @@ static inline int inotify_rm_watch(int fd, __u32 wd) return syscall(__NR_inotify_rm_watch, fd, wd); } +#ifdef IN_CLOEXEC +static inline int inotify_init1(int flags) +{ + return syscall(__NR_inotify_init1, flags); +} +#endif + // the following struct and values are documented in linux/inotify.h extern "C" { @@ -185,9 +212,16 @@ QT_BEGIN_NAMESPACE QInotifyFileSystemWatcherEngine *QInotifyFileSystemWatcherEngine::create() { - int fd = inotify_init(); - if (fd <= 0) - return 0; + register int fd = -1; +#ifdef IN_CLOEXEC + fd = inotify_init1(IN_CLOEXEC); +#endif + if (fd == -1) { + fd = inotify_init(); + if (fd == -1) + return 0; + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + } return new QInotifyFileSystemWatcherEngine(fd); } -- cgit v0.12 From 1d965e189dfd5c9977565ca0c20224806aa7473d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 19:02:32 +0200 Subject: Use the safe versions in these system calls I've just introduced. Reviewed-By: ossi --- src/corelib/io/qfilesystemwatcher_dnotify.cpp | 20 ++++++++++---------- src/corelib/io/qfsfileengine.cpp | 3 +++ src/corelib/io/qfsfileengine_unix.cpp | 2 +- src/corelib/kernel/qeventdispatcher_unix.cpp | 12 +++++++----- src/gui/painting/qpdf.cpp | 20 ++++++++++++-------- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_dnotify.cpp b/src/corelib/io/qfilesystemwatcher_dnotify.cpp index c68af85..6df3746 100644 --- a/src/corelib/io/qfilesystemwatcher_dnotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_dnotify.cpp @@ -59,6 +59,8 @@ #include #include +#include "private/qcore_unix_p.h" + #ifdef QT_LINUXBASE /* LSB doesn't standardize these */ @@ -80,7 +82,7 @@ static void (*qfswd_old_sigio_handler)(int) = 0; static void (*qfswd_old_sigio_action)(int, siginfo_t *, void *) = 0; static void qfswd_sigio_monitor(int signum, siginfo_t *i, void *v) { - ::write(qfswd_fileChanged_pipe[1], &i->si_fd, sizeof(int)); + qt_safe_write(qfswd_fileChanged_pipe[1], reinterpret_cast(&i->si_fd), sizeof(int)); if (qfswd_old_sigio_handler && qfswd_old_sigio_handler != SIG_IGN) qfswd_old_sigio_handler(signum); @@ -121,9 +123,7 @@ QDnotifySignalThread::QDnotifySignalThread() { moveToThread(this); - ::pipe(qfswd_fileChanged_pipe); - ::fcntl(qfswd_fileChanged_pipe[0], F_SETFL, - ::fcntl(qfswd_fileChanged_pipe[0], F_GETFL) | O_NONBLOCK); + qt_safe_pipe(qfswd_fileChanged_pipe, O_NONBLOCK); struct sigaction oldAction; struct sigaction action; @@ -181,7 +181,7 @@ void QDnotifySignalThread::run() void QDnotifySignalThread::readFromDnotify() { int fd; - int readrv = ::read(qfswd_fileChanged_pipe[0], &fd,sizeof(int)); + int readrv = qt_safe_read(qfswd_fileChanged_pipe[0], reinterpret_cast(&fd), sizeof(int)); // Only expect EAGAIN or EINTR. Other errors are assumed to be impossible. if(readrv != -1) { Q_ASSERT(readrv == sizeof(int)); @@ -207,9 +207,9 @@ QDnotifyFileSystemWatcherEngine::~QDnotifyFileSystemWatcherEngine() for(QHash::ConstIterator iter = fdToDirectory.constBegin(); iter != fdToDirectory.constEnd(); ++iter) { - ::close(iter->fd); + qt_safe_close(iter->fd); if(iter->parentFd) - ::close(iter->parentFd); + qt_safe_close(iter->parentFd); } } @@ -353,7 +353,7 @@ QStringList QDnotifyFileSystemWatcherEngine::removePaths(const QStringList &path if(!directory.isMonitored && directory.files.isEmpty()) { // No longer needed - ::close(directory.fd); + qt_safe_close(directory.fd); pathToFD.remove(directory.path); fdToDirectory.remove(fd); } @@ -419,9 +419,9 @@ void QDnotifyFileSystemWatcherEngine::refresh(int fd) } if(!directory.isMonitored && directory.files.isEmpty()) { - ::close(directory.fd); + qt_safe_close(directory.fd); if(directory.parentFd) { - ::close(directory.parentFd); + qt_safe_close(directory.parentFd); parentToFD.remove(directory.parentFd); } fdToDirectory.erase(iter); diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index e32b818..beafe72 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -50,6 +50,9 @@ #if !defined(Q_OS_WINCE) #include #endif +#if defined(Q_OS_UNIX) +#include "private/qcore_unix_p.h" +#endif #include QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 5708e9f..47e3db0 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -458,7 +458,7 @@ bool QFSFileEngine::caseSensitive() const bool QFSFileEngine::setCurrentPath(const QString &path) { int r; - r = ::chdir(QFile::encodeName(path)); + r = QT_CHDIR(QFile::encodeName(path)); return r >= 0; } diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 161398e..0eeea04 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -49,6 +49,7 @@ #include "qeventdispatcher_unix_p.h" #include #include +#include #include #include @@ -76,6 +77,7 @@ static void signalHandler(int sig) } +#ifdef Q_OS_INTEGRITY static void initThreadPipeFD(int fd) { int ret = fcntl(fd, F_SETFD, FD_CLOEXEC); @@ -90,7 +92,7 @@ static void initThreadPipeFD(int fd) if (ret == -1) perror("QEventDispatcherUNIXPrivate: Unable to set flags on thread pipe"); } - +#endif QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() { @@ -102,13 +104,13 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() // INTEGRITY doesn't like a "select" on pipes, so use socketpair instead if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair"); -#else - if (pipe(thread_pipe) == -1) - perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe"); -#endif initThreadPipeFD(thread_pipe[0]); initThreadPipeFD(thread_pipe[1]); +#else + if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1) + perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe"); +#endif sn_highest = -1; diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index a6ecd4e..178d519 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -48,6 +48,10 @@ #include "qprinterinfo.h" #include +#ifdef Q_OS_UNIX +#include "private/qcore_unix_p.h" // overrides QT_OPEN +#endif + QT_BEGIN_NAMESPACE extern int qt_defaultDpi(); @@ -1647,7 +1651,7 @@ static void closeAllOpenFds() #endif // leave stdin/out/err untouched while(--i > 2) - ::close(i); + QT_CLOSE(i); } #endif @@ -1681,7 +1685,7 @@ bool QPdfBaseEnginePrivate::openPrintDevice() if (!printerName.isEmpty()) pr = printerName; int fds[2]; - if (pipe(fds) != 0) { + if (qt_safe_pipe(fds) != 0) { qWarning("QPdfPrinter: Could not open pipe to print"); return false; } @@ -1700,9 +1704,9 @@ bool QPdfBaseEnginePrivate::openPrintDevice() (void)execlp("true", "true", (char *)0); (void)execl("/bin/true", "true", (char *)0); (void)execl("/usr/bin/true", "true", (char *)0); - ::exit(0); + ::_exit(0); } - dup2(fds[0], 0); + qt_safe_dup2(fds[0], 0, 0); closeAllOpenFds(); @@ -1769,14 +1773,14 @@ bool QPdfBaseEnginePrivate::openPrintDevice() // wait for a second so the parent process (the // child of the GUI process) has exited. then // exit. - ::close(0); + QT_CLOSE(0); (void)::sleep(1); - ::exit(0); + ::_exit(0); } // parent process - ::close(fds[0]); + QT_CLOSE(fds[0]); fd = fds[1]; - (void)::waitpid(pid, 0, 0); + (void)qt_safe_waitpid(pid, 0, 0); if (fd < 0) return false; -- cgit v0.12 From de05f9a40e41deb79daf5c4935b2645d70d7f322 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 19:04:32 +0200 Subject: Port QProcess to use the EINTR-safe and thread-safe functions Reviewed-By: ossi --- src/corelib/io/qprocess_unix.cpp | 213 ++++++++++++--------------------------- 1 file changed, 65 insertions(+), 148 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 49869a4..c81da44 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -84,6 +84,7 @@ QT_END_NAMESPACE #include "qprocess.h" #include "qprocess_p.h" +#include "private/qcore_unix_p.h" #ifdef Q_OS_MAC #include @@ -114,78 +115,11 @@ static inline char *strdup(const char *data) } #endif -static qint64 qt_native_read(int fd, char *data, qint64 maxlen) -{ - qint64 ret = 0; - do { - ret = ::read(fd, data, maxlen); - } while (ret == -1 && errno == EINTR); - return ret; -} - -static qint64 qt_native_write(int fd, const char *data, qint64 len) -{ - qint64 ret = 0; - do { - ret = ::write(fd, data, len); - } while (ret == -1 && errno == EINTR); - return ret; -} - -static void qt_native_close(int fd) -{ - int ret; - do { - ret = ::close(fd); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_dup2(int oldfd, int newfd) -{ - int ret; - do { - ret = ::dup2(oldfd, newfd); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_chdir(const char *path) -{ - int ret; - do { - ret = ::chdir(path); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_execve(const char *filename, char *const argv[], - char *const envp[]) -{ - int ret; - do { - ret = ::execve(filename, argv, envp); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_execv(const char *path, char *const argv[]) -{ - int ret; - do { - ret = ::execv(path, argv); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_execvp(const char *file, char *const argv[]) -{ - int ret; - do { - ret = ::execvp(file, argv); - } while (ret == -1 && errno == EINTR); -} - static int qt_qprocess_deadChild_pipe[2]; static void (*qt_sa_old_sigchld_handler)(int) = 0; static void qt_sa_sigchld_handler(int signum) { - qt_native_write(qt_qprocess_deadChild_pipe[1], "", 1); + qt_safe_write(qt_qprocess_deadChild_pipe[1], "", 1); #if defined (QPROCESS_DEBUG) fprintf(stderr, "*** SIGCHLD\n"); #endif @@ -231,13 +165,7 @@ QProcessManager::QProcessManager() // initialize the dead child pipe and make it non-blocking. in the // extremely unlikely event that the pipe fills up, we do not under any // circumstances want to block. - ::pipe(qt_qprocess_deadChild_pipe); - ::fcntl(qt_qprocess_deadChild_pipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(qt_qprocess_deadChild_pipe[1], F_SETFD, FD_CLOEXEC); - ::fcntl(qt_qprocess_deadChild_pipe[0], F_SETFL, - ::fcntl(qt_qprocess_deadChild_pipe[0], F_GETFL) | O_NONBLOCK); - ::fcntl(qt_qprocess_deadChild_pipe[1], F_SETFL, - ::fcntl(qt_qprocess_deadChild_pipe[1], F_GETFL) | O_NONBLOCK); + qt_safe_pipe(qt_qprocess_deadChild_pipe, O_NONBLOCK); // set up the SIGCHLD handler, which writes a single byte to the dead // child pipe every time a child dies. @@ -254,13 +182,13 @@ QProcessManager::QProcessManager() QProcessManager::~QProcessManager() { // notify the thread that we're shutting down. - qt_native_write(qt_qprocess_deadChild_pipe[1], "@", 1); - qt_native_close(qt_qprocess_deadChild_pipe[1]); + qt_safe_write(qt_qprocess_deadChild_pipe[1], "@", 1); + qt_safe_close(qt_qprocess_deadChild_pipe[1]); wait(); // on certain unixes, closing the reading end of the pipe will cause // select in run() to block forever, rather than return with EBADF. - qt_native_close(qt_qprocess_deadChild_pipe[0]); + qt_safe_close(qt_qprocess_deadChild_pipe[0]); qt_qprocess_deadChild_pipe[0] = -1; qt_qprocess_deadChild_pipe[1] = -1; @@ -304,7 +232,7 @@ void QProcessManager::run() // signals may have been delivered in the meantime, to avoid race // conditions. char c; - if (qt_native_read(qt_qprocess_deadChild_pipe[0], &c, 1) < 0 || c == '@') + if (qt_safe_read(qt_qprocess_deadChild_pipe[0], &c, 1) < 0 || c == '@') break; // catch any and all children that we can. @@ -323,7 +251,7 @@ void QProcessManager::catchDeadChildren() // notify all children that they may have died. they need to run // waitpid() in their own thread. QProcessInfo *info = it.value(); - qt_native_write(info->deathPipe, "", 1); + qt_safe_write(info->deathPipe, "", 1); #if defined (QPROCESS_DEBUG) qDebug() << "QProcessManager::run() sending death notice to" << info->process; @@ -382,25 +310,23 @@ void QProcessManager::unlock() static void qt_create_pipe(int *pipe) { if (pipe[0] != -1) - qt_native_close(pipe[0]); + qt_safe_close(pipe[0]); if (pipe[1] != -1) - qt_native_close(pipe[1]); - if (::pipe(pipe) != 0) { + qt_safe_close(pipe[1]); + if (qt_safe_pipe(pipe) != 0) { qWarning("QProcessPrivate::createPipe: Cannot create pipe %p: %s", pipe, qPrintable(qt_error_string(errno))); } - ::fcntl(pipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(pipe[1], F_SETFD, FD_CLOEXEC); } void QProcessPrivate::destroyPipe(int *pipe) { if (pipe[1] != -1) { - qt_native_close(pipe[1]); + qt_safe_close(pipe[1]); pipe[1] = -1; } if (pipe[0] != -1) { - qt_native_close(pipe[0]); + qt_safe_close(pipe[0]); pipe[0] = -1; } } @@ -453,7 +379,7 @@ bool QProcessPrivate::createChannel(Channel &channel) if (&channel == &stdinChannel) { // try to open in read-only mode channel.pipe[1] = -1; - if ( (channel.pipe[0] = QT_OPEN(fname, O_RDONLY)) != -1) + if ( (channel.pipe[0] = qt_safe_open(fname, O_RDONLY)) != -1) return true; // success q->setErrorString(QProcess::tr("Could not open input redirection for reading")); @@ -465,7 +391,7 @@ bool QProcessPrivate::createChannel(Channel &channel) mode |= O_TRUNC; channel.pipe[0] = -1; - if ( (channel.pipe[1] = QT_OPEN(fname, mode, 0666)) != -1) + if ( (channel.pipe[1] = qt_safe_open(fname, mode, 0666)) != -1) return true; // success q->setErrorString(QProcess::tr("Could not open output redirection for writing")); @@ -586,8 +512,6 @@ void QProcessPrivate::startProcess() return; qt_create_pipe(childStartedPipe); qt_create_pipe(deathPipe); - ::fcntl(deathPipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(deathPipe[1], F_SETFD, FD_CLOEXEC); if (threadData->eventDispatcher) { startupSocketNotifier = new QSocketNotifier(childStartedPipe[0], @@ -728,11 +652,11 @@ void QProcessPrivate::startProcess() // parent // close the ends we don't use and make all pipes non-blocking ::fcntl(deathPipe[0], F_SETFL, ::fcntl(deathPipe[0], F_GETFL) | O_NONBLOCK); - qt_native_close(childStartedPipe[1]); + qt_safe_close(childStartedPipe[1]); childStartedPipe[1] = -1; if (stdinChannel.pipe[0] != -1) { - qt_native_close(stdinChannel.pipe[0]); + qt_safe_close(stdinChannel.pipe[0]); stdinChannel.pipe[0] = -1; } @@ -740,7 +664,7 @@ void QProcessPrivate::startProcess() ::fcntl(stdinChannel.pipe[1], F_SETFL, ::fcntl(stdinChannel.pipe[1], F_GETFL) | O_NONBLOCK); if (stdoutChannel.pipe[1] != -1) { - qt_native_close(stdoutChannel.pipe[1]); + qt_safe_close(stdoutChannel.pipe[1]); stdoutChannel.pipe[1] = -1; } @@ -748,7 +672,7 @@ void QProcessPrivate::startProcess() ::fcntl(stdoutChannel.pipe[0], F_SETFL, ::fcntl(stdoutChannel.pipe[0], F_GETFL) | O_NONBLOCK); if (stderrChannel.pipe[1] != -1) { - qt_native_close(stderrChannel.pipe[1]); + qt_safe_close(stderrChannel.pipe[1]); stderrChannel.pipe[1] = -1; } if (stderrChannel.pipe[0] != -1) @@ -761,35 +685,34 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv Q_Q(QProcess); - // copy the stdin socket - qt_native_dup2(stdinChannel.pipe[0], fileno(stdin)); + // copy the stdin socket (without closing on exec) + qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0); // copy the stdout and stderr if asked to if (processChannelMode != QProcess::ForwardedChannels) { - qt_native_dup2(stdoutChannel.pipe[1], fileno(stdout)); + qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0); // merge stdout and stderr if asked to if (processChannelMode == QProcess::MergedChannels) { - qt_native_dup2(fileno(stdout), fileno(stderr)); + qt_safe_dup2(fileno(stdout), fileno(stderr), 0); } else { - qt_native_dup2(stderrChannel.pipe[1], fileno(stderr)); + qt_safe_dup2(stderrChannel.pipe[1], fileno(stderr), 0); } } // make sure this fd is closed if execvp() succeeds - qt_native_close(childStartedPipe[0]); - ::fcntl(childStartedPipe[1], F_SETFD, FD_CLOEXEC); + qt_safe_close(childStartedPipe[0]); // enter the working directory if (workingDir) - qt_native_chdir(workingDir); + QT_CHDIR(workingDir); // this is a virtual call, and it base behavior is to do nothing. q->setupChildProcess(); // execute the process if (!envp) { - qt_native_execvp(argv[0], argv); + qt_safe_execvp(argv[0], argv); } else { if (path) { char **arg = path; @@ -798,14 +721,14 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() searching / starting %s\n", argv[0]); #endif - qt_native_execve(argv[0], argv, envp); + qt_safe_execve(argv[0], argv, envp); ++arg; } } else { #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() starting %s\n", argv[0]); #endif - qt_native_execve(argv[0], argv, envp); + qt_safe_execve(argv[0], argv, envp); } } @@ -813,21 +736,21 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() failed, notifying parent process\n"); #endif - qt_native_write(childStartedPipe[1], "", 1); - qt_native_close(childStartedPipe[1]); + qt_safe_write(childStartedPipe[1], "", 1); + qt_safe_close(childStartedPipe[1]); childStartedPipe[1] = -1; } bool QProcessPrivate::processStarted() { char c; - int i = qt_native_read(childStartedPipe[0], &c, 1); + int i = qt_safe_read(childStartedPipe[0], &c, 1); if (startupSocketNotifier) { startupSocketNotifier->setEnabled(false); startupSocketNotifier->deleteLater(); startupSocketNotifier = 0; } - qt_native_close(childStartedPipe[0]); + qt_safe_close(childStartedPipe[0]); childStartedPipe[0] = -1; #if defined (QPROCESS_DEBUG) @@ -862,7 +785,7 @@ qint64 QProcessPrivate::bytesAvailableFromStderr() const qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen) { - qint64 bytesRead = qt_native_read(stdoutChannel.pipe[0], data, maxlen); + qint64 bytesRead = qt_safe_read(stdoutChannel.pipe[0], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::readFromStdout(%p \"%s\", %lld) == %lld", data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead); @@ -872,7 +795,7 @@ qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen) qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen) { - qint64 bytesRead = qt_native_read(stderrChannel.pipe[0], data, maxlen); + qint64 bytesRead = qt_safe_read(stderrChannel.pipe[0], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::readFromStderr(%p \"%s\", %lld) == %lld", data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead); @@ -896,7 +819,7 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) { qt_ignore_sigpipe(); - qint64 written = qt_native_write(stdinChannel.pipe[1], data, maxlen); + qint64 written = qt_safe_write(stdinChannel.pipe[1], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld", data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written); @@ -922,7 +845,7 @@ void QProcessPrivate::killProcess() ::kill(pid_t(pid), SIGKILL); } -static int qt_native_select(fd_set *fdread, fd_set *fdwrite, int timeout) +static int qt_safe_select(fd_set *fdread, fd_set *fdwrite, int timeout) { struct timeval tv; tv.tv_sec = timeout / 1000; @@ -962,7 +885,7 @@ bool QProcessPrivate::waitForStarted(int msecs) FD_SET(childStartedPipe[0], &fds); int ret; do { - ret = qt_native_select(&fds, 0, msecs); + ret = qt_safe_select(&fds, 0, msecs); } while (ret < 0 && errno == EINTR); if (ret == 0) { processError = QProcess::Timedout; @@ -1011,7 +934,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_native_select(&fdread, &fdwrite, timeout); + int ret = qt_safe_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; @@ -1084,7 +1007,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_native_select(&fdread, &fdwrite, timeout); + int ret = qt_safe_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; @@ -1152,7 +1075,7 @@ bool QProcessPrivate::waitForFinished(int msecs) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_native_select(&fdread, &fdwrite, timeout); + int ret = qt_safe_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; @@ -1193,7 +1116,7 @@ bool QProcessPrivate::waitForWrite(int msecs) int ret; do { - ret = qt_native_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; + ret = qt_safe_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; } while (ret < 0 && errno == EINTR); return ret == 1; } @@ -1210,15 +1133,11 @@ bool QProcessPrivate::waitForDeadChild() // read a byte from the death pipe char c; - qt_native_read(deathPipe[0], &c, 1); + qt_safe_read(deathPipe[0], &c, 1); // check if our process is dead int exitStatus; - pid_t waitResult = 0; - do { - waitResult = waitpid(pid_t(pid), &exitStatus, WNOHANG); - } while ((waitResult == -1 && errno == EINTR)); - if (waitResult > 0) { + if (qt_safe_waitpid(pid_t(pid), &exitStatus, WNOHANG) > 0) { processManager()->remove(q); crashed = !WIFEXITED(exitStatus); exitCode = WEXITSTATUS(exitStatus); @@ -1262,16 +1181,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a ::setsid(); - qt_native_close(startedPipe[0]); - qt_native_close(pidPipe[0]); + qt_safe_close(startedPipe[0]); + qt_safe_close(pidPipe[0]); pid_t doubleForkPid = qt_fork(); if (doubleForkPid == 0) { - ::fcntl(startedPipe[1], F_SETFD, FD_CLOEXEC); - qt_native_close(pidPipe[1]); + qt_safe_close(pidPipe[1]); if (!encodedWorkingDirectory.isEmpty()) - qt_native_chdir(encodedWorkingDirectory.constData()); + QT_CHDIR(encodedWorkingDirectory.constData()); char **argv = new char *[arguments.size() + 2]; for (int i = 0; i < arguments.size(); ++i) { @@ -1292,13 +1210,13 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a if (!tmp.endsWith('/')) tmp += '/'; tmp += QFile::encodeName(program); argv[0] = tmp.data(); - qt_native_execv(argv[0], argv); + qt_safe_execv(argv[0], argv); } } } else { QByteArray tmp = QFile::encodeName(program); argv[0] = tmp.data(); - qt_native_execv(argv[0], argv); + qt_safe_execv(argv[0], argv); } struct sigaction noaction; @@ -1308,8 +1226,8 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a // '\1' means execv failed char c = '\1'; - qt_native_write(startedPipe[1], &c, 1); - qt_native_close(startedPipe[1]); + qt_safe_write(startedPipe[1], &c, 1); + qt_safe_close(startedPipe[1]); ::_exit(1); } else if (doubleForkPid == -1) { struct sigaction noaction; @@ -1319,40 +1237,39 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a // '\2' means internal error char c = '\2'; - qt_native_write(startedPipe[1], &c, 1); + qt_safe_write(startedPipe[1], &c, 1); } - qt_native_close(startedPipe[1]); - qt_native_write(pidPipe[1], (const char *)&doubleForkPid, sizeof(pid_t)); - qt_native_chdir("/"); + qt_safe_close(startedPipe[1]); + qt_safe_write(pidPipe[1], (const char *)&doubleForkPid, sizeof(pid_t)); + QT_CHDIR("/"); ::_exit(1); } - qt_native_close(startedPipe[1]); - qt_native_close(pidPipe[1]); + qt_safe_close(startedPipe[1]); + qt_safe_close(pidPipe[1]); if (childPid == -1) { - qt_native_close(startedPipe[0]); - qt_native_close(pidPipe[0]); + qt_safe_close(startedPipe[0]); + qt_safe_close(pidPipe[0]); return false; } char reply = '\0'; - int startResult = qt_native_read(startedPipe[0], &reply, 1); + int startResult = qt_safe_read(startedPipe[0], &reply, 1); int result; - qt_native_close(startedPipe[0]); - while (::waitpid(childPid, &result, 0) == -1 && errno == EINTR) - { } + qt_safe_close(startedPipe[0]); + qt_safe_waitpid(childPid, &result, 0); bool success = (startResult != -1 && reply == '\0'); if (success && pid) { pid_t actualPid = 0; - if (qt_native_read(pidPipe[0], (char *)&actualPid, sizeof(pid_t)) == sizeof(pid_t)) { + if (qt_safe_read(pidPipe[0], (char *)&actualPid, sizeof(pid_t)) == sizeof(pid_t)) { *pid = actualPid; } else { *pid = 0; } } - qt_native_close(pidPipe[0]); + qt_safe_close(pidPipe[0]); return success; } -- cgit v0.12 From 27fc6ef5dfb7d58af778de162298fdc4da34459f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 20:54:17 +0200 Subject: Add a properly-safe version of select(2). Do the timeout handling the right and cross-platform way. The code that was in QProcess worked only on Linux, where the kernel sets the remainder in the returned timeval structure. Reviewed-By: ossi --- src/corelib/io/qprocess_unix.cpp | 80 ++++++++-------- src/corelib/kernel/kernel.pri | 1 + src/corelib/kernel/qcore_unix.cpp | 121 ++++++++++++++++++++++++ src/network/socket/qnativesocketengine_unix.cpp | 53 ++--------- 4 files changed, 165 insertions(+), 90 deletions(-) create mode 100644 src/corelib/kernel/qcore_unix.cpp diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index c81da44..fafce07 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -128,6 +128,13 @@ static void qt_sa_sigchld_handler(int signum) qt_sa_old_sigchld_handler(signum); } +static inline void add_fd(int &nfds, int fd, fd_set *fdset) +{ + FD_SET(fd, fdset); + if ((fd) > nfds) + nfds = fd; +} + struct QProcessInfo { QProcess *process; int deathPipe; @@ -845,17 +852,15 @@ void QProcessPrivate::killProcess() ::kill(pid_t(pid), SIGKILL); } -static int qt_safe_select(fd_set *fdread, fd_set *fdwrite, int timeout) +static int select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout) { + if (timeout < 0) + return qt_safe_select(nfds, fdread, fdwrite, 0, 0); + struct timeval tv; tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; - - int ret; - do { - ret = select(FD_SETSIZE, fdread, fdwrite, 0, timeout < 0 ? 0 : &tv); - } while (ret < 0 && (errno == EINTR)); - return ret; + return qt_safe_select(nfds, fdread, fdwrite, 0, &tv); } /* @@ -883,11 +888,7 @@ bool QProcessPrivate::waitForStarted(int msecs) fd_set fds; FD_ZERO(&fds); FD_SET(childStartedPipe[0], &fds); - int ret; - do { - ret = qt_safe_select(&fds, 0, msecs); - } while (ret < 0 && errno == EINTR); - if (ret == 0) { + if (select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { processError = QProcess::Timedout; q->setErrorString(QProcess::tr("Process operation timed out")); #if defined (QPROCESS_DEBUG) @@ -920,24 +921,23 @@ bool QProcessPrivate::waitForReadyRead(int msecs) FD_ZERO(&fdread); FD_ZERO(&fdwrite); + int nfds = deathPipe[0]; + FD_SET(deathPipe[0], &fdread); + if (processState == QProcess::Starting) - FD_SET(childStartedPipe[0], &fdread); + add_fd(nfds, childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) - FD_SET(stdoutChannel.pipe[0], &fdread); + add_fd(nfds, stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) - FD_SET(stderrChannel.pipe[0], &fdread); - - FD_SET(deathPipe[0], &fdread); + add_fd(nfds, stderrChannel.pipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) - FD_SET(stdinChannel.pipe[1], &fdwrite); + add_fd(nfds, stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_safe_select(&fdread, &fdwrite, timeout); + int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); if (ret < 0) { - if (errno == EINTR) - continue; break; } if (ret == 0) { @@ -993,24 +993,24 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) FD_ZERO(&fdread); FD_ZERO(&fdwrite); + int nfds = deathPipe[0]; + FD_SET(deathPipe[0], &fdread); + if (processState == QProcess::Starting) - FD_SET(childStartedPipe[0], &fdread); + add_fd(nfds, childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) - FD_SET(stdoutChannel.pipe[0], &fdread); + add_fd(nfds, stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) - FD_SET(stderrChannel.pipe[0], &fdread); + add_fd(nfds, stderrChannel.pipe[0], &fdread); - FD_SET(deathPipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) - FD_SET(stdinChannel.pipe[1], &fdwrite); + add_fd(nfds, stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_safe_select(&fdread, &fdwrite, timeout); + int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); if (ret < 0) { - if (errno == EINTR) - continue; break; } @@ -1056,29 +1056,28 @@ bool QProcessPrivate::waitForFinished(int msecs) forever { fd_set fdread; fd_set fdwrite; + int nfds = -1; FD_ZERO(&fdread); FD_ZERO(&fdwrite); if (processState == QProcess::Starting) - FD_SET(childStartedPipe[0], &fdread); + add_fd(nfds, childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) - FD_SET(stdoutChannel.pipe[0], &fdread); + add_fd(nfds, stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) - FD_SET(stderrChannel.pipe[0], &fdread); + add_fd(nfds, stderrChannel.pipe[0], &fdread); if (processState == QProcess::Running) - FD_SET(deathPipe[0], &fdread); + add_fd(nfds, deathPipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) - FD_SET(stdinChannel.pipe[1], &fdwrite); + add_fd(nfds, stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_safe_select(&fdread, &fdwrite, timeout); + int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); if (ret < 0) { - if (errno == EINTR) - continue; break; } if (ret == 0) { @@ -1113,12 +1112,7 @@ bool QProcessPrivate::waitForWrite(int msecs) fd_set fdwrite; FD_ZERO(&fdwrite); FD_SET(stdinChannel.pipe[1], &fdwrite); - - int ret; - do { - ret = qt_safe_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; - } while (ret < 0 && errno == EINTR); - return ret == 1; + return select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; } void QProcessPrivate::findExitCode() diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 6f28029..8759578 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -88,6 +88,7 @@ mac { unix { SOURCES += \ + kernel/qcore_unix.cpp \ kernel/qcrashhandler.cpp \ kernel/qsharedmemory_unix.cpp \ kernel/qsystemsemaphore_unix.cpp diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp new file mode 100644 index 0000000..ffaf958 --- /dev/null +++ b/src/corelib/kernel/qcore_unix.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcore_unix_p.h" + +#include +#include +#include + +#include "qeventdispatcher_unix_p.h" // for the timeval operators + +#if !defined(QT_NO_CLOCK_MONOTONIC) +# if defined(QT_BOOTSTRAPPED) +# define QT_NO_CLOCK_MONOTONIC +# endif +#endif + +QT_BEGIN_NAMESPACE + +static inline timeval gettime() +{ + timeval tv; +#ifndef QT_NO_CLOCK_MONOTONIC + // use the monotonic clock + static volatile bool monotonicClockDisabled = false; + struct timespec ts; + if (!monotonicClockDisabled) { + if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) { + monotonicClockDisabled = true; + } else { + tv.tv_sec = ts.tv_sec; + tv.tv_usec = ts.tv_nsec / 1000; + return tv; + } + } +#endif + // use gettimeofday + ::gettimeofday(&tv, 0); + return tv; +} + +static inline bool time_update(struct timeval *tv, const struct timeval &start, + const struct timeval &timeout) +{ + struct timeval now = gettime(); + if (now < start) { + // clock reset, give up + return false; + } + + *tv = timeout + start - now; + return true; +} + +int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + const struct timeval *orig_timeout) +{ + if (!orig_timeout) { + // no timeout -> block forever + register int ret; + EINTR_LOOP(ret, select(nfds, fdread, fdwrite, fdexcept, 0)); + return ret; + } + + timeval start = gettime(); + timeval timeout = *orig_timeout; + + // loop and recalculate the timeout as needed + int ret; + forever { + ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeout); + if (ret != -1 || errno != EINTR) + return ret; + + // recalculate the timeout + if (!time_update(&timeout, start, *orig_timeout)) { + // clock reset, fake timeout error + return 0; + } + } +} + +QT_END_NAMESPACE diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index b130a9b..6eafe05 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -42,6 +42,7 @@ //#define QNATIVESOCKETENGINE_DEBUG #include "qnativesocketengine_p.h" +#include "private/qcore_unix_p.h" #include "qiodevice.h" #include "qhostaddress.h" #include "qvarlengtharray.h" @@ -833,33 +834,11 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) co tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; - QTime timer; - timer.start(); - int retval; - do { - if (selectForRead) - retval = select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); - else - retval = select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); - - if (retval != -1 || errno != EINTR) - break; - - if (timeout > 0) { - // recalculate the timeout - int t = timeout - timer.elapsed(); - if (t < 0) { - // oops, timeout turned negative? - retval = -1; - break; - } - - tv.tv_sec = t / 1000; - tv.tv_usec = (t % 1000) * 1000; - } - } while (true); - + if (selectForRead) + retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); + else + retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); return retval; } @@ -880,28 +859,8 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; - QTime timer; - timer.start(); - int ret; - do { - ret = select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); - if (ret != -1 || errno != EINTR) - break; - - if (timeout > 0) { - // recalculate the timeout - int t = timeout - timer.elapsed(); - if (t < 0) { - // oops, timeout turned negative? - ret = -1; - break; - } - - tv.tv_sec = t / 1000; - tv.tv_usec = (t % 1000) * 1000; - } - } while (true); + ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); if (ret <= 0) return ret; -- cgit v0.12 From cad1bf4c902899ec1a8277d46272afa23fc2b34b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Apr 2009 11:55:02 +0200 Subject: Port gui/embedded to the EINTR-safe functions. I think I found two file descriptor that aren't closed. One seems like a genuine leak, the other seems intentional. Reviewed-By: ossi --- src/gui/embedded/qkbdlinuxinput_qws.cpp | 1 + src/gui/embedded/qkbdsl5000_qws.cpp | 6 +++-- src/gui/embedded/qkbdtty_qws.cpp | 4 ++++ src/gui/embedded/qkbdvfb_qws.cpp | 9 ++++---- src/gui/embedded/qkbdvr41xx_qws.cpp | 7 +++--- src/gui/embedded/qkbdyopy_qws.cpp | 10 +++++---- src/gui/embedded/qlock.cpp | 6 +++-- src/gui/embedded/qmousebus_qws.cpp | 11 +++++----- src/gui/embedded/qmouselinuxtp_qws.cpp | 7 +++--- src/gui/embedded/qmousepc_qws.cpp | 39 +++++++++++++++++---------------- src/gui/embedded/qmousevfb_qws.cpp | 9 ++++---- src/gui/embedded/qmousevr41xx_qws.cpp | 11 +++++----- src/gui/embedded/qmouseyopy_qws.cpp | 7 +++--- src/gui/embedded/qscreenlinuxfb_qws.cpp | 20 ++++++++++------- src/gui/embedded/qsoundqss_qws.cpp | 9 ++++---- src/gui/embedded/qtransportauth_qws.cpp | 7 +++--- src/gui/embedded/qunixsocket.cpp | 18 ++++++++++----- src/gui/text/qfontdatabase_qws.cpp | 5 +++-- src/gui/text/qfontengine_qpf.cpp | 11 +++++----- src/gui/text/qfontengine_qws.cpp | 5 +++-- 20 files changed, 118 insertions(+), 84 deletions(-) diff --git a/src/gui/embedded/qkbdlinuxinput_qws.cpp b/src/gui/embedded/qkbdlinuxinput_qws.cpp index d5720f7..e552731 100644 --- a/src/gui/embedded/qkbdlinuxinput_qws.cpp +++ b/src/gui/embedded/qkbdlinuxinput_qws.cpp @@ -47,6 +47,7 @@ #include #include +#include // overrides QT_OPEN #include #include diff --git a/src/gui/embedded/qkbdsl5000_qws.cpp b/src/gui/embedded/qkbdsl5000_qws.cpp index 36cb903..cf82c10 100644 --- a/src/gui/embedded/qkbdsl5000_qws.cpp +++ b/src/gui/embedded/qkbdsl5000_qws.cpp @@ -51,6 +51,8 @@ #include "qnamespace.h" #include "qtimer.h" +#include // overrides QT_OPEN + #include #include #include @@ -207,14 +209,14 @@ QWSSL5000KeyboardHandler::QWSSL5000KeyboardHandler(const QString &device) numLock = false; sharp_kbdctl_modifstat st; - int dev = ::open(device.isEmpty()?"/dev/sharp_kbdctl":device.toLocal8Bit().constData(), O_RDWR); + int dev = QT_OPEN(device.isEmpty()?"/dev/sharp_kbdctl":device.toLocal8Bit().constData(), O_RDWR); if (dev >= 0) { memset(&st, 0, sizeof(st)); st.which = 3; int ret = ioctl(dev, SHARP_KBDCTL_GETMODIFSTAT, (char*)&st); if(!ret) numLock = (bool)st.stat; - ::close(dev); + QT_CLOSE(dev); } } diff --git a/src/gui/embedded/qkbdtty_qws.cpp b/src/gui/embedded/qkbdtty_qws.cpp index 33777eb..8c1e79b 100644 --- a/src/gui/embedded/qkbdtty_qws.cpp +++ b/src/gui/embedded/qkbdtty_qws.cpp @@ -47,6 +47,7 @@ #include #include +#include // overrides QT_OPEN #include #include @@ -213,6 +214,9 @@ QWSTtyKbPrivate::~QWSTtyKbPrivate() ::ioctl(m_tty_fd, KDSKBMODE, m_originalKbdMode); #endif tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr); + + // we're leaking m_tty_fd here? + //QT_CLOSE(m_tty_fd); } } diff --git a/src/gui/embedded/qkbdvfb_qws.cpp b/src/gui/embedded/qkbdvfb_qws.cpp index 082aac1..a44183b 100644 --- a/src/gui/embedded/qkbdvfb_qws.cpp +++ b/src/gui/embedded/qkbdvfb_qws.cpp @@ -55,6 +55,7 @@ #include #include #include +#include // overrides QT_OPEN QT_BEGIN_NAMESPACE @@ -69,13 +70,13 @@ QVFbKeyboardHandler::QVFbKeyboardHandler(const QString &device) kbdBufferLen = sizeof(QVFbKeyData) * 5; kbdBuffer = new unsigned char [kbdBufferLen]; - if ((kbdFD = open(terminalName.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { + if ((kbdFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { qWarning("Cannot open %s (%s)", terminalName.toLatin1().constData(), strerror(errno)); } else { // Clear pending input char buf[2]; - while (read(kbdFD, buf, 1) > 0) { } + while (QT_READ(kbdFD, buf, 1) > 0) { } notifier = new QSocketNotifier(kbdFD, QSocketNotifier::Read, this); connect(notifier, SIGNAL(activated(int)),this, SLOT(readKeyboardData())); @@ -85,7 +86,7 @@ QVFbKeyboardHandler::QVFbKeyboardHandler(const QString &device) QVFbKeyboardHandler::~QVFbKeyboardHandler() { if (kbdFD >= 0) - close(kbdFD); + QT_CLOSE(kbdFD); delete [] kbdBuffer; } @@ -94,7 +95,7 @@ void QVFbKeyboardHandler::readKeyboardData() { int n; do { - n = read(kbdFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); + n = QT_READ(kbdFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); if (n > 0) kbdIdx += n; } while (n > 0); diff --git a/src/gui/embedded/qkbdvr41xx_qws.cpp b/src/gui/embedded/qkbdvr41xx_qws.cpp index 03c2a67..6d8299b 100644 --- a/src/gui/embedded/qkbdvr41xx_qws.cpp +++ b/src/gui/embedded/qkbdvr41xx_qws.cpp @@ -52,6 +52,7 @@ #include #include +#include // overrides QT_OPEN QT_BEGIN_NAMESPACE @@ -95,7 +96,7 @@ QWSVr41xxKbPrivate::QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QStrin buttonFD = -1; notifier = 0; - buttonFD = open(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0);; + buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0);; if (buttonFD < 0) { qWarning("Cannot open %s\n", qPrintable(terminalName)); return; @@ -115,7 +116,7 @@ QWSVr41xxKbPrivate::QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QStrin QWSVr41xxKbPrivate::~QWSVr41xxKbPrivate() { if (buttonFD > 0) { - ::close(buttonFD); + QT_CLOSE(buttonFD); buttonFD = -1; } delete notifier; @@ -127,7 +128,7 @@ void QWSVr41xxKbPrivate::readKeyboardData() { int n = 0; do { - n = read(buttonFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); + n = QT_READ(buttonFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); if (n > 0) kbdIdx += n; } while (n > 0); diff --git a/src/gui/embedded/qkbdyopy_qws.cpp b/src/gui/embedded/qkbdyopy_qws.cpp index 5c9d28d..edb732c 100644 --- a/src/gui/embedded/qkbdyopy_qws.cpp +++ b/src/gui/embedded/qkbdyopy_qws.cpp @@ -60,6 +60,8 @@ #include #include +#include // overrides QT_OPEN + extern "C" { int getpgid(int); } @@ -105,7 +107,7 @@ QWSYopyKbPrivate::QWSYopyKbPrivate(QWSYopyKeyboardHandler *h, const QString &dev buttonFD = -1; notifier = 0; - buttonFD = ::open(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0); + buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0); if (buttonFD < 0) { qWarning("Cannot open %s\n", qPrintable(terminalName)); return; @@ -177,10 +179,10 @@ void QWSYopyKbPrivate::readKeyboardData() case 40: k=Qt::Key_Up; break; // prev case 45: k=Qt::Key_Down; break; // next case 35: if(!press) { - fd = open("/proc/sys/pm/sleep",O_RDWR,0); + fd = QT_OPEN("/proc/sys/pm/sleep",O_RDWR,0); if(fd >= 0) { - write(fd,&c,sizeof(c)); - close(fd); + QT_WRITE(fd,&c,sizeof(c)); + QT_CLOSE(fd); // // Updates all widgets. // diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp index c23608f..305832c 100644 --- a/src/gui/embedded/qlock.cpp +++ b/src/gui/embedded/qlock.cpp @@ -73,6 +73,8 @@ union semun { #endif // QT_NO_QWS_MULTIPROCESS +#include // overrides QT_OPEN + #define MAX_LOCKS 200 // maximum simultaneous read locks QT_BEGIN_NAMESPACE @@ -134,7 +136,7 @@ QLock::QLock(const QString &filename, char id, bool create) #ifdef Q_NO_SEMAPHORE data->file = QString(filename+id).toLocal8Bit().constData(); for(int x = 0; x < 2; x++) { - data->id = open(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU); + data->id = QT_OPEN(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU); if(data->id != -1 || !create) { data->owned = x; break; @@ -177,7 +179,7 @@ QLock::~QLock() unlock(); #ifdef Q_NO_SEMAPHORE if(isValid()) { - close(data->id); + QT_CLOSE(data->id); if(data->owned) unlink(data->file); } diff --git a/src/gui/embedded/qmousebus_qws.cpp b/src/gui/embedded/qmousebus_qws.cpp index a88ca5b..0b674b6 100644 --- a/src/gui/embedded/qmousebus_qws.cpp +++ b/src/gui/embedded/qmousebus_qws.cpp @@ -47,6 +47,7 @@ #include "qsocketnotifier.h" #include "qapplication.h" +#include // overrides QT_OPEN #include #include @@ -119,9 +120,9 @@ QWSBusMouseHandlerPrivate::QWSBusMouseHandlerPrivate(QWSBusMouseHandler *h, mouseDev = QLatin1String("/dev/mouse"); obstate = -1; mouseFD = -1; - mouseFD = open(mouseDev.toLocal8Bit(), O_RDWR | O_NDELAY); + mouseFD = QT_OPEN(mouseDev.toLocal8Bit(), O_RDWR | O_NDELAY); if (mouseFD < 0) - mouseFD = open(mouseDev.toLocal8Bit(), O_RDONLY | O_NDELAY); + mouseFD = QT_OPEN(mouseDev.toLocal8Bit(), O_RDONLY | O_NDELAY); if (mouseFD < 0) qDebug("Cannot open %s (%s)", qPrintable(mouseDev), strerror(errno)); @@ -130,7 +131,7 @@ QWSBusMouseHandlerPrivate::QWSBusMouseHandlerPrivate(QWSBusMouseHandler *h, usleep(50000); char buf[100]; // busmouse driver will not read if bufsize < 3, YYD - while (read(mouseFD, buf, 100) > 0) { } // eat unwanted replies + while (QT_READ(mouseFD, buf, 100) > 0) { } // eat unwanted replies mouseIdx = 0; @@ -142,7 +143,7 @@ QWSBusMouseHandlerPrivate::~QWSBusMouseHandlerPrivate() { if (mouseFD >= 0) { tcflush(mouseFD,TCIFLUSH); // yyd. - close(mouseFD); + QT_CLOSE(mouseFD); } } @@ -167,7 +168,7 @@ void QWSBusMouseHandlerPrivate::readMouseData() for (;;) { if (mouseBufSize - mouseIdx < 3) break; - n = read(mouseFD, mouseBuf+mouseIdx, 3); + n = QT_READ(mouseFD, mouseBuf+mouseIdx, 3); if (n != 3) break; mouseIdx += 3; diff --git a/src/gui/embedded/qmouselinuxtp_qws.cpp b/src/gui/embedded/qmouselinuxtp_qws.cpp index 1b4d96e..e64407e 100644 --- a/src/gui/embedded/qmouselinuxtp_qws.cpp +++ b/src/gui/embedded/qmouselinuxtp_qws.cpp @@ -47,6 +47,7 @@ #include "qtimer.h" #include "qapplication.h" #include "qscreen_qws.h" +#include // overrides QT_OPEN #include #include @@ -190,7 +191,7 @@ QWSLinuxTPMouseHandlerPrivate::QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHand } else { mousedev = device; } - if ((mouseFD = open(mousedev.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { + if ((mouseFD = QT_OPEN(mousedev.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { qWarning("Cannot open %s (%s)", qPrintable(mousedev), strerror(errno)); return; } @@ -205,7 +206,7 @@ QWSLinuxTPMouseHandlerPrivate::QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHand QWSLinuxTPMouseHandlerPrivate::~QWSLinuxTPMouseHandlerPrivate() { if (mouseFD >= 0) - close(mouseFD); + QT_CLOSE(mouseFD); } void QWSLinuxTPMouseHandlerPrivate::suspend() @@ -233,7 +234,7 @@ void QWSLinuxTPMouseHandlerPrivate::readMouseData() int n; do { - n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); + n = QT_READ(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); if (n > 0) mouseIdx += n; } while (n > 0 && mouseIdx < mouseBufSize); diff --git a/src/gui/embedded/qmousepc_qws.cpp b/src/gui/embedded/qmousepc_qws.cpp index a9f2bc8..317bb8a 100644 --- a/src/gui/embedded/qmousepc_qws.cpp +++ b/src/gui/embedded/qmousepc_qws.cpp @@ -55,6 +55,7 @@ #include "qfile.h" #include "qtextstream.h" #include "qstringlist.h" +#include // overrides QT_OPEN #include #include @@ -107,7 +108,7 @@ public: { if (fd != f) { f = fd; - close(fd); + QT_CLOSE(fd); } } @@ -170,7 +171,7 @@ public: } static const uchar initseq[] = { 243, 200, 243, 100, 243, 80 }; static const uchar query[] = { 0xf2 }; - if (write(fd, initseq, sizeof(initseq))!=sizeof(initseq)) { + if (QT_WRITE(fd, initseq, sizeof(initseq))!=sizeof(initseq)) { badness = 100; return; } @@ -180,12 +181,12 @@ public: perror("QWSPcMouseSubHandler_intellimouse: post-init tcflush"); #endif } - if (write(fd, query, sizeof(query))!=sizeof(query)) { + if (QT_WRITE(fd, query, sizeof(query))!=sizeof(query)) { badness = 100; return; } usleep(10000); - n = read(fd, reply, 20); + n = QT_READ(fd, reply, 20); if (n > 0) { goodness = 10; switch (reply[n-1]) { @@ -256,13 +257,13 @@ public: perror("QWSPcMouseSubHandler_mouseman: initial tcflush"); #endif } - write(fd,"",1); + QT_WRITE(fd,"",1); usleep(50000); - write(fd,"@EeI!",5); + QT_WRITE(fd,"@EeI!",5); usleep(10000); static const char ibuf[] = { 246, 244 }; - write(fd,ibuf,1); - write(fd,ibuf+1,1); + QT_WRITE(fd,ibuf,1); + QT_WRITE(fd,ibuf+1,1); if (tcflush(fd,TCIOFLUSH) == -1) { #ifdef QWS_MOUSE_DEBUG perror("QWSPcMouseSubHandler_mouseman: tcflush"); @@ -271,7 +272,7 @@ public: usleep(10000); char buf[100]; - while (read(fd, buf, 100) > 0) { } // eat unwanted replies + while (QT_READ(fd, buf, 100) > 0) { } // eat unwanted replies } int tryData() @@ -350,7 +351,7 @@ private: for (int n = 0; n < 4; n++) { setflags(CSTOPB | speed[n]); - write(fd, "*q", 2); + QT_WRITE(fd, "*q", 2); usleep(10000); } } @@ -369,7 +370,7 @@ public: { setflags(B1200|CS8|CSTOPB); // 60Hz - if (write(fd, "R", 1)!=1) { + if (QT_WRITE(fd, "R", 1)!=1) { badness = 100; return; } @@ -418,7 +419,7 @@ public: { setflags(B1200|CS7); // 60Hz - if (write(fd, "R", 1)!=1) { + if (QT_WRITE(fd, "R", 1)!=1) { badness = 100; return; } @@ -648,25 +649,25 @@ void QWSPcMouseHandlerPrivate::openDevices() if (drv == QLatin1String("intellimouse")) { if (dev.isEmpty()) dev = "/dev/psaux"; - fd = open(dev, O_RDWR | O_NDELAY); + fd = QT_OPEN(dev, O_RDWR | O_NDELAY); if (fd >= 0) sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd); } else if (drv == QLatin1String("microsoft")) { if (dev.isEmpty()) dev = "/dev/ttyS0"; - fd = open(dev, O_RDWR | O_NDELAY); + fd = QT_OPEN(dev, O_RDWR | O_NDELAY); if (fd >= 0) sub[nsub++] = new QWSPcMouseSubHandler_ms(fd); } else if (drv == QLatin1String("mousesystems")) { if (dev.isEmpty()) dev = "/dev/ttyS0"; - fd = open(dev, O_RDWR | O_NDELAY); + fd = QT_OPEN(dev, O_RDWR | O_NDELAY); if (fd >= 0) sub[nsub++] = new QWSPcMouseSubHandler_mousesystems(fd); } else if (drv == QLatin1String("mouseman")) { if (dev.isEmpty()) dev = "/dev/psaux"; - fd = open(dev, O_RDWR | O_NDELAY); + fd = QT_OPEN(dev, O_RDWR | O_NDELAY); if (fd >= 0) sub[nsub++] = new QWSPcMouseSubHandler_mouseman(fd); } @@ -677,12 +678,12 @@ void QWSPcMouseHandlerPrivate::openDevices() dev.constData(), strerror(errno)); } else { // Try automatically - fd = open("/dev/psaux", O_RDWR | O_NDELAY); + fd = QT_OPEN("/dev/psaux", O_RDWR | O_NDELAY); if (fd >= 0) { sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd); notify(fd); } - fd = open("/dev/input/mice", O_RDWR | O_NDELAY); + fd = QT_OPEN("/dev/input/mice", O_RDWR | O_NDELAY); if (fd >= 0) { sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd); notify(fd); @@ -694,7 +695,7 @@ void QWSPcMouseHandlerPrivate::openDevices() #if 0 const char fn[4][11] = { "/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2", "/dev/ttyS3" }; for (int ch = 0; ch < 4; ++ch) { - fd = open(fn[ch], O_RDWR | O_NDELAY); + fd = QT_OPEN(fn[ch], O_RDWR | O_NDELAY); if (fd >= 0) { //sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd); sub[nsub++] = new QWSPcMouseSubHandler_mousesystems(fd); diff --git a/src/gui/embedded/qmousevfb_qws.cpp b/src/gui/embedded/qmousevfb_qws.cpp index 17d051f..dd553bc 100644 --- a/src/gui/embedded/qmousevfb_qws.cpp +++ b/src/gui/embedded/qmousevfb_qws.cpp @@ -54,6 +54,7 @@ #include #include #include +#include // overrides QT_OPEN QT_BEGIN_NAMESPACE @@ -64,7 +65,7 @@ QVFbMouseHandler::QVFbMouseHandler(const QString &driver, const QString &device) if (device.isEmpty()) mouseDev = QLatin1String("/dev/vmouse"); - mouseFD = open(mouseDev.toLatin1().constData(), O_RDWR | O_NDELAY); + mouseFD = QT_OPEN(mouseDev.toLatin1().constData(), O_RDWR | O_NDELAY); if (mouseFD == -1) { perror("QVFbMouseHandler::QVFbMouseHandler"); qWarning("QVFbMouseHander: Unable to open device %s", @@ -74,7 +75,7 @@ QVFbMouseHandler::QVFbMouseHandler(const QString &driver, const QString &device) // Clear pending input char buf[2]; - while (read(mouseFD, buf, 1) > 0) { } + while (QT_READ(mouseFD, buf, 1) > 0) { } mouseIdx = 0; @@ -85,7 +86,7 @@ QVFbMouseHandler::QVFbMouseHandler(const QString &driver, const QString &device) QVFbMouseHandler::~QVFbMouseHandler() { if (mouseFD >= 0) - close(mouseFD); + QT_CLOSE(mouseFD); } void QVFbMouseHandler::resume() @@ -102,7 +103,7 @@ void QVFbMouseHandler::readMouseData() { int n; do { - n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); + n = QT_READ(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); if (n > 0) mouseIdx += n; } while (n > 0); diff --git a/src/gui/embedded/qmousevr41xx_qws.cpp b/src/gui/embedded/qmousevr41xx_qws.cpp index 8748055..b7491d9 100644 --- a/src/gui/embedded/qmousevr41xx_qws.cpp +++ b/src/gui/embedded/qmousevr41xx_qws.cpp @@ -49,6 +49,7 @@ #include "qscreen_qws.h" #include #include +#include // overrides QT_OPEN #include #include @@ -144,7 +145,7 @@ QWSVr41xxMouseHandlerPrivate::QWSVr41xxMouseHandlerPrivate(QWSVr41xxMouseHandler else dev = options.first(); - if ((mouseFD = open(dev.toLocal8Bit().constData(), O_RDONLY)) < 0) { + if ((mouseFD = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY)) < 0) { qWarning("Cannot open %s (%s)", qPrintable(dev), strerror(errno)); return; } @@ -167,7 +168,7 @@ QWSVr41xxMouseHandlerPrivate::QWSVr41xxMouseHandlerPrivate(QWSVr41xxMouseHandler QWSVr41xxMouseHandlerPrivate::~QWSVr41xxMouseHandlerPrivate() { if (mouseFD >= 0) - close(mouseFD); + QT_CLOSE(mouseFD); } void QWSVr41xxMouseHandlerPrivate::suspend() @@ -190,9 +191,9 @@ void QWSVr41xxMouseHandlerPrivate::sendRelease() bool QWSVr41xxMouseHandlerPrivate::getSample() { - const int n = read(mouseFD, - reinterpret_cast(currSample) + currLength, - sizeof(currSample) - currLength); + const int n = QT_READ(mouseFD, + reinterpret_cast(currSample) + currLength, + sizeof(currSample) - currLength); if (n > 0) currLength += n; diff --git a/src/gui/embedded/qmouseyopy_qws.cpp b/src/gui/embedded/qmouseyopy_qws.cpp index 7b1141a..3a541d3 100644 --- a/src/gui/embedded/qmouseyopy_qws.cpp +++ b/src/gui/embedded/qmouseyopy_qws.cpp @@ -46,6 +46,7 @@ #include "qsocketnotifier.h" #include "qapplication.h" #include "qscreen_qws.h" +#include // overrides QT_OPEN #include #include @@ -103,7 +104,7 @@ void QWSYopyMouseHandler::suspend() QWSYopyMouseHandlerPrivate::QWSYopyMouseHandlerPrivate(QWSYopyMouseHandler *h) : handler(h) { - if ((mouseFD = open("/dev/ts", O_RDONLY)) < 0) { + if ((mouseFD = QT_OPEN("/dev/ts", O_RDONLY)) < 0) { qWarning("Cannot open /dev/ts (%s)", strerror(errno)); return; } else { @@ -118,7 +119,7 @@ QWSYopyMouseHandlerPrivate::QWSYopyMouseHandlerPrivate(QWSYopyMouseHandler *h) QWSYopyMouseHandlerPrivate::~QWSYopyMouseHandlerPrivate() { if (mouseFD >= 0) - close(mouseFD); + QT_CLOSE(mouseFD); } #define YOPY_XPOS(d) (d[1]&0x3FF) @@ -156,7 +157,7 @@ void QWSYopyMouseHandlerPrivate::readMouseData() int ret; - ret=read(mouseFD,&yopDat,sizeof(yopDat)); + ret=QT_READ(mouseFD,&yopDat,sizeof(yopDat)); if(ret) { data.status= (YOPY_PRES(yopDat)) ? 1 : 0; diff --git a/src/gui/embedded/qscreenlinuxfb_qws.cpp b/src/gui/embedded/qscreenlinuxfb_qws.cpp index 42c4fcd..2845842 100644 --- a/src/gui/embedded/qscreenlinuxfb_qws.cpp +++ b/src/gui/embedded/qscreenlinuxfb_qws.cpp @@ -46,6 +46,7 @@ #include "qwsdisplay_qws.h" #include "qpixmap.h" #include +#include // overrides QT_OPEN #include #include @@ -122,12 +123,12 @@ void QLinuxFbScreenPrivate::openTty() if (ttyDevice.isEmpty()) { for (const char * const *dev = devs; *dev; ++dev) { - ttyfd = ::open(*dev, O_RDWR); + ttyfd = QT_OPEN(*dev, O_RDWR); if (ttyfd != -1) break; } } else { - ttyfd = ::open(ttyDevice.toAscii().constData(), O_RDWR); + ttyfd = QT_OPEN(ttyDevice.toAscii().constData(), O_RDWR); } if (ttyfd == -1) @@ -144,7 +145,7 @@ void QLinuxFbScreenPrivate::openTty() // No blankin' screen, no blinkin' cursor!, no cursor! const char termctl[] = "\033[9;0]\033[?33l\033[?25l\033[?1c"; - ::write(ttyfd, termctl, sizeof(termctl)); + QT_WRITE(ttyfd, termctl, sizeof(termctl)); } void QLinuxFbScreenPrivate::closeTty() @@ -157,9 +158,9 @@ void QLinuxFbScreenPrivate::closeTty() // Blankin' screen, blinkin' cursor! const char termctl[] = "\033[9;15]\033[?33h\033[?25h\033[?0c"; - ::write(ttyfd, termctl, sizeof(termctl)); + QT_WRITE(ttyfd, termctl, sizeof(termctl)); - ::close(ttyfd); + QT_CLOSE(ttyfd); ttyfd = -1; } @@ -281,7 +282,7 @@ bool QLinuxFbScreen::connect(const QString &displaySpec) dev = QLatin1String("/dev/fb0"); if (access(dev.toLatin1().constData(), R_OK|W_OK) == 0) - d_ptr->fd = open(dev.toLatin1().constData(), O_RDWR); + d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDWR); if (d_ptr->fd == -1) { if (QApplication::type() == QApplication::GuiServer) { perror("QScreenLinuxFb::connect"); @@ -289,7 +290,7 @@ bool QLinuxFbScreen::connect(const QString &displaySpec) return false; } if (access(dev.toLatin1().constData(), R_OK) == 0) - d_ptr->fd = open(dev.toLatin1().constData(), O_RDONLY); + d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDONLY); } fb_fix_screeninfo finfo; @@ -681,7 +682,7 @@ bool QLinuxFbScreen::initDevice() #ifdef __i386__ // Now init mtrr if(!::getenv("QWS_NOMTRR")) { - int mfd=open("/proc/mtrr",O_WRONLY,0); + int mfd=QT_OPEN("/proc/mtrr",O_WRONLY,0); // MTRR entry goes away when file is closed - i.e. // hopefully when QWS is killed if(mfd != -1) { @@ -702,6 +703,9 @@ bool QLinuxFbScreen::initDevice() //sentry.base,sentry.size,strerror(errno)); } } + + // Should we close mfd here? + //QT_CLOSE(mfd); } #endif if ((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4) || (finfo.visual==FB_VISUAL_DIRECTCOLOR)) diff --git a/src/gui/embedded/qsoundqss_qws.cpp b/src/gui/embedded/qsoundqss_qws.cpp index ac0ac9d..a45d0fe 100644 --- a/src/gui/embedded/qsoundqss_qws.cpp +++ b/src/gui/embedded/qsoundqss_qws.cpp @@ -53,6 +53,7 @@ #include #include #include +#include // overrides QT_OPEN #include #include @@ -1137,7 +1138,7 @@ void QWSSoundServerPrivate::sendCompletedSignals() int QWSSoundServerPrivate::openFile(int wid, int sid, const QString& filename) { stopFile(wid, sid); // close and re-open. - int f = ::open(QFile::encodeName(filename), O_RDONLY|O_NONBLOCK); + int f = QT_OPEN(QFile::encodeName(filename), O_RDONLY|O_NONBLOCK); if (f == -1) { // XXX check ferror, check reason. qDebug("Failed opening \"%s\"",filename.toLatin1().data()); @@ -1157,7 +1158,7 @@ bool QWSSoundServerPrivate::openDevice() { if (fd < 0) { if( silent ) { - fd = ::open( "/dev/null", O_WRONLY ); + fd = QT_OPEN( "/dev/null", O_WRONLY ); // Emulate write to audio device int delay = 1000*(sound_buffer_size>>(sound_stereo+sound_16bit))/sound_speed/2; timerId = startTimer(delay); @@ -1168,7 +1169,7 @@ bool QWSSoundServerPrivate::openDevice() // Don't block open right away. // bool openOkay = false; - if ((fd = ::open("/dev/dsp", O_WRONLY|O_NONBLOCK)) != -1) { + if ((fd = QT_OPEN("/dev/dsp", O_WRONLY|O_NONBLOCK)) != -1) { int flags = fcntl(fd, F_GETFL); flags &= ~O_NONBLOCK; openOkay = (fcntl(fd, F_SETFL, flags) == 0); @@ -1222,7 +1223,7 @@ bool QWSSoundServerPrivate::openDevice() // // Check system volume // - int mixerHandle = ::open( "/dev/mixer", O_RDWR|O_NONBLOCK ); + int mixerHandle = QT_OPEN( "/dev/mixer", O_RDWR|O_NONBLOCK ); if ( mixerHandle >= 0 ) { int volume; ioctl( mixerHandle, MIXER_READ(0), &volume ); diff --git a/src/gui/embedded/qtransportauth_qws.cpp b/src/gui/embedded/qtransportauth_qws.cpp index 05dce11..8523e27 100644 --- a/src/gui/embedded/qtransportauth_qws.cpp +++ b/src/gui/embedded/qtransportauth_qws.cpp @@ -56,6 +56,7 @@ #include "qlibraryinfo.h" #include "qfile.h" #include "qdebug.h" +#include // overrides QT_OPEN #include #include @@ -572,7 +573,7 @@ bool QTransportAuth::authorizeRequest( QTransportAuth::Data &d, const QString &r //get cmdline from proc/pid/cmdline snprintf( cmdlinePath, BUF_SIZE, "/proc/%d/cmdline", d.processId ); - int cmdlineFd = open( cmdlinePath, O_RDONLY ); + int cmdlineFd = QT_OPEN( cmdlinePath, O_RDONLY ); if ( cmdlineFd == -1 ) { qWarning( "SXE:- Error encountered in opening /proc/%u/cmdline: %s", @@ -581,13 +582,13 @@ bool QTransportAuth::authorizeRequest( QTransportAuth::Data &d, const QString &r } else { - if ( -1 == ::read(cmdlineFd, cmdline, BUF_SIZE - 1 ) ) + if ( -1 == QT_READ(cmdlineFd, cmdline, BUF_SIZE - 1 ) ) { qWarning( "SXE:- Error encountered in reading /proc/%u/cmdline : %s", d.processId, strerror(errno) ); snprintf( cmdline, BUF_SIZE, "%s", "Unknown" ); } - close( cmdlineFd ); + QT_CLOSE( cmdlineFd ); } syslog( LOG_ERR | LOG_LOCAL6, "%s // PID:%u // ProgId:%u // Exe:%s // Request:%s // Cmdline:%s", diff --git a/src/gui/embedded/qunixsocket.cpp b/src/gui/embedded/qunixsocket.cpp index 070d3cf..57a4a11 100644 --- a/src/gui/embedded/qunixsocket.cpp +++ b/src/gui/embedded/qunixsocket.cpp @@ -46,6 +46,7 @@ #include #include #include +#include "private/qcore_unix_p.h" // overrides QT_OPEN #ifdef QUNIXSOCKET_DEBUG #include @@ -131,7 +132,7 @@ struct QUnixSocketRightsPrivate : public QSharedData #ifdef QUNIXSOCKET_DEBUG int closerv = #endif - ::close(fd); + QT_CLOSE(fd); #ifdef QUNIXSOCKET_DEBUG if(0 != closerv) { qDebug() << "QUnixSocketRightsPrivate: Unable to close managed" @@ -162,7 +163,7 @@ QUnixSocketRights::QUnixSocketRights(int fd) if(-1 == fd) { d->fd = -1; } else { - d->fd = ::dup(fd); + d->fd = qt_safe_dup(fd); #ifdef QUNIXSOCKET_DEBUG if(-1 == d->fd) { qDebug() << "QUnixSocketRights: Unable to duplicate fd " @@ -232,7 +233,7 @@ int QUnixSocketRights::dupFd() const { if(-1 == d->fd) return -1; - int rv = ::dup(d->fd); + int rv = qt_safe_dup(d->fd); #ifdef QUNIXSOCKET_DEBUG if(-1 == rv) @@ -825,7 +826,7 @@ public: int numFds = (h->cmsg_len - CMSG_LEN(0)) / sizeof(int); for(int ii = 0; ii < numFds; ++ii) - ::close(fds[ii]); + QT_CLOSE(fds[ii]); } h = (::cmsghdr *)CMSG_NXTHDR(&(message), h); @@ -1017,7 +1018,7 @@ connect_error: // Cleanup failed connection #ifdef QUNIXSOCKET_DEBUG int closerv = #endif - ::close(d->fd); + QT_CLOSE(d->fd); #ifdef QUNIXSOCKET_DEBUG if(0 != closerv) { qDebug() << "QUnixSocket: Unable to close file descriptor after " @@ -1762,7 +1763,12 @@ void QUnixSocketPrivate::readActivated() message.msg_controllen = ancillaryBufferCapacity(); message.msg_control = ancillaryBuffer; - int recvrv = ::recvmsg(fd, &message, 0); + int flags = 0; +#ifdef MSG_CMSG_CLOEXEC + flags = MSG_CMSG_CLOEXEC; +#endif + + int recvrv = ::recvmsg(fd, &message, flags); #ifdef QUNIXSOCKET_DEBUG qDebug() << "QUnixSocket: Received message (" << recvrv << ')'; #endif diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp index 2c359ba..d348e1b 100644 --- a/src/gui/text/qfontdatabase_qws.cpp +++ b/src/gui/text/qfontdatabase_qws.cpp @@ -55,6 +55,7 @@ #endif #include "qfontengine_qpf_p.h" #include "private/qfactoryloader_p.h" +#include "private/qcore_unix_p.h" // overrides QT_OPEN #include "qabstractfontengine_qws.h" #include "qabstractfontengine_p.h" #include @@ -128,7 +129,7 @@ void QFontDatabasePrivate::addQPF2File(const QByteArray &file) struct stat st; if (stat(file.constData(), &st)) return; - int f = ::open(file, O_RDONLY, 0); + int f = QT_OPEN(file, O_RDONLY, 0); if (f < 0) return; const uchar *data = (const uchar *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, f, 0); @@ -176,7 +177,7 @@ void QFontDatabasePrivate::addQPF2File(const QByteArray &file) #endif } #ifndef QT_FONTS_ARE_RESOURCES - ::close(f); + QT_CLOSE(f); #endif } #endif diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index 2df4095..b255694 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -51,6 +51,7 @@ #if !defined(QT_NO_FREETYPE) #include "private/qfontengine_ft_p.h" #endif +#include "private/qcore_unix_p.h" // overrides QT_OPEN // for mmap #include @@ -252,7 +253,7 @@ QList QFontEngineQPF::cleanUpAfterClientCrash(const QList &cras for (int i = 0; i < int(dir.count()); ++i) { const QByteArray fileName = QFile::encodeName(dir.absoluteFilePath(dir[i])); - int fd = ::open(fileName.constData(), O_RDONLY, 0); + int fd = QT_OPEN(fileName.constData(), O_RDONLY, 0); if (fd >= 0) { void *header = ::mmap(0, sizeof(QFontEngineQPF::Header), PROT_READ, MAP_SHARED, fd, 0); if (header && header != MAP_FAILED) { @@ -265,7 +266,7 @@ QList QFontEngineQPF::cleanUpAfterClientCrash(const QList &cras ::munmap(header, sizeof(QFontEngineQPF::Header)); } - ::close(fd); + QT_CLOSE(fd); } } if (!removedFonts.isEmpty()) @@ -331,15 +332,15 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng qDebug() << "found existing qpf:" << fileName; #endif if (::access(encodedName, W_OK | R_OK) == 0) - fd = ::open(encodedName, O_RDWR, 0); + fd = QT_OPEN(encodedName, O_RDWR, 0); else if (::access(encodedName, R_OK) == 0) - fd = ::open(encodedName, O_RDONLY, 0); + fd = QT_OPEN(encodedName, O_RDONLY, 0); } else { #if defined(DEBUG_FONTENGINE) qDebug() << "creating qpf on the fly:" << fileName; #endif if (::access(QFile::encodeName(qws_fontCacheDir()), W_OK) == 0) { - fd = ::open(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644); + fd = QT_OPEN(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644); QBuffer buffer; buffer.open(QIODevice::ReadWrite); diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp index 6fb4f15..70ce8f9 100644 --- a/src/gui/text/qfontengine_qws.cpp +++ b/src/gui/text/qfontengine_qws.cpp @@ -47,6 +47,7 @@ #include #include #include "qtextengine_p.h" +#include "private/qcore_unix_p.h" // overrides QT_OPEN #include @@ -387,7 +388,7 @@ QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) { cache_cost = 1; - int f = ::open( QFile::encodeName(fn), O_RDONLY, 0); + int f = QT_OPEN( QFile::encodeName(fn), O_RDONLY, 0); Q_ASSERT(f>=0); QT_STATBUF st; if ( QT_FSTAT( f, &st ) ) @@ -406,7 +407,7 @@ QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) #endif if ( !data || data == (uchar*)MAP_FAILED ) qFatal("Failed to mmap %s",QFile::encodeName(fn).data()); - ::close(f); + QT_CLOSE(f); d = new QFontEngineQPF1Data; memcpy(reinterpret_cast(&d->fm),data,sizeof(d->fm)); -- cgit v0.12 From d7d0d20469d447933c827d169651c3751c7069ad Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Apr 2009 20:07:34 +0200 Subject: Add the support for the EINTR- and CLOEXEC-safe network calls too. The SOCK_NONBLOCK, SOCK_CLOEXEC and accept4(2) calls are Linux-specific. Other platforms get the same behaviour through emulation. Reviewed-By: ossi --- src/network/socket/qnet_unix_p.h | 153 +++++++++++++++++++++++++++++++++++++++ src/network/socket/socket.pri | 3 +- 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 src/network/socket/qnet_unix_p.h diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h new file mode 100644 index 0000000..5256131 --- /dev/null +++ b/src/network/socket/qnet_unix_p.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNET_UNIX_P_H +#define QNET_UNIX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt code on Unix. This header file may change from version to +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include "private/qcore_unix_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +// Almost always the same. If not, specify in qplatformdefs.h. +#if !defined(QT_SOCKOPTLEN_T) +# define QT_SOCKOPTLEN_T QT_SOCKLEN_T +#endif + +// UnixWare 7 redefines socket -> _socket +static inline int qt_safe_socket(int domain, int type, int protocol, int flags = 0) +{ + Q_ASSERT((flags & ~O_NONBLOCK) == 0); + + register int fd; +#ifdef SOCK_CLOEXEC + int newtype = type | SOCK_CLOEXEC; + if (flags & O_NONBLOCK) + newtype |= SOCK_NONBLOCK; + fd = ::socket(domain, newtype, protocol); + if (fd != -1 || errno != EINVAL) + return fd; +#endif + + fd = ::socket(domain, type, protocol); + if (fd == -1) + return -1; + + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + + // set non-block too? + if (flags & O_NONBLOCK) + ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) | O_NONBLOCK); + + return fd; +} + +// Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDED +static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags = 0) +{ + Q_ASSERT((flags & ~O_NONBLOCK) == 0); + + register int fd; +#if 0 // no released version of glibc contains accept4 yet + // use accept4 + int sockflags = SOCK_CLOEXEC; + if (flags & O_NONBLOCK) + sockflags |= SOCK_NONBLOCK; + fd = ::accept4(s, addr, static_cast(addrlen), sockflags); + if (fd != -1 || !(errno == ENOSYS || errno == EINVAL)) + return fd; +#endif + + fd = ::accept(s, addr, static_cast(addrlen)); + if (fd == -1) + return -1; + + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + + // set non-block too? + if (flags & O_NONBLOCK) + ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) | O_NONBLOCK); + + return fd; +} + +// UnixWare 7 redefines listen -> _listen +static inline int qt_safe_listen(int s, int backlog) +{ + return ::listen(s, backlog); +} + +static inline int qt_safe_connect(int sockfd, const struct sockaddr *addr, QT_SOCKLEN_T addrlen) +{ + register int ret; + EINTR_LOOP(ret, QT_SOCKET_CONNECT(sockfd, addr, addrlen)); + return ret; +} +#undef QT_SOCKET_CONNECT +#define QT_SOCKET_CONNECT qt_safe_connect + +#if defined(socket) +# undef socket +#endif +#if defined(accept) +# undef accept +#endif +#if defined(listen) +# undef listen +#endif + +QT_END_NAMESPACE + +#endif // QNET_UNIX_P_H diff --git a/src/network/socket/socket.pri b/src/network/socket/socket.pri index b1fe64a..17e49d2 100644 --- a/src/network/socket/socket.pri +++ b/src/network/socket/socket.pri @@ -28,7 +28,8 @@ SOURCES += socket/qabstractsocketengine.cpp \ unix:SOURCES += socket/qnativesocketengine_unix.cpp \ socket/qlocalsocket_unix.cpp \ socket/qlocalserver_unix.cpp - +unix:HEADERS += \ + socket/qnet_unix_p.h win32:SOURCES += socket/qnativesocketengine_win.cpp \ socket/qlocalsocket_win.cpp \ -- cgit v0.12 From 0b757d0c1b6f64d17086621ec692369d37fd62fc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Apr 2009 20:07:47 +0200 Subject: Use the safe versions of the network system calls I have just added. Reviewed-By: ossi --- src/corelib/kernel/qcore_unix.cpp | 63 +++++++++++++++++++++++++ src/corelib/kernel/qcore_unix_p.h | 13 ++++- src/network/socket/qlocalserver_unix.cpp | 9 ++-- src/network/socket/qlocalsocket_p.h | 37 --------------- src/network/socket/qlocalsocket_unix.cpp | 5 +- src/network/socket/qnativesocketengine_unix.cpp | 8 ++-- src/network/socket/qnet_unix_p.h | 2 +- 7 files changed, 88 insertions(+), 49 deletions(-) diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index ffaf958..2549f77 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -119,3 +119,66 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, } QT_END_NAMESPACE + +#ifdef Q_OS_LINUX +// Don't wait for libc to supply the calls we need +// Make syscalls directly + +# if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 +// glibc 2.4 has syscall(...) +# include +# include +# else +// no syscall(...) +static inline int syscall(...) { errno = ENOSYS; return -1;} +# endif + +# ifndef __NR_dup3 +# if defined(__i386__) +# define __NR_dup3 330 +# define __NR_pipe2 331 +# elif defined(__x86_64__) +# define __NR_accept4 288 +# define __NR_dup3 292 +# define __NR_pipe2 293 +# elif defined(__ia64__) +# define __NR_accept4 -1 +# define __NR_dup3 1316 +# define __NR_pipe2 1317 +# else +// set the syscalls to absurd numbers so that they'll cause ENOSYS errors +# warning "Please port the pipe2/dup3/accept4 code to this platform" +# define __NR_accept4 -1 +# define __NR_dup3 -1 +# define __NR_pipe2 -1 +# endif +# endif + +QT_BEGIN_NAMESPACE +namespace QtLibcSupplement { + int pipe2(int pipes[], int flags) + { + return syscall(__NR_pipe2, pipes, flags); + } + + int dup3(int oldfd, int newfd, int flags) + { + return syscall(__NR_dup3, oldfd, newfd, flags); + } + + int accept4(int s, sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags) + { +# if defined(__NR_socketcall) + // This platform uses socketcall() instead of raw syscalls + // the SYS_ACCEPT4 number is cross-platform: 18 + return syscall(__NR_socketcall, 18, &s); +# else + return syscall(__NR_accept4, s, addr, addrlen, flags); +# endif + + Q_UNUSED(addr); Q_UNUSED(addrlen); Q_UNUSED(flags); // they're actually used + } +} +QT_END_NAMESPACE +#endif // Q_OS_LINUX + diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 4e3158a..6ae4ff0 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -67,10 +67,21 @@ #include #include +struct sockaddr; + QT_BEGIN_NAMESPACE -#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0209 +#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 +// Linux supports thread-safe FD_CLOEXEC # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 + +namespace QtLibcSupplement { + Q_CORE_EXPORT int accept4(int, sockaddr *, QT_SOCKLEN_T *, int flags); + Q_CORE_EXPORT int dup3(int oldfd, int newfd, int flags); + Q_CORE_EXPORT int pipe2(int pipes[], int flags); +} + +using namespace QtLibcSupplement; #else # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0 #endif diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp index 1cb804a..c2e05cd 100644 --- a/src/network/socket/qlocalserver_unix.cpp +++ b/src/network/socket/qlocalserver_unix.cpp @@ -43,6 +43,7 @@ #include "qlocalserver_p.h" #include "qlocalsocket.h" #include "qlocalsocket_p.h" +#include "qnet_unix_p.h" #ifndef QT_NO_LOCALSERVER @@ -88,7 +89,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) serverName = requestedServerName; // create the unix socket - listenSocket = qSocket(PF_UNIX, SOCK_STREAM, 0); + listenSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0); if (-1 == listenSocket) { setError(QLatin1String("QLocalServer::listen")); closeServer(); @@ -107,7 +108,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) fullServerName.toLatin1().size() + 1); // bind - if(-1 == qBind(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) { + if(-1 == QT_SOCKET_BIND(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) { setError(QLatin1String("QLocalServer::listen")); // if address is in use already, just close the socket, but do not delete the file if(errno == EADDRINUSE) @@ -120,7 +121,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) } // listen for connections - if (-1 == qListen(listenSocket, 50)) { + if (-1 == qt_safe_listen(listenSocket, 50)) { setError(QLatin1String("QLocalServer::listen")); closeServer(); listenSocket = -1; @@ -172,7 +173,7 @@ void QLocalServerPrivate::_q_onNewConnection() ::sockaddr_un addr; QT_SOCKLEN_T length = sizeof(sockaddr_un); - int connectedSocket = qAccept(listenSocket, (sockaddr *)&addr, &length); + int connectedSocket = qt_safe_accept(listenSocket, (sockaddr *)&addr, &length); if(-1 == connectedSocket) { setError(QLatin1String("QLocalSocket::activated")); closeServer(); diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index 24b5dd6..bdbba42 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -74,43 +74,6 @@ QT_BEGIN_NAMESPACE -#if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP) -static inline int qSocket(int af, int socketype, int proto) -{ - int ret; - while((ret = qt_socket_socket(af, socketype, proto)) == -1 && errno == EINTR){} - return ret; -} - -static inline int qBind(int fd, const sockaddr *sa, int len) -{ - int ret; - while((ret = QT_SOCKET_BIND(fd, (sockaddr*)sa, len)) == -1 && errno == EINTR){} - return ret; -} - -static inline int qConnect(int fd, const sockaddr *sa, int len) -{ - int ret; - while((ret = QT_SOCKET_CONNECT(fd, (sockaddr*)sa, len)) == -1 && errno == EINTR){} - return ret; -} - -static inline int qListen(int fd, int backlog) -{ - int ret; - while((ret = qt_socket_listen(fd, backlog)) == -1 && errno == EINTR){} - return ret; -} - -static inline int qAccept(int fd, struct sockaddr *addr, QT_SOCKLEN_T *addrlen) -{ - int ret; - while((ret = qt_socket_accept(fd, addr, addrlen)) == -1 && errno == EINTR){} - return ret; -} -#endif //#if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP) - #if !defined(Q_OS_WIN) || defined(QT_LOCALSOCKET_TCP) class QLocalUnixSocket : public QTcpSocket { diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index 41dac3c..d038794 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -41,6 +41,7 @@ #include "qlocalsocket.h" #include "qlocalsocket_p.h" +#include "qnet_unix_p.h" #ifndef QT_NO_LOCALSOCKET @@ -232,7 +233,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) } // create the socket - if (-1 == (d->connectingSocket = qSocket(PF_UNIX, SOCK_STREAM, 0))) { + if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0))) { d->errorOccurred(UnsupportedSocketOperationError, QLatin1String("QLocalSocket::connectToServer")); return; @@ -282,7 +283,7 @@ void QLocalSocketPrivate::_q_connectToSocket() } ::memcpy(name.sun_path, connectingPathName.toLatin1().data(), connectingPathName.toLatin1().size() + 1); - if (-1 == qConnect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) { + if (-1 == qt_safe_connect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) { QString function = QLatin1String("QLocalSocket::connectToServer"); switch (errno) { diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 6eafe05..0c1fa19 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -42,7 +42,7 @@ //#define QNATIVESOCKETENGINE_DEBUG #include "qnativesocketengine_p.h" -#include "private/qcore_unix_p.h" +#include "private/qnet_unix_p.h" #include "qiodevice.h" #include "qhostaddress.h" #include "qvarlengtharray.h" @@ -162,7 +162,7 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc int protocol = AF_INET; #endif int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; - int socket = qt_socket_socket(protocol, type, 0); + int socket = qt_safe_socket(protocol, type, 0); if (socket <= 0) { switch (errno) { @@ -467,7 +467,7 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 bool QNativeSocketEnginePrivate::nativeListen(int backlog) { - if (qt_socket_listen(socketDescriptor, backlog) < 0) { + if (qt_safe_listen(socketDescriptor, backlog) < 0) { switch (errno) { case EADDRINUSE: setError(QAbstractSocket::AddressInUseError, @@ -494,7 +494,7 @@ bool QNativeSocketEnginePrivate::nativeListen(int backlog) int QNativeSocketEnginePrivate::nativeAccept() { - int acceptedDescriptor = qt_socket_accept(socketDescriptor, 0, 0); + int acceptedDescriptor = qt_safe_accept(socketDescriptor, 0, 0); #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeAccept() == %i", acceptedDescriptor); #endif diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index 5256131..80a4c58 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -100,7 +100,7 @@ static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *add Q_ASSERT((flags & ~O_NONBLOCK) == 0); register int fd; -#if 0 // no released version of glibc contains accept4 yet +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC // use accept4 int sockflags = SOCK_CLOEXEC; if (flags & O_NONBLOCK) -- cgit v0.12 From a32019f4c2f56a84172bde739d7ea174be0db381 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Jun 2009 17:22:53 +0200 Subject: Add qobject_cast for QSharedPointer. This obviously only works for classes that derive from QObject. And you must remember that QSharedPointer controls the QObject's lifetime, not the QObject parent-child relationship. Reviewed-by: dt Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qsharedpointer.cpp | 56 +++++++++++ src/corelib/tools/qsharedpointer.h | 3 + src/corelib/tools/qsharedpointer_impl.h | 51 ++++++++++ tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 123 +++++++++++++++++++++++ 4 files changed, 233 insertions(+) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index ba62ce1..71bf318 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -340,6 +340,23 @@ */ /*! + \fn QSharedPointer QSharedPointer::objectCast() const + + Performs a \ref qobject_cast from this pointer's type to \tt X and + returns a QSharedPointer that shares the reference. If this + function is used to up-cast, then QSharedPointer will perform a \tt + qobject_cast, which means that if the object being pointed by this + QSharedPointer is not of type \tt X, the returned object will be + null. + + Note: the template type \c X must have the same const and volatile + qualifiers as the template of this object, or the cast will + fail. Use constCast() if you need to drop those qualifiers. + + \sa qSharedPointerObjectCast() +*/ + +/*! \fn QWeakPointer QSharedPointer::toWeakRef() const Returns a weak reference object that shares the pointer referenced @@ -718,6 +735,45 @@ */ /*! + \fn QSharedPointer qSharedPointerObjectCast(const QSharedPointer &other) + \relates QSharedPointer + + Returns a shared pointer to the pointer held by \a other, using a + \ref qobject_cast to type \tt X to obtain an internal pointer of the + appropriate type. If the \tt qobject_cast fails, the object + returned will be null. + + Note that \tt X must have the same cv-qualifiers (\tt const and + \tt volatile) that \tt T has, or the code will fail to + compile. Use qSharedPointerConstCast to cast away the constness. + + \sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast() +*/ + +/*! + \fn QSharedPointer qSharedPointerObjectCast(const QWeakPointer &other) + \relates QSharedPointer + \relates QWeakPointer + + Returns a shared pointer to the pointer held by \a other, using a + \ref qobject_cast to type \tt X to obtain an internal pointer of the + appropriate type. If the \tt qobject_cast fails, the object + returned will be null. + + The \a other object is converted first to a strong reference. If + that conversion fails (because the object it's pointing to has + already been deleted), this function also returns a null + QSharedPointer. + + Note that \tt X must have the same cv-qualifiers (\tt const and + \tt volatile) that \tt T has, or the code will fail to + compile. Use qSharedPointerConstCast to cast away the constness. + + \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast() +*/ + + +/*! \fn QWeakPointer qWeakPointerCast(const QWeakPointer &other) \relates QWeakPointer diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h index cd6bc62..abd83ad 100644 --- a/src/corelib/tools/qsharedpointer.h +++ b/src/corelib/tools/qsharedpointer.h @@ -93,6 +93,7 @@ public: template QSharedPointer staticCast() const; template QSharedPointer dynamicCast() const; template QSharedPointer constCast() const; + template QSharedPointer objectCast() const; }; template @@ -136,6 +137,8 @@ template QSharedPointer qSharedPointerDynamicCast(const QS template QSharedPointer qSharedPointerDynamicCast(const QWeakPointer &src); template QSharedPointer qSharedPointerConstCast(const QSharedPointer &src); template QSharedPointer qSharedPointerConstCast(const QWeakPointer &src); +template QSharedPointer qSharedPointerObjectCast(const QSharedPointer &src); +template QSharedPointer qSharedPointerObjectCast(const QWeakPointer &src); template QWeakPointer qWeakPointerCast(const QWeakPointer &src); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 2797622..df31fec 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -49,6 +49,7 @@ #endif #include +#include // for qobject_cast QT_BEGIN_HEADER @@ -83,6 +84,11 @@ QSharedPointer qSharedPointerDynamicCast(const QSharedPointer &ptr); template QSharedPointer qSharedPointerConstCast(const QSharedPointer &ptr); +#ifndef QT_NO_QOBJECT +template +QSharedPointer qSharedPointerObjectCast(const QSharedPointer &ptr); +#endif + namespace QtSharedPointer { template class InternalRefCount; template class ExternalRefCount; @@ -330,6 +336,14 @@ public: return qSharedPointerConstCast(*this); } +#ifndef QT_NO_QOBJECT + template + QSharedPointer objectCast() const + { + return qSharedPointerObjectCast(*this); + } +#endif + inline void clear() { *this = QSharedPointer(); } QWeakPointer toWeakRef() const; @@ -545,6 +559,43 @@ QWeakPointer qWeakPointerCast(const QSharedPointer &src) return qSharedPointerCast(src).toWeakRef(); } +#ifndef QT_NO_QOBJECT +template +Q_INLINE_TEMPLATE QSharedPointer qSharedPointerObjectCast(const QSharedPointer &src) +{ + register X *ptr = qobject_cast(src.data()); + return QtSharedPointer::copyAndSetPointer(ptr, src); +} +template +Q_INLINE_TEMPLATE QSharedPointer qSharedPointerObjectCast(const QWeakPointer &src) +{ + return qSharedPointerObjectCast(src.toStrongRef()); +} + +# ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION +namespace QtSharedPointer { + template struct RemovePointer; + template struct RemovePointer { typedef T Type; }; + template struct RemovePointer > { typedef T Type; }; + template struct RemovePointer > { typedef T Type; }; +} + +template +inline QSharedPointer::Type> +qobject_cast(const QSharedPointer &src) +{ + return qSharedPointerObjectCast::Type, T>(src); +} +template +inline QSharedPointer::Type> +qobject_cast(const QWeakPointer &src) +{ + return qSharedPointerObjectCast::Type, T>(src); +} +# endif + +#endif + QT_END_NAMESPACE QT_END_HEADER diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index db93fc9..57ebdce 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -56,6 +56,7 @@ private slots: void memoryManagement(); void downCast(); void upCast(); + void objectCast(); void differentPointers(); void virtualBaseDifferentPointers(); #ifndef QTEST_NO_RTTI @@ -424,6 +425,109 @@ void tst_QSharedPointer::upCast() QCOMPARE(int(baseptr.d->strongref), 1); } +class OtherObject: public QObject +{ + Q_OBJECT +}; + +void tst_QSharedPointer::objectCast() +{ + { + OtherObject *data = new OtherObject; + QSharedPointer baseptr = QSharedPointer(data); + QVERIFY(baseptr == data); + QVERIFY(data == baseptr); + + // perform object cast + QSharedPointer ptr = qSharedPointerObjectCast(baseptr); + QVERIFY(!ptr.isNull()); + QCOMPARE(ptr.data(), data); + QVERIFY(ptr == data); + + // again: + ptr = baseptr.objectCast(); + QVERIFY(ptr == data); + +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + // again: + ptr = qobject_cast(baseptr); + QVERIFY(ptr == data); + + // again: + ptr = qobject_cast >(baseptr); + QVERIFY(ptr == data); +#endif + } + + { + const OtherObject *data = new OtherObject; + QSharedPointer baseptr = QSharedPointer(data); + QVERIFY(baseptr == data); + QVERIFY(data == baseptr); + + // perform object cast + QSharedPointer ptr = qSharedPointerObjectCast(baseptr); + QVERIFY(!ptr.isNull()); + QCOMPARE(ptr.data(), data); + QVERIFY(ptr == data); + + // again: + ptr = baseptr.objectCast(); + QVERIFY(ptr == data); + +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + // again: + ptr = qobject_cast(baseptr); + QVERIFY(ptr == data); + + // again: + ptr = qobject_cast >(baseptr); + QVERIFY(ptr == data); +#endif + } + + { + OtherObject *data = new OtherObject; + QPointer qptr = data; + QSharedPointer ptr = QSharedPointer(data); + QWeakPointer weakptr = ptr; + + { + // perform object cast + QSharedPointer otherptr = qSharedPointerObjectCast(weakptr); + QVERIFY(otherptr == ptr); + + // again: + otherptr = qobject_cast(weakptr); + QVERIFY(otherptr == ptr); + + // again: + otherptr = qobject_cast >(weakptr); + QVERIFY(otherptr == ptr); + } + + // drop the reference: + ptr.clear(); + QVERIFY(ptr.isNull()); + QVERIFY(qptr.isNull()); + QVERIFY(weakptr.toStrongRef().isNull()); + + // verify that the object casts fail without crash + QSharedPointer otherptr = qSharedPointerObjectCast(weakptr); + QVERIFY(otherptr.isNull()); + +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + // again: + otherptr = qobject_cast(weakptr); + QVERIFY(otherptr.isNull()); + + // again: + otherptr = qobject_cast >(weakptr); + QVERIFY(otherptr.isNull()); +#endif + } +} + void tst_QSharedPointer::differentPointers() { { @@ -939,6 +1043,20 @@ void tst_QSharedPointer::invalidConstructs_data() << "QSharedPointer baseptr = QSharedPointer(new Data);\n" "QSharedPointer ptr;" "ptr = baseptr;"; + QTest::newRow("const-dropping-static-cast") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer baseptr = QSharedPointer(new Data);\n" + "qSharedPointerCast(baseptr);"; +#ifndef QTEST_NO_RTTI + QTest::newRow("const-dropping-dynamic-cast") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer baseptr = QSharedPointer(new Data);\n" + "qSharedPointerDynamicCast(baseptr);"; +#endif + QTest::newRow("const-dropping-object-cast") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" + "qSharedPointerObjectCast(baseptr);"; // arithmethics through automatic cast operators QTest::newRow("arithmethic1") @@ -982,6 +1100,10 @@ void tst_QSharedPointer::invalidConstructs_data() << &QTest::QExternalTest::tryCompileFail << "QSharedPointer ptr1;\n" "QSharedPointer ptr2 = qSharedPointerConstCast(ptr1);"; + QTest::newRow("invalid-cast4") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer ptr1;\n" + "QSharedPointer ptr2 = qSharedPointerObjectCast(ptr1);"; } void tst_QSharedPointer::invalidConstructs() @@ -999,6 +1121,7 @@ void tst_QSharedPointer::invalidConstructs() test.setProgramHeader( "#define QT_SHAREDPOINTER_TRACK_POINTERS\n" "#include \n" + "#include \n" "\n" "struct Data { int i; };\n" "struct DerivedData: public Data { int j; };\n" -- cgit v0.12 From fb51a10ee0451274a430227566ae26efb2ac4474 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Jun 2009 20:52:36 +0200 Subject: Add support for creating the object alongside the Data structure in one go. This avoids one memory allocation. Currently, we only support calling the default constructors. I will *NOT* implement argument passing for C++03. I will implement it with rvalue references for C++0x-capable compilers. --- src/corelib/tools/qsharedpointer_impl.h | 47 +++++++++++ tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 102 ++++++++++++++++++++++- 2 files changed, 147 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index df31fec..cb78f29 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -48,6 +48,7 @@ #pragma qt_sync_stop_processing #endif +#include #include #include // for qobject_cast @@ -190,6 +191,34 @@ namespace QtSharedPointer { }; template + struct ExternalRefCountWithContiguousData: public ExternalRefCountData + { +#ifdef Q_DECL_ALIGN +# ifdef Q_ALIGNOF +# define QSP_ALIGNOF(T) Q_ALIGNOF(T) +# else +# define QSP_ALIGNOF(T) (sizeof(T) >= 16 ? 16 : sizeof(T) >= 8 ? 8 : sizeof(T) >= 4 ? 4 : sizeof(T) >= 2 ? 2 : 1) +# endif + + char data[sizeof(T)] Q_DECL_ALIGN(QSP_ALIGNOF(T)); + inline T *pointer() { return reinterpret_cast(data); } + +# undef QSP_ALIGNOF +#else + union { + char data[sizeof(T) + 16]; + double dummy1; +# ifndef Q_OS_DARWIN + long double dummy2; +# endif + }; + inline T *pointer() { return reinterpret_cast(data + 16 - (quintptr(data) & 0xf)); } +#endif + + inline bool destroy() { this->pointer()->~T(); return true; } + }; + + template class ExternalRefCount: public Basic { typedef ExternalRefCountData Data; @@ -220,6 +249,16 @@ namespace QtSharedPointer { d = new ExternalRefCountWithSpecializedDeleter(ptr, deleter); } + inline void internalCreate() + { + ExternalRefCountWithContiguousData *dd = new ExternalRefCountWithContiguousData; + T *ptr = dd->pointer(); + new (ptr) T(); // create + + Basic::internalConstruct(ptr); + d = dd; + } + inline ExternalRefCount() : d(0) { } inline ~ExternalRefCount() { if (d && !deref()) delete d; } inline ExternalRefCount(const ExternalRefCount &other) : Basic(other), d(other.d) @@ -347,6 +386,14 @@ public: inline void clear() { *this = QSharedPointer(); } QWeakPointer toWeakRef() const; + +public: + static QSharedPointer create() + { + QSharedPointer result; + result.internalCreate(); + return result; + } }; template diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 57ebdce..d6321c7 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -65,8 +65,9 @@ private slots: void dynamicCastVirtualBase(); void dynamicCastFailure(); #endif - void customDeleter(); void constCorrectness(); + void customDeleter(); + void creating(); void validConstructs(); void invalidConstructs_data(); void invalidConstructs(); @@ -104,6 +105,8 @@ public: { delete this; } + + virtual int classLevel() { return 1; } }; int Data::generationCounter = 0; int Data::destructorCounter = 0; @@ -311,6 +314,8 @@ public: { delete this; } + + virtual int classLevel() { return 2; } }; int DerivedData::derivedDestructorCounter = 0; @@ -318,15 +323,23 @@ class Stuffing { public: char buffer[16]; + Stuffing() { for (uint i = 0; i < sizeof buffer; ++i) buffer[i] = 16 - i; } virtual ~Stuffing() { } }; class DiffPtrDerivedData: public Stuffing, public Data { +public: + virtual int classLevel() { return 3; } }; class VirtualDerived: virtual public Data { +public: + int moreData; + + VirtualDerived() : moreData(0xc0ffee) { } + virtual int classLevel() { return 4; } }; void tst_QSharedPointer::downCast() @@ -972,6 +985,82 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(derivedDataDeleter.callCount, 1); } +void tst_QSharedPointer::creating() +{ + Data::generationCounter = Data::destructorCounter = 0; + { + QSharedPointer ptr = QSharedPointer::create(); + QVERIFY(ptr.data()); + QCOMPARE(Data::generationCounter, 1); + QCOMPARE(ptr->generation, 1); + QCOMPARE(Data::destructorCounter, 0); + + QCOMPARE(ptr->classLevel(), 1); + + ptr.clear(); + QCOMPARE(Data::destructorCounter, 1); + } + + Data::generationCounter = Data::destructorCounter = 0; + { + QSharedPointer ptr = QSharedPointer::create(); + QWeakPointer weakptr = ptr; + QtSharedPointer::ExternalRefCountData *d = ptr.d; + + ptr.clear(); + QVERIFY(ptr.isNull()); + QCOMPARE(Data::destructorCounter, 1); + + // valgrind will complain here if something happened to the pointer + QVERIFY(d->weakref == 1); + QVERIFY(d->strongref == 0); + } + + Data::generationCounter = Data::destructorCounter = 0; + DerivedData::derivedDestructorCounter = 0; + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->classLevel(), 2); + QCOMPARE(ptr.staticCast()->moreData, 0); + ptr.clear(); + + QCOMPARE(Data::destructorCounter, 1); + QCOMPARE(DerivedData::derivedDestructorCounter, 1); + } + + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->classLevel(), 3); + QCOMPARE(ptr.staticCast()->buffer[7]+0, 16-7); + QCOMPARE(ptr.staticCast()->buffer[3]+0, 16-3); + QCOMPARE(ptr.staticCast()->buffer[0]+0, 16); + } + + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->classLevel(), 4); + QCOMPARE(ptr->moreData, 0xc0ffee); + + QSharedPointer baseptr = ptr; + QCOMPARE(baseptr->classLevel(), 4); + } + + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->metaObject(), &QObject::staticMetaObject); + + QPointer qptr = ptr.data(); + ptr.clear(); + + QVERIFY(qptr.isNull()); + } + + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->metaObject(), &OtherObject::staticMetaObject); + } +} + void tst_QSharedPointer::validConstructs() { { @@ -1021,6 +1110,9 @@ void tst_QSharedPointer::invalidConstructs_data() QTest::newRow("forward-declaration") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer ptr;"; + QTest::newRow("creating-forward-declaration") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer::create();"; // upcast without cast operator: QTest::newRow("upcast1") @@ -1053,10 +1145,16 @@ void tst_QSharedPointer::invalidConstructs_data() << "QSharedPointer baseptr = QSharedPointer(new Data);\n" "qSharedPointerDynamicCast(baseptr);"; #endif - QTest::newRow("const-dropping-object-cast") + QTest::newRow("const-dropping-object-cast1") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" "qSharedPointerObjectCast(baseptr);"; +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + QTest::newRow("const-dropping-object-cast2") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" + "qobject_cast(baseptr);"; +#endif // arithmethics through automatic cast operators QTest::newRow("arithmethic1") -- cgit v0.12 From 6f673e2cf55755a97aeb8971994ab9fc62fb794e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Jun 2009 21:01:24 +0200 Subject: Experimental: allow QSharedPointer to be used with forward declarations that are declared in this file. The one-definition rule allows the forward declaration appearing below to apply to code that was earlier. Therefore, if the compiler finds out how to delete the object, we can allow a QSharedPointer of a forward- declared-type. This means the actual problem is just a warning with g++. To catch the error, we need a separate .cpp file and I'd rather run this as an external test. --- src/corelib/tools/qsharedpointer_impl.h | 2 +- tests/auto/qsharedpointer/externaltests.cpp | 20 ++++++++- tests/auto/qsharedpointer/externaltests.h | 4 ++ tests/auto/qsharedpointer/externaltests.pri | 1 + tests/auto/qsharedpointer/forwarddeclaration.cpp | 52 +++++++++++++++++++++++ tests/auto/qsharedpointer/forwarddeclared.cpp | 53 +++++++++++++++++++++++ tests/auto/qsharedpointer/forwarddeclared.h | 54 ++++++++++++++++++++++++ tests/auto/qsharedpointer/qsharedpointer.pro | 9 ++-- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 42 +++++++++++++++--- 9 files changed, 224 insertions(+), 13 deletions(-) create mode 100644 tests/auto/qsharedpointer/forwarddeclaration.cpp create mode 100644 tests/auto/qsharedpointer/forwarddeclared.cpp create mode 100644 tests/auto/qsharedpointer/forwarddeclared.h diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index cb78f29..2fa9eb2 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -129,7 +129,7 @@ namespace QtSharedPointer { inline T *operator->() const { return data(); } protected: - inline Basic() : value(0 * sizeof(T)) { } + inline Basic() : value(0) { } // ~Basic(); inline void verifyReconstruction(const T *ptr) diff --git a/tests/auto/qsharedpointer/externaltests.cpp b/tests/auto/qsharedpointer/externaltests.cpp index 75ac5f1..8077b84 100644 --- a/tests/auto/qsharedpointer/externaltests.cpp +++ b/tests/auto/qsharedpointer/externaltests.cpp @@ -59,7 +59,7 @@ static QString makespec() { static const char default_makespec[] = DEFAULT_MAKESPEC; const char *p; - for (p = default_makespec + sizeof(default_makespec); p >= default_makespec; --p) + for (p = default_makespec + sizeof(default_makespec) - 1; p >= default_makespec; --p) if (*p == '/' || *p == '\\') break; @@ -122,6 +122,7 @@ namespace QTest { enum Target { Compile, Link, Run }; QList qmakeLines; + QStringList extraProgramSources; QByteArray programHeader; QExternalTest::QtModules qtModules; QExternalTest::ApplicationType appType; @@ -199,6 +200,16 @@ namespace QTest { d->appType = type; } + QStringList QExternalTest::extraProgramSources() const + { + return d->extraProgramSources; + } + + void QExternalTest::setExtraProgramSources(const QStringList &extra) + { + d->extraProgramSources = extra; + } + QByteArray QExternalTest::programHeader() const { return d->programHeader; @@ -483,6 +494,13 @@ namespace QTest { else projectFile.write("\nCONFIG += release\n"); + QByteArray extraSources = QFile::encodeName(extraProgramSources.join(" ")); + if (!extraSources.isEmpty()) { + projectFile.write("SOURCES += "); + projectFile.write(extraSources); + projectFile.putChar('\n'); + } + // Add Qt modules if (qtModules & QExternalTest::QtCore) projectFile.write("QT += core\n"); diff --git a/tests/auto/qsharedpointer/externaltests.h b/tests/auto/qsharedpointer/externaltests.h index 24a3236..ecc107e 100644 --- a/tests/auto/qsharedpointer/externaltests.h +++ b/tests/auto/qsharedpointer/externaltests.h @@ -45,6 +45,7 @@ #include #include +#include QT_BEGIN_NAMESPACE namespace QTest { @@ -102,6 +103,9 @@ namespace QTest { ApplicationType applicationType() const; void setApplicationType(ApplicationType type); + QStringList extraProgramSources() const; + void setExtraProgramSources(const QStringList &list); + QByteArray programHeader() const; void setProgramHeader(const QByteArray &header); diff --git a/tests/auto/qsharedpointer/externaltests.pri b/tests/auto/qsharedpointer/externaltests.pri index 717acac..1fdcf65 100644 --- a/tests/auto/qsharedpointer/externaltests.pri +++ b/tests/auto/qsharedpointer/externaltests.pri @@ -1,4 +1,5 @@ SOURCES += $$PWD/externaltests.cpp +HEADERS += $$PWD/externaltests.h cleanedQMAKESPEC = $$replace(QMAKESPEC, \\\\, /) DEFINES += DEFAULT_MAKESPEC=\\\"$$cleanedQMAKESPEC\\\" diff --git a/tests/auto/qsharedpointer/forwarddeclaration.cpp b/tests/auto/qsharedpointer/forwarddeclaration.cpp new file mode 100644 index 0000000..1dbbeec --- /dev/null +++ b/tests/auto/qsharedpointer/forwarddeclaration.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#define QT_SHAREDPOINTER_TRACK_POINTERS +#include "qsharedpointer.h" + +class ForwardDeclared; +ForwardDeclared *forwardPointer(); + +void externalForwardDeclaration() +{ + struct Wrapper { QSharedPointer pointer; }; +} + diff --git a/tests/auto/qsharedpointer/forwarddeclared.cpp b/tests/auto/qsharedpointer/forwarddeclared.cpp new file mode 100644 index 0000000..4ab467a --- /dev/null +++ b/tests/auto/qsharedpointer/forwarddeclared.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "forwarddeclared.h" + +ForwardDeclared *forwardPointer() +{ + return new ForwardDeclared; +} + +int forwardDeclaredDestructorRunCount; +ForwardDeclared::~ForwardDeclared() +{ + ++forwardDeclaredDestructorRunCount; +} diff --git a/tests/auto/qsharedpointer/forwarddeclared.h b/tests/auto/qsharedpointer/forwarddeclared.h new file mode 100644 index 0000000..a4cc2b4 --- /dev/null +++ b/tests/auto/qsharedpointer/forwarddeclared.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FORWARDDECLARED_H +#define FORWARDDECLARED_H + +extern int forwardDeclaredDestructorRunCount; +class ForwardDeclared +{ +public: + ~ForwardDeclared(); +}; + +ForwardDeclared *forwardPointer(); + +#endif // FORWARDDECLARED_H diff --git a/tests/auto/qsharedpointer/qsharedpointer.pro b/tests/auto/qsharedpointer/qsharedpointer.pro index e329803..30c81cb 100644 --- a/tests/auto/qsharedpointer/qsharedpointer.pro +++ b/tests/auto/qsharedpointer/qsharedpointer.pro @@ -1,7 +1,8 @@ load(qttest_p4) - -SOURCES += tst_qsharedpointer.cpp +SOURCES += tst_qsharedpointer.cpp \ + forwarddeclaration.cpp \ + forwarddeclared.cpp QT = core -DEFINES += SRCDIR=\\\"$$PWD\\\" - +DEFINES += SRCDIR=\\\"$$PWD/\\\" include(externaltests.pri) +HEADERS += forwarddeclared.h diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index d6321c7..dd53e3c 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -225,16 +225,37 @@ void tst_QSharedPointer::basics() } class ForwardDeclared; +ForwardDeclared *forwardPointer(); +void externalForwardDeclaration(); +extern int forwardDeclaredDestructorRunCount; + void tst_QSharedPointer::forwardDeclaration1() { - class Wrapper { QSharedPointer pointer; }; + externalForwardDeclaration(); + + struct Wrapper { QSharedPointer pointer; }; + + forwardDeclaredDestructorRunCount = 0; + { + Wrapper w; + w.pointer = QSharedPointer(forwardPointer()); + QVERIFY(!w.pointer.isNull()); + } + QCOMPARE(forwardDeclaredDestructorRunCount, 1); } -class ForwardDeclared { }; +#include "forwarddeclared.h" + void tst_QSharedPointer::forwardDeclaration2() { - class Wrapper { QSharedPointer pointer; }; - Wrapper w; + forwardDeclaredDestructorRunCount = 0; + { + struct Wrapper { QSharedPointer pointer; }; + Wrapper w1, w2; + w1.pointer = QSharedPointer(forwardPointer()); + QVERIFY(!w1.pointer.isNull()); + } + QCOMPARE(forwardDeclaredDestructorRunCount, 1); } void tst_QSharedPointer::memoryManagement() @@ -1108,8 +1129,10 @@ void tst_QSharedPointer::invalidConstructs_data() // use of forward-declared class QTest::newRow("forward-declaration") - << &QTest::QExternalTest::tryCompileFail - << "QSharedPointer ptr;"; + << &QTest::QExternalTest::tryRun + << "forwardDeclaredDestructorRunCount = 0;\n" + "{ QSharedPointer ptr = QSharedPointer(forwardPointer()); }\n" + "exit(forwardDeclaredDestructorRunCount);"; QTest::newRow("creating-forward-declaration") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer::create();"; @@ -1216,6 +1239,7 @@ void tst_QSharedPointer::invalidConstructs() QTest::QExternalTest test; test.setDebugMode(true); test.setQtModules(QTest::QExternalTest::QtCore); + test.setExtraProgramSources(QStringList() << SRCDIR "forwarddeclared.cpp"); test.setProgramHeader( "#define QT_SHAREDPOINTER_TRACK_POINTERS\n" "#include \n" @@ -1223,7 +1247,11 @@ void tst_QSharedPointer::invalidConstructs() "\n" "struct Data { int i; };\n" "struct DerivedData: public Data { int j; };\n" - "struct ForwardDeclared;"); + "\n" + "extern int forwardDeclaredDestructorRunCount;\n" + "struct ForwardDeclared;\n" + "ForwardDeclared *forwardPointer();\n" + ); QFETCH(QString, code); static bool sane = true; -- cgit v0.12 From b3a0229d70ac87d2ae1fd70a7489e3caf66a2f6f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 14:06:04 +0200 Subject: Fix oops in strcmp in QBuffer. Reported via qt-bugs. Reviewed-By: Peter Hartmann --- src/corelib/io/qbuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp index aed5b82..3883d30 100644 --- a/src/corelib/io/qbuffer.cpp +++ b/src/corelib/io/qbuffer.cpp @@ -452,7 +452,7 @@ qint64 QBuffer::writeData(const char *data, qint64 len) */ void QBuffer::connectNotify(const char *signal) { - if (strcmp(signal + 1, "readyRead()") == 0 || strcmp(signal + 1, "bytesWritten(qint64)")) + if (strcmp(signal + 1, "readyRead()") == 0 || strcmp(signal + 1, "bytesWritten(qint64)") == 0) d_func()->signalConnectionCount++; } -- cgit v0.12 From d70839d4fd855d6d5f6bf8d982b677402f71e5ba Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 14:14:51 +0200 Subject: These files don't have to have CRLF line-termination. The other files here don't, so I see no reason why these should --- examples/tools/codecs/encodedfiles/.gitattributes | 2 -- examples/tools/codecs/encodedfiles/iso-8859-1.txt | 12 ++++++------ examples/tools/codecs/encodedfiles/iso-8859-15.txt | 16 ++++++++-------- 3 files changed, 14 insertions(+), 16 deletions(-) delete mode 100644 examples/tools/codecs/encodedfiles/.gitattributes diff --git a/examples/tools/codecs/encodedfiles/.gitattributes b/examples/tools/codecs/encodedfiles/.gitattributes deleted file mode 100644 index 996aab2..0000000 --- a/examples/tools/codecs/encodedfiles/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -iso-8859-15.txt -crlf -iso-8859-1.txt -crlf diff --git a/examples/tools/codecs/encodedfiles/iso-8859-1.txt b/examples/tools/codecs/encodedfiles/iso-8859-1.txt index 4a7ebe3..d7fcaca 100644 --- a/examples/tools/codecs/encodedfiles/iso-8859-1.txt +++ b/examples/tools/codecs/encodedfiles/iso-8859-1.txt @@ -1,6 +1,6 @@ -Paulo Coelho: O Gnio e as Rosas -Anna Hallstrm, Urban stberg: Svr svenska -Darrell Huff: How to Lie with Statistics -Franz Kafka: Das Schlo -Walter Moers: Die 13 Leben des Kpt'n Blaubr -Dag Solstad: Forsk p beskrive det ugjennomtrengelige +Paulo Coelho: O Gnio e as Rosas +Anna Hallstrm, Urban stberg: Svr svenska +Darrell Huff: How to Lie with Statistics +Franz Kafka: Das Schlo +Walter Moers: Die 13 Leben des Kpt'n Blaubr +Dag Solstad: Forsk p beskrive det ugjennomtrengelige diff --git a/examples/tools/codecs/encodedfiles/iso-8859-15.txt b/examples/tools/codecs/encodedfiles/iso-8859-15.txt index cd43ea3..be2d83c 100644 --- a/examples/tools/codecs/encodedfiles/iso-8859-15.txt +++ b/examples/tools/codecs/encodedfiles/iso-8859-15.txt @@ -1,8 +1,8 @@ -Paulo Coelho: O Gnio e as Rosas -Jean-Pierre Coffe: table en famille avec 15 par jour -Anna Hallstrm, Urban stberg: Svr svenska -Darrell Huff: How to Lie with Statistics -Franz Kafka: Das Schlo -Helena Leheckov: Tekki suomalaisille -Arthur Rimbaud: uvres compltes -Dag Solstad: Forsk p beskrive det ugjennomtrengelige +Paulo Coelho: O Gnio e as Rosas +Jean-Pierre Coffe: table en famille avec 15 par jour +Anna Hallstrm, Urban stberg: Svr svenska +Darrell Huff: How to Lie with Statistics +Franz Kafka: Das Schlo +Helena Leheckov: Tekki suomalaisille +Arthur Rimbaud: uvres compltes +Dag Solstad: Forsk p beskrive det ugjennomtrengelige -- cgit v0.12 From 349997b5c4167b07d0bdc55beff175b39f3abe75 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 14:18:47 +0200 Subject: Minor: fix spelling in configure.exe -help output. Reported via qt-bugs --- tools/configure/configureapp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 9ee5eef..1e501c5 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1531,7 +1531,7 @@ bool Configure::displayHelp() desc( "-graphicssystem ", "Specify which graphicssystem should be used.\n" "Available values for :"); desc("GRAPHICS_SYSTEM", "raster", "", " raster - Software rasterizer", ' '); - desc("GRAPHICS_SYSTEM", "opengl", "", " opengl - Using OpenGL accelleration, experimental!", ' '); + desc("GRAPHICS_SYSTEM", "opengl", "", " opengl - Using OpenGL acceleration, experimental!", ' '); desc( "-help, -h, -?", "Display this information.\n"); -- cgit v0.12 From 3473453dda9f40bf94733bc971b0cc1658e7c3c8 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Thu, 2 Jul 2009 14:28:46 +0200 Subject: Fix a regression where dynamic tooltips wouldn't show up in Cocoa. Tracking of mouse events was only enabled when enableMouseTracking or Hover or a tooltip had been set explictly on the item, but this meant that the dynamic QEvent::Tooltips would never get dispatched. So, in order to help out people that might use this feature, all QCocoaViews must pay the mouse move event tax *sigh*. I added comments in the proper places so that we DO the right thing for a release where we can force the change in behavior. Task-number: 257320 Reviewed-by: Denis --- src/gui/kernel/qapplication.cpp | 7 +++++++ src/gui/kernel/qcocoaview_mac.mm | 12 ++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 40795d1..c6af728 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -3724,6 +3724,13 @@ bool QApplication::notify(QObject *receiver, QEvent *e) } } + // ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms + // like Mac OS X (probably others too), can optimize their views by not + // dispatching mouse move events. We have attributes to control hover, + // and mouse tracking, but as long as we are deciding to implement this + // feature without choice of opting-in or out, you ALWAYS have to have + // tracking enabled. Therefore, the other properties give a false sense of + // performance enhancement. if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) { d->toolTipWidget = w; d->toolTipPos = relpos; diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index ae3265b..17e3313 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -564,11 +564,15 @@ extern "C" { [self removeTrackingArea:t]; } } + + // Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should + // only be turned on if mouseTracking, hover is on or a tool tip is set. + // Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to + // turn it on in ALL case. That means EVERY QCocoaView gets to pay the cost of + // mouse moves delivered to it (Apple recommends keeping it OFF because there + // is a performance hit). So it goes. NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp - | NSTrackingInVisibleRect; - if (qwidget->hasMouseTracking() || !qwidgetprivate->toolTip.isEmpty() - || qwidget->testAttribute(Qt::WA_Hover)) - trackingOptions |= NSTrackingMouseMoved; + | NSTrackingInVisibleRect | NSTrackingMouseMoved; NSTrackingArea *ta = [[NSTrackingArea alloc] initWithRect:NSMakeRect(0, 0, qwidget->width(), qwidget->height()) -- cgit v0.12 From 501d1395bd3fc6c67e50216345959d31c0db7707 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 15:44:17 +0200 Subject: Revert "Add support for creating the object alongside the Data structure in QSharedPointer" This reverts commit fb51a10ee0451274a430227566ae26efb2ac4474. Sorry, it didn't work. I can fix the MSVC error, but the problem is that older GCC versions (4.2) fail with the following code: template struct Buffer { char buffer[128] __attribute__((aligned(__alignof__(T)))); }; The same works fine in GCC 4.4. --- src/corelib/tools/qsharedpointer_impl.h | 47 ----------- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 102 +---------------------- 2 files changed, 2 insertions(+), 147 deletions(-) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 2fa9eb2..739a949 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -48,7 +48,6 @@ #pragma qt_sync_stop_processing #endif -#include #include #include // for qobject_cast @@ -191,34 +190,6 @@ namespace QtSharedPointer { }; template - struct ExternalRefCountWithContiguousData: public ExternalRefCountData - { -#ifdef Q_DECL_ALIGN -# ifdef Q_ALIGNOF -# define QSP_ALIGNOF(T) Q_ALIGNOF(T) -# else -# define QSP_ALIGNOF(T) (sizeof(T) >= 16 ? 16 : sizeof(T) >= 8 ? 8 : sizeof(T) >= 4 ? 4 : sizeof(T) >= 2 ? 2 : 1) -# endif - - char data[sizeof(T)] Q_DECL_ALIGN(QSP_ALIGNOF(T)); - inline T *pointer() { return reinterpret_cast(data); } - -# undef QSP_ALIGNOF -#else - union { - char data[sizeof(T) + 16]; - double dummy1; -# ifndef Q_OS_DARWIN - long double dummy2; -# endif - }; - inline T *pointer() { return reinterpret_cast(data + 16 - (quintptr(data) & 0xf)); } -#endif - - inline bool destroy() { this->pointer()->~T(); return true; } - }; - - template class ExternalRefCount: public Basic { typedef ExternalRefCountData Data; @@ -249,16 +220,6 @@ namespace QtSharedPointer { d = new ExternalRefCountWithSpecializedDeleter(ptr, deleter); } - inline void internalCreate() - { - ExternalRefCountWithContiguousData *dd = new ExternalRefCountWithContiguousData; - T *ptr = dd->pointer(); - new (ptr) T(); // create - - Basic::internalConstruct(ptr); - d = dd; - } - inline ExternalRefCount() : d(0) { } inline ~ExternalRefCount() { if (d && !deref()) delete d; } inline ExternalRefCount(const ExternalRefCount &other) : Basic(other), d(other.d) @@ -386,14 +347,6 @@ public: inline void clear() { *this = QSharedPointer(); } QWeakPointer toWeakRef() const; - -public: - static QSharedPointer create() - { - QSharedPointer result; - result.internalCreate(); - return result; - } }; template diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index dd53e3c..5cb435a 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -65,9 +65,8 @@ private slots: void dynamicCastVirtualBase(); void dynamicCastFailure(); #endif - void constCorrectness(); void customDeleter(); - void creating(); + void constCorrectness(); void validConstructs(); void invalidConstructs_data(); void invalidConstructs(); @@ -105,8 +104,6 @@ public: { delete this; } - - virtual int classLevel() { return 1; } }; int Data::generationCounter = 0; int Data::destructorCounter = 0; @@ -335,8 +332,6 @@ public: { delete this; } - - virtual int classLevel() { return 2; } }; int DerivedData::derivedDestructorCounter = 0; @@ -344,23 +339,15 @@ class Stuffing { public: char buffer[16]; - Stuffing() { for (uint i = 0; i < sizeof buffer; ++i) buffer[i] = 16 - i; } virtual ~Stuffing() { } }; class DiffPtrDerivedData: public Stuffing, public Data { -public: - virtual int classLevel() { return 3; } }; class VirtualDerived: virtual public Data { -public: - int moreData; - - VirtualDerived() : moreData(0xc0ffee) { } - virtual int classLevel() { return 4; } }; void tst_QSharedPointer::downCast() @@ -1006,82 +993,6 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(derivedDataDeleter.callCount, 1); } -void tst_QSharedPointer::creating() -{ - Data::generationCounter = Data::destructorCounter = 0; - { - QSharedPointer ptr = QSharedPointer::create(); - QVERIFY(ptr.data()); - QCOMPARE(Data::generationCounter, 1); - QCOMPARE(ptr->generation, 1); - QCOMPARE(Data::destructorCounter, 0); - - QCOMPARE(ptr->classLevel(), 1); - - ptr.clear(); - QCOMPARE(Data::destructorCounter, 1); - } - - Data::generationCounter = Data::destructorCounter = 0; - { - QSharedPointer ptr = QSharedPointer::create(); - QWeakPointer weakptr = ptr; - QtSharedPointer::ExternalRefCountData *d = ptr.d; - - ptr.clear(); - QVERIFY(ptr.isNull()); - QCOMPARE(Data::destructorCounter, 1); - - // valgrind will complain here if something happened to the pointer - QVERIFY(d->weakref == 1); - QVERIFY(d->strongref == 0); - } - - Data::generationCounter = Data::destructorCounter = 0; - DerivedData::derivedDestructorCounter = 0; - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->classLevel(), 2); - QCOMPARE(ptr.staticCast()->moreData, 0); - ptr.clear(); - - QCOMPARE(Data::destructorCounter, 1); - QCOMPARE(DerivedData::derivedDestructorCounter, 1); - } - - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->classLevel(), 3); - QCOMPARE(ptr.staticCast()->buffer[7]+0, 16-7); - QCOMPARE(ptr.staticCast()->buffer[3]+0, 16-3); - QCOMPARE(ptr.staticCast()->buffer[0]+0, 16); - } - - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->classLevel(), 4); - QCOMPARE(ptr->moreData, 0xc0ffee); - - QSharedPointer baseptr = ptr; - QCOMPARE(baseptr->classLevel(), 4); - } - - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->metaObject(), &QObject::staticMetaObject); - - QPointer qptr = ptr.data(); - ptr.clear(); - - QVERIFY(qptr.isNull()); - } - - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->metaObject(), &OtherObject::staticMetaObject); - } -} - void tst_QSharedPointer::validConstructs() { { @@ -1133,9 +1044,6 @@ void tst_QSharedPointer::invalidConstructs_data() << "forwardDeclaredDestructorRunCount = 0;\n" "{ QSharedPointer ptr = QSharedPointer(forwardPointer()); }\n" "exit(forwardDeclaredDestructorRunCount);"; - QTest::newRow("creating-forward-declaration") - << &QTest::QExternalTest::tryCompileFail - << "QSharedPointer::create();"; // upcast without cast operator: QTest::newRow("upcast1") @@ -1168,16 +1076,10 @@ void tst_QSharedPointer::invalidConstructs_data() << "QSharedPointer baseptr = QSharedPointer(new Data);\n" "qSharedPointerDynamicCast(baseptr);"; #endif - QTest::newRow("const-dropping-object-cast1") + QTest::newRow("const-dropping-object-cast") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" "qSharedPointerObjectCast(baseptr);"; -#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION - QTest::newRow("const-dropping-object-cast2") - << &QTest::QExternalTest::tryCompileFail - << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" - "qobject_cast(baseptr);"; -#endif // arithmethics through automatic cast operators QTest::newRow("arithmethic1") -- cgit v0.12 From d9b28812d0065227e6f66817cd9bf917dfadb0f0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 15:49:49 +0200 Subject: Don't compile the FD_CLOEXEC-safe accept4 call if we don't know about SOCK_CLOEXEC --- src/network/socket/qnet_unix_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index 80a4c58..ffd5b39 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -100,7 +100,7 @@ static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *add Q_ASSERT((flags & ~O_NONBLOCK) == 0); register int fd; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) // use accept4 int sockflags = SOCK_CLOEXEC; if (flags & O_NONBLOCK) -- cgit v0.12 From f30f3e7bdc846baf49ef51721a5b11d31be22cf2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 16:43:40 +0200 Subject: Fix build with MSVC2003: apparently the code path I thought was Unix was also older MSVC --- src/corelib/io/qtemporaryfile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 2ae4611..b520bee 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -61,7 +61,7 @@ #include #if defined(Q_OS_UNIX) -# include "private/qcore_unix_p.h" +# include "private/qcore_unix_p.h" // overrides QT_OPEN #endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) @@ -211,9 +211,9 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) if ((*doopen = QT_OPEN(targetPath.toLocal8Bit(), O_CREAT|O_EXCL|O_RDWR # else // CE - // this is Unix + // this is Unix or older MSVC if ((*doopen = - qt_safe_open(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR + QT_OPEN(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR # endif # ifdef QT_LARGEFILE_SUPPORT |QT_OPEN_LARGEFILE -- cgit v0.12 From 8dbdcc129a7bb5f924aeb451799bc4d7495714ba Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 2 Jul 2009 16:41:53 +0200 Subject: QHeaderView: the sizeHint for section now takes the indicator into account for all sections is sorting is enabled. Task-number: 208320 --- src/gui/itemviews/qheaderview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index b35c30b..aea288b 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -2540,7 +2540,7 @@ QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const if (opt.icon.isNull()) opt.icon = qvariant_cast(variant); QSize size = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this); - if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex) { + if (isSortIndicatorShown()) { int margin = style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this); if (d->orientation == Qt::Horizontal) size.rwidth() += size.height() + margin; -- cgit v0.12 From 097476afe24d69bac65b84b70ed2f93e88875b40 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 1 Jul 2009 14:34:21 +0200 Subject: Implement hitTest Cocoa calls hitTest on our view to determine if the view should get the mouse press. We always said, "yes" and did all the logic ourselves. Turns out that we can say "no" if I'm transparent to mouse events and remove all that code where we do all the work ourselves. Big maintenance win! For the time being I've kept the "transparentViewForEvent" method since it might be useful for others, but no one is using it at the moment and we may just kill it soon. HitTest should handle this situation correctly. --- src/gui/kernel/qcocoaview_mac.mm | 17 ++++++------- src/gui/kernel/qt_cocoa_helpers_mac.mm | 44 ---------------------------------- 2 files changed, 7 insertions(+), 54 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 17e3313..81e06a9 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -554,6 +554,13 @@ extern "C" { return !qwidget->testAttribute(Qt::WA_MacNoClickThrough); } +- (NSView *)hitTest:(NSPoint)aPoint +{ + if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) + return nil; // You cannot hit a transparent for mouse event widget. + return [super hitTest:aPoint]; +} + - (void)updateTrackingAreas { QMacCocoaAutoReleasePool pool; @@ -794,16 +801,6 @@ extern "C" { Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]); QWidget *widgetToGetMouse = qwidget; - if (widgetToGetMouse->testAttribute(Qt::WA_TransparentForMouseEvents)) { - // Simulate passing the event through since Cocoa doesn't do that for us. - // Start by building a tree up. - NSView *candidateView = [self viewUnderTransparentForMouseView:self - widget:widgetToGetMouse - withWindowPoint:windowPoint]; - if (candidateView != nil) { - widgetToGetMouse = QWidget::find(WId(candidateView)); - } - } // Mouse wheel deltas seem to tick in at increments of 0.1. Qt widgets // expect the delta to be a multiple of 120. diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 2dd4fdf..241ea44 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -851,50 +851,6 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil]; QPoint qlocalPoint(localPoint.x, localPoint.y); - if (widgetToGetMouse->testAttribute(Qt::WA_TransparentForMouseEvents)) { - // Simulate passing the event through since Cocoa doesn't do that for us. - // Start by building a tree up. - NSView *candidateView = [theView viewUnderTransparentForMouseView:tmpView - widget:widgetToGetMouse - withWindowPoint:windowPoint]; - if (candidateView != nil) { - // Fast-track our views, since dispatching trough the normal ways - // would just end up going through here anyway. - if ([candidateView isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) { - return qt_mac_handleMouseEvent(candidateView, theEvent, eventType, button); - } else { - switch (eventType) { - default: - qWarning("not handled! %d", eventType); - break; - case QEvent::MouseMove: - [candidateView mouseMoved:theEvent]; - break; - case QEvent::MouseButtonPress: - if (button == Qt::LeftButton) - [candidateView mouseDown:theEvent]; - else if (button == Qt::RightButton) - [candidateView rightMouseDown:theEvent]; - else - [candidateView otherMouseDown:theEvent]; - break; - case QEvent::MouseButtonRelease: - if (button == Qt::LeftButton) - [candidateView mouseUp:theEvent]; - else if (button == Qt::RightButton) - [candidateView rightMouseUp:theEvent]; - else - [candidateView otherMouseUp:theEvent]; - break; - } - return true; // We've done the dispatching, no need go further. - } - } - // Nothing below me return false - return false; - } - - EventRef carbonEvent = static_cast(const_cast([theEvent eventRef])); if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent)) return true; -- cgit v0.12 From c6cc00316b2ce95adddc9fdb658d737057b40682 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 2 Jul 2009 16:25:44 +0200 Subject: Drag and drop events are not delivered correctly in Cocoa Drag and drop events should consider the WA_TransparentForMouseEvents attribute like the mouse events. If this attribute is set for a widget, the event has to be passed to right widget under mouse. The widget is identified by calling hitTest. In such cases the leave event has to be delivered to the widget which actually accepted the enter event. Task-number: 252088 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qcocoaview_mac.mm | 49 ++++++++++++++++++++++++++++++++------- src/gui/kernel/qcocoaview_mac_p.h | 2 ++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 81e06a9..4479531 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -288,11 +288,18 @@ extern "C" { { if (qwidget->testAttribute(Qt::WA_DropSiteRegistered) == false) return NSDragOperationNone; + NSPoint windowPoint = [sender draggingLocation]; + if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) { + // pass the drag enter event to the view underneath. + NSView *candidateView = [[[self window] contentView] hitTest:windowPoint]; + if (candidateView && candidateView != self) + return [candidateView draggingEntered:sender]; + } + dragEnterSequence = [sender draggingSequenceNumber]; [self addDropData:sender]; QMimeData *mimeData = dropData; if (QDragManager::self()->source()) mimeData = QDragManager::self()->dragPrivate()->data; - NSPoint windowPoint = [sender draggingLocation]; NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint]; NSPoint localPoint = [self convertPoint:windowPoint fromView:nil]; QPoint posDrag(localPoint.x, localPoint.y); @@ -316,6 +323,9 @@ extern "C" { [self removeDropData]; return NSDragOperationNone; } else { + // save the mouse position, used by draggingExited handler. + DnDParams *dndParams = [QCocoaView currentMouseEvent]; + dndParams->activeDragEnterPos = windowPoint; // send a drag move event immediately after a drag enter event (as per documentation). QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers); qDMEvent.setDropAction(qDEEvent.dropAction()); @@ -336,11 +346,22 @@ extern "C" { - (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender { - // drag enter event was rejected, so ignore the move event. + NSPoint windowPoint = [sender draggingLocation]; + if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) { + // pass the drag move event to the view underneath. + NSView *candidateView = [[[self window] contentView] hitTest:windowPoint]; + if (candidateView && candidateView != self) + return [candidateView draggingUpdated:sender]; + } + // in cases like QFocusFrame, the view under the mouse might + // not have received the drag enter. Generate a synthetic + // drag enter event for that view. + if (dragEnterSequence != [sender draggingSequenceNumber]) + [self draggingEntered:sender]; + // drag enter event was rejected, so ignore the move event. if (dropData == 0) return NSDragOperationNone; // return last value, if we are still in the answerRect. - NSPoint windowPoint = [sender draggingLocation]; NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint]; NSPoint localPoint = [self convertPoint:windowPoint fromView:nil]; NSDragOperation nsActions = [sender draggingSourceOperationMask]; @@ -379,21 +400,34 @@ extern "C" { - (void)draggingExited:(id < NSDraggingInfo >)sender { - Q_UNUSED(sender) - // drag enter event was rejected, so ignore the move event. + dragEnterSequence = -1; + if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) { + // try sending the leave event to the last view which accepted drag enter. + DnDParams *dndParams = [QCocoaView currentMouseEvent]; + NSView *candidateView = [[[self window] contentView] hitTest:dndParams->activeDragEnterPos]; + if (candidateView && candidateView != self) + return [candidateView draggingExited:sender]; + } + // drag enter event was rejected, so ignore the move event. if (dropData) { QDragLeaveEvent de; QApplication::sendEvent(qwidget, &de); [self removeDropData]; } - } - (BOOL)performDragOperation:(id )sender { + NSPoint windowPoint = [sender draggingLocation]; + dragEnterSequence = -1; + if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) { + // pass the drop event to the view underneath. + NSView *candidateView = [[[self window] contentView] hitTest:windowPoint]; + if (candidateView && candidateView != self) + return [candidateView performDragOperation:sender]; + } [self addDropData:sender]; - NSPoint windowPoint = [sender draggingLocation]; NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint]; NSPoint localPoint = [self convertPoint:windowPoint fromView:nil]; QPoint posDrop(localPoint.x, localPoint.y); @@ -688,7 +722,6 @@ extern "C" { } if (!lowerView) // Low as we can be at this point. candidateView = viewForDescent; - // Try to go deeper, will also exit out of the loop, if we found the point. viewForDescent = lowerView; lowerView = nil; diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index b4a60b6..7c227cc 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -68,6 +68,7 @@ struct DnDParams NSEvent *theEvent; NSPoint localPoint; NSDragOperation performedAction; + NSPoint activeDragEnterPos; }; QT_END_NAMESPACE @@ -85,6 +86,7 @@ Q_GUI_EXPORT int composingLength; bool sendKeyEvents; QStringList *currentCustomTypes; + NSInteger dragEnterSequence; } - (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; - (void) finishInitWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; -- cgit v0.12 From d2bfae633e99a818c9086846bf330d722afd86f4 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 2 Jul 2009 16:55:38 +0200 Subject: Remove unused function viewUnderTransparentForMouseView in QCocoaView. After we implemented hitTest for QCocoaView, this function is no longer used. Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qcocoaview_mac.mm | 55 --------------------------------------- src/gui/kernel/qcocoaview_mac_p.h | 2 -- 2 files changed, 57 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 4479531..e3ec30a 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -678,61 +678,6 @@ extern "C" { qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); } -- (NSView *)viewUnderTransparentForMouseView:(NSView *)mouseView widget:(QWidget *)widgetToGetMouse - withWindowPoint:(NSPoint)windowPoint -{ - NSMutableArray *viewsToLookAt = [NSMutableArray arrayWithCapacity:5]; - [viewsToLookAt addObject:mouseView]; - QWidget *parentWidget = widgetToGetMouse->parentWidget(); - while (parentWidget) { - [viewsToLookAt addObject:qt_mac_nativeview_for(parentWidget)]; - parentWidget = parentWidget->parentWidget(); - } - - // Now walk through the subviews of each view and determine which subview should - // get the event. We look through all the subviews at a given level with - // the assumption that the last item to be found the candidate has a higher z-order. - // Unfortunately, fast enumeration doesn't go backwards in 10.5, so assume go fast - // forward is quicker than the slow normal way backwards. - NSView *candidateView = nil; - for (NSView *lookView in viewsToLookAt) { - NSPoint tmpPoint = [lookView convertPoint:windowPoint fromView:nil]; - for (NSView *view in [lookView subviews]) { - if (view == mouseView || [view isHidden]) - continue; - NSRect frameRect = [view frame]; - if (NSMouseInRect(tmpPoint, [view frame], [view isFlipped])) - candidateView = view; - } - if (candidateView) - break; - } - - - if (candidateView != nil) { - // Now that we've got a candidate, we have to dig into it's tree and see where it is. - NSView *lowerView = nil; - NSView *viewForDescent = candidateView; - while (viewForDescent) { - NSPoint tmpPoint = [viewForDescent convertPoint:windowPoint fromView:nil]; - // Apply same rule as above wrt z-order. - for (NSView *view in [viewForDescent subviews]) { - if (![view isHidden] && NSMouseInRect(tmpPoint, [view frame], [view isFlipped])) - lowerView = view; - } - if (!lowerView) // Low as we can be at this point. - candidateView = viewForDescent; - // Try to go deeper, will also exit out of the loop, if we found the point. - viewForDescent = lowerView; - lowerView = nil; - } - } - // I am transparent, so I can't be a candidate. - if (candidateView == mouseView) - candidateView = nil; - return candidateView; -} - - (void)mouseDown:(NSEvent *)theEvent { qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::LeftButton); diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index 7c227cc..24040ba 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -105,8 +105,6 @@ Q_GUI_EXPORT - (QWidget *)qt_qwidget; - (BOOL)qt_leftButtonIsRightButton; - (void)qt_setLeftButtonIsRightButton:(BOOL)isSwapped; -- (NSView *)viewUnderTransparentForMouseView:(NSView *)mouseView widget:(QWidget *)widgetToGetMouse - withWindowPoint:(NSPoint)windowPoint; + (DnDParams*)currentMouseEvent; @end -- cgit v0.12 From 8b8e6a7e12e7f5769b60d827f7c8443aa71c339a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 17:03:59 +0200 Subject: Use void* in the read/write replacements That's what unistd.h uses: void* can receive any pointer, while char* can't --- src/corelib/kernel/qcore_unix_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 6ae4ff0..1f3fe39 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -193,7 +193,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) return 0; } -static inline qint64 qt_safe_read(int fd, char *data, qint64 maxlen) +static inline qint64 qt_safe_read(int fd, void *data, qint64 maxlen) { qint64 ret = 0; EINTR_LOOP(ret, QT_READ(fd, data, maxlen)); @@ -202,7 +202,7 @@ static inline qint64 qt_safe_read(int fd, char *data, qint64 maxlen) #undef QT_READ #define QT_READ qt_safe_read -static inline qint64 qt_safe_write(int fd, const char *data, qint64 len) +static inline qint64 qt_safe_write(int fd, const void *data, qint64 len) { qint64 ret = 0; EINTR_LOOP(ret, QT_WRITE(fd, data, len)); -- cgit v0.12 From 27360dd89f0ea72610cf2cd725c62f7a7dd2ea91 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 17:09:59 +0200 Subject: Correct #include path for qcore_unix_p.h --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 721f52c..dfed6a4 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -43,7 +43,7 @@ #include "qfilesystemwatcher.h" #include "qfilesystemwatcher_kqueue_p.h" -#include "qcore_unix_p.h" +#include "private/qcore_unix_p.h" #include #include -- cgit v0.12 From 099a32d121cbc80a1a234c3146f4be9b5237e7e8 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 2 Jul 2009 11:46:42 +0200 Subject: Don't insert text into a text widget when a modifier is pressed. For example when an unhandled key sequence (i.e. that has now shortcut assosiated with it) like Alt-L is pressed, we shouldn't insert the 'L' text from the QKeyEvent::text() into the text widget. Reviewed-by: Thomas Zander --- src/gui/text/qtextcontrol.cpp | 3 ++- src/gui/widgets/qlineedit.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index b2ad686..2a590fd 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1245,7 +1245,8 @@ void QTextControlPrivate::keyPressEvent(QKeyEvent *e) process: { QString text = e->text(); - if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) { + if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t')) && + ((e->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) == Qt::NoModifier)) { if (overwriteMode // no need to call deleteChar() if we have a selection, insertText // does it already diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index c7f3e97..d1067a8 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -2169,7 +2169,8 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) if (unknown && !d->readOnly) { QString t = event->text(); - if (!t.isEmpty() && t.at(0).isPrint()) { + if (!t.isEmpty() && t.at(0).isPrint() && + ((event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) == Qt::NoModifier)) { insert(t); #ifndef QT_NO_COMPLETER d->complete(event->key()); -- cgit v0.12 From 60e965fd35037f4a27816d2aeccafdff0d6ae9d6 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 15 Jun 2009 16:00:46 +0200 Subject: Refactored gesture api Rewritten the api almost from scratch, making it simplier and more flexible at the same time. The current implementation will not have complex gseturemanager class inside Qt, but the QGesture base class, which represents both a gesture recognizer and a gesture itself with a set of properties. A set of common gestures that can use used in third-party applications (and in Qt itself internally) is supposed to be found in qstandardgestures.h, and a base class for user-defined gestures is in qgesture.h Gesture implementation for Pan on Windows7 has also been added as a reference implementation for platform gestures. --- doc/src/qnamespace.qdoc | 38 +- examples/gestures/browser/Info_mac.plist | 43 - examples/gestures/browser/addbookmarkdialog.ui | 98 -- examples/gestures/browser/autosaver.cpp | 94 -- examples/gestures/browser/autosaver.h | 76 -- examples/gestures/browser/bookmarks.cpp | 987 --------------- examples/gestures/browser/bookmarks.h | 310 ----- examples/gestures/browser/bookmarks.ui | 106 -- examples/gestures/browser/browser.icns | Bin 50218 -> 0 bytes examples/gestures/browser/browser.ico | Bin 15374 -> 0 bytes examples/gestures/browser/browser.pro | 91 -- examples/gestures/browser/browser.rc | 2 - examples/gestures/browser/browserapplication.cpp | 447 ------- examples/gestures/browser/browserapplication.h | 119 -- examples/gestures/browser/browsermainwindow.cpp | 991 --------------- examples/gestures/browser/browsermainwindow.h | 169 --- examples/gestures/browser/chasewidget.cpp | 142 --- examples/gestures/browser/chasewidget.h | 85 -- examples/gestures/browser/cookiejar.cpp | 733 ----------- examples/gestures/browser/cookiejar.h | 204 ---- examples/gestures/browser/cookies.ui | 106 -- examples/gestures/browser/cookiesexceptions.ui | 184 --- examples/gestures/browser/data/addtab.png | Bin 469 -> 0 bytes examples/gestures/browser/data/browser.svg | 411 ------- examples/gestures/browser/data/closetab.png | Bin 516 -> 0 bytes examples/gestures/browser/data/data.qrc | 11 - .../gestures/browser/data/defaultbookmarks.xbel | 40 - examples/gestures/browser/data/defaulticon.png | Bin 1473 -> 0 bytes examples/gestures/browser/data/history.png | Bin 1527 -> 0 bytes examples/gestures/browser/data/loading.gif | Bin 847 -> 0 bytes examples/gestures/browser/downloaditem.ui | 134 -- examples/gestures/browser/downloadmanager.cpp | 579 --------- examples/gestures/browser/downloadmanager.h | 162 --- examples/gestures/browser/downloads.ui | 83 -- examples/gestures/browser/edittableview.cpp | 78 -- examples/gestures/browser/edittableview.h | 61 - examples/gestures/browser/edittreeview.cpp | 77 -- examples/gestures/browser/edittreeview.h | 61 - examples/gestures/browser/history.cpp | 1282 -------------------- examples/gestures/browser/history.h | 350 ------ examples/gestures/browser/history.ui | 106 -- examples/gestures/browser/htmls/htmls.qrc | 5 - examples/gestures/browser/htmls/notfound.html | 63 - examples/gestures/browser/main.cpp | 53 - examples/gestures/browser/modelmenu.cpp | 227 ---- examples/gestures/browser/modelmenu.h | 105 -- examples/gestures/browser/networkaccessmanager.cpp | 171 --- examples/gestures/browser/networkaccessmanager.h | 68 -- examples/gestures/browser/passworddialog.ui | 111 -- examples/gestures/browser/proxy.ui | 104 -- examples/gestures/browser/searchlineedit.cpp | 238 ---- examples/gestures/browser/searchlineedit.h | 103 -- examples/gestures/browser/settings.cpp | 324 ----- examples/gestures/browser/settings.h | 74 -- examples/gestures/browser/settings.ui | 614 ---------- examples/gestures/browser/squeezelabel.cpp | 61 - examples/gestures/browser/squeezelabel.h | 60 - examples/gestures/browser/tabwidget.cpp | 830 ------------- examples/gestures/browser/tabwidget.h | 224 ---- examples/gestures/browser/toolbarsearch.cpp | 161 --- examples/gestures/browser/toolbarsearch.h | 84 -- examples/gestures/browser/urllineedit.cpp | 340 ------ examples/gestures/browser/urllineedit.h | 115 -- examples/gestures/browser/webview.cpp | 363 ------ examples/gestures/browser/webview.h | 124 -- examples/gestures/browser/xbel.cpp | 320 ----- examples/gestures/browser/xbel.h | 113 -- examples/gestures/collidingmice/collidingmice.pro | 18 - .../collidingmice/gesturerecognizerlinjazax.cpp | 213 ---- .../collidingmice/gesturerecognizerlinjazax.h | 106 -- examples/gestures/collidingmice/images/cheese.jpg | Bin 3029 -> 0 bytes examples/gestures/collidingmice/linjazaxgesture.h | 102 -- examples/gestures/collidingmice/main.cpp | 163 --- examples/gestures/collidingmice/mice.qrc | 5 - examples/gestures/collidingmice/mouse.cpp | 200 --- examples/gestures/collidingmice/mouse.h | 72 -- examples/gestures/gestures.pro | 9 +- examples/gestures/graphicsview/graphicsview.pro | 2 - examples/gestures/graphicsview/main.cpp | 150 --- examples/gestures/imageviewer/imagewidget.cpp | 79 +- examples/gestures/imageviewer/imagewidget.h | 14 +- examples/gestures/pannablewebview/main.cpp | 90 -- .../gestures/pannablewebview/pannablewebview.pro | 4 - src/corelib/global/qnamespace.h | 29 - src/corelib/kernel/qcoreevent.cpp | 3 +- src/corelib/kernel/qcoreevent.h | 3 +- src/gui/graphicsview/qgraphicsitem.cpp | 119 -- src/gui/graphicsview/qgraphicsitem.h | 5 - src/gui/graphicsview/qgraphicsitem_p.h | 33 +- src/gui/graphicsview/qgraphicsproxywidget.cpp | 13 - src/gui/graphicsview/qgraphicsscene.cpp | 127 -- src/gui/graphicsview/qgraphicsscene.h | 1 - src/gui/graphicsview/qgraphicsscene_p.h | 8 - src/gui/graphicsview/qgraphicssceneevent.cpp | 249 ---- src/gui/graphicsview/qgraphicssceneevent.h | 43 - src/gui/graphicsview/qgraphicsview.cpp | 14 - src/gui/kernel/kernel.pri | 13 +- src/gui/kernel/qapplication.cpp | 84 +- src/gui/kernel/qapplication.h | 9 - src/gui/kernel/qapplication_p.h | 121 +- src/gui/kernel/qapplication_win.cpp | 89 ++ src/gui/kernel/qdirectionrecognizer.cpp | 182 --- src/gui/kernel/qdirectionrecognizer_p.h | 105 -- src/gui/kernel/qdirectionsimplificator_p.h | 172 --- src/gui/kernel/qevent.cpp | 156 --- src/gui/kernel/qevent.h | 35 - src/gui/kernel/qevent_p.h | 16 + src/gui/kernel/qgesture.cpp | 308 ++--- src/gui/kernel/qgesture.h | 82 +- src/gui/kernel/qgesture_p.h | 35 +- src/gui/kernel/qgesturemanager.cpp | 644 ---------- src/gui/kernel/qgesturemanager_p.h | 126 -- src/gui/kernel/qgesturerecognizer.cpp | 160 --- src/gui/kernel/qgesturerecognizer.h | 87 -- src/gui/kernel/qgesturerecognizer_p.h | 72 -- src/gui/kernel/qgesturestandardrecognizers.cpp | 306 ----- src/gui/kernel/qgesturestandardrecognizers_p.h | 131 -- src/gui/kernel/qstandardgestures.cpp | 254 ++++ src/gui/kernel/qstandardgestures.h | 102 ++ src/gui/kernel/qstandardgestures_p.h | 91 ++ src/gui/kernel/qwidget.cpp | 163 +-- src/gui/kernel/qwidget.h | 7 - src/gui/kernel/qwidget_p.h | 5 - src/gui/widgets/qabstractscrollarea.cpp | 34 +- src/gui/widgets/qabstractscrollarea_p.h | 5 + src/gui/widgets/qplaintextedit.cpp | 32 + src/gui/widgets/qplaintextedit.h | 1 + src/gui/widgets/qplaintextedit_p.h | 5 + src/gui/widgets/qtextedit.cpp | 26 + src/gui/widgets/qtextedit.h | 1 + src/gui/widgets/qtextedit_p.h | 5 +- tests/auto/gestures/tst_gestures.cpp | 29 +- 132 files changed, 1091 insertions(+), 17991 deletions(-) delete mode 100644 examples/gestures/browser/Info_mac.plist delete mode 100644 examples/gestures/browser/addbookmarkdialog.ui delete mode 100644 examples/gestures/browser/autosaver.cpp delete mode 100644 examples/gestures/browser/autosaver.h delete mode 100644 examples/gestures/browser/bookmarks.cpp delete mode 100644 examples/gestures/browser/bookmarks.h delete mode 100644 examples/gestures/browser/bookmarks.ui delete mode 100644 examples/gestures/browser/browser.icns delete mode 100644 examples/gestures/browser/browser.ico delete mode 100644 examples/gestures/browser/browser.pro delete mode 100644 examples/gestures/browser/browser.rc delete mode 100644 examples/gestures/browser/browserapplication.cpp delete mode 100644 examples/gestures/browser/browserapplication.h delete mode 100644 examples/gestures/browser/browsermainwindow.cpp delete mode 100644 examples/gestures/browser/browsermainwindow.h delete mode 100644 examples/gestures/browser/chasewidget.cpp delete mode 100644 examples/gestures/browser/chasewidget.h delete mode 100644 examples/gestures/browser/cookiejar.cpp delete mode 100644 examples/gestures/browser/cookiejar.h delete mode 100644 examples/gestures/browser/cookies.ui delete mode 100644 examples/gestures/browser/cookiesexceptions.ui delete mode 100644 examples/gestures/browser/data/addtab.png delete mode 100644 examples/gestures/browser/data/browser.svg delete mode 100644 examples/gestures/browser/data/closetab.png delete mode 100644 examples/gestures/browser/data/data.qrc delete mode 100644 examples/gestures/browser/data/defaultbookmarks.xbel delete mode 100644 examples/gestures/browser/data/defaulticon.png delete mode 100644 examples/gestures/browser/data/history.png delete mode 100644 examples/gestures/browser/data/loading.gif delete mode 100644 examples/gestures/browser/downloaditem.ui delete mode 100644 examples/gestures/browser/downloadmanager.cpp delete mode 100644 examples/gestures/browser/downloadmanager.h delete mode 100644 examples/gestures/browser/downloads.ui delete mode 100644 examples/gestures/browser/edittableview.cpp delete mode 100644 examples/gestures/browser/edittableview.h delete mode 100644 examples/gestures/browser/edittreeview.cpp delete mode 100644 examples/gestures/browser/edittreeview.h delete mode 100644 examples/gestures/browser/history.cpp delete mode 100644 examples/gestures/browser/history.h delete mode 100644 examples/gestures/browser/history.ui delete mode 100644 examples/gestures/browser/htmls/htmls.qrc delete mode 100644 examples/gestures/browser/htmls/notfound.html delete mode 100644 examples/gestures/browser/main.cpp delete mode 100644 examples/gestures/browser/modelmenu.cpp delete mode 100644 examples/gestures/browser/modelmenu.h delete mode 100644 examples/gestures/browser/networkaccessmanager.cpp delete mode 100644 examples/gestures/browser/networkaccessmanager.h delete mode 100644 examples/gestures/browser/passworddialog.ui delete mode 100644 examples/gestures/browser/proxy.ui delete mode 100644 examples/gestures/browser/searchlineedit.cpp delete mode 100644 examples/gestures/browser/searchlineedit.h delete mode 100644 examples/gestures/browser/settings.cpp delete mode 100644 examples/gestures/browser/settings.h delete mode 100644 examples/gestures/browser/settings.ui delete mode 100644 examples/gestures/browser/squeezelabel.cpp delete mode 100644 examples/gestures/browser/squeezelabel.h delete mode 100644 examples/gestures/browser/tabwidget.cpp delete mode 100644 examples/gestures/browser/tabwidget.h delete mode 100644 examples/gestures/browser/toolbarsearch.cpp delete mode 100644 examples/gestures/browser/toolbarsearch.h delete mode 100644 examples/gestures/browser/urllineedit.cpp delete mode 100644 examples/gestures/browser/urllineedit.h delete mode 100644 examples/gestures/browser/webview.cpp delete mode 100644 examples/gestures/browser/webview.h delete mode 100644 examples/gestures/browser/xbel.cpp delete mode 100644 examples/gestures/browser/xbel.h delete mode 100644 examples/gestures/collidingmice/collidingmice.pro delete mode 100644 examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp delete mode 100644 examples/gestures/collidingmice/gesturerecognizerlinjazax.h delete mode 100644 examples/gestures/collidingmice/images/cheese.jpg delete mode 100644 examples/gestures/collidingmice/linjazaxgesture.h delete mode 100644 examples/gestures/collidingmice/main.cpp delete mode 100644 examples/gestures/collidingmice/mice.qrc delete mode 100644 examples/gestures/collidingmice/mouse.cpp delete mode 100644 examples/gestures/collidingmice/mouse.h delete mode 100644 examples/gestures/graphicsview/graphicsview.pro delete mode 100644 examples/gestures/graphicsview/main.cpp delete mode 100644 examples/gestures/pannablewebview/main.cpp delete mode 100644 examples/gestures/pannablewebview/pannablewebview.pro delete mode 100644 src/gui/kernel/qdirectionrecognizer.cpp delete mode 100644 src/gui/kernel/qdirectionrecognizer_p.h delete mode 100644 src/gui/kernel/qdirectionsimplificator_p.h delete mode 100644 src/gui/kernel/qgesturemanager.cpp delete mode 100644 src/gui/kernel/qgesturemanager_p.h delete mode 100644 src/gui/kernel/qgesturerecognizer.cpp delete mode 100644 src/gui/kernel/qgesturerecognizer.h delete mode 100644 src/gui/kernel/qgesturerecognizer_p.h delete mode 100644 src/gui/kernel/qgesturestandardrecognizers.cpp delete mode 100644 src/gui/kernel/qgesturestandardrecognizers_p.h create mode 100644 src/gui/kernel/qstandardgestures.cpp create mode 100644 src/gui/kernel/qstandardgestures.h create mode 100644 src/gui/kernel/qstandardgestures_p.h diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index e77cc7e..b691ac7 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -2700,20 +2700,6 @@ \internal */ -/*! \enum Qt::GestureType - \since 4.6 - - This enum lists standard gestures. - - \value UnknownGesture An unknown gesture. This enum value shouldn't be used. - \value TapGesture A single tap gesture. - \value DoubleTapGesture A double tap gesture. - \value TrippleTapGesture A tripple tap gesture. - \value TapAndHoldGesture A tap-and-hold (long tap) gesture. - \value PanGesture A pan gesture. - \value PinchGesture A pinch gesture. -*/ - /*! \enum Qt::GestureState \since 4.6 @@ -2722,30 +2708,8 @@ \omitvalue NoGesture \value GestureStarted A continuous gesture has started. - \value GestureUpdated A gesture continiues. + \value GestureUpdated A gesture continues. \value GestureFinished A gesture has finished. \sa QGesture */ - -/*! - \enum Qt::DirectionType - \since 4.6 - - This enum type describes directions. This could be used by the - gesture recognizers. - - \value NoDirection Non-specific direction. - \value LeftDownDirection - \value DownLeftDirection - \value DownDirection - \value RightDownDirection - \value DownRightDirection - \value LeftDirection - \value RightDirection - \value LeftUpDirection - \value UpLeftDirection - \value UpDirection - \value RightUpDirection - \value UpRightDirection -*/ diff --git a/examples/gestures/browser/Info_mac.plist b/examples/gestures/browser/Info_mac.plist deleted file mode 100644 index 5648631..0000000 --- a/examples/gestures/browser/Info_mac.plist +++ /dev/null @@ -1,43 +0,0 @@ - - - - - CFBundleIconFile - @ICON@ - CFBundlePackageType - APPL - CFBundleGetInfoString - Created by Qt/QMake - CFBundleIdentifier - com.trolltech.DemoBrowser - CFBundleSignature - ttxt - CFBundleExecutable - @EXECUTABLE@ - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - html - htm - shtml - xht - xhtml - - CFBundleTypeIconFile - @ICON@ - CFBundleTypeName - HTML Document - CFBundleTypeOSTypes - - HTML - - CFBundleTypeRole - Viewer - - - NOTE - DemoBrowser by Nokia Corporation and/or its subsidiary(-ies) - - diff --git a/examples/gestures/browser/addbookmarkdialog.ui b/examples/gestures/browser/addbookmarkdialog.ui deleted file mode 100644 index 3460d7b..0000000 --- a/examples/gestures/browser/addbookmarkdialog.ui +++ /dev/null @@ -1,98 +0,0 @@ - - AddBookmarkDialog - - - - 0 - 0 - 240 - 168 - - - - Add Bookmark - - - - - - Type a name for the bookmark, and choose where to keep it. - - - Qt::PlainText - - - true - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 2 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - false - - - - - - - - - buttonBox - accepted() - AddBookmarkDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - AddBookmarkDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/examples/gestures/browser/autosaver.cpp b/examples/gestures/browser/autosaver.cpp deleted file mode 100644 index 77888ce..0000000 --- a/examples/gestures/browser/autosaver.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "autosaver.h" - -#include -#include -#include -#include - -#define AUTOSAVE_IN 1000 * 3 // seconds -#define MAXWAIT 1000 * 15 // seconds - -AutoSaver::AutoSaver(QObject *parent) : QObject(parent) -{ - Q_ASSERT(parent); -} - -AutoSaver::~AutoSaver() -{ - if (m_timer.isActive()) - qWarning() << "AutoSaver: still active when destroyed, changes not saved."; -} - -void AutoSaver::changeOccurred() -{ - if (m_firstChange.isNull()) - m_firstChange.start(); - - if (m_firstChange.elapsed() > MAXWAIT) { - saveIfNeccessary(); - } else { - m_timer.start(AUTOSAVE_IN, this); - } -} - -void AutoSaver::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == m_timer.timerId()) { - saveIfNeccessary(); - } else { - QObject::timerEvent(event); - } -} - -void AutoSaver::saveIfNeccessary() -{ - if (!m_timer.isActive()) - return; - m_timer.stop(); - m_firstChange = QTime(); - if (!QMetaObject::invokeMethod(parent(), "save", Qt::DirectConnection)) { - qWarning() << "AutoSaver: error invoking slot save() on parent"; - } -} - diff --git a/examples/gestures/browser/autosaver.h b/examples/gestures/browser/autosaver.h deleted file mode 100644 index e6b44ed..0000000 --- a/examples/gestures/browser/autosaver.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef AUTOSAVER_H -#define AUTOSAVER_H - -#include -#include -#include - -/* - This class will call the save() slot on the parent object when the parent changes. - It will wait several seconds after changed() to combining multiple changes and - prevent continuous writing to disk. - */ -class AutoSaver : public QObject { - -Q_OBJECT - -public: - AutoSaver(QObject *parent); - ~AutoSaver(); - void saveIfNeccessary(); - -public slots: - void changeOccurred(); - -protected: - void timerEvent(QTimerEvent *event); - -private: - QBasicTimer m_timer; - QTime m_firstChange; - -}; - -#endif // AUTOSAVER_H - diff --git a/examples/gestures/browser/bookmarks.cpp b/examples/gestures/browser/bookmarks.cpp deleted file mode 100644 index 125bcbe..0000000 --- a/examples/gestures/browser/bookmarks.cpp +++ /dev/null @@ -1,987 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "bookmarks.h" - -#include "autosaver.h" -#include "browserapplication.h" -#include "history.h" -#include "xbel.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define BOOKMARKBAR "Bookmarks Bar" -#define BOOKMARKMENU "Bookmarks Menu" - -BookmarksManager::BookmarksManager(QObject *parent) - : QObject(parent) - , m_loaded(false) - , m_saveTimer(new AutoSaver(this)) - , m_bookmarkRootNode(0) - , m_bookmarkModel(0) -{ - connect(this, SIGNAL(entryAdded(BookmarkNode *)), - m_saveTimer, SLOT(changeOccurred())); - connect(this, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)), - m_saveTimer, SLOT(changeOccurred())); - connect(this, SIGNAL(entryChanged(BookmarkNode *)), - m_saveTimer, SLOT(changeOccurred())); -} - -BookmarksManager::~BookmarksManager() -{ - m_saveTimer->saveIfNeccessary(); -} - -void BookmarksManager::changeExpanded() -{ - m_saveTimer->changeOccurred(); -} - -void BookmarksManager::load() -{ - if (m_loaded) - return; - m_loaded = true; - - QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel"); - if (!QFile::exists(bookmarkFile)) - bookmarkFile = QLatin1String(":defaultbookmarks.xbel"); - - XbelReader reader; - m_bookmarkRootNode = reader.read(bookmarkFile); - if (reader.error() != QXmlStreamReader::NoError) { - QMessageBox::warning(0, QLatin1String("Loading Bookmark"), - tr("Error when loading bookmarks on line %1, column %2:\n" - "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString())); - } - - BookmarkNode *toolbar = 0; - BookmarkNode *menu = 0; - QList others; - for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { - BookmarkNode *node = m_bookmarkRootNode->children().at(i); - if (node->type() == BookmarkNode::Folder) { - // Automatically convert - if (node->title == tr("Toolbar Bookmarks") && !toolbar) { - node->title = tr(BOOKMARKBAR); - } - if (node->title == tr(BOOKMARKBAR) && !toolbar) { - toolbar = node; - } - - // Automatically convert - if (node->title == tr("Menu") && !menu) { - node->title = tr(BOOKMARKMENU); - } - if (node->title == tr(BOOKMARKMENU) && !menu) { - menu = node; - } - } else { - others.append(node); - } - m_bookmarkRootNode->remove(node); - } - Q_ASSERT(m_bookmarkRootNode->children().count() == 0); - if (!toolbar) { - toolbar = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode); - toolbar->title = tr(BOOKMARKBAR); - } else { - m_bookmarkRootNode->add(toolbar); - } - - if (!menu) { - menu = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode); - menu->title = tr(BOOKMARKMENU); - } else { - m_bookmarkRootNode->add(menu); - } - - for (int i = 0; i < others.count(); ++i) - menu->add(others.at(i)); -} - -void BookmarksManager::save() const -{ - if (!m_loaded) - return; - - XbelWriter writer; - QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel"); - if (!writer.write(bookmarkFile, m_bookmarkRootNode)) - qWarning() << "BookmarkManager: error saving to" << bookmarkFile; -} - -void BookmarksManager::addBookmark(BookmarkNode *parent, BookmarkNode *node, int row) -{ - if (!m_loaded) - return; - Q_ASSERT(parent); - InsertBookmarksCommand *command = new InsertBookmarksCommand(this, parent, node, row); - m_commands.push(command); -} - -void BookmarksManager::removeBookmark(BookmarkNode *node) -{ - if (!m_loaded) - return; - - Q_ASSERT(node); - BookmarkNode *parent = node->parent(); - int row = parent->children().indexOf(node); - RemoveBookmarksCommand *command = new RemoveBookmarksCommand(this, parent, row); - m_commands.push(command); -} - -void BookmarksManager::setTitle(BookmarkNode *node, const QString &newTitle) -{ - if (!m_loaded) - return; - - Q_ASSERT(node); - ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newTitle, true); - m_commands.push(command); -} - -void BookmarksManager::setUrl(BookmarkNode *node, const QString &newUrl) -{ - if (!m_loaded) - return; - - Q_ASSERT(node); - ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newUrl, false); - m_commands.push(command); -} - -BookmarkNode *BookmarksManager::bookmarks() -{ - if (!m_loaded) - load(); - return m_bookmarkRootNode; -} - -BookmarkNode *BookmarksManager::menu() -{ - if (!m_loaded) - load(); - - for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { - BookmarkNode *node = m_bookmarkRootNode->children().at(i); - if (node->title == tr(BOOKMARKMENU)) - return node; - } - Q_ASSERT(false); - return 0; -} - -BookmarkNode *BookmarksManager::toolbar() -{ - if (!m_loaded) - load(); - - for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { - BookmarkNode *node = m_bookmarkRootNode->children().at(i); - if (node->title == tr(BOOKMARKBAR)) - return node; - } - Q_ASSERT(false); - return 0; -} - -BookmarksModel *BookmarksManager::bookmarksModel() -{ - if (!m_bookmarkModel) - m_bookmarkModel = new BookmarksModel(this, this); - return m_bookmarkModel; -} - -void BookmarksManager::importBookmarks() -{ - QString fileName = QFileDialog::getOpenFileName(0, tr("Open File"), - QString(), - tr("XBEL (*.xbel *.xml)")); - if (fileName.isEmpty()) - return; - - XbelReader reader; - BookmarkNode *importRootNode = reader.read(fileName); - if (reader.error() != QXmlStreamReader::NoError) { - QMessageBox::warning(0, QLatin1String("Loading Bookmark"), - tr("Error when loading bookmarks on line %1, column %2:\n" - "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString())); - } - - importRootNode->setType(BookmarkNode::Folder); - importRootNode->title = (tr("Imported %1").arg(QDate::currentDate().toString(Qt::SystemLocaleShortDate))); - addBookmark(menu(), importRootNode); -} - -void BookmarksManager::exportBookmarks() -{ - QString fileName = QFileDialog::getSaveFileName(0, tr("Save File"), - tr("%1 Bookmarks.xbel").arg(QCoreApplication::applicationName()), - tr("XBEL (*.xbel *.xml)")); - if (fileName.isEmpty()) - return; - - XbelWriter writer; - if (!writer.write(fileName, m_bookmarkRootNode)) - QMessageBox::critical(0, tr("Export error"), tr("error saving bookmarks")); -} - -RemoveBookmarksCommand::RemoveBookmarksCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *parent, int row) - : QUndoCommand(BookmarksManager::tr("Remove Bookmark")) - , m_row(row) - , m_bookmarkManagaer(m_bookmarkManagaer) - , m_node(parent->children().value(row)) - , m_parent(parent) - , m_done(false) -{ -} - -RemoveBookmarksCommand::~RemoveBookmarksCommand() -{ - if (m_done && !m_node->parent()) { - delete m_node; - } -} - -void RemoveBookmarksCommand::undo() -{ - m_parent->add(m_node, m_row); - emit m_bookmarkManagaer->entryAdded(m_node); - m_done = false; -} - -void RemoveBookmarksCommand::redo() -{ - m_parent->remove(m_node); - emit m_bookmarkManagaer->entryRemoved(m_parent, m_row, m_node); - m_done = true; -} - -InsertBookmarksCommand::InsertBookmarksCommand(BookmarksManager *m_bookmarkManagaer, - BookmarkNode *parent, BookmarkNode *node, int row) - : RemoveBookmarksCommand(m_bookmarkManagaer, parent, row) -{ - setText(BookmarksManager::tr("Insert Bookmark")); - m_node = node; -} - -ChangeBookmarkCommand::ChangeBookmarkCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *node, - const QString &newValue, bool title) - : QUndoCommand() - , m_bookmarkManagaer(m_bookmarkManagaer) - , m_title(title) - , m_newValue(newValue) - , m_node(node) -{ - if (m_title) { - m_oldValue = m_node->title; - setText(BookmarksManager::tr("Name Change")); - } else { - m_oldValue = m_node->url; - setText(BookmarksManager::tr("Address Change")); - } -} - -void ChangeBookmarkCommand::undo() -{ - if (m_title) - m_node->title = m_oldValue; - else - m_node->url = m_oldValue; - emit m_bookmarkManagaer->entryChanged(m_node); -} - -void ChangeBookmarkCommand::redo() -{ - if (m_title) - m_node->title = m_newValue; - else - m_node->url = m_newValue; - emit m_bookmarkManagaer->entryChanged(m_node); -} - -BookmarksModel::BookmarksModel(BookmarksManager *bookmarkManager, QObject *parent) - : QAbstractItemModel(parent) - , m_endMacro(false) - , m_bookmarksManager(bookmarkManager) -{ - connect(bookmarkManager, SIGNAL(entryAdded(BookmarkNode *)), - this, SLOT(entryAdded(BookmarkNode *))); - connect(bookmarkManager, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)), - this, SLOT(entryRemoved(BookmarkNode *, int, BookmarkNode *))); - connect(bookmarkManager, SIGNAL(entryChanged(BookmarkNode *)), - this, SLOT(entryChanged(BookmarkNode *))); -} - -QModelIndex BookmarksModel::index(BookmarkNode *node) const -{ - BookmarkNode *parent = node->parent(); - if (!parent) - return QModelIndex(); - return createIndex(parent->children().indexOf(node), 0, node); -} - -void BookmarksModel::entryAdded(BookmarkNode *item) -{ - Q_ASSERT(item && item->parent()); - int row = item->parent()->children().indexOf(item); - BookmarkNode *parent = item->parent(); - // item was already added so remove beore beginInsertRows is called - parent->remove(item); - beginInsertRows(index(parent), row, row); - parent->add(item, row); - endInsertRows(); -} - -void BookmarksModel::entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item) -{ - // item was already removed, re-add so beginRemoveRows works - parent->add(item, row); - beginRemoveRows(index(parent), row, row); - parent->remove(item); - endRemoveRows(); -} - -void BookmarksModel::entryChanged(BookmarkNode *item) -{ - QModelIndex idx = index(item); - emit dataChanged(idx, idx); -} - -bool BookmarksModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (row < 0 || count <= 0 || row + count > rowCount(parent)) - return false; - - BookmarkNode *bookmarkNode = node(parent); - for (int i = row + count - 1; i >= row; --i) { - BookmarkNode *node = bookmarkNode->children().at(i); - if (node == m_bookmarksManager->menu() - || node == m_bookmarksManager->toolbar()) - continue; - - m_bookmarksManager->removeBookmark(node); - } - if (m_endMacro) { - m_bookmarksManager->undoRedoStack()->endMacro(); - m_endMacro = false; - } - return true; -} - -QVariant BookmarksModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - switch (section) { - case 0: return tr("Title"); - case 1: return tr("Address"); - } - } - return QAbstractItemModel::headerData(section, orientation, role); -} - -QVariant BookmarksModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.model() != this) - return QVariant(); - - const BookmarkNode *bookmarkNode = node(index); - switch (role) { - case Qt::EditRole: - case Qt::DisplayRole: - if (bookmarkNode->type() == BookmarkNode::Separator) { - switch (index.column()) { - case 0: return QString(50, 0xB7); - case 1: return QString(); - } - } - - switch (index.column()) { - case 0: return bookmarkNode->title; - case 1: return bookmarkNode->url; - } - break; - case BookmarksModel::UrlRole: - return QUrl(bookmarkNode->url); - break; - case BookmarksModel::UrlStringRole: - return bookmarkNode->url; - break; - case BookmarksModel::TypeRole: - return bookmarkNode->type(); - break; - case BookmarksModel::SeparatorRole: - return (bookmarkNode->type() == BookmarkNode::Separator); - break; - case Qt::DecorationRole: - if (index.column() == 0) { - if (bookmarkNode->type() == BookmarkNode::Folder) - return QApplication::style()->standardIcon(QStyle::SP_DirIcon); - return BrowserApplication::instance()->icon(bookmarkNode->url); - } - } - - return QVariant(); -} - -int BookmarksModel::columnCount(const QModelIndex &parent) const -{ - return (parent.column() > 0) ? 0 : 2; -} - -int BookmarksModel::rowCount(const QModelIndex &parent) const -{ - if (parent.column() > 0) - return 0; - - if (!parent.isValid()) - return m_bookmarksManager->bookmarks()->children().count(); - - const BookmarkNode *item = static_cast(parent.internalPointer()); - return item->children().count(); -} - -QModelIndex BookmarksModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 || column < 0 || row >= rowCount(parent) || column >= columnCount(parent)) - return QModelIndex(); - - // get the parent node - BookmarkNode *parentNode = node(parent); - return createIndex(row, column, parentNode->children().at(row)); -} - -QModelIndex BookmarksModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - BookmarkNode *itemNode = node(index); - BookmarkNode *parentNode = (itemNode ? itemNode->parent() : 0); - if (!parentNode || parentNode == m_bookmarksManager->bookmarks()) - return QModelIndex(); - - // get the parent's row - BookmarkNode *grandParentNode = parentNode->parent(); - int parentRow = grandParentNode->children().indexOf(parentNode); - Q_ASSERT(parentRow >= 0); - return createIndex(parentRow, 0, parentNode); -} - -bool BookmarksModel::hasChildren(const QModelIndex &parent) const -{ - if (!parent.isValid()) - return true; - const BookmarkNode *parentNode = node(parent); - return (parentNode->type() == BookmarkNode::Folder); -} - -Qt::ItemFlags BookmarksModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::NoItemFlags; - - Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - - BookmarkNode *bookmarkNode = node(index); - - if (bookmarkNode != m_bookmarksManager->menu() - && bookmarkNode != m_bookmarksManager->toolbar()) { - flags |= Qt::ItemIsDragEnabled; - if (bookmarkNode->type() != BookmarkNode::Separator) - flags |= Qt::ItemIsEditable; - } - if (hasChildren(index)) - flags |= Qt::ItemIsDropEnabled; - return flags; -} - -Qt::DropActions BookmarksModel::supportedDropActions () const -{ - return Qt::CopyAction | Qt::MoveAction; -} - -#define MIMETYPE QLatin1String("application/bookmarks.xbel") - -QStringList BookmarksModel::mimeTypes() const -{ - QStringList types; - types << MIMETYPE; - return types; -} - -QMimeData *BookmarksModel::mimeData(const QModelIndexList &indexes) const -{ - QMimeData *mimeData = new QMimeData(); - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - foreach (QModelIndex index, indexes) { - if (index.column() != 0 || !index.isValid()) - continue; - QByteArray encodedData; - QBuffer buffer(&encodedData); - buffer.open(QBuffer::ReadWrite); - XbelWriter writer; - const BookmarkNode *parentNode = node(index); - writer.write(&buffer, parentNode); - stream << encodedData; - } - mimeData->setData(MIMETYPE, data); - return mimeData; -} - -bool BookmarksModel::dropMimeData(const QMimeData *data, - Qt::DropAction action, int row, int column, const QModelIndex &parent) -{ - if (action == Qt::IgnoreAction) - return true; - - if (!data->hasFormat(MIMETYPE) - || column > 0) - return false; - - QByteArray ba = data->data(MIMETYPE); - QDataStream stream(&ba, QIODevice::ReadOnly); - if (stream.atEnd()) - return false; - - QUndoStack *undoStack = m_bookmarksManager->undoRedoStack(); - undoStack->beginMacro(QLatin1String("Move Bookmarks")); - - while (!stream.atEnd()) { - QByteArray encodedData; - stream >> encodedData; - QBuffer buffer(&encodedData); - buffer.open(QBuffer::ReadOnly); - - XbelReader reader; - BookmarkNode *rootNode = reader.read(&buffer); - QList children = rootNode->children(); - for (int i = 0; i < children.count(); ++i) { - BookmarkNode *bookmarkNode = children.at(i); - rootNode->remove(bookmarkNode); - row = qMax(0, row); - BookmarkNode *parentNode = node(parent); - m_bookmarksManager->addBookmark(parentNode, bookmarkNode, row); - m_endMacro = true; - } - delete rootNode; - } - return true; -} - -bool BookmarksModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid() || (flags(index) & Qt::ItemIsEditable) == 0) - return false; - - BookmarkNode *item = node(index); - - switch (role) { - case Qt::EditRole: - case Qt::DisplayRole: - if (index.column() == 0) { - m_bookmarksManager->setTitle(item, value.toString()); - break; - } - if (index.column() == 1) { - m_bookmarksManager->setUrl(item, value.toString()); - break; - } - return false; - case BookmarksModel::UrlRole: - m_bookmarksManager->setUrl(item, value.toUrl().toString()); - break; - case BookmarksModel::UrlStringRole: - m_bookmarksManager->setUrl(item, value.toString()); - break; - default: - break; - return false; - } - - return true; -} - -BookmarkNode *BookmarksModel::node(const QModelIndex &index) const -{ - BookmarkNode *itemNode = static_cast(index.internalPointer()); - if (!itemNode) - return m_bookmarksManager->bookmarks(); - return itemNode; -} - - -AddBookmarkProxyModel::AddBookmarkProxyModel(QObject *parent) - : QSortFilterProxyModel(parent) -{ -} - -int AddBookmarkProxyModel::columnCount(const QModelIndex &parent) const -{ - return qMin(1, QSortFilterProxyModel::columnCount(parent)); -} - -bool AddBookmarkProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const -{ - QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); - return sourceModel()->hasChildren(idx); -} - -AddBookmarkDialog::AddBookmarkDialog(const QString &url, const QString &title, QWidget *parent, BookmarksManager *bookmarkManager) - : QDialog(parent) - , m_url(url) - , m_bookmarksManager(bookmarkManager) -{ - setWindowFlags(Qt::Sheet); - if (!m_bookmarksManager) - m_bookmarksManager = BrowserApplication::bookmarksManager(); - setupUi(this); - QTreeView *view = new QTreeView(this); - m_proxyModel = new AddBookmarkProxyModel(this); - BookmarksModel *model = m_bookmarksManager->bookmarksModel(); - m_proxyModel->setSourceModel(model); - view->setModel(m_proxyModel); - view->expandAll(); - view->header()->setStretchLastSection(true); - view->header()->hide(); - view->setItemsExpandable(false); - view->setRootIsDecorated(false); - view->setIndentation(10); - location->setModel(m_proxyModel); - view->show(); - location->setView(view); - BookmarkNode *menu = m_bookmarksManager->menu(); - QModelIndex idx = m_proxyModel->mapFromSource(model->index(menu)); - view->setCurrentIndex(idx); - location->setCurrentIndex(idx.row()); - name->setText(title); -} - -void AddBookmarkDialog::accept() -{ - QModelIndex index = location->view()->currentIndex(); - index = m_proxyModel->mapToSource(index); - if (!index.isValid()) - index = m_bookmarksManager->bookmarksModel()->index(0, 0); - BookmarkNode *parent = m_bookmarksManager->bookmarksModel()->node(index); - BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark); - bookmark->url = m_url; - bookmark->title = name->text(); - m_bookmarksManager->addBookmark(parent, bookmark); - QDialog::accept(); -} - -BookmarksMenu::BookmarksMenu(QWidget *parent) - : ModelMenu(parent) - , m_bookmarksManager(0) -{ - connect(this, SIGNAL(activated(const QModelIndex &)), - this, SLOT(activated(const QModelIndex &))); - setMaxRows(-1); - setHoverRole(BookmarksModel::UrlStringRole); - setSeparatorRole(BookmarksModel::SeparatorRole); -} - -void BookmarksMenu::activated(const QModelIndex &index) -{ - emit openUrl(index.data(BookmarksModel::UrlRole).toUrl()); -} - -bool BookmarksMenu::prePopulated() -{ - m_bookmarksManager = BrowserApplication::bookmarksManager(); - setModel(m_bookmarksManager->bookmarksModel()); - setRootIndex(m_bookmarksManager->bookmarksModel()->index(1, 0)); - // initial actions - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); - if (!m_initialActions.isEmpty()) - addSeparator(); - createMenu(model()->index(0, 0), 1, this); - return true; -} - -void BookmarksMenu::setInitialActions(QList actions) -{ - m_initialActions = actions; - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); -} - -BookmarksDialog::BookmarksDialog(QWidget *parent, BookmarksManager *manager) - : QDialog(parent) -{ - m_bookmarksManager = manager; - if (!m_bookmarksManager) - m_bookmarksManager = BrowserApplication::bookmarksManager(); - setupUi(this); - - tree->setUniformRowHeights(true); - tree->setSelectionBehavior(QAbstractItemView::SelectRows); - tree->setSelectionMode(QAbstractItemView::ContiguousSelection); - tree->setTextElideMode(Qt::ElideMiddle); - m_bookmarksModel = m_bookmarksManager->bookmarksModel(); - m_proxyModel = new TreeProxyModel(this); - connect(search, SIGNAL(textChanged(QString)), - m_proxyModel, SLOT(setFilterFixedString(QString))); - connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeOne())); - m_proxyModel->setSourceModel(m_bookmarksModel); - tree->setModel(m_proxyModel); - tree->setDragDropMode(QAbstractItemView::InternalMove); - tree->setExpanded(m_proxyModel->index(0, 0), true); - tree->setAlternatingRowColors(true); - QFontMetrics fm(font()); - int header = fm.width(QLatin1Char('m')) * 40; - tree->header()->resizeSection(0, header); - tree->header()->setStretchLastSection(true); - connect(tree, SIGNAL(activated(const QModelIndex&)), - this, SLOT(open())); - tree->setContextMenuPolicy(Qt::CustomContextMenu); - connect(tree, SIGNAL(customContextMenuRequested(const QPoint &)), - this, SLOT(customContextMenuRequested(const QPoint &))); - connect(addFolderButton, SIGNAL(clicked()), - this, SLOT(newFolder())); - expandNodes(m_bookmarksManager->bookmarks()); - setAttribute(Qt::WA_DeleteOnClose); -} - -BookmarksDialog::~BookmarksDialog() -{ - if (saveExpandedNodes(tree->rootIndex())) - m_bookmarksManager->changeExpanded(); -} - -bool BookmarksDialog::saveExpandedNodes(const QModelIndex &parent) -{ - bool changed = false; - for (int i = 0; i < m_proxyModel->rowCount(parent); ++i) { - QModelIndex child = m_proxyModel->index(i, 0, parent); - QModelIndex sourceIndex = m_proxyModel->mapToSource(child); - BookmarkNode *childNode = m_bookmarksModel->node(sourceIndex); - bool wasExpanded = childNode->expanded; - if (tree->isExpanded(child)) { - childNode->expanded = true; - changed |= saveExpandedNodes(child); - } else { - childNode->expanded = false; - } - changed |= (wasExpanded != childNode->expanded); - } - return changed; -} - -void BookmarksDialog::expandNodes(BookmarkNode *node) -{ - for (int i = 0; i < node->children().count(); ++i) { - BookmarkNode *childNode = node->children()[i]; - if (childNode->expanded) { - QModelIndex idx = m_bookmarksModel->index(childNode); - idx = m_proxyModel->mapFromSource(idx); - tree->setExpanded(idx, true); - expandNodes(childNode); - } - } -} - -void BookmarksDialog::customContextMenuRequested(const QPoint &pos) -{ - QMenu menu; - QModelIndex index = tree->indexAt(pos); - index = index.sibling(index.row(), 0); - if (index.isValid() && !tree->model()->hasChildren(index)) { - menu.addAction(tr("Open"), this, SLOT(open())); - menu.addSeparator(); - } - menu.addAction(tr("Delete"), tree, SLOT(removeOne())); - menu.exec(QCursor::pos()); -} - -void BookmarksDialog::open() -{ - QModelIndex index = tree->currentIndex(); - if (!index.parent().isValid()) - return; - emit openUrl(index.sibling(index.row(), 1).data(BookmarksModel::UrlRole).toUrl()); -} - -void BookmarksDialog::newFolder() -{ - QModelIndex currentIndex = tree->currentIndex(); - QModelIndex idx = currentIndex; - if (idx.isValid() && !idx.model()->hasChildren(idx)) - idx = idx.parent(); - if (!idx.isValid()) - idx = tree->rootIndex(); - idx = m_proxyModel->mapToSource(idx); - BookmarkNode *parent = m_bookmarksManager->bookmarksModel()->node(idx); - BookmarkNode *node = new BookmarkNode(BookmarkNode::Folder); - node->title = tr("New Folder"); - m_bookmarksManager->addBookmark(parent, node, currentIndex.row() + 1); -} - -BookmarksToolBar::BookmarksToolBar(BookmarksModel *model, QWidget *parent) - : QToolBar(tr("Bookmark"), parent) - , m_bookmarksModel(model) -{ - connect(this, SIGNAL(actionTriggered(QAction*)), this, SLOT(triggered(QAction*))); - setRootIndex(model->index(0, 0)); - connect(m_bookmarksModel, SIGNAL(modelReset()), this, SLOT(build())); - connect(m_bookmarksModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(build())); - connect(m_bookmarksModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(build())); - connect(m_bookmarksModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(build())); - setAcceptDrops(true); -} - -void BookmarksToolBar::dragEnterEvent(QDragEnterEvent *event) -{ - const QMimeData *mimeData = event->mimeData(); - if (mimeData->hasUrls()) - event->acceptProposedAction(); - QToolBar::dragEnterEvent(event); -} - -void BookmarksToolBar::dropEvent(QDropEvent *event) -{ - const QMimeData *mimeData = event->mimeData(); - if (mimeData->hasUrls() && mimeData->hasText()) { - QList urls = mimeData->urls(); - QAction *action = actionAt(event->pos()); - QString dropText; - if (action) - dropText = action->text(); - int row = -1; - QModelIndex parentIndex = m_root; - for (int i = 0; i < m_bookmarksModel->rowCount(m_root); ++i) { - QModelIndex idx = m_bookmarksModel->index(i, 0, m_root); - QString title = idx.data().toString(); - if (title == dropText) { - row = i; - if (m_bookmarksModel->hasChildren(idx)) { - parentIndex = idx; - row = -1; - } - break; - } - } - BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark); - bookmark->url = urls.at(0).toString(); - bookmark->title = mimeData->text(); - - BookmarkNode *parent = m_bookmarksModel->node(parentIndex); - BookmarksManager *bookmarksManager = m_bookmarksModel->bookmarksManager(); - bookmarksManager->addBookmark(parent, bookmark, row); - event->acceptProposedAction(); - } - QToolBar::dropEvent(event); -} - - -void BookmarksToolBar::setRootIndex(const QModelIndex &index) -{ - m_root = index; - build(); -} - -QModelIndex BookmarksToolBar::rootIndex() const -{ - return m_root; -} - -void BookmarksToolBar::build() -{ - clear(); - for (int i = 0; i < m_bookmarksModel->rowCount(m_root); ++i) { - QModelIndex idx = m_bookmarksModel->index(i, 0, m_root); - if (m_bookmarksModel->hasChildren(idx)) { - QToolButton *button = new QToolButton(this); - button->setPopupMode(QToolButton::InstantPopup); - button->setArrowType(Qt::DownArrow); - button->setText(idx.data().toString()); - ModelMenu *menu = new ModelMenu(this); - connect(menu, SIGNAL(activated(const QModelIndex &)), - this, SLOT(activated(const QModelIndex &))); - menu->setModel(m_bookmarksModel); - menu->setRootIndex(idx); - menu->addAction(new QAction(menu)); - button->setMenu(menu); - button->setToolButtonStyle(Qt::ToolButtonTextOnly); - QAction *a = addWidget(button); - a->setText(idx.data().toString()); - } else { - QAction *action = addAction(idx.data().toString()); - action->setData(idx.data(BookmarksModel::UrlRole)); - } - } -} - -void BookmarksToolBar::triggered(QAction *action) -{ - QVariant v = action->data(); - if (v.canConvert()) { - emit openUrl(v.toUrl()); - } -} - -void BookmarksToolBar::activated(const QModelIndex &index) -{ - emit openUrl(index.data(BookmarksModel::UrlRole).toUrl()); -} - diff --git a/examples/gestures/browser/bookmarks.h b/examples/gestures/browser/bookmarks.h deleted file mode 100644 index 7fcdae1..0000000 --- a/examples/gestures/browser/bookmarks.h +++ /dev/null @@ -1,310 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BOOKMARKS_H -#define BOOKMARKS_H - -#include -#include - -#include - -/*! - Bookmark manager, owner of the bookmarks, loads, saves and basic tasks - */ -class AutoSaver; -class BookmarkNode; -class BookmarksModel; -class BookmarksManager : public QObject -{ - Q_OBJECT - -signals: - void entryAdded(BookmarkNode *item); - void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item); - void entryChanged(BookmarkNode *item); - -public: - BookmarksManager(QObject *parent = 0); - ~BookmarksManager(); - - void addBookmark(BookmarkNode *parent, BookmarkNode *node, int row = -1); - void removeBookmark(BookmarkNode *node); - void setTitle(BookmarkNode *node, const QString &newTitle); - void setUrl(BookmarkNode *node, const QString &newUrl); - void changeExpanded(); - - BookmarkNode *bookmarks(); - BookmarkNode *menu(); - BookmarkNode *toolbar(); - - BookmarksModel *bookmarksModel(); - QUndoStack *undoRedoStack() { return &m_commands; }; - -public slots: - void importBookmarks(); - void exportBookmarks(); - -private slots: - void save() const; - -private: - void load(); - - bool m_loaded; - AutoSaver *m_saveTimer; - BookmarkNode *m_bookmarkRootNode; - BookmarksModel *m_bookmarkModel; - QUndoStack m_commands; - - friend class RemoveBookmarksCommand; - friend class ChangeBookmarkCommand; -}; - -class RemoveBookmarksCommand : public QUndoCommand -{ - -public: - RemoveBookmarksCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *parent, int row); - ~RemoveBookmarksCommand(); - void undo(); - void redo(); - -protected: - int m_row; - BookmarksManager *m_bookmarkManagaer; - BookmarkNode *m_node; - BookmarkNode *m_parent; - bool m_done; -}; - -class InsertBookmarksCommand : public RemoveBookmarksCommand -{ - -public: - InsertBookmarksCommand(BookmarksManager *m_bookmarkManagaer, - BookmarkNode *parent, BookmarkNode *node, int row); - void undo() { RemoveBookmarksCommand::redo(); } - void redo() { RemoveBookmarksCommand::undo(); } - -}; - -class ChangeBookmarkCommand : public QUndoCommand -{ - -public: - ChangeBookmarkCommand(BookmarksManager *m_bookmarkManagaer, - BookmarkNode *node, const QString &newValue, bool title); - void undo(); - void redo(); - -private: - BookmarksManager *m_bookmarkManagaer; - bool m_title; - QString m_oldValue; - QString m_newValue; - BookmarkNode *m_node; -}; - -/*! - BookmarksModel is a QAbstractItemModel wrapper around the BookmarkManager - */ -#include -class BookmarksModel : public QAbstractItemModel -{ - Q_OBJECT - -public slots: - void entryAdded(BookmarkNode *item); - void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item); - void entryChanged(BookmarkNode *item); - -public: - enum Roles { - TypeRole = Qt::UserRole + 1, - UrlRole = Qt::UserRole + 2, - UrlStringRole = Qt::UserRole + 3, - SeparatorRole = Qt::UserRole + 4 - }; - - BookmarksModel(BookmarksManager *bookmarkManager, QObject *parent = 0); - inline BookmarksManager *bookmarksManager() const { return m_bookmarksManager; } - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index= QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - Qt::DropActions supportedDropActions () const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - QMimeData *mimeData(const QModelIndexList &indexes) const; - QStringList mimeTypes() const; - bool dropMimeData(const QMimeData *data, - Qt::DropAction action, int row, int column, const QModelIndex &parent); - bool hasChildren(const QModelIndex &parent = QModelIndex()) const; - - BookmarkNode *node(const QModelIndex &index) const; - QModelIndex index(BookmarkNode *node) const; - -private: - - bool m_endMacro; - BookmarksManager *m_bookmarksManager; -}; - -// Menu that is dynamically populated from the bookmarks -#include "modelmenu.h" -class BookmarksMenu : public ModelMenu -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - BookmarksMenu(QWidget *parent = 0); - void setInitialActions(QList actions); - -protected: - bool prePopulated(); - -private slots: - void activated(const QModelIndex &index); - -private: - BookmarksManager *m_bookmarksManager; - QList m_initialActions; -}; - -/* - Proxy model that filters out the bookmarks so only the folders - are left behind. Used in the add bookmark dialog combobox. - */ -#include -class AddBookmarkProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT -public: - AddBookmarkProxyModel(QObject * parent = 0); - int columnCount(const QModelIndex & parent = QModelIndex()) const; - -protected: - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; -}; - -/*! - Add bookmark dialog - */ -#include "ui_addbookmarkdialog.h" -class AddBookmarkDialog : public QDialog, public Ui_AddBookmarkDialog -{ - Q_OBJECT - -public: - AddBookmarkDialog(const QString &url, const QString &title, QWidget *parent = 0, BookmarksManager *bookmarkManager = 0); - -private slots: - void accept(); - -private: - QString m_url; - BookmarksManager *m_bookmarksManager; - AddBookmarkProxyModel *m_proxyModel; -}; - -#include "ui_bookmarks.h" -class TreeProxyModel; -class BookmarksDialog : public QDialog, public Ui_BookmarksDialog -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - BookmarksDialog(QWidget *parent = 0, BookmarksManager *manager = 0); - ~BookmarksDialog(); - -private slots: - void customContextMenuRequested(const QPoint &pos); - void open(); - void newFolder(); - -private: - void expandNodes(BookmarkNode *node); - bool saveExpandedNodes(const QModelIndex &parent); - - BookmarksManager *m_bookmarksManager; - BookmarksModel *m_bookmarksModel; - TreeProxyModel *m_proxyModel; -}; - -#include -class BookmarksToolBar : public QToolBar -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - BookmarksToolBar(BookmarksModel *model, QWidget *parent = 0); - void setRootIndex(const QModelIndex &index); - QModelIndex rootIndex() const; - -protected: - void dragEnterEvent(QDragEnterEvent *event); - void dropEvent(QDropEvent *event); - -private slots: - void triggered(QAction *action); - void activated(const QModelIndex &index); - void build(); - -private: - BookmarksModel *m_bookmarksModel; - QPersistentModelIndex m_root; -}; - -#endif // BOOKMARKS_H diff --git a/examples/gestures/browser/bookmarks.ui b/examples/gestures/browser/bookmarks.ui deleted file mode 100644 index c893e94..0000000 --- a/examples/gestures/browser/bookmarks.ui +++ /dev/null @@ -1,106 +0,0 @@ - - BookmarksDialog - - - - 0 - 0 - 758 - 450 - - - - Bookmarks - - - - - - Qt::Horizontal - - - - 252 - 20 - - - - - - - - - - - - - - - - &Remove - - - - - - - Add Folder - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QDialogButtonBox::Ok - - - - - - - - - - SearchLineEdit - QLineEdit -
searchlineedit.h
-
- - EditTreeView - QTreeView -
edittreeview.h
-
-
- - - - buttonBox - accepted() - BookmarksDialog - accept() - - - 472 - 329 - - - 461 - 356 - - - - -
diff --git a/examples/gestures/browser/browser.icns b/examples/gestures/browser/browser.icns deleted file mode 100644 index f591ae4..0000000 Binary files a/examples/gestures/browser/browser.icns and /dev/null differ diff --git a/examples/gestures/browser/browser.ico b/examples/gestures/browser/browser.ico deleted file mode 100644 index 7f9be93..0000000 Binary files a/examples/gestures/browser/browser.ico and /dev/null differ diff --git a/examples/gestures/browser/browser.pro b/examples/gestures/browser/browser.pro deleted file mode 100644 index d970f99..0000000 --- a/examples/gestures/browser/browser.pro +++ /dev/null @@ -1,91 +0,0 @@ -TEMPLATE = app -TARGET = browser -QT += webkit network - -CONFIG += qt warn_on -contains(QT_BUILD_PARTS, tools): CONFIG += uitools -else: DEFINES += QT_NO_UITOOLS - -FORMS += \ - addbookmarkdialog.ui \ - bookmarks.ui \ - cookies.ui \ - cookiesexceptions.ui \ - downloaditem.ui \ - downloads.ui \ - history.ui \ - passworddialog.ui \ - proxy.ui \ - settings.ui - -HEADERS += \ - autosaver.h \ - bookmarks.h \ - browserapplication.h \ - browsermainwindow.h \ - chasewidget.h \ - cookiejar.h \ - downloadmanager.h \ - edittableview.h \ - edittreeview.h \ - history.h \ - modelmenu.h \ - networkaccessmanager.h \ - searchlineedit.h \ - settings.h \ - squeezelabel.h \ - tabwidget.h \ - toolbarsearch.h \ - urllineedit.h \ - webview.h \ - xbel.h - -SOURCES += \ - autosaver.cpp \ - bookmarks.cpp \ - browserapplication.cpp \ - browsermainwindow.cpp \ - chasewidget.cpp \ - cookiejar.cpp \ - downloadmanager.cpp \ - edittableview.cpp \ - edittreeview.cpp \ - history.cpp \ - modelmenu.cpp \ - networkaccessmanager.cpp \ - searchlineedit.cpp \ - settings.cpp \ - squeezelabel.cpp \ - tabwidget.cpp \ - toolbarsearch.cpp \ - urllineedit.cpp \ - webview.cpp \ - xbel.cpp \ - main.cpp - -RESOURCES += data/data.qrc htmls/htmls.qrc - -build_all:!build_pass { - CONFIG -= build_all - CONFIG += release -} - -win32 { - RC_FILE = browser.rc -} - -mac { - ICON = browser.icns - QMAKE_INFO_PLIST = Info_mac.plist - TARGET = Browser -} - -wince*: { - DEPLOYMENT_PLUGIN += qjpeg qgif -} - -# install -target.path = $$[QT_INSTALL_DEMOS]/browser -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.plist *.icns *.ico *.rc *.pro *.html *.doc images htmls -sources.path = $$[QT_INSTALL_DEMOS]/browser -INSTALLS += target sources diff --git a/examples/gestures/browser/browser.rc b/examples/gestures/browser/browser.rc deleted file mode 100644 index 89a237c..0000000 --- a/examples/gestures/browser/browser.rc +++ /dev/null @@ -1,2 +0,0 @@ -IDI_ICON1 ICON DISCARDABLE "browser.ico" - diff --git a/examples/gestures/browser/browserapplication.cpp b/examples/gestures/browser/browserapplication.cpp deleted file mode 100644 index 718a8ec..0000000 --- a/examples/gestures/browser/browserapplication.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "browserapplication.h" - -#include "bookmarks.h" -#include "browsermainwindow.h" -#include "cookiejar.h" -#include "downloadmanager.h" -#include "history.h" -#include "networkaccessmanager.h" -#include "tabwidget.h" -#include "webview.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#include - -DownloadManager *BrowserApplication::s_downloadManager = 0; -HistoryManager *BrowserApplication::s_historyManager = 0; -NetworkAccessManager *BrowserApplication::s_networkAccessManager = 0; -BookmarksManager *BrowserApplication::s_bookmarksManager = 0; - -BrowserApplication::BrowserApplication(int &argc, char **argv) - : QApplication(argc, argv) - , m_localServer(0) -{ - QCoreApplication::setOrganizationName(QLatin1String("Trolltech")); - QCoreApplication::setApplicationName(QLatin1String("demobrowser")); - QCoreApplication::setApplicationVersion(QLatin1String("0.1")); -#ifdef Q_WS_QWS - // Use a different server name for QWS so we can run an X11 - // browser and a QWS browser in parallel on the same machine for - // debugging - QString serverName = QCoreApplication::applicationName() + QLatin1String("_qws"); -#else - QString serverName = QCoreApplication::applicationName(); -#endif - QLocalSocket socket; - socket.connectToServer(serverName); - if (socket.waitForConnected(500)) { - QTextStream stream(&socket); - QStringList args = QCoreApplication::arguments(); - if (args.count() > 1) - stream << args.last(); - else - stream << QString(); - stream.flush(); - socket.waitForBytesWritten(); - return; - } - -#if defined(Q_WS_MAC) - QApplication::setQuitOnLastWindowClosed(false); -#else - QApplication::setQuitOnLastWindowClosed(true); -#endif - - m_localServer = new QLocalServer(this); - connect(m_localServer, SIGNAL(newConnection()), - this, SLOT(newLocalSocketConnection())); - if (!m_localServer->listen(serverName)) { - if (m_localServer->serverError() == QAbstractSocket::AddressInUseError - && QFile::exists(m_localServer->serverName())) { - QFile::remove(m_localServer->serverName()); - m_localServer->listen(serverName); - } - } - - QDesktopServices::setUrlHandler(QLatin1String("http"), this, "openUrl"); - QString localSysName = QLocale::system().name(); - - installTranslator(QLatin1String("qt_") + localSysName); - - QSettings settings; - settings.beginGroup(QLatin1String("sessions")); - m_lastSession = settings.value(QLatin1String("lastSession")).toByteArray(); - settings.endGroup(); - -#if defined(Q_WS_MAC) - connect(this, SIGNAL(lastWindowClosed()), - this, SLOT(lastWindowClosed())); -#endif - - QTimer::singleShot(0, this, SLOT(postLaunch())); -} - -BrowserApplication::~BrowserApplication() -{ - delete s_downloadManager; - for (int i = 0; i < m_mainWindows.size(); ++i) { - BrowserMainWindow *window = m_mainWindows.at(i); - delete window; - } - delete s_networkAccessManager; - delete s_bookmarksManager; -} - -#if defined(Q_WS_MAC) -void BrowserApplication::lastWindowClosed() -{ - clean(); - BrowserMainWindow *mw = new BrowserMainWindow; - mw->slotHome(); - m_mainWindows.prepend(mw); -} -#endif - -BrowserApplication *BrowserApplication::instance() -{ - return (static_cast(QCoreApplication::instance())); -} - -#if defined(Q_WS_MAC) -#include -void BrowserApplication::quitBrowser() -{ - clean(); - int tabCount = 0; - for (int i = 0; i < m_mainWindows.count(); ++i) { - tabCount =+ m_mainWindows.at(i)->tabWidget()->count(); - } - - if (tabCount > 1) { - int ret = QMessageBox::warning(mainWindow(), QString(), - tr("There are %1 windows and %2 tabs open\n" - "Do you want to quit anyway?").arg(m_mainWindows.count()).arg(tabCount), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No); - if (ret == QMessageBox::No) - return; - } - - exit(0); -} -#endif - -/*! - Any actions that can be delayed until the window is visible - */ -void BrowserApplication::postLaunch() -{ - QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - if (directory.isEmpty()) - directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - QWebSettings::setIconDatabasePath(directory); - - setWindowIcon(QIcon(QLatin1String(":browser.svg"))); - - loadSettings(); - - // newMainWindow() needs to be called in main() for this to happen - if (m_mainWindows.count() > 0) { - QStringList args = QCoreApplication::arguments(); - if (args.count() > 1) - mainWindow()->loadPage(args.last()); - else - mainWindow()->slotHome(); - } - BrowserApplication::historyManager(); -} - -void BrowserApplication::loadSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("websettings")); - - QWebSettings *defaultSettings = QWebSettings::globalSettings(); - QString standardFontFamily = defaultSettings->fontFamily(QWebSettings::StandardFont); - int standardFontSize = defaultSettings->fontSize(QWebSettings::DefaultFontSize); - QFont standardFont = QFont(standardFontFamily, standardFontSize); - standardFont = qVariantValue(settings.value(QLatin1String("standardFont"), standardFont)); - defaultSettings->setFontFamily(QWebSettings::StandardFont, standardFont.family()); - defaultSettings->setFontSize(QWebSettings::DefaultFontSize, standardFont.pointSize()); - - QString fixedFontFamily = defaultSettings->fontFamily(QWebSettings::FixedFont); - int fixedFontSize = defaultSettings->fontSize(QWebSettings::DefaultFixedFontSize); - QFont fixedFont = QFont(fixedFontFamily, fixedFontSize); - fixedFont = qVariantValue(settings.value(QLatin1String("fixedFont"), fixedFont)); - defaultSettings->setFontFamily(QWebSettings::FixedFont, fixedFont.family()); - defaultSettings->setFontSize(QWebSettings::DefaultFixedFontSize, fixedFont.pointSize()); - - defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, settings.value(QLatin1String("enableJavascript"), true).toBool()); - defaultSettings->setAttribute(QWebSettings::PluginsEnabled, settings.value(QLatin1String("enablePlugins"), true).toBool()); - - QUrl url = settings.value(QLatin1String("userStyleSheet")).toUrl(); - defaultSettings->setUserStyleSheetUrl(url); - - settings.endGroup(); -} - -QList BrowserApplication::mainWindows() -{ - clean(); - QList list; - for (int i = 0; i < m_mainWindows.count(); ++i) - list.append(m_mainWindows.at(i)); - return list; -} - -void BrowserApplication::clean() -{ - // cleanup any deleted main windows first - for (int i = m_mainWindows.count() - 1; i >= 0; --i) - if (m_mainWindows.at(i).isNull()) - m_mainWindows.removeAt(i); -} - -void BrowserApplication::saveSession() -{ - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - return; - - clean(); - - QSettings settings; - settings.beginGroup(QLatin1String("sessions")); - - QByteArray data; - QBuffer buffer(&data); - QDataStream stream(&buffer); - buffer.open(QIODevice::ReadWrite); - - stream << m_mainWindows.count(); - for (int i = 0; i < m_mainWindows.count(); ++i) - stream << m_mainWindows.at(i)->saveState(); - settings.setValue(QLatin1String("lastSession"), data); - settings.endGroup(); -} - -bool BrowserApplication::canRestoreSession() const -{ - return !m_lastSession.isEmpty(); -} - -void BrowserApplication::restoreLastSession() -{ - QList windows; - QBuffer buffer(&m_lastSession); - QDataStream stream(&buffer); - buffer.open(QIODevice::ReadOnly); - int windowCount; - stream >> windowCount; - for (int i = 0; i < windowCount; ++i) { - QByteArray windowState; - stream >> windowState; - windows.append(windowState); - } - for (int i = 0; i < windows.count(); ++i) { - BrowserMainWindow *newWindow = 0; - if (m_mainWindows.count() == 1 - && mainWindow()->tabWidget()->count() == 1 - && mainWindow()->currentTab()->url() == QUrl()) { - newWindow = mainWindow(); - } else { - newWindow = newMainWindow(); - } - newWindow->restoreState(windows.at(i)); - } -} - -bool BrowserApplication::isTheOnlyBrowser() const -{ - return (m_localServer != 0); -} - -void BrowserApplication::installTranslator(const QString &name) -{ - QTranslator *translator = new QTranslator(this); - translator->load(name, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - QApplication::installTranslator(translator); -} - -#if defined(Q_WS_MAC) -bool BrowserApplication::event(QEvent* event) -{ - switch (event->type()) { - case QEvent::ApplicationActivate: { - clean(); - if (!m_mainWindows.isEmpty()) { - BrowserMainWindow *mw = mainWindow(); - if (mw && !mw->isMinimized()) { - mainWindow()->show(); - } - return true; - } - } - case QEvent::FileOpen: - if (!m_mainWindows.isEmpty()) { - mainWindow()->loadPage(static_cast(event)->file()); - return true; - } - default: - break; - } - return QApplication::event(event); -} -#endif - -void BrowserApplication::openUrl(const QUrl &url) -{ - mainWindow()->loadPage(url.toString()); -} - -BrowserMainWindow *BrowserApplication::newMainWindow() -{ - BrowserMainWindow *browser = new BrowserMainWindow(); - m_mainWindows.prepend(browser); - browser->show(); - return browser; -} - -BrowserMainWindow *BrowserApplication::mainWindow() -{ - clean(); - if (m_mainWindows.isEmpty()) - newMainWindow(); - return m_mainWindows[0]; -} - -void BrowserApplication::newLocalSocketConnection() -{ - QLocalSocket *socket = m_localServer->nextPendingConnection(); - if (!socket) - return; - socket->waitForReadyRead(1000); - QTextStream stream(socket); - QString url; - stream >> url; - if (!url.isEmpty()) { - QSettings settings; - settings.beginGroup(QLatin1String("general")); - int openLinksIn = settings.value(QLatin1String("openLinksIn"), 0).toInt(); - settings.endGroup(); - if (openLinksIn == 1) - newMainWindow(); - else - mainWindow()->tabWidget()->newTab(); - openUrl(url); - } - delete socket; - mainWindow()->raise(); - mainWindow()->activateWindow(); -} - -CookieJar *BrowserApplication::cookieJar() -{ - return (CookieJar*)networkAccessManager()->cookieJar(); -} - -DownloadManager *BrowserApplication::downloadManager() -{ - if (!s_downloadManager) { - s_downloadManager = new DownloadManager(); - } - return s_downloadManager; -} - -NetworkAccessManager *BrowserApplication::networkAccessManager() -{ - if (!s_networkAccessManager) { - s_networkAccessManager = new NetworkAccessManager(); - s_networkAccessManager->setCookieJar(new CookieJar); - } - return s_networkAccessManager; -} - -HistoryManager *BrowserApplication::historyManager() -{ - if (!s_historyManager) { - s_historyManager = new HistoryManager(); - QWebHistoryInterface::setDefaultInterface(s_historyManager); - } - return s_historyManager; -} - -BookmarksManager *BrowserApplication::bookmarksManager() -{ - if (!s_bookmarksManager) { - s_bookmarksManager = new BookmarksManager; - } - return s_bookmarksManager; -} - -QIcon BrowserApplication::icon(const QUrl &url) const -{ - QIcon icon = QWebSettings::iconForUrl(url); - if (!icon.isNull()) - return icon.pixmap(16, 16); - if (m_defaultIcon.isNull()) - m_defaultIcon = QIcon(QLatin1String(":defaulticon.png")); - return m_defaultIcon.pixmap(16, 16); -} - diff --git a/examples/gestures/browser/browserapplication.h b/examples/gestures/browser/browserapplication.h deleted file mode 100644 index db83a85..0000000 --- a/examples/gestures/browser/browserapplication.h +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BROWSERAPPLICATION_H -#define BROWSERAPPLICATION_H - -#include - -#include -#include - -#include - -QT_BEGIN_NAMESPACE -class QLocalServer; -QT_END_NAMESPACE - -class BookmarksManager; -class BrowserMainWindow; -class CookieJar; -class DownloadManager; -class HistoryManager; -class NetworkAccessManager; -class BrowserApplication : public QApplication -{ - Q_OBJECT - -public: - BrowserApplication(int &argc, char **argv); - ~BrowserApplication(); - static BrowserApplication *instance(); - void loadSettings(); - - bool isTheOnlyBrowser() const; - BrowserMainWindow *mainWindow(); - QList mainWindows(); - QIcon icon(const QUrl &url) const; - - void saveSession(); - bool canRestoreSession() const; - - static HistoryManager *historyManager(); - static CookieJar *cookieJar(); - static DownloadManager *downloadManager(); - static NetworkAccessManager *networkAccessManager(); - static BookmarksManager *bookmarksManager(); - -#if defined(Q_WS_MAC) - bool event(QEvent *event); -#endif - -public slots: - BrowserMainWindow *newMainWindow(); - void restoreLastSession(); -#if defined(Q_WS_MAC) - void lastWindowClosed(); - void quitBrowser(); -#endif - -private slots: - void postLaunch(); - void openUrl(const QUrl &url); - void newLocalSocketConnection(); - -private: - void clean(); - void installTranslator(const QString &name); - - static HistoryManager *s_historyManager; - static DownloadManager *s_downloadManager; - static NetworkAccessManager *s_networkAccessManager; - static BookmarksManager *s_bookmarksManager; - - QList > m_mainWindows; - QLocalServer *m_localServer; - QByteArray m_lastSession; - mutable QIcon m_defaultIcon; -}; - -#endif // BROWSERAPPLICATION_H - diff --git a/examples/gestures/browser/browsermainwindow.cpp b/examples/gestures/browser/browsermainwindow.cpp deleted file mode 100644 index c6fe82d..0000000 --- a/examples/gestures/browser/browsermainwindow.cpp +++ /dev/null @@ -1,991 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "browsermainwindow.h" - -#include "autosaver.h" -#include "bookmarks.h" -#include "browserapplication.h" -#include "chasewidget.h" -#include "downloadmanager.h" -#include "history.h" -#include "settings.h" -#include "tabwidget.h" -#include "toolbarsearch.h" -#include "ui_passworddialog.h" -#include "webview.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -BrowserMainWindow::BrowserMainWindow(QWidget *parent, Qt::WindowFlags flags) - : QMainWindow(parent, flags) - , m_tabWidget(new TabWidget(this)) - , m_autoSaver(new AutoSaver(this)) - , m_historyBack(0) - , m_historyForward(0) - , m_stop(0) - , m_reload(0) -{ - setAttribute(Qt::WA_DeleteOnClose, true); - statusBar()->setSizeGripEnabled(true); - setupMenu(); - setupToolBar(); - - QWidget *centralWidget = new QWidget(this); - BookmarksModel *boomarksModel = BrowserApplication::bookmarksManager()->bookmarksModel(); - m_bookmarksToolbar = new BookmarksToolBar(boomarksModel, this); - connect(m_bookmarksToolbar, SIGNAL(openUrl(const QUrl&)), - m_tabWidget, SLOT(loadUrlInCurrentTab(const QUrl&))); - connect(m_bookmarksToolbar->toggleViewAction(), SIGNAL(toggled(bool)), - this, SLOT(updateBookmarksToolbarActionText(bool))); - - QVBoxLayout *layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setMargin(0); -#if defined(Q_WS_MAC) - layout->addWidget(m_bookmarksToolbar); - layout->addWidget(new QWidget); // <- OS X tab widget style bug -#else - addToolBarBreak(); - addToolBar(m_bookmarksToolbar); -#endif - layout->addWidget(m_tabWidget); - centralWidget->setLayout(layout); - setCentralWidget(centralWidget); - - connect(m_tabWidget, SIGNAL(loadPage(const QString &)), - this, SLOT(loadPage(const QString &))); - connect(m_tabWidget, SIGNAL(setCurrentTitle(const QString &)), - this, SLOT(slotUpdateWindowTitle(const QString &))); - connect(m_tabWidget, SIGNAL(showStatusBarMessage(const QString&)), - statusBar(), SLOT(showMessage(const QString&))); - connect(m_tabWidget, SIGNAL(linkHovered(const QString&)), - statusBar(), SLOT(showMessage(const QString&))); - connect(m_tabWidget, SIGNAL(loadProgress(int)), - this, SLOT(slotLoadProgress(int))); - connect(m_tabWidget, SIGNAL(tabsChanged()), - m_autoSaver, SLOT(changeOccurred())); - connect(m_tabWidget, SIGNAL(geometryChangeRequested(const QRect &)), - this, SLOT(geometryChangeRequested(const QRect &))); - connect(m_tabWidget, SIGNAL(printRequested(QWebFrame *)), - this, SLOT(printRequested(QWebFrame *))); - connect(m_tabWidget, SIGNAL(menuBarVisibilityChangeRequested(bool)), - menuBar(), SLOT(setVisible(bool))); - connect(m_tabWidget, SIGNAL(statusBarVisibilityChangeRequested(bool)), - statusBar(), SLOT(setVisible(bool))); - connect(m_tabWidget, SIGNAL(toolBarVisibilityChangeRequested(bool)), - m_navigationBar, SLOT(setVisible(bool))); - connect(m_tabWidget, SIGNAL(toolBarVisibilityChangeRequested(bool)), - m_bookmarksToolbar, SLOT(setVisible(bool))); -#if defined(Q_WS_MAC) - connect(m_tabWidget, SIGNAL(lastTabClosed()), - this, SLOT(close())); -#else - connect(m_tabWidget, SIGNAL(lastTabClosed()), - m_tabWidget, SLOT(newTab())); -#endif - - slotUpdateWindowTitle(); - loadDefaultState(); - m_tabWidget->newTab(); - - int size = m_tabWidget->lineEditStack()->sizeHint().height(); - m_navigationBar->setIconSize(QSize(size, size)); - -} - -BrowserMainWindow::~BrowserMainWindow() -{ - m_autoSaver->changeOccurred(); - m_autoSaver->saveIfNeccessary(); -} - -void BrowserMainWindow::loadDefaultState() -{ - QSettings settings; - settings.beginGroup(QLatin1String("BrowserMainWindow")); - QByteArray data = settings.value(QLatin1String("defaultState")).toByteArray(); - restoreState(data); - settings.endGroup(); -} - -QSize BrowserMainWindow::sizeHint() const -{ - QRect desktopRect = QApplication::desktop()->screenGeometry(); - QSize size = desktopRect.size() * qreal(0.9); - return size; -} - -void BrowserMainWindow::save() -{ - BrowserApplication::instance()->saveSession(); - - QSettings settings; - settings.beginGroup(QLatin1String("BrowserMainWindow")); - QByteArray data = saveState(false); - settings.setValue(QLatin1String("defaultState"), data); - settings.endGroup(); -} - -static const qint32 BrowserMainWindowMagic = 0xba; - -QByteArray BrowserMainWindow::saveState(bool withTabs) const -{ - int version = 2; - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - - stream << qint32(BrowserMainWindowMagic); - stream << qint32(version); - - stream << size(); - stream << !m_navigationBar->isHidden(); - stream << !m_bookmarksToolbar->isHidden(); - stream << !statusBar()->isHidden(); - if (withTabs) - stream << tabWidget()->saveState(); - else - stream << QByteArray(); - return data; -} - -bool BrowserMainWindow::restoreState(const QByteArray &state) -{ - int version = 2; - QByteArray sd = state; - QDataStream stream(&sd, QIODevice::ReadOnly); - if (stream.atEnd()) - return false; - - qint32 marker; - qint32 v; - stream >> marker; - stream >> v; - if (marker != BrowserMainWindowMagic || v != version) - return false; - - QSize size; - bool showToolbar; - bool showBookmarksBar; - bool showStatusbar; - QByteArray tabState; - - stream >> size; - stream >> showToolbar; - stream >> showBookmarksBar; - stream >> showStatusbar; - stream >> tabState; - - resize(size); - - m_navigationBar->setVisible(showToolbar); - updateToolbarActionText(showToolbar); - - m_bookmarksToolbar->setVisible(showBookmarksBar); - updateBookmarksToolbarActionText(showBookmarksBar); - - statusBar()->setVisible(showStatusbar); - updateStatusbarActionText(showStatusbar); - - if (!tabWidget()->restoreState(tabState)) - return false; - - return true; -} - -void BrowserMainWindow::setupMenu() -{ - new QShortcut(QKeySequence(Qt::Key_F6), this, SLOT(slotSwapFocus())); - - // File - QMenu *fileMenu = menuBar()->addMenu(tr("&File")); - - fileMenu->addAction(tr("&New Window"), this, SLOT(slotFileNew()), QKeySequence::New); - fileMenu->addAction(m_tabWidget->newTabAction()); - fileMenu->addAction(tr("&Open File..."), this, SLOT(slotFileOpen()), QKeySequence::Open); - fileMenu->addAction(tr("Open &Location..."), this, - SLOT(slotSelectLineEdit()), QKeySequence(Qt::ControlModifier + Qt::Key_L)); - fileMenu->addSeparator(); - fileMenu->addAction(m_tabWidget->closeTabAction()); - fileMenu->addSeparator(); - fileMenu->addAction(tr("&Save As..."), this, - SLOT(slotFileSaveAs()), QKeySequence(QKeySequence::Save)); - fileMenu->addSeparator(); - BookmarksManager *bookmarksManager = BrowserApplication::bookmarksManager(); - fileMenu->addAction(tr("&Import Bookmarks..."), bookmarksManager, SLOT(importBookmarks())); - fileMenu->addAction(tr("&Export Bookmarks..."), bookmarksManager, SLOT(exportBookmarks())); - fileMenu->addSeparator(); - fileMenu->addAction(tr("P&rint Preview..."), this, SLOT(slotFilePrintPreview())); - fileMenu->addAction(tr("&Print..."), this, SLOT(slotFilePrint()), QKeySequence::Print); - fileMenu->addSeparator(); - QAction *action = fileMenu->addAction(tr("Private &Browsing..."), this, SLOT(slotPrivateBrowsing())); - action->setCheckable(true); - fileMenu->addSeparator(); - -#if defined(Q_WS_MAC) - fileMenu->addAction(tr("&Quit"), BrowserApplication::instance(), SLOT(quitBrowser()), QKeySequence(Qt::CTRL | Qt::Key_Q)); -#else - fileMenu->addAction(tr("&Quit"), this, SLOT(close()), QKeySequence(Qt::CTRL | Qt::Key_Q)); -#endif - - // Edit - QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); - QAction *m_undo = editMenu->addAction(tr("&Undo")); - m_undo->setShortcuts(QKeySequence::Undo); - m_tabWidget->addWebAction(m_undo, QWebPage::Undo); - QAction *m_redo = editMenu->addAction(tr("&Redo")); - m_redo->setShortcuts(QKeySequence::Redo); - m_tabWidget->addWebAction(m_redo, QWebPage::Redo); - editMenu->addSeparator(); - QAction *m_cut = editMenu->addAction(tr("Cu&t")); - m_cut->setShortcuts(QKeySequence::Cut); - m_tabWidget->addWebAction(m_cut, QWebPage::Cut); - QAction *m_copy = editMenu->addAction(tr("&Copy")); - m_copy->setShortcuts(QKeySequence::Copy); - m_tabWidget->addWebAction(m_copy, QWebPage::Copy); - QAction *m_paste = editMenu->addAction(tr("&Paste")); - m_paste->setShortcuts(QKeySequence::Paste); - m_tabWidget->addWebAction(m_paste, QWebPage::Paste); - editMenu->addSeparator(); - - QAction *m_find = editMenu->addAction(tr("&Find")); - m_find->setShortcuts(QKeySequence::Find); - connect(m_find, SIGNAL(triggered()), this, SLOT(slotEditFind())); - new QShortcut(QKeySequence(Qt::Key_Slash), this, SLOT(slotEditFind())); - - QAction *m_findNext = editMenu->addAction(tr("&Find Next")); - m_findNext->setShortcuts(QKeySequence::FindNext); - connect(m_findNext, SIGNAL(triggered()), this, SLOT(slotEditFindNext())); - - QAction *m_findPrevious = editMenu->addAction(tr("&Find Previous")); - m_findPrevious->setShortcuts(QKeySequence::FindPrevious); - connect(m_findPrevious, SIGNAL(triggered()), this, SLOT(slotEditFindPrevious())); - - editMenu->addSeparator(); - editMenu->addAction(tr("&Preferences"), this, SLOT(slotPreferences()), tr("Ctrl+,")); - - // View - QMenu *viewMenu = menuBar()->addMenu(tr("&View")); - - m_viewBookmarkBar = new QAction(this); - updateBookmarksToolbarActionText(true); - m_viewBookmarkBar->setShortcut(tr("Shift+Ctrl+B")); - connect(m_viewBookmarkBar, SIGNAL(triggered()), this, SLOT(slotViewBookmarksBar())); - viewMenu->addAction(m_viewBookmarkBar); - - m_viewToolbar = new QAction(this); - updateToolbarActionText(true); - m_viewToolbar->setShortcut(tr("Ctrl+|")); - connect(m_viewToolbar, SIGNAL(triggered()), this, SLOT(slotViewToolbar())); - viewMenu->addAction(m_viewToolbar); - - m_viewStatusbar = new QAction(this); - updateStatusbarActionText(true); - m_viewStatusbar->setShortcut(tr("Ctrl+/")); - connect(m_viewStatusbar, SIGNAL(triggered()), this, SLOT(slotViewStatusbar())); - viewMenu->addAction(m_viewStatusbar); - - viewMenu->addSeparator(); - - m_stop = viewMenu->addAction(tr("&Stop")); - QList shortcuts; - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Period)); - shortcuts.append(Qt::Key_Escape); - m_stop->setShortcuts(shortcuts); - m_tabWidget->addWebAction(m_stop, QWebPage::Stop); - - m_reload = viewMenu->addAction(tr("Reload Page")); - m_reload->setShortcuts(QKeySequence::Refresh); - m_tabWidget->addWebAction(m_reload, QWebPage::Reload); - - viewMenu->addAction(tr("Zoom &In"), this, SLOT(slotViewZoomIn()), QKeySequence(Qt::CTRL | Qt::Key_Plus)); - viewMenu->addAction(tr("Zoom &Out"), this, SLOT(slotViewZoomOut()), QKeySequence(Qt::CTRL | Qt::Key_Minus)); - viewMenu->addAction(tr("Reset &Zoom"), this, SLOT(slotViewResetZoom()), QKeySequence(Qt::CTRL | Qt::Key_0)); - QAction *zoomTextOnlyAction = viewMenu->addAction(tr("Zoom &Text Only")); - connect(zoomTextOnlyAction, SIGNAL(toggled(bool)), this, SLOT(slotViewZoomTextOnly(bool))); - zoomTextOnlyAction->setCheckable(true); - zoomTextOnlyAction->setChecked(false); - - viewMenu->addSeparator(); - viewMenu->addAction(tr("Page S&ource"), this, SLOT(slotViewPageSource()), tr("Ctrl+Alt+U")); - QAction *a = viewMenu->addAction(tr("&Full Screen"), this, SLOT(slotViewFullScreen(bool)), Qt::Key_F11); - a->setCheckable(true); - - // History - HistoryMenu *historyMenu = new HistoryMenu(this); - connect(historyMenu, SIGNAL(openUrl(const QUrl&)), - m_tabWidget, SLOT(loadUrlInCurrentTab(const QUrl&))); - connect(historyMenu, SIGNAL(hovered(const QString&)), this, - SLOT(slotUpdateStatusbar(const QString&))); - historyMenu->setTitle(tr("Hi&story")); - menuBar()->addMenu(historyMenu); - QList historyActions; - - m_historyBack = new QAction(tr("Back"), this); - m_tabWidget->addWebAction(m_historyBack, QWebPage::Back); - m_historyBack->setShortcuts(QKeySequence::Back); - m_historyBack->setIconVisibleInMenu(false); - - m_historyForward = new QAction(tr("Forward"), this); - m_tabWidget->addWebAction(m_historyForward, QWebPage::Forward); - m_historyForward->setShortcuts(QKeySequence::Forward); - m_historyForward->setIconVisibleInMenu(false); - - QAction *m_historyHome = new QAction(tr("Home"), this); - connect(m_historyHome, SIGNAL(triggered()), this, SLOT(slotHome())); - m_historyHome->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_H)); - - m_restoreLastSession = new QAction(tr("Restore Last Session"), this); - connect(m_restoreLastSession, SIGNAL(triggered()), BrowserApplication::instance(), SLOT(restoreLastSession())); - m_restoreLastSession->setEnabled(BrowserApplication::instance()->canRestoreSession()); - - historyActions.append(m_historyBack); - historyActions.append(m_historyForward); - historyActions.append(m_historyHome); - historyActions.append(m_tabWidget->recentlyClosedTabsAction()); - historyActions.append(m_restoreLastSession); - historyMenu->setInitialActions(historyActions); - - // Bookmarks - BookmarksMenu *bookmarksMenu = new BookmarksMenu(this); - connect(bookmarksMenu, SIGNAL(openUrl(const QUrl&)), - m_tabWidget, SLOT(loadUrlInCurrentTab(const QUrl&))); - connect(bookmarksMenu, SIGNAL(hovered(const QString&)), - this, SLOT(slotUpdateStatusbar(const QString&))); - bookmarksMenu->setTitle(tr("&Bookmarks")); - menuBar()->addMenu(bookmarksMenu); - - QList bookmarksActions; - - QAction *showAllBookmarksAction = new QAction(tr("Show All Bookmarks"), this); - connect(showAllBookmarksAction, SIGNAL(triggered()), this, SLOT(slotShowBookmarksDialog())); - m_addBookmark = new QAction(QIcon(QLatin1String(":addbookmark.png")), tr("Add Bookmark..."), this); - m_addBookmark->setIconVisibleInMenu(false); - - connect(m_addBookmark, SIGNAL(triggered()), this, SLOT(slotAddBookmark())); - m_addBookmark->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D)); - - bookmarksActions.append(showAllBookmarksAction); - bookmarksActions.append(m_addBookmark); - bookmarksMenu->setInitialActions(bookmarksActions); - - // Window - m_windowMenu = menuBar()->addMenu(tr("&Window")); - connect(m_windowMenu, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShowWindowMenu())); - slotAboutToShowWindowMenu(); - - QMenu *toolsMenu = menuBar()->addMenu(tr("&Tools")); - toolsMenu->addAction(tr("Web &Search"), this, SLOT(slotWebSearch()), QKeySequence(tr("Ctrl+K", "Web Search"))); -#ifndef Q_CC_MINGW - a = toolsMenu->addAction(tr("Enable Web &Inspector"), this, SLOT(slotToggleInspector(bool))); - a->setCheckable(true); -#endif - - QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt())); - helpMenu->addAction(tr("About &Demo Browser"), this, SLOT(slotAboutApplication())); -} - -void BrowserMainWindow::setupToolBar() -{ - setUnifiedTitleAndToolBarOnMac(true); - m_navigationBar = addToolBar(tr("Navigation")); - connect(m_navigationBar->toggleViewAction(), SIGNAL(toggled(bool)), - this, SLOT(updateToolbarActionText(bool))); - - m_historyBack->setIcon(style()->standardIcon(QStyle::SP_ArrowBack, 0, this)); - m_historyBackMenu = new QMenu(this); - m_historyBack->setMenu(m_historyBackMenu); - connect(m_historyBackMenu, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShowBackMenu())); - connect(m_historyBackMenu, SIGNAL(triggered(QAction *)), - this, SLOT(slotOpenActionUrl(QAction *))); - m_navigationBar->addAction(m_historyBack); - - m_historyForward->setIcon(style()->standardIcon(QStyle::SP_ArrowForward, 0, this)); - m_historyForwardMenu = new QMenu(this); - connect(m_historyForwardMenu, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShowForwardMenu())); - connect(m_historyForwardMenu, SIGNAL(triggered(QAction *)), - this, SLOT(slotOpenActionUrl(QAction *))); - m_historyForward->setMenu(m_historyForwardMenu); - m_navigationBar->addAction(m_historyForward); - - m_stopReload = new QAction(this); - m_reloadIcon = style()->standardIcon(QStyle::SP_BrowserReload); - m_stopReload->setIcon(m_reloadIcon); - - m_navigationBar->addAction(m_stopReload); - - m_navigationBar->addWidget(m_tabWidget->lineEditStack()); - - m_toolbarSearch = new ToolbarSearch(m_navigationBar); - m_navigationBar->addWidget(m_toolbarSearch); - connect(m_toolbarSearch, SIGNAL(search(const QUrl&)), SLOT(loadUrl(const QUrl&))); - - m_chaseWidget = new ChaseWidget(this); - m_navigationBar->addWidget(m_chaseWidget); -} - -void BrowserMainWindow::slotShowBookmarksDialog() -{ - BookmarksDialog *dialog = new BookmarksDialog(this); - connect(dialog, SIGNAL(openUrl(const QUrl&)), - m_tabWidget, SLOT(loadUrlInCurrentTab(const QUrl&))); - dialog->show(); -} - -void BrowserMainWindow::slotAddBookmark() -{ - WebView *webView = currentTab(); - QString url = webView->url().toString(); - QString title = webView->title(); - AddBookmarkDialog dialog(url, title); - dialog.exec(); -} - -void BrowserMainWindow::slotViewToolbar() -{ - if (m_navigationBar->isVisible()) { - updateToolbarActionText(false); - m_navigationBar->close(); - } else { - updateToolbarActionText(true); - m_navigationBar->show(); - } - m_autoSaver->changeOccurred(); -} - -void BrowserMainWindow::slotViewBookmarksBar() -{ - if (m_bookmarksToolbar->isVisible()) { - updateBookmarksToolbarActionText(false); - m_bookmarksToolbar->close(); - } else { - updateBookmarksToolbarActionText(true); - m_bookmarksToolbar->show(); - } - m_autoSaver->changeOccurred(); -} - -void BrowserMainWindow::updateStatusbarActionText(bool visible) -{ - m_viewStatusbar->setText(!visible ? tr("Show Status Bar") : tr("Hide Status Bar")); -} - -void BrowserMainWindow::updateToolbarActionText(bool visible) -{ - m_viewToolbar->setText(!visible ? tr("Show Toolbar") : tr("Hide Toolbar")); -} - -void BrowserMainWindow::updateBookmarksToolbarActionText(bool visible) -{ - m_viewBookmarkBar->setText(!visible ? tr("Show Bookmarks bar") : tr("Hide Bookmarks bar")); -} - -void BrowserMainWindow::slotViewStatusbar() -{ - if (statusBar()->isVisible()) { - updateStatusbarActionText(false); - statusBar()->close(); - } else { - updateStatusbarActionText(true); - statusBar()->show(); - } - m_autoSaver->changeOccurred(); -} - -QUrl BrowserMainWindow::guessUrlFromString(const QString &string) -{ - QString urlStr = string.trimmed(); - QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*")); - - // Check if it looks like a qualified URL. Try parsing it and see. - bool hasSchema = test.exactMatch(urlStr); - if (hasSchema) { - QUrl url = QUrl::fromEncoded(urlStr.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - - // Might be a file. - if (QFile::exists(urlStr)) { - QFileInfo info(urlStr); - return QUrl::fromLocalFile(info.absoluteFilePath()); - } - - // Might be a shorturl - try to detect the schema. - if (!hasSchema) { - int dotIndex = urlStr.indexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString prefix = urlStr.left(dotIndex).toLower(); - QByteArray schema = (prefix == QLatin1String("ftp")) ? prefix.toLatin1() : "http"; - QUrl url = - QUrl::fromEncoded(schema + "://" + urlStr.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - } - - // Fall back to QUrl's own tolerant parser. - QUrl url = QUrl::fromEncoded(string.toUtf8(), QUrl::TolerantMode); - - // finally for cases where the user just types in a hostname add http - if (url.scheme().isEmpty()) - url = QUrl::fromEncoded("http://" + string.toUtf8(), QUrl::TolerantMode); - return url; -} - -void BrowserMainWindow::loadUrl(const QUrl &url) -{ - if (!currentTab() || !url.isValid()) - return; - - m_tabWidget->currentLineEdit()->setText(QString::fromUtf8(url.toEncoded())); - m_tabWidget->loadUrlInCurrentTab(url); -} - -void BrowserMainWindow::slotDownloadManager() -{ - BrowserApplication::downloadManager()->show(); -} - -void BrowserMainWindow::slotSelectLineEdit() -{ - m_tabWidget->currentLineEdit()->selectAll(); - m_tabWidget->currentLineEdit()->setFocus(); -} - -void BrowserMainWindow::slotFileSaveAs() -{ - BrowserApplication::downloadManager()->download(currentTab()->url(), true); -} - -void BrowserMainWindow::slotPreferences() -{ - SettingsDialog *s = new SettingsDialog(this); - s->show(); -} - -void BrowserMainWindow::slotUpdateStatusbar(const QString &string) -{ - statusBar()->showMessage(string, 2000); -} - -void BrowserMainWindow::slotUpdateWindowTitle(const QString &title) -{ - if (title.isEmpty()) { - setWindowTitle(tr("Qt Demo Browser")); - } else { -#if defined(Q_WS_MAC) - setWindowTitle(title); -#else - setWindowTitle(tr("%1 - Qt Demo Browser", "Page title and Browser name").arg(title)); -#endif - } -} - -void BrowserMainWindow::slotAboutApplication() -{ - QMessageBox::about(this, tr("About"), tr( - "Version %1" - "

This demo demonstrates Qt's " - "webkit facilities in action, providing an example " - "browser for you to experiment with.

" - "

QtWebKit is based on the Open Source WebKit Project developed at http://webkit.org/." - ).arg(QCoreApplication::applicationVersion())); -} - -void BrowserMainWindow::slotFileNew() -{ - BrowserApplication::instance()->newMainWindow(); - BrowserMainWindow *mw = BrowserApplication::instance()->mainWindow(); - mw->slotHome(); -} - -void BrowserMainWindow::slotFileOpen() -{ - QString file = QFileDialog::getOpenFileName(this, tr("Open Web Resource"), QString(), - tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)")); - - if (file.isEmpty()) - return; - - loadPage(file); -} - -void BrowserMainWindow::slotFilePrintPreview() -{ -#ifndef QT_NO_PRINTER - if (!currentTab()) - return; - QPrintPreviewDialog *dialog = new QPrintPreviewDialog(this); - connect(dialog, SIGNAL(paintRequested(QPrinter *)), - currentTab(), SLOT(print(QPrinter *))); - dialog->exec(); -#endif -} - -void BrowserMainWindow::slotFilePrint() -{ - if (!currentTab()) - return; - printRequested(currentTab()->page()->mainFrame()); -} - -void BrowserMainWindow::printRequested(QWebFrame *frame) -{ -#ifndef QT_NO_PRINTER - QPrinter printer; - QPrintDialog *dialog = new QPrintDialog(&printer, this); - dialog->setWindowTitle(tr("Print Document")); - if (dialog->exec() != QDialog::Accepted) - return; - frame->print(&printer); -#endif -} - -void BrowserMainWindow::slotPrivateBrowsing() -{ - QWebSettings *settings = QWebSettings::globalSettings(); - bool pb = settings->testAttribute(QWebSettings::PrivateBrowsingEnabled); - if (!pb) { - QString title = tr("Are you sure you want to turn on private browsing?"); - QString text = tr("%1

When private browsing in turned on," - " webpages are not added to the history," - " items are automatically removed from the Downloads window," \ - " new cookies are not stored, current cookies can't be accessed," \ - " site icons wont be stored, session wont be saved, " \ - " and searches are not addded to the pop-up menu in the Google search box." \ - " Until you close the window, you can still click the Back and Forward buttons" \ - " to return to the webpages you have opened.").arg(title); - - QMessageBox::StandardButton button = QMessageBox::question(this, QString(), text, - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok); - if (button == QMessageBox::Ok) { - settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); - } - } else { - settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false); - - QList windows = BrowserApplication::instance()->mainWindows(); - for (int i = 0; i < windows.count(); ++i) { - BrowserMainWindow *window = windows.at(i); - window->m_lastSearch = QString::null; - window->tabWidget()->clear(); - } - } -} - -void BrowserMainWindow::closeEvent(QCloseEvent *event) -{ - if (m_tabWidget->count() > 1) { - int ret = QMessageBox::warning(this, QString(), - tr("Are you sure you want to close the window?" - " There are %1 tab open").arg(m_tabWidget->count()), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No); - if (ret == QMessageBox::No) { - event->ignore(); - return; - } - } - event->accept(); - deleteLater(); -} - -void BrowserMainWindow::slotEditFind() -{ - if (!currentTab()) - return; - bool ok; - QString search = QInputDialog::getText(this, tr("Find"), - tr("Text:"), QLineEdit::Normal, - m_lastSearch, &ok); - if (ok && !search.isEmpty()) { - m_lastSearch = search; - if (!currentTab()->findText(m_lastSearch)) - slotUpdateStatusbar(tr("\"%1\" not found.").arg(m_lastSearch)); - } -} - -void BrowserMainWindow::slotEditFindNext() -{ - if (!currentTab() && !m_lastSearch.isEmpty()) - return; - currentTab()->findText(m_lastSearch); -} - -void BrowserMainWindow::slotEditFindPrevious() -{ - if (!currentTab() && !m_lastSearch.isEmpty()) - return; - currentTab()->findText(m_lastSearch, QWebPage::FindBackward); -} - -void BrowserMainWindow::slotViewZoomIn() -{ - if (!currentTab()) - return; - currentTab()->setZoomFactor(currentTab()->zoomFactor() + 0.1); -} - -void BrowserMainWindow::slotViewZoomOut() -{ - if (!currentTab()) - return; - currentTab()->setZoomFactor(currentTab()->zoomFactor() - 0.1); -} - -void BrowserMainWindow::slotViewResetZoom() -{ - if (!currentTab()) - return; - currentTab()->setZoomFactor(1.0); -} - -void BrowserMainWindow::slotViewZoomTextOnly(bool enable) -{ - if (!currentTab()) - return; - currentTab()->page()->settings()->setAttribute(QWebSettings::ZoomTextOnly, enable); -} - -void BrowserMainWindow::slotViewFullScreen(bool makeFullScreen) -{ - if (makeFullScreen) { - showFullScreen(); - } else { - if (isMinimized()) - showMinimized(); - else if (isMaximized()) - showMaximized(); - else showNormal(); - } -} - -void BrowserMainWindow::slotViewPageSource() -{ - if (!currentTab()) - return; - - QString markup = currentTab()->page()->mainFrame()->toHtml(); - QPlainTextEdit *view = new QPlainTextEdit(markup); - view->setWindowTitle(tr("Page Source of %1").arg(currentTab()->title())); - view->setMinimumWidth(640); - view->setAttribute(Qt::WA_DeleteOnClose); - view->show(); -} - -void BrowserMainWindow::slotHome() -{ - QSettings settings; - settings.beginGroup(QLatin1String("MainWindow")); - QString home = settings.value(QLatin1String("home"), QLatin1String("http://qtsoftware.com/")).toString(); - loadPage(home); -} - -void BrowserMainWindow::slotWebSearch() -{ - m_toolbarSearch->lineEdit()->selectAll(); - m_toolbarSearch->lineEdit()->setFocus(); -} - -void BrowserMainWindow::slotToggleInspector(bool enable) -{ - QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enable); - if (enable) { - int result = QMessageBox::question(this, tr("Web Inspector"), - tr("The web inspector will only work correctly for pages that were loaded after enabling.\n" - "Do you want to reload all pages?"), - QMessageBox::Yes | QMessageBox::No); - if (result == QMessageBox::Yes) { - m_tabWidget->reloadAllTabs(); - } - } -} - -void BrowserMainWindow::slotSwapFocus() -{ - if (currentTab()->hasFocus()) - m_tabWidget->currentLineEdit()->setFocus(); - else - currentTab()->setFocus(); -} - -void BrowserMainWindow::loadPage(const QString &page) -{ - QUrl url = guessUrlFromString(page); - loadUrl(url); -} - -TabWidget *BrowserMainWindow::tabWidget() const -{ - return m_tabWidget; -} - -WebView *BrowserMainWindow::currentTab() const -{ - return m_tabWidget->currentWebView(); -} - -void BrowserMainWindow::slotLoadProgress(int progress) -{ - if (progress < 100 && progress > 0) { - m_chaseWidget->setAnimated(true); - disconnect(m_stopReload, SIGNAL(triggered()), m_reload, SLOT(trigger())); - if (m_stopIcon.isNull()) - m_stopIcon = style()->standardIcon(QStyle::SP_BrowserStop); - m_stopReload->setIcon(m_stopIcon); - connect(m_stopReload, SIGNAL(triggered()), m_stop, SLOT(trigger())); - m_stopReload->setToolTip(tr("Stop loading the current page")); - } else { - m_chaseWidget->setAnimated(false); - disconnect(m_stopReload, SIGNAL(triggered()), m_stop, SLOT(trigger())); - m_stopReload->setIcon(m_reloadIcon); - connect(m_stopReload, SIGNAL(triggered()), m_reload, SLOT(trigger())); - m_stopReload->setToolTip(tr("Reload the current page")); - } -} - -void BrowserMainWindow::slotAboutToShowBackMenu() -{ - m_historyBackMenu->clear(); - if (!currentTab()) - return; - QWebHistory *history = currentTab()->history(); - int historyCount = history->count(); - for (int i = history->backItems(historyCount).count() - 1; i >= 0; --i) { - QWebHistoryItem item = history->backItems(history->count()).at(i); - QAction *action = new QAction(this); - action->setData(-1*(historyCount-i-1)); - QIcon icon = BrowserApplication::instance()->icon(item.url()); - action->setIcon(icon); - action->setText(item.title()); - m_historyBackMenu->addAction(action); - } -} - -void BrowserMainWindow::slotAboutToShowForwardMenu() -{ - m_historyForwardMenu->clear(); - if (!currentTab()) - return; - QWebHistory *history = currentTab()->history(); - int historyCount = history->count(); - for (int i = 0; i < history->forwardItems(history->count()).count(); ++i) { - QWebHistoryItem item = history->forwardItems(historyCount).at(i); - QAction *action = new QAction(this); - action->setData(historyCount-i); - QIcon icon = BrowserApplication::instance()->icon(item.url()); - action->setIcon(icon); - action->setText(item.title()); - m_historyForwardMenu->addAction(action); - } -} - -void BrowserMainWindow::slotAboutToShowWindowMenu() -{ - m_windowMenu->clear(); - m_windowMenu->addAction(m_tabWidget->nextTabAction()); - m_windowMenu->addAction(m_tabWidget->previousTabAction()); - m_windowMenu->addSeparator(); - m_windowMenu->addAction(tr("Downloads"), this, SLOT(slotDownloadManager()), QKeySequence(tr("Alt+Ctrl+L", "Download Manager"))); - - m_windowMenu->addSeparator(); - QList windows = BrowserApplication::instance()->mainWindows(); - for (int i = 0; i < windows.count(); ++i) { - BrowserMainWindow *window = windows.at(i); - QAction *action = m_windowMenu->addAction(window->windowTitle(), this, SLOT(slotShowWindow())); - action->setData(i); - action->setCheckable(true); - if (window == this) - action->setChecked(true); - } -} - -void BrowserMainWindow::slotShowWindow() -{ - if (QAction *action = qobject_cast(sender())) { - QVariant v = action->data(); - if (v.canConvert()) { - int offset = qvariant_cast(v); - QList windows = BrowserApplication::instance()->mainWindows(); - windows.at(offset)->activateWindow(); - windows.at(offset)->currentTab()->setFocus(); - } - } -} - -void BrowserMainWindow::slotOpenActionUrl(QAction *action) -{ - int offset = action->data().toInt(); - QWebHistory *history = currentTab()->history(); - if (offset < 0) - history->goToItem(history->backItems(-1*offset).first()); // back - else if (offset > 0) - history->goToItem(history->forwardItems(history->count() - offset + 1).back()); // forward - } - -void BrowserMainWindow::geometryChangeRequested(const QRect &geometry) -{ - setGeometry(geometry); -} - diff --git a/examples/gestures/browser/browsermainwindow.h b/examples/gestures/browser/browsermainwindow.h deleted file mode 100644 index 04f6c0c..0000000 --- a/examples/gestures/browser/browsermainwindow.h +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BROWSERMAINWINDOW_H -#define BROWSERMAINWINDOW_H - -#include -#include -#include - -class AutoSaver; -class BookmarksToolBar; -class ChaseWidget; -class QWebFrame; -class TabWidget; -class ToolbarSearch; -class WebView; - -/*! - The MainWindow of the Browser Application. - - Handles the tab widget and all the actions - */ -class BrowserMainWindow : public QMainWindow { - Q_OBJECT - -public: - BrowserMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); - ~BrowserMainWindow(); - QSize sizeHint() const; - -public: - static QUrl guessUrlFromString(const QString &url); - TabWidget *tabWidget() const; - WebView *currentTab() const; - QByteArray saveState(bool withTabs = true) const; - bool restoreState(const QByteArray &state); - -public slots: - void loadPage(const QString &url); - void slotHome(); - -protected: - void closeEvent(QCloseEvent *event); - -private slots: - void save(); - - void slotLoadProgress(int); - void slotUpdateStatusbar(const QString &string); - void slotUpdateWindowTitle(const QString &title = QString()); - - void loadUrl(const QUrl &url); - void slotPreferences(); - - void slotFileNew(); - void slotFileOpen(); - void slotFilePrintPreview(); - void slotFilePrint(); - void slotPrivateBrowsing(); - void slotFileSaveAs(); - void slotEditFind(); - void slotEditFindNext(); - void slotEditFindPrevious(); - void slotShowBookmarksDialog(); - void slotAddBookmark(); - void slotViewZoomIn(); - void slotViewZoomOut(); - void slotViewResetZoom(); - void slotViewZoomTextOnly(bool enable); - void slotViewToolbar(); - void slotViewBookmarksBar(); - void slotViewStatusbar(); - void slotViewPageSource(); - void slotViewFullScreen(bool enable); - - void slotWebSearch(); - void slotToggleInspector(bool enable); - void slotAboutApplication(); - void slotDownloadManager(); - void slotSelectLineEdit(); - - void slotAboutToShowBackMenu(); - void slotAboutToShowForwardMenu(); - void slotAboutToShowWindowMenu(); - void slotOpenActionUrl(QAction *action); - void slotShowWindow(); - void slotSwapFocus(); - - void printRequested(QWebFrame *frame); - void geometryChangeRequested(const QRect &geometry); - void updateToolbarActionText(bool visible); - void updateBookmarksToolbarActionText(bool visible); - -private: - void loadDefaultState(); - void setupMenu(); - void setupToolBar(); - void updateStatusbarActionText(bool visible); - -private: - QToolBar *m_navigationBar; - ToolbarSearch *m_toolbarSearch; - BookmarksToolBar *m_bookmarksToolbar; - ChaseWidget *m_chaseWidget; - TabWidget *m_tabWidget; - AutoSaver *m_autoSaver; - - QAction *m_historyBack; - QMenu *m_historyBackMenu; - QAction *m_historyForward; - QMenu *m_historyForwardMenu; - QMenu *m_windowMenu; - - QAction *m_stop; - QAction *m_reload; - QAction *m_stopReload; - QAction *m_viewToolbar; - QAction *m_viewBookmarkBar; - QAction *m_viewStatusbar; - QAction *m_restoreLastSession; - QAction *m_addBookmark; - - QIcon m_reloadIcon; - QIcon m_stopIcon; - - QString m_lastSearch; -}; - -#endif // BROWSERMAINWINDOW_H - diff --git a/examples/gestures/browser/chasewidget.cpp b/examples/gestures/browser/chasewidget.cpp deleted file mode 100644 index de6c90b..0000000 --- a/examples/gestures/browser/chasewidget.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "chasewidget.h" - -#include - -#include -#include -#include -#include -#include - -ChaseWidget::ChaseWidget(QWidget *parent, QPixmap pixmap, bool pixmapEnabled) - : QWidget(parent) - , m_segment(0) - , m_delay(100) - , m_step(40) - , m_timerId(-1) - , m_animated(false) - , m_pixmap(pixmap) - , m_pixmapEnabled(pixmapEnabled) -{ -} - -void ChaseWidget::setAnimated(bool value) -{ - if (m_animated == value) - return; - m_animated = value; - if (m_timerId != -1) { - killTimer(m_timerId); - m_timerId = -1; - } - if (m_animated) { - m_segment = 0; - m_timerId = startTimer(m_delay); - } - update(); -} - -void ChaseWidget::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QPainter p(this); - if (m_pixmapEnabled && !m_pixmap.isNull()) { - p.drawPixmap(0, 0, m_pixmap); - return; - } - - const int extent = qMin(width() - 8, height() - 8); - const int displ = extent / 4; - const int ext = extent / 4 - 1; - - p.setRenderHint(QPainter::Antialiasing, true); - - if(m_animated) - p.setPen(Qt::gray); - else - p.setPen(QPen(palette().dark().color())); - - p.translate(width() / 2, height() / 2); // center - - for (int segment = 0; segment < segmentCount(); ++segment) { - p.rotate(QApplication::isRightToLeft() ? m_step : -m_step); - if(m_animated) - p.setBrush(colorForSegment(segment)); - else - p.setBrush(palette().background()); - p.drawEllipse(QRect(displ, -ext / 2, ext, ext)); - } -} - -QSize ChaseWidget::sizeHint() const -{ - return QSize(32, 32); -} - -void ChaseWidget::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == m_timerId) { - ++m_segment; - update(); - } - QWidget::timerEvent(event); -} - -QColor ChaseWidget::colorForSegment(int seg) const -{ - int index = ((seg + m_segment) % segmentCount()); - int comp = qMax(0, 255 - (index * (255 / segmentCount()))); - return QColor(comp, comp, comp, 255); -} - -int ChaseWidget::segmentCount() const -{ - return 360 / m_step; -} - -void ChaseWidget::setPixmapEnabled(bool enable) -{ - m_pixmapEnabled = enable; -} - diff --git a/examples/gestures/browser/chasewidget.h b/examples/gestures/browser/chasewidget.h deleted file mode 100644 index 5b983e4..0000000 --- a/examples/gestures/browser/chasewidget.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CHASEWIDGET_H -#define CHASEWIDGET_H - -#include - -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QHideEvent; -class QShowEvent; -class QPaintEvent; -class QTimerEvent; -QT_END_NAMESPACE - -class ChaseWidget : public QWidget -{ - Q_OBJECT -public: - ChaseWidget(QWidget *parent = 0, QPixmap pixmap = QPixmap(), bool pixmapEnabled = false); - - void setAnimated(bool value); - void setPixmapEnabled(bool enable); - QSize sizeHint() const; - -protected: - void paintEvent(QPaintEvent *event); - void timerEvent(QTimerEvent *event); - -private: - int segmentCount() const; - QColor colorForSegment(int segment) const; - - int m_segment; - int m_delay; - int m_step; - int m_timerId; - bool m_animated; - QPixmap m_pixmap; - bool m_pixmapEnabled; -}; - -#endif diff --git a/examples/gestures/browser/cookiejar.cpp b/examples/gestures/browser/cookiejar.cpp deleted file mode 100644 index 3ae443f..0000000 --- a/examples/gestures/browser/cookiejar.cpp +++ /dev/null @@ -1,733 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "cookiejar.h" - -#include "autosaver.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -static const unsigned int JAR_VERSION = 23; - -QT_BEGIN_NAMESPACE -QDataStream &operator<<(QDataStream &stream, const QList &list) -{ - stream << JAR_VERSION; - stream << quint32(list.size()); - for (int i = 0; i < list.size(); ++i) - stream << list.at(i).toRawForm(); - return stream; -} - -QDataStream &operator>>(QDataStream &stream, QList &list) -{ - list.clear(); - - quint32 version; - stream >> version; - - if (version != JAR_VERSION) - return stream; - - quint32 count; - stream >> count; - for(quint32 i = 0; i < count; ++i) - { - QByteArray value; - stream >> value; - QList newCookies = QNetworkCookie::parseCookies(value); - if (newCookies.count() == 0 && value.length() != 0) { - qWarning() << "CookieJar: Unable to parse saved cookie:" << value; - } - for (int j = 0; j < newCookies.count(); ++j) - list.append(newCookies.at(j)); - if (stream.atEnd()) - break; - } - return stream; -} -QT_END_NAMESPACE - -CookieJar::CookieJar(QObject *parent) - : QNetworkCookieJar(parent) - , m_loaded(false) - , m_saveTimer(new AutoSaver(this)) - , m_acceptCookies(AcceptOnlyFromSitesNavigatedTo) -{ -} - -CookieJar::~CookieJar() -{ - if (m_keepCookies == KeepUntilExit) - clear(); - m_saveTimer->saveIfNeccessary(); -} - -void CookieJar::clear() -{ - setAllCookies(QList()); - m_saveTimer->changeOccurred(); - emit cookiesChanged(); -} - -void CookieJar::load() -{ - if (m_loaded) - return; - // load cookies and exceptions - qRegisterMetaTypeStreamOperators >("QList"); - QSettings cookieSettings(QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QLatin1String("/cookies.ini"), QSettings::IniFormat); - setAllCookies(qvariant_cast >(cookieSettings.value(QLatin1String("cookies")))); - cookieSettings.beginGroup(QLatin1String("Exceptions")); - m_exceptions_block = cookieSettings.value(QLatin1String("block")).toStringList(); - m_exceptions_allow = cookieSettings.value(QLatin1String("allow")).toStringList(); - m_exceptions_allowForSession = cookieSettings.value(QLatin1String("allowForSession")).toStringList(); - qSort(m_exceptions_block.begin(), m_exceptions_block.end()); - qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); - qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); - - loadSettings(); -} - -void CookieJar::loadSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("cookies")); - QByteArray value = settings.value(QLatin1String("acceptCookies"), - QLatin1String("AcceptOnlyFromSitesNavigatedTo")).toByteArray(); - QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); - m_acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ? - AcceptOnlyFromSitesNavigatedTo : - static_cast(acceptPolicyEnum.keyToValue(value)); - - value = settings.value(QLatin1String("keepCookiesUntil"), QLatin1String("KeepUntilExpire")).toByteArray(); - QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); - m_keepCookies = keepPolicyEnum.keyToValue(value) == -1 ? - KeepUntilExpire : - static_cast(keepPolicyEnum.keyToValue(value)); - - if (m_keepCookies == KeepUntilExit) - setAllCookies(QList()); - - m_loaded = true; - emit cookiesChanged(); -} - -void CookieJar::save() -{ - if (!m_loaded) - return; - purgeOldCookies(); - QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - if (directory.isEmpty()) - directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - if (!QFile::exists(directory)) { - QDir dir; - dir.mkpath(directory); - } - QSettings cookieSettings(directory + QLatin1String("/cookies.ini"), QSettings::IniFormat); - QList cookies = allCookies(); - for (int i = cookies.count() - 1; i >= 0; --i) { - if (cookies.at(i).isSessionCookie()) - cookies.removeAt(i); - } - cookieSettings.setValue(QLatin1String("cookies"), qVariantFromValue >(cookies)); - cookieSettings.beginGroup(QLatin1String("Exceptions")); - cookieSettings.setValue(QLatin1String("block"), m_exceptions_block); - cookieSettings.setValue(QLatin1String("allow"), m_exceptions_allow); - cookieSettings.setValue(QLatin1String("allowForSession"), m_exceptions_allowForSession); - - // save cookie settings - QSettings settings; - settings.beginGroup(QLatin1String("cookies")); - QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); - settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(m_acceptCookies))); - - QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); - settings.setValue(QLatin1String("keepCookiesUntil"), QLatin1String(keepPolicyEnum.valueToKey(m_keepCookies))); -} - -void CookieJar::purgeOldCookies() -{ - QList cookies = allCookies(); - if (cookies.isEmpty()) - return; - int oldCount = cookies.count(); - QDateTime now = QDateTime::currentDateTime(); - for (int i = cookies.count() - 1; i >= 0; --i) { - if (!cookies.at(i).isSessionCookie() && cookies.at(i).expirationDate() < now) - cookies.removeAt(i); - } - if (oldCount == cookies.count()) - return; - setAllCookies(cookies); - emit cookiesChanged(); -} - -QList CookieJar::cookiesForUrl(const QUrl &url) const -{ - CookieJar *that = const_cast(this); - if (!m_loaded) - that->load(); - - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) { - QList noCookies; - return noCookies; - } - - return QNetworkCookieJar::cookiesForUrl(url); -} - -bool CookieJar::setCookiesFromUrl(const QList &cookieList, const QUrl &url) -{ - if (!m_loaded) - load(); - - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - return false; - - QString host = url.host(); - bool eBlock = qBinaryFind(m_exceptions_block.begin(), m_exceptions_block.end(), host) != m_exceptions_block.end(); - bool eAllow = qBinaryFind(m_exceptions_allow.begin(), m_exceptions_allow.end(), host) != m_exceptions_allow.end(); - bool eAllowSession = qBinaryFind(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end(), host) != m_exceptions_allowForSession.end(); - - bool addedCookies = false; - // pass exceptions - bool acceptInitially = (m_acceptCookies != AcceptNever); - if ((acceptInitially && !eBlock) - || (!acceptInitially && (eAllow || eAllowSession))) { - // pass url domain == cookie domain - QDateTime soon = QDateTime::currentDateTime(); - soon = soon.addDays(90); - foreach(QNetworkCookie cookie, cookieList) { - QList lst; - if (m_keepCookies == KeepUntilTimeLimit - && !cookie.isSessionCookie() - && cookie.expirationDate() > soon) { - cookie.setExpirationDate(soon); - } - lst += cookie; - if (QNetworkCookieJar::setCookiesFromUrl(lst, url)) { - addedCookies = true; - } else { - // finally force it in if wanted - if (m_acceptCookies == AcceptAlways) { - QList cookies = allCookies(); - cookies += cookie; - setAllCookies(cookies); - addedCookies = true; - } -#if 0 - else - qWarning() << "setCookiesFromUrl failed" << url << cookieList.value(0).toRawForm(); -#endif - } - } - } - - if (addedCookies) { - m_saveTimer->changeOccurred(); - emit cookiesChanged(); - } - return addedCookies; -} - -CookieJar::AcceptPolicy CookieJar::acceptPolicy() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_acceptCookies; -} - -void CookieJar::setAcceptPolicy(AcceptPolicy policy) -{ - if (!m_loaded) - load(); - if (policy == m_acceptCookies) - return; - m_acceptCookies = policy; - m_saveTimer->changeOccurred(); -} - -CookieJar::KeepPolicy CookieJar::keepPolicy() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_keepCookies; -} - -void CookieJar::setKeepPolicy(KeepPolicy policy) -{ - if (!m_loaded) - load(); - if (policy == m_keepCookies) - return; - m_keepCookies = policy; - m_saveTimer->changeOccurred(); -} - -QStringList CookieJar::blockedCookies() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_exceptions_block; -} - -QStringList CookieJar::allowedCookies() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_exceptions_allow; -} - -QStringList CookieJar::allowForSessionCookies() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_exceptions_allowForSession; -} - -void CookieJar::setBlockedCookies(const QStringList &list) -{ - if (!m_loaded) - load(); - m_exceptions_block = list; - qSort(m_exceptions_block.begin(), m_exceptions_block.end()); - m_saveTimer->changeOccurred(); -} - -void CookieJar::setAllowedCookies(const QStringList &list) -{ - if (!m_loaded) - load(); - m_exceptions_allow = list; - qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); - m_saveTimer->changeOccurred(); -} - -void CookieJar::setAllowForSessionCookies(const QStringList &list) -{ - if (!m_loaded) - load(); - m_exceptions_allowForSession = list; - qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); - m_saveTimer->changeOccurred(); -} - -CookieModel::CookieModel(CookieJar *cookieJar, QObject *parent) - : QAbstractTableModel(parent) - , m_cookieJar(cookieJar) -{ - connect(m_cookieJar, SIGNAL(cookiesChanged()), this, SLOT(cookiesChanged())); - m_cookieJar->load(); -} - -QVariant CookieModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role == Qt::SizeHintRole) { - QFont font; - font.setPointSize(10); - QFontMetrics fm(font); - int height = fm.height() + fm.height()/3; - int width = fm.width(headerData(section, orientation, Qt::DisplayRole).toString()); - return QSize(width, height); - } - - if (orientation == Qt::Horizontal) { - if (role != Qt::DisplayRole) - return QVariant(); - - switch (section) { - case 0: - return tr("Website"); - case 1: - return tr("Name"); - case 2: - return tr("Path"); - case 3: - return tr("Secure"); - case 4: - return tr("Expires"); - case 5: - return tr("Contents"); - default: - return QVariant(); - } - } - return QAbstractTableModel::headerData(section, orientation, role); -} - -QVariant CookieModel::data(const QModelIndex &index, int role) const -{ - QList lst; - if (m_cookieJar) - lst = m_cookieJar->allCookies(); - if (index.row() < 0 || index.row() >= lst.size()) - return QVariant(); - - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - QNetworkCookie cookie = lst.at(index.row()); - switch (index.column()) { - case 0: - return cookie.domain(); - case 1: - return cookie.name(); - case 2: - return cookie.path(); - case 3: - return cookie.isSecure(); - case 4: - return cookie.expirationDate(); - case 5: - return cookie.value(); - } - } - case Qt::FontRole:{ - QFont font; - font.setPointSize(10); - return font; - } - } - - return QVariant(); -} - -int CookieModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 6; -} - -int CookieModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !m_cookieJar) ? 0 : m_cookieJar->allCookies().count(); -} - -bool CookieModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid() || !m_cookieJar) - return false; - int lastRow = row + count - 1; - beginRemoveRows(parent, row, lastRow); - QList lst = m_cookieJar->allCookies(); - for (int i = lastRow; i >= row; --i) { - lst.removeAt(i); - } - m_cookieJar->setAllCookies(lst); - endRemoveRows(); - return true; -} - -void CookieModel::cookiesChanged() -{ - reset(); -} - -CookiesDialog::CookiesDialog(CookieJar *cookieJar, QWidget *parent) : QDialog(parent) -{ - setupUi(this); - setWindowFlags(Qt::Sheet); - CookieModel *model = new CookieModel(cookieJar, this); - m_proxyModel = new QSortFilterProxyModel(this); - connect(search, SIGNAL(textChanged(QString)), - m_proxyModel, SLOT(setFilterFixedString(QString))); - connect(removeButton, SIGNAL(clicked()), cookiesTable, SLOT(removeOne())); - connect(removeAllButton, SIGNAL(clicked()), cookiesTable, SLOT(removeAll())); - m_proxyModel->setSourceModel(model); - cookiesTable->verticalHeader()->hide(); - cookiesTable->setSelectionBehavior(QAbstractItemView::SelectRows); - cookiesTable->setModel(m_proxyModel); - cookiesTable->setAlternatingRowColors(true); - cookiesTable->setTextElideMode(Qt::ElideMiddle); - cookiesTable->setShowGrid(false); - cookiesTable->setSortingEnabled(true); - QFont f = font(); - f.setPointSize(10); - QFontMetrics fm(f); - int height = fm.height() + fm.height()/3; - cookiesTable->verticalHeader()->setDefaultSectionSize(height); - cookiesTable->verticalHeader()->setMinimumSectionSize(-1); - for (int i = 0; i < model->columnCount(); ++i){ - int header = cookiesTable->horizontalHeader()->sectionSizeHint(i); - switch (i) { - case 0: - header = fm.width(QLatin1String("averagehost.domain.com")); - break; - case 1: - header = fm.width(QLatin1String("_session_id")); - break; - case 4: - header = fm.width(QDateTime::currentDateTime().toString(Qt::LocalDate)); - break; - } - int buffer = fm.width(QLatin1String("xx")); - header += buffer; - cookiesTable->horizontalHeader()->resizeSection(i, header); - } - cookiesTable->horizontalHeader()->setStretchLastSection(true); -} - - - -CookieExceptionsModel::CookieExceptionsModel(CookieJar *cookiejar, QObject *parent) - : QAbstractTableModel(parent) - , m_cookieJar(cookiejar) -{ - m_allowedCookies = m_cookieJar->allowedCookies(); - m_blockedCookies = m_cookieJar->blockedCookies(); - m_sessionCookies = m_cookieJar->allowForSessionCookies(); -} - -QVariant CookieExceptionsModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role == Qt::SizeHintRole) { - QFont font; - font.setPointSize(10); - QFontMetrics fm(font); - int height = fm.height() + fm.height()/3; - int width = fm.width(headerData(section, orientation, Qt::DisplayRole).toString()); - return QSize(width, height); - } - - if (orientation == Qt::Horizontal - && role == Qt::DisplayRole) { - switch (section) { - case 0: - return tr("Website"); - case 1: - return tr("Status"); - } - } - return QAbstractTableModel::headerData(section, orientation, role); -} - -QVariant CookieExceptionsModel::data(const QModelIndex &index, int role) const -{ - if (index.row() < 0 || index.row() >= rowCount()) - return QVariant(); - - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - int row = index.row(); - if (row < m_allowedCookies.count()) { - switch (index.column()) { - case 0: - return m_allowedCookies.at(row); - case 1: - return tr("Allow"); - } - } - row = row - m_allowedCookies.count(); - if (row < m_blockedCookies.count()) { - switch (index.column()) { - case 0: - return m_blockedCookies.at(row); - case 1: - return tr("Block"); - } - } - row = row - m_blockedCookies.count(); - if (row < m_sessionCookies.count()) { - switch (index.column()) { - case 0: - return m_sessionCookies.at(row); - case 1: - return tr("Allow For Session"); - } - } - } - case Qt::FontRole:{ - QFont font; - font.setPointSize(10); - return font; - } - } - return QVariant(); -} - -int CookieExceptionsModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 2; -} - -int CookieExceptionsModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !m_cookieJar) ? 0 : m_allowedCookies.count() + m_blockedCookies.count() + m_sessionCookies.count(); -} - -bool CookieExceptionsModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid() || !m_cookieJar) - return false; - - int lastRow = row + count - 1; - beginRemoveRows(parent, row, lastRow); - for (int i = lastRow; i >= row; --i) { - if (i < m_allowedCookies.count()) { - m_allowedCookies.removeAt(row); - continue; - } - i = i - m_allowedCookies.count(); - if (i < m_blockedCookies.count()) { - m_blockedCookies.removeAt(row); - continue; - } - i = i - m_blockedCookies.count(); - if (i < m_sessionCookies.count()) { - m_sessionCookies.removeAt(row); - continue; - } - } - m_cookieJar->setAllowedCookies(m_allowedCookies); - m_cookieJar->setBlockedCookies(m_blockedCookies); - m_cookieJar->setAllowForSessionCookies(m_sessionCookies); - endRemoveRows(); - return true; -} - -CookiesExceptionsDialog::CookiesExceptionsDialog(CookieJar *cookieJar, QWidget *parent) - : QDialog(parent) - , m_cookieJar(cookieJar) -{ - setupUi(this); - setWindowFlags(Qt::Sheet); - connect(removeButton, SIGNAL(clicked()), exceptionTable, SLOT(removeOne())); - connect(removeAllButton, SIGNAL(clicked()), exceptionTable, SLOT(removeAll())); - exceptionTable->verticalHeader()->hide(); - exceptionTable->setSelectionBehavior(QAbstractItemView::SelectRows); - exceptionTable->setAlternatingRowColors(true); - exceptionTable->setTextElideMode(Qt::ElideMiddle); - exceptionTable->setShowGrid(false); - exceptionTable->setSortingEnabled(true); - m_exceptionsModel = new CookieExceptionsModel(cookieJar, this); - m_proxyModel = new QSortFilterProxyModel(this); - m_proxyModel->setSourceModel(m_exceptionsModel); - connect(search, SIGNAL(textChanged(QString)), - m_proxyModel, SLOT(setFilterFixedString(QString))); - exceptionTable->setModel(m_proxyModel); - - CookieModel *cookieModel = new CookieModel(cookieJar, this); - domainLineEdit->setCompleter(new QCompleter(cookieModel, domainLineEdit)); - - connect(domainLineEdit, SIGNAL(textChanged(const QString &)), - this, SLOT(textChanged(const QString &))); - connect(blockButton, SIGNAL(clicked()), this, SLOT(block())); - connect(allowButton, SIGNAL(clicked()), this, SLOT(allow())); - connect(allowForSessionButton, SIGNAL(clicked()), this, SLOT(allowForSession())); - - QFont f = font(); - f.setPointSize(10); - QFontMetrics fm(f); - int height = fm.height() + fm.height()/3; - exceptionTable->verticalHeader()->setDefaultSectionSize(height); - exceptionTable->verticalHeader()->setMinimumSectionSize(-1); - for (int i = 0; i < m_exceptionsModel->columnCount(); ++i){ - int header = exceptionTable->horizontalHeader()->sectionSizeHint(i); - switch (i) { - case 0: - header = fm.width(QLatin1String("averagebiglonghost.domain.com")); - break; - case 1: - header = fm.width(QLatin1String("Allow For Session")); - break; - } - int buffer = fm.width(QLatin1String("xx")); - header += buffer; - exceptionTable->horizontalHeader()->resizeSection(i, header); - } -} - -void CookiesExceptionsDialog::textChanged(const QString &text) -{ - bool enabled = !text.isEmpty(); - blockButton->setEnabled(enabled); - allowButton->setEnabled(enabled); - allowForSessionButton->setEnabled(enabled); -} - -void CookiesExceptionsDialog::block() -{ - if (domainLineEdit->text().isEmpty()) - return; - m_exceptionsModel->m_blockedCookies.append(domainLineEdit->text()); - m_cookieJar->setBlockedCookies(m_exceptionsModel->m_blockedCookies); - m_exceptionsModel->reset(); -} - -void CookiesExceptionsDialog::allow() -{ - if (domainLineEdit->text().isEmpty()) - return; - m_exceptionsModel->m_allowedCookies.append(domainLineEdit->text()); - m_cookieJar->setAllowedCookies(m_exceptionsModel->m_allowedCookies); - m_exceptionsModel->reset(); -} - -void CookiesExceptionsDialog::allowForSession() -{ - if (domainLineEdit->text().isEmpty()) - return; - m_exceptionsModel->m_sessionCookies.append(domainLineEdit->text()); - m_cookieJar->setAllowForSessionCookies(m_exceptionsModel->m_sessionCookies); - m_exceptionsModel->reset(); -} - diff --git a/examples/gestures/browser/cookiejar.h b/examples/gestures/browser/cookiejar.h deleted file mode 100644 index 55ba185..0000000 --- a/examples/gestures/browser/cookiejar.h +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef COOKIEJAR_H -#define COOKIEJAR_H - -#include - -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE -class QSortFilterProxyModel; -class QKeyEvent; -QT_END_NAMESPACE - -class AutoSaver; - -class CookieJar : public QNetworkCookieJar -{ - friend class CookieModel; - Q_OBJECT - Q_PROPERTY(AcceptPolicy acceptPolicy READ acceptPolicy WRITE setAcceptPolicy) - Q_PROPERTY(KeepPolicy keepPolicy READ keepPolicy WRITE setKeepPolicy) - Q_PROPERTY(QStringList blockedCookies READ blockedCookies WRITE setBlockedCookies) - Q_PROPERTY(QStringList allowedCookies READ allowedCookies WRITE setAllowedCookies) - Q_PROPERTY(QStringList allowForSessionCookies READ allowForSessionCookies WRITE setAllowForSessionCookies) - Q_ENUMS(KeepPolicy) - Q_ENUMS(AcceptPolicy) - -signals: - void cookiesChanged(); - -public: - enum AcceptPolicy { - AcceptAlways, - AcceptNever, - AcceptOnlyFromSitesNavigatedTo - }; - - enum KeepPolicy { - KeepUntilExpire, - KeepUntilExit, - KeepUntilTimeLimit - }; - - CookieJar(QObject *parent = 0); - ~CookieJar(); - - QList cookiesForUrl(const QUrl &url) const; - bool setCookiesFromUrl(const QList &cookieList, const QUrl &url); - - AcceptPolicy acceptPolicy() const; - void setAcceptPolicy(AcceptPolicy policy); - - KeepPolicy keepPolicy() const; - void setKeepPolicy(KeepPolicy policy); - - QStringList blockedCookies() const; - QStringList allowedCookies() const; - QStringList allowForSessionCookies() const; - - void setBlockedCookies(const QStringList &list); - void setAllowedCookies(const QStringList &list); - void setAllowForSessionCookies(const QStringList &list); - -public slots: - void clear(); - void loadSettings(); - -private slots: - void save(); - -private: - void purgeOldCookies(); - void load(); - bool m_loaded; - AutoSaver *m_saveTimer; - - AcceptPolicy m_acceptCookies; - KeepPolicy m_keepCookies; - - QStringList m_exceptions_block; - QStringList m_exceptions_allow; - QStringList m_exceptions_allowForSession; -}; - -class CookieModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - CookieModel(CookieJar *jar, QObject *parent = 0); - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private slots: - void cookiesChanged(); - -private: - CookieJar *m_cookieJar; -}; - -#include "ui_cookies.h" -#include "ui_cookiesexceptions.h" - -class CookiesDialog : public QDialog, public Ui_CookiesDialog -{ - Q_OBJECT - -public: - CookiesDialog(CookieJar *cookieJar, QWidget *parent = 0); - -private: - QSortFilterProxyModel *m_proxyModel; -}; - -class CookieExceptionsModel : public QAbstractTableModel -{ - Q_OBJECT - friend class CookiesExceptionsDialog; - -public: - CookieExceptionsModel(CookieJar *cookieJar, QObject *parent = 0); - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private: - CookieJar *m_cookieJar; - - // Domains we allow, Domains we block, Domains we allow for this session - QStringList m_allowedCookies; - QStringList m_blockedCookies; - QStringList m_sessionCookies; -}; - -class CookiesExceptionsDialog : public QDialog, public Ui_CookiesExceptionsDialog -{ - Q_OBJECT - -public: - CookiesExceptionsDialog(CookieJar *cookieJar, QWidget *parent = 0); - -private slots: - void block(); - void allow(); - void allowForSession(); - void textChanged(const QString &text); - -private: - CookieExceptionsModel *m_exceptionsModel; - QSortFilterProxyModel *m_proxyModel; - CookieJar *m_cookieJar; -}; - -#endif // COOKIEJAR_H - diff --git a/examples/gestures/browser/cookies.ui b/examples/gestures/browser/cookies.ui deleted file mode 100644 index c4bccc5..0000000 --- a/examples/gestures/browser/cookies.ui +++ /dev/null @@ -1,106 +0,0 @@ - - CookiesDialog - - - - 0 - 0 - 550 - 370 - - - - Cookies - - - - - - Qt::Horizontal - - - - 252 - 20 - - - - - - - - - - - - - - - - &Remove - - - - - - - Remove &All Cookies - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QDialogButtonBox::Ok - - - - - - - - - - SearchLineEdit - QLineEdit -

searchlineedit.h
- - - EditTableView - QTableView -
edittableview.h
-
- - - - - buttonBox - accepted() - CookiesDialog - accept() - - - 472 - 329 - - - 461 - 356 - - - - - diff --git a/examples/gestures/browser/cookiesexceptions.ui b/examples/gestures/browser/cookiesexceptions.ui deleted file mode 100644 index 3d9ef62..0000000 --- a/examples/gestures/browser/cookiesexceptions.ui +++ /dev/null @@ -1,184 +0,0 @@ - - CookiesExceptionsDialog - - - - 0 - 0 - 466 - 446 - - - - Cookie Exceptions - - - - - - New Exception - - - - - - - - Domain: - - - - - - - - - - - - - - Qt::Horizontal - - - - 81 - 25 - - - - - - - - false - - - Block - - - - - - - false - - - Allow For Session - - - - - - - false - - - Allow - - - - - - - - - - - - Exceptions - - - - - - Qt::Horizontal - - - - 252 - 20 - - - - - - - - - - - - - - &Remove - - - - - - - Remove &All - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Ok - - - - - - - - SearchLineEdit - QLineEdit -
searchlineedit.h
-
- - EditTableView - QTableView -
edittableview.h
-
-
- - - - buttonBox - accepted() - CookiesExceptionsDialog - accept() - - - 381 - 428 - - - 336 - 443 - - - - -
diff --git a/examples/gestures/browser/data/addtab.png b/examples/gestures/browser/data/addtab.png deleted file mode 100644 index 20928fb..0000000 Binary files a/examples/gestures/browser/data/addtab.png and /dev/null differ diff --git a/examples/gestures/browser/data/browser.svg b/examples/gestures/browser/data/browser.svg deleted file mode 100644 index 4b0fa72..0000000 --- a/examples/gestures/browser/data/browser.svg +++ /dev/null @@ -1,411 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Qt Browser - - - Jens Bache-Wiig - - - - - Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/gestures/browser/data/closetab.png b/examples/gestures/browser/data/closetab.png deleted file mode 100644 index ab9d669..0000000 Binary files a/examples/gestures/browser/data/closetab.png and /dev/null differ diff --git a/examples/gestures/browser/data/data.qrc b/examples/gestures/browser/data/data.qrc deleted file mode 100644 index c7d0294..0000000 --- a/examples/gestures/browser/data/data.qrc +++ /dev/null @@ -1,11 +0,0 @@ - - - addtab.png - closetab.png - history.png - browser.svg - defaultbookmarks.xbel - loading.gif - defaulticon.png - - diff --git a/examples/gestures/browser/data/defaultbookmarks.xbel b/examples/gestures/browser/data/defaultbookmarks.xbel deleted file mode 100644 index a168244..0000000 --- a/examples/gestures/browser/data/defaultbookmarks.xbel +++ /dev/null @@ -1,40 +0,0 @@ - - - - - Bookmarks Bar - - Qt Software - - - WebKit.org - - - Qt Documentation - - - Qt Quarterly - - - Qt Labs - - - Qt Centre - - - Qt-Apps.org - - - qtnode - - - xkcd - - - - Bookmarks Menu - - reddit.com: what's new online! - - - diff --git a/examples/gestures/browser/data/defaulticon.png b/examples/gestures/browser/data/defaulticon.png deleted file mode 100644 index 01a0920..0000000 Binary files a/examples/gestures/browser/data/defaulticon.png and /dev/null differ diff --git a/examples/gestures/browser/data/history.png b/examples/gestures/browser/data/history.png deleted file mode 100644 index 552a1cb..0000000 Binary files a/examples/gestures/browser/data/history.png and /dev/null differ diff --git a/examples/gestures/browser/data/loading.gif b/examples/gestures/browser/data/loading.gif deleted file mode 100644 index c1545eb..0000000 Binary files a/examples/gestures/browser/data/loading.gif and /dev/null differ diff --git a/examples/gestures/browser/downloaditem.ui b/examples/gestures/browser/downloaditem.ui deleted file mode 100644 index 4a0a0fd..0000000 --- a/examples/gestures/browser/downloaditem.ui +++ /dev/null @@ -1,134 +0,0 @@ - - DownloadItem - - - - 0 - 0 - 423 - 110 - - - - Form - - - - 0 - - - - - - 0 - 0 - - - - Ico - - - - - - - - - - 0 - 0 - - - - Filename - - - - - - - 0 - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - Qt::Vertical - - - - 17 - 1 - - - - - - - - false - - - Try Again - - - - - - - Stop - - - - - - - Open - - - - - - - Qt::Vertical - - - - 17 - 5 - - - - - - - - - - - SqueezeLabel - QWidget -
squeezelabel.h
-
-
- - -
diff --git a/examples/gestures/browser/downloadmanager.cpp b/examples/gestures/browser/downloadmanager.cpp deleted file mode 100644 index 8e23795..0000000 --- a/examples/gestures/browser/downloadmanager.cpp +++ /dev/null @@ -1,579 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "downloadmanager.h" - -#include "autosaver.h" -#include "browserapplication.h" -#include "networkaccessmanager.h" - -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include - -/*! - DownloadItem is a widget that is displayed in the download manager list. - It moves the data from the QNetworkReply into the QFile as well - as update the information/progressbar and report errors. - */ -DownloadItem::DownloadItem(QNetworkReply *reply, bool requestFileName, QWidget *parent) - : QWidget(parent) - , m_reply(reply) - , m_requestFileName(requestFileName) - , m_bytesReceived(0) -{ - setupUi(this); - QPalette p = downloadInfoLabel->palette(); - p.setColor(QPalette::Text, Qt::darkGray); - downloadInfoLabel->setPalette(p); - progressBar->setMaximum(0); - tryAgainButton->hide(); - connect(stopButton, SIGNAL(clicked()), this, SLOT(stop())); - connect(openButton, SIGNAL(clicked()), this, SLOT(open())); - connect(tryAgainButton, SIGNAL(clicked()), this, SLOT(tryAgain())); - - init(); -} - -void DownloadItem::init() -{ - if (!m_reply) - return; - - // attach to the m_reply - m_url = m_reply->url(); - m_reply->setParent(this); - connect(m_reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead())); - connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), - this, SLOT(error(QNetworkReply::NetworkError))); - connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), - this, SLOT(downloadProgress(qint64, qint64))); - connect(m_reply, SIGNAL(metaDataChanged()), - this, SLOT(metaDataChanged())); - connect(m_reply, SIGNAL(finished()), - this, SLOT(finished())); - - // reset info - downloadInfoLabel->clear(); - progressBar->setValue(0); - getFileName(); - - // start timer for the download estimation - m_downloadTime.start(); - - if (m_reply->error() != QNetworkReply::NoError) { - error(m_reply->error()); - finished(); - } -} - -void DownloadItem::getFileName() -{ - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QString defaultLocation = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); - QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString(); - if (!downloadDirectory.isEmpty()) - downloadDirectory += QLatin1Char('/'); - - QString defaultFileName = saveFileName(downloadDirectory); - QString fileName = defaultFileName; - if (m_requestFileName) { - fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName); - if (fileName.isEmpty()) { - m_reply->close(); - fileNameLabel->setText(tr("Download canceled: %1").arg(QFileInfo(defaultFileName).fileName())); - return; - } - } - m_output.setFileName(fileName); - fileNameLabel->setText(QFileInfo(m_output.fileName()).fileName()); - if (m_requestFileName) - downloadReadyRead(); -} - -QString DownloadItem::saveFileName(const QString &directory) const -{ - // Move this function into QNetworkReply to also get file name sent from the server - QString path = m_url.path(); - QFileInfo info(path); - QString baseName = info.completeBaseName(); - QString endName = info.suffix(); - - if (baseName.isEmpty()) { - baseName = QLatin1String("unnamed_download"); - qDebug() << "DownloadManager:: downloading unknown file:" << m_url; - } - QString name = directory + baseName + QLatin1Char('.') + endName; - if (QFile::exists(name)) { - // already exists, don't overwrite - int i = 1; - do { - name = directory + baseName + QLatin1Char('-') + QString::number(i++) + QLatin1Char('.') + endName; - } while (QFile::exists(name)); - } - return name; -} - - -void DownloadItem::stop() -{ - setUpdatesEnabled(false); - stopButton->setEnabled(false); - stopButton->hide(); - tryAgainButton->setEnabled(true); - tryAgainButton->show(); - setUpdatesEnabled(true); - m_reply->abort(); -} - -void DownloadItem::open() -{ - QFileInfo info(m_output); - QUrl url = QUrl::fromLocalFile(info.absolutePath()); - QDesktopServices::openUrl(url); -} - -void DownloadItem::tryAgain() -{ - if (!tryAgainButton->isEnabled()) - return; - - tryAgainButton->setEnabled(false); - tryAgainButton->setVisible(false); - stopButton->setEnabled(true); - stopButton->setVisible(true); - progressBar->setVisible(true); - - QNetworkReply *r = BrowserApplication::networkAccessManager()->get(QNetworkRequest(m_url)); - if (m_reply) - m_reply->deleteLater(); - if (m_output.exists()) - m_output.remove(); - m_reply = r; - init(); - emit statusChanged(); -} - -void DownloadItem::downloadReadyRead() -{ - if (m_requestFileName && m_output.fileName().isEmpty()) - return; - if (!m_output.isOpen()) { - // in case someone else has already put a file there - if (!m_requestFileName) - getFileName(); - if (!m_output.open(QIODevice::WriteOnly)) { - downloadInfoLabel->setText(tr("Error opening save file: %1") - .arg(m_output.errorString())); - stopButton->click(); - emit statusChanged(); - return; - } - emit statusChanged(); - } - if (-1 == m_output.write(m_reply->readAll())) { - downloadInfoLabel->setText(tr("Error saving: %1") - .arg(m_output.errorString())); - stopButton->click(); - } -} - -void DownloadItem::error(QNetworkReply::NetworkError) -{ - qDebug() << "DownloadItem::error" << m_reply->errorString() << m_url; - downloadInfoLabel->setText(tr("Network Error: %1").arg(m_reply->errorString())); - tryAgainButton->setEnabled(true); - tryAgainButton->setVisible(true); -} - -void DownloadItem::metaDataChanged() -{ - qDebug() << "DownloadItem::metaDataChanged: not handled."; -} - -void DownloadItem::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_bytesReceived = bytesReceived; - if (bytesTotal == -1) { - progressBar->setValue(0); - progressBar->setMaximum(0); - } else { - progressBar->setValue(bytesReceived); - progressBar->setMaximum(bytesTotal); - } - updateInfoLabel(); -} - -void DownloadItem::updateInfoLabel() -{ - if (m_reply->error() == QNetworkReply::NoError) - return; - - qint64 bytesTotal = progressBar->maximum(); - bool running = !downloadedSuccessfully(); - - // update info label - double speed = m_bytesReceived * 1000.0 / m_downloadTime.elapsed(); - double timeRemaining = ((double)(bytesTotal - m_bytesReceived)) / speed; - QString timeRemainingString = tr("seconds"); - if (timeRemaining > 60) { - timeRemaining = timeRemaining / 60; - timeRemainingString = tr("minutes"); - } - timeRemaining = floor(timeRemaining); - - // When downloading the eta should never be 0 - if (timeRemaining == 0) - timeRemaining = 1; - - QString info; - if (running) { - QString remaining; - if (bytesTotal != 0) - remaining = tr("- %4 %5 remaining") - .arg(timeRemaining) - .arg(timeRemainingString); - info = QString(tr("%1 of %2 (%3/sec) %4")) - .arg(dataString(m_bytesReceived)) - .arg(bytesTotal == 0 ? tr("?") : dataString(bytesTotal)) - .arg(dataString((int)speed)) - .arg(remaining); - } else { - if (m_bytesReceived == bytesTotal) - info = dataString(m_output.size()); - else - info = tr("%1 of %2 - Stopped") - .arg(dataString(m_bytesReceived)) - .arg(dataString(bytesTotal)); - } - downloadInfoLabel->setText(info); -} - -QString DownloadItem::dataString(int size) const -{ - QString unit; - if (size < 1024) { - unit = tr("bytes"); - } else if (size < 1024*1024) { - size /= 1024; - unit = tr("kB"); - } else { - size /= 1024*1024; - unit = tr("MB"); - } - return QString(QLatin1String("%1 %2")).arg(size).arg(unit); -} - -bool DownloadItem::downloading() const -{ - return (progressBar->isVisible()); -} - -bool DownloadItem::downloadedSuccessfully() const -{ - return (stopButton->isHidden() && tryAgainButton->isHidden()); -} - -void DownloadItem::finished() -{ - progressBar->hide(); - stopButton->setEnabled(false); - stopButton->hide(); - m_output.close(); - updateInfoLabel(); - emit statusChanged(); -} - -/*! - DownloadManager is a Dialog that contains a list of DownloadItems - - It is a basic download manager. It only downloads the file, doesn't do BitTorrent, - extract zipped files or anything fancy. - */ -DownloadManager::DownloadManager(QWidget *parent) - : QDialog(parent) - , m_autoSaver(new AutoSaver(this)) - , m_manager(BrowserApplication::networkAccessManager()) - , m_iconProvider(0) - , m_removePolicy(Never) -{ - setupUi(this); - downloadsView->setShowGrid(false); - downloadsView->verticalHeader()->hide(); - downloadsView->horizontalHeader()->hide(); - downloadsView->setAlternatingRowColors(true); - downloadsView->horizontalHeader()->setStretchLastSection(true); - m_model = new DownloadModel(this); - downloadsView->setModel(m_model); - connect(cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup())); - load(); -} - -DownloadManager::~DownloadManager() -{ - m_autoSaver->changeOccurred(); - m_autoSaver->saveIfNeccessary(); - if (m_iconProvider) - delete m_iconProvider; -} - -int DownloadManager::activeDownloads() const -{ - int count = 0; - for (int i = 0; i < m_downloads.count(); ++i) { - if (m_downloads.at(i)->stopButton->isEnabled()) - ++count; - } - return count; -} - -void DownloadManager::download(const QNetworkRequest &request, bool requestFileName) -{ - if (request.url().isEmpty()) - return; - handleUnsupportedContent(m_manager->get(request), requestFileName); -} - -void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool requestFileName) -{ - if (!reply || reply->url().isEmpty()) - return; - QVariant header = reply->header(QNetworkRequest::ContentLengthHeader); - bool ok; - int size = header.toInt(&ok); - if (ok && size == 0) - return; - - qDebug() << "DownloadManager::handleUnsupportedContent" << reply->url() << "requestFileName" << requestFileName; - DownloadItem *item = new DownloadItem(reply, requestFileName, this); - addItem(item); -} - -void DownloadManager::addItem(DownloadItem *item) -{ - connect(item, SIGNAL(statusChanged()), this, SLOT(updateRow())); - int row = m_downloads.count(); - m_model->beginInsertRows(QModelIndex(), row, row); - m_downloads.append(item); - m_model->endInsertRows(); - updateItemCount(); - if (row == 0) - show(); - downloadsView->setIndexWidget(m_model->index(row, 0), item); - QIcon icon = style()->standardIcon(QStyle::SP_FileIcon); - item->fileIcon->setPixmap(icon.pixmap(48, 48)); - downloadsView->setRowHeight(row, item->sizeHint().height()); -} - -void DownloadManager::updateRow() -{ - DownloadItem *item = qobject_cast(sender()); - int row = m_downloads.indexOf(item); - if (-1 == row) - return; - if (!m_iconProvider) - m_iconProvider = new QFileIconProvider(); - QIcon icon = m_iconProvider->icon(item->m_output.fileName()); - if (icon.isNull()) - icon = style()->standardIcon(QStyle::SP_FileIcon); - item->fileIcon->setPixmap(icon.pixmap(48, 48)); - downloadsView->setRowHeight(row, item->minimumSizeHint().height()); - - bool remove = false; - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (!item->downloading() - && globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - remove = true; - - if (item->downloadedSuccessfully() - && removePolicy() == DownloadManager::SuccessFullDownload) { - remove = true; - } - if (remove) - m_model->removeRow(row); - - cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0); -} - -DownloadManager::RemovePolicy DownloadManager::removePolicy() const -{ - return m_removePolicy; -} - -void DownloadManager::setRemovePolicy(RemovePolicy policy) -{ - if (policy == m_removePolicy) - return; - m_removePolicy = policy; - m_autoSaver->changeOccurred(); -} - -void DownloadManager::save() const -{ - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy")); - settings.setValue(QLatin1String("removeDownloadsPolicy"), QLatin1String(removePolicyEnum.valueToKey(m_removePolicy))); - settings.setValue(QLatin1String("size"), size()); - if (m_removePolicy == Exit) - return; - - for (int i = 0; i < m_downloads.count(); ++i) { - QString key = QString(QLatin1String("download_%1_")).arg(i); - settings.setValue(key + QLatin1String("url"), m_downloads[i]->m_url); - settings.setValue(key + QLatin1String("location"), QFileInfo(m_downloads[i]->m_output).filePath()); - settings.setValue(key + QLatin1String("done"), m_downloads[i]->downloadedSuccessfully()); - } - int i = m_downloads.count(); - QString key = QString(QLatin1String("download_%1_")).arg(i); - while (settings.contains(key + QLatin1String("url"))) { - settings.remove(key + QLatin1String("url")); - settings.remove(key + QLatin1String("location")); - settings.remove(key + QLatin1String("done")); - key = QString(QLatin1String("download_%1_")).arg(++i); - } -} - -void DownloadManager::load() -{ - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QSize size = settings.value(QLatin1String("size")).toSize(); - if (size.isValid()) - resize(size); - QByteArray value = settings.value(QLatin1String("removeDownloadsPolicy"), QLatin1String("Never")).toByteArray(); - QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy")); - m_removePolicy = removePolicyEnum.keyToValue(value) == -1 ? - Never : - static_cast(removePolicyEnum.keyToValue(value)); - - int i = 0; - QString key = QString(QLatin1String("download_%1_")).arg(i); - while (settings.contains(key + QLatin1String("url"))) { - QUrl url = settings.value(key + QLatin1String("url")).toUrl(); - QString fileName = settings.value(key + QLatin1String("location")).toString(); - bool done = settings.value(key + QLatin1String("done"), true).toBool(); - if (!url.isEmpty() && !fileName.isEmpty()) { - DownloadItem *item = new DownloadItem(0, this); - item->m_output.setFileName(fileName); - item->fileNameLabel->setText(QFileInfo(item->m_output.fileName()).fileName()); - item->m_url = url; - item->stopButton->setVisible(false); - item->stopButton->setEnabled(false); - item->tryAgainButton->setVisible(!done); - item->tryAgainButton->setEnabled(!done); - item->progressBar->setVisible(!done); - addItem(item); - } - key = QString(QLatin1String("download_%1_")).arg(++i); - } - cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0); -} - -void DownloadManager::cleanup() -{ - if (m_downloads.isEmpty()) - return; - m_model->removeRows(0, m_downloads.count()); - updateItemCount(); - if (m_downloads.isEmpty() && m_iconProvider) { - delete m_iconProvider; - m_iconProvider = 0; - } - m_autoSaver->changeOccurred(); -} - -void DownloadManager::updateItemCount() -{ - int count = m_downloads.count(); - itemCount->setText(count == 1 ? tr("1 Download") : tr("%1 Downloads").arg(count)); -} - -DownloadModel::DownloadModel(DownloadManager *downloadManager, QObject *parent) - : QAbstractListModel(parent) - , m_downloadManager(downloadManager) -{ -} - -QVariant DownloadModel::data(const QModelIndex &index, int role) const -{ - if (index.row() < 0 || index.row() >= rowCount(index.parent())) - return QVariant(); - if (role == Qt::ToolTipRole) - if (!m_downloadManager->m_downloads.at(index.row())->downloadedSuccessfully()) - return m_downloadManager->m_downloads.at(index.row())->downloadInfoLabel->text(); - return QVariant(); -} - -int DownloadModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : m_downloadManager->m_downloads.count(); -} - -bool DownloadModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid()) - return false; - - int lastRow = row + count - 1; - for (int i = lastRow; i >= row; --i) { - if (m_downloadManager->m_downloads.at(i)->downloadedSuccessfully() - || m_downloadManager->m_downloads.at(i)->tryAgainButton->isEnabled()) { - beginRemoveRows(parent, i, i); - m_downloadManager->m_downloads.takeAt(i)->deleteLater(); - endRemoveRows(); - } - } - m_downloadManager->m_autoSaver->changeOccurred(); - return true; -} - diff --git a/examples/gestures/browser/downloadmanager.h b/examples/gestures/browser/downloadmanager.h deleted file mode 100644 index af13fec..0000000 --- a/examples/gestures/browser/downloadmanager.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DOWNLOADMANAGER_H -#define DOWNLOADMANAGER_H - -#include "ui_downloads.h" -#include "ui_downloaditem.h" - -#include - -#include -#include - -class DownloadItem : public QWidget, public Ui_DownloadItem -{ - Q_OBJECT - -signals: - void statusChanged(); - -public: - DownloadItem(QNetworkReply *reply = 0, bool requestFileName = false, QWidget *parent = 0); - bool downloading() const; - bool downloadedSuccessfully() const; - - QUrl m_url; - - QFile m_output; - QNetworkReply *m_reply; - -private slots: - void stop(); - void tryAgain(); - void open(); - - void downloadReadyRead(); - void error(QNetworkReply::NetworkError code); - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - void metaDataChanged(); - void finished(); - -private: - void getFileName(); - void init(); - void updateInfoLabel(); - QString dataString(int size) const; - - QString saveFileName(const QString &directory) const; - - bool m_requestFileName; - qint64 m_bytesReceived; - QTime m_downloadTime; -}; - -class AutoSaver; -class DownloadModel; -QT_BEGIN_NAMESPACE -class QFileIconProvider; -QT_END_NAMESPACE - -class DownloadManager : public QDialog, public Ui_DownloadDialog -{ - Q_OBJECT - Q_PROPERTY(RemovePolicy removePolicy READ removePolicy WRITE setRemovePolicy) - Q_ENUMS(RemovePolicy) - -public: - enum RemovePolicy { - Never, - Exit, - SuccessFullDownload - }; - - DownloadManager(QWidget *parent = 0); - ~DownloadManager(); - int activeDownloads() const; - - RemovePolicy removePolicy() const; - void setRemovePolicy(RemovePolicy policy); - -public slots: - void download(const QNetworkRequest &request, bool requestFileName = false); - inline void download(const QUrl &url, bool requestFileName = false) - { download(QNetworkRequest(url), requestFileName); } - void handleUnsupportedContent(QNetworkReply *reply, bool requestFileName = false); - void cleanup(); - -private slots: - void save() const; - void updateRow(); - -private: - void addItem(DownloadItem *item); - void updateItemCount(); - void load(); - - AutoSaver *m_autoSaver; - DownloadModel *m_model; - QNetworkAccessManager *m_manager; - QFileIconProvider *m_iconProvider; - QList m_downloads; - RemovePolicy m_removePolicy; - friend class DownloadModel; -}; - -class DownloadModel : public QAbstractListModel -{ - friend class DownloadManager; - Q_OBJECT - -public: - DownloadModel(DownloadManager *downloadManager, QObject *parent = 0); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private: - DownloadManager *m_downloadManager; - -}; - -#endif // DOWNLOADMANAGER_H - diff --git a/examples/gestures/browser/downloads.ui b/examples/gestures/browser/downloads.ui deleted file mode 100644 index a2e2569..0000000 --- a/examples/gestures/browser/downloads.ui +++ /dev/null @@ -1,83 +0,0 @@ - - DownloadDialog - - - - 0 - 0 - 332 - 252 - - - - Downloads - - - - 0 - - - 0 - - - - - - - - - - false - - - Clean up - - - - - - - Qt::Horizontal - - - - 58 - 24 - - - - - - - - - - 0 Items - - - - - - - Qt::Horizontal - - - - 148 - 20 - - - - - - - - - EditTableView - QTableView -
edittableview.h
-
-
- - -
diff --git a/examples/gestures/browser/edittableview.cpp b/examples/gestures/browser/edittableview.cpp deleted file mode 100644 index f7d5e67..0000000 --- a/examples/gestures/browser/edittableview.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "edittableview.h" -#include - -EditTableView::EditTableView(QWidget *parent) - : QTableView(parent) -{ -} - -void EditTableView::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Delete - || event->key() == Qt::Key_Backspace) - && model()) { - removeOne(); - } else { - QAbstractItemView::keyPressEvent(event); - } -} - -void EditTableView::removeOne() -{ - if (!model() || !selectionModel()) - return; - int row = currentIndex().row(); - model()->removeRow(row, rootIndex()); - QModelIndex idx = model()->index(row, 0, rootIndex()); - if (!idx.isValid()) - idx = model()->index(row - 1, 0, rootIndex()); - selectionModel()->select(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); -} - -void EditTableView::removeAll() -{ - if (model()) - model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); -} - diff --git a/examples/gestures/browser/edittableview.h b/examples/gestures/browser/edittableview.h deleted file mode 100644 index fb033ce..0000000 --- a/examples/gestures/browser/edittableview.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EDITTABLEVIEW_H -#define EDITTABLEVIEW_H - -#include - -class EditTableView : public QTableView -{ - Q_OBJECT - -public: - EditTableView(QWidget *parent = 0); - void keyPressEvent(QKeyEvent *event); - -public slots: - void removeOne(); - void removeAll(); -}; - -#endif // EDITTABLEVIEW_H - diff --git a/examples/gestures/browser/edittreeview.cpp b/examples/gestures/browser/edittreeview.cpp deleted file mode 100644 index c7cefe6..0000000 --- a/examples/gestures/browser/edittreeview.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "edittreeview.h" - -#include - -EditTreeView::EditTreeView(QWidget *parent) - : QTreeView(parent) -{ -} - -void EditTreeView::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Delete - || event->key() == Qt::Key_Backspace) - && model()) { - removeOne(); - } else { - QAbstractItemView::keyPressEvent(event); - } -} - -void EditTreeView::removeOne() -{ - if (!model()) - return; - QModelIndex ci = currentIndex(); - int row = ci.row(); - model()->removeRow(row, ci.parent()); -} - -void EditTreeView::removeAll() -{ - if (!model()) - return; - model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); -} - diff --git a/examples/gestures/browser/edittreeview.h b/examples/gestures/browser/edittreeview.h deleted file mode 100644 index 3a6fcaf..0000000 --- a/examples/gestures/browser/edittreeview.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EDITTREEVIEW_H -#define EDITTREEVIEW_H - -#include - -class EditTreeView : public QTreeView -{ - Q_OBJECT - -public: - EditTreeView(QWidget *parent = 0); - void keyPressEvent(QKeyEvent *event); - -public slots: - void removeOne(); - void removeAll(); -}; - -#endif // EDITTREEVIEW_H - diff --git a/examples/gestures/browser/history.cpp b/examples/gestures/browser/history.cpp deleted file mode 100644 index 0e0652d..0000000 --- a/examples/gestures/browser/history.cpp +++ /dev/null @@ -1,1282 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "history.h" - -#include "autosaver.h" -#include "browserapplication.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include - -static const unsigned int HISTORY_VERSION = 23; - -HistoryManager::HistoryManager(QObject *parent) - : QWebHistoryInterface(parent) - , m_saveTimer(new AutoSaver(this)) - , m_historyLimit(30) - , m_historyModel(0) - , m_historyFilterModel(0) - , m_historyTreeModel(0) -{ - m_expiredTimer.setSingleShot(true); - connect(&m_expiredTimer, SIGNAL(timeout()), - this, SLOT(checkForExpired())); - connect(this, SIGNAL(entryAdded(const HistoryItem &)), - m_saveTimer, SLOT(changeOccurred())); - connect(this, SIGNAL(entryRemoved(const HistoryItem &)), - m_saveTimer, SLOT(changeOccurred())); - load(); - - m_historyModel = new HistoryModel(this, this); - m_historyFilterModel = new HistoryFilterModel(m_historyModel, this); - m_historyTreeModel = new HistoryTreeModel(m_historyFilterModel, this); - - // QWebHistoryInterface will delete the history manager - QWebHistoryInterface::setDefaultInterface(this); -} - -HistoryManager::~HistoryManager() -{ - m_saveTimer->saveIfNeccessary(); -} - -QList HistoryManager::history() const -{ - return m_history; -} - -bool HistoryManager::historyContains(const QString &url) const -{ - return m_historyFilterModel->historyContains(url); -} - -void HistoryManager::addHistoryEntry(const QString &url) -{ - QUrl cleanUrl(url); - cleanUrl.setPassword(QString()); - cleanUrl.setHost(cleanUrl.host().toLower()); - HistoryItem item(cleanUrl.toString(), QDateTime::currentDateTime()); - addHistoryItem(item); -} - -void HistoryManager::setHistory(const QList &history, bool loadedAndSorted) -{ - m_history = history; - - // verify that it is sorted by date - if (!loadedAndSorted) - qSort(m_history.begin(), m_history.end()); - - checkForExpired(); - - if (loadedAndSorted) { - m_lastSavedUrl = m_history.value(0).url; - } else { - m_lastSavedUrl = QString(); - m_saveTimer->changeOccurred(); - } - emit historyReset(); -} - -HistoryModel *HistoryManager::historyModel() const -{ - return m_historyModel; -} - -HistoryFilterModel *HistoryManager::historyFilterModel() const -{ - return m_historyFilterModel; -} - -HistoryTreeModel *HistoryManager::historyTreeModel() const -{ - return m_historyTreeModel; -} - -void HistoryManager::checkForExpired() -{ - if (m_historyLimit < 0 || m_history.isEmpty()) - return; - - QDateTime now = QDateTime::currentDateTime(); - int nextTimeout = 0; - - while (!m_history.isEmpty()) { - QDateTime checkForExpired = m_history.last().dateTime; - checkForExpired.setDate(checkForExpired.date().addDays(m_historyLimit)); - if (now.daysTo(checkForExpired) > 7) { - // check at most in a week to prevent int overflows on the timer - nextTimeout = 7 * 86400; - } else { - nextTimeout = now.secsTo(checkForExpired); - } - if (nextTimeout > 0) - break; - HistoryItem item = m_history.takeLast(); - // remove from saved file also - m_lastSavedUrl = QString(); - emit entryRemoved(item); - } - - if (nextTimeout > 0) - m_expiredTimer.start(nextTimeout * 1000); -} - -void HistoryManager::addHistoryItem(const HistoryItem &item) -{ - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - return; - - m_history.prepend(item); - emit entryAdded(item); - if (m_history.count() == 1) - checkForExpired(); -} - -void HistoryManager::updateHistoryItem(const QUrl &url, const QString &title) -{ - for (int i = 0; i < m_history.count(); ++i) { - if (url == m_history.at(i).url) { - m_history[i].title = title; - m_saveTimer->changeOccurred(); - if (m_lastSavedUrl.isEmpty()) - m_lastSavedUrl = m_history.at(i).url; - emit entryUpdated(i); - break; - } - } -} - -int HistoryManager::historyLimit() const -{ - return m_historyLimit; -} - -void HistoryManager::setHistoryLimit(int limit) -{ - if (m_historyLimit == limit) - return; - m_historyLimit = limit; - checkForExpired(); - m_saveTimer->changeOccurred(); -} - -void HistoryManager::clear() -{ - m_history.clear(); - m_lastSavedUrl = QString(); - m_saveTimer->changeOccurred(); - m_saveTimer->saveIfNeccessary(); - historyReset(); -} - -void HistoryManager::loadSettings() -{ - // load settings - QSettings settings; - settings.beginGroup(QLatin1String("history")); - m_historyLimit = settings.value(QLatin1String("historyLimit"), 30).toInt(); -} - -void HistoryManager::load() -{ - loadSettings(); - - QFile historyFile(QDesktopServices::storageLocation(QDesktopServices::DataLocation) - + QLatin1String("/history")); - if (!historyFile.exists()) - return; - if (!historyFile.open(QFile::ReadOnly)) { - qWarning() << "Unable to open history file" << historyFile.fileName(); - return; - } - - QList list; - QDataStream in(&historyFile); - // Double check that the history file is sorted as it is read in - bool needToSort = false; - HistoryItem lastInsertedItem; - QByteArray data; - QDataStream stream; - QBuffer buffer; - stream.setDevice(&buffer); - while (!historyFile.atEnd()) { - in >> data; - buffer.close(); - buffer.setBuffer(&data); - buffer.open(QIODevice::ReadOnly); - quint32 ver; - stream >> ver; - if (ver != HISTORY_VERSION) - continue; - HistoryItem item; - stream >> item.url; - stream >> item.dateTime; - stream >> item.title; - - if (!item.dateTime.isValid()) - continue; - - if (item == lastInsertedItem) { - if (lastInsertedItem.title.isEmpty() && !list.isEmpty()) - list[0].title = item.title; - continue; - } - - if (!needToSort && !list.isEmpty() && lastInsertedItem < item) - needToSort = true; - - list.prepend(item); - lastInsertedItem = item; - } - if (needToSort) - qSort(list.begin(), list.end()); - - setHistory(list, true); - - // If we had to sort re-write the whole history sorted - if (needToSort) { - m_lastSavedUrl = QString(); - m_saveTimer->changeOccurred(); - } -} - -void HistoryManager::save() -{ - QSettings settings; - settings.beginGroup(QLatin1String("history")); - settings.setValue(QLatin1String("historyLimit"), m_historyLimit); - - bool saveAll = m_lastSavedUrl.isEmpty(); - int first = m_history.count() - 1; - if (!saveAll) { - // find the first one to save - for (int i = 0; i < m_history.count(); ++i) { - if (m_history.at(i).url == m_lastSavedUrl) { - first = i - 1; - break; - } - } - } - if (first == m_history.count() - 1) - saveAll = true; - - QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - if (directory.isEmpty()) - directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - if (!QFile::exists(directory)) { - QDir dir; - dir.mkpath(directory); - } - - QFile historyFile(directory + QLatin1String("/history")); - // When saving everything use a temporary file to prevent possible data loss. - QTemporaryFile tempFile; - tempFile.setAutoRemove(false); - bool open = false; - if (saveAll) { - open = tempFile.open(); - } else { - open = historyFile.open(QFile::Append); - } - - if (!open) { - qWarning() << "Unable to open history file for saving" - << (saveAll ? tempFile.fileName() : historyFile.fileName()); - return; - } - - QDataStream out(saveAll ? &tempFile : &historyFile); - for (int i = first; i >= 0; --i) { - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - HistoryItem item = m_history.at(i); - stream << HISTORY_VERSION << item.url << item.dateTime << item.title; - out << data; - } - tempFile.close(); - - if (saveAll) { - if (historyFile.exists() && !historyFile.remove()) - qWarning() << "History: error removing old history." << historyFile.errorString(); - if (!tempFile.rename(historyFile.fileName())) - qWarning() << "History: error moving new history over old." << tempFile.errorString() << historyFile.fileName(); - } - m_lastSavedUrl = m_history.value(0).url; -} - -HistoryModel::HistoryModel(HistoryManager *history, QObject *parent) - : QAbstractTableModel(parent) - , m_history(history) -{ - Q_ASSERT(m_history); - connect(m_history, SIGNAL(historyReset()), - this, SLOT(historyReset())); - connect(m_history, SIGNAL(entryRemoved(const HistoryItem &)), - this, SLOT(historyReset())); - - connect(m_history, SIGNAL(entryAdded(const HistoryItem &)), - this, SLOT(entryAdded())); - connect(m_history, SIGNAL(entryUpdated(int)), - this, SLOT(entryUpdated(int))); -} - -void HistoryModel::historyReset() -{ - reset(); -} - -void HistoryModel::entryAdded() -{ - beginInsertRows(QModelIndex(), 0, 0); - endInsertRows(); -} - -void HistoryModel::entryUpdated(int offset) -{ - QModelIndex idx = index(offset, 0); - emit dataChanged(idx, idx); -} - -QVariant HistoryModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal - && role == Qt::DisplayRole) { - switch (section) { - case 0: return tr("Title"); - case 1: return tr("Address"); - } - } - return QAbstractTableModel::headerData(section, orientation, role); -} - -QVariant HistoryModel::data(const QModelIndex &index, int role) const -{ - QList lst = m_history->history(); - if (index.row() < 0 || index.row() >= lst.size()) - return QVariant(); - - const HistoryItem &item = lst.at(index.row()); - switch (role) { - case DateTimeRole: - return item.dateTime; - case DateRole: - return item.dateTime.date(); - case UrlRole: - return QUrl(item.url); - case UrlStringRole: - return item.url; - case Qt::DisplayRole: - case Qt::EditRole: { - switch (index.column()) { - case 0: - // when there is no title try to generate one from the url - if (item.title.isEmpty()) { - QString page = QFileInfo(QUrl(item.url).path()).fileName(); - if (!page.isEmpty()) - return page; - return item.url; - } - return item.title; - case 1: - return item.url; - } - } - case Qt::DecorationRole: - if (index.column() == 0) { - return BrowserApplication::instance()->icon(item.url); - } - } - return QVariant(); -} - -int HistoryModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 2; -} - -int HistoryModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : m_history->history().count(); -} - -bool HistoryModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid()) - return false; - int lastRow = row + count - 1; - beginRemoveRows(parent, row, lastRow); - QList lst = m_history->history(); - for (int i = lastRow; i >= row; --i) - lst.removeAt(i); - disconnect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); - m_history->setHistory(lst); - connect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); - endRemoveRows(); - return true; -} - -#define MOVEDROWS 15 - -/* - Maps the first bunch of items of the source model to the root -*/ -HistoryMenuModel::HistoryMenuModel(HistoryTreeModel *sourceModel, QObject *parent) - : QAbstractProxyModel(parent) - , m_treeModel(sourceModel) -{ - setSourceModel(sourceModel); -} - -int HistoryMenuModel::bumpedRows() const -{ - QModelIndex first = m_treeModel->index(0, 0); - if (!first.isValid()) - return 0; - return qMin(m_treeModel->rowCount(first), MOVEDROWS); -} - -int HistoryMenuModel::columnCount(const QModelIndex &parent) const -{ - return m_treeModel->columnCount(mapToSource(parent)); -} - -int HistoryMenuModel::rowCount(const QModelIndex &parent) const -{ - if (parent.column() > 0) - return 0; - - if (!parent.isValid()) { - int folders = sourceModel()->rowCount(); - int bumpedItems = bumpedRows(); - if (bumpedItems <= MOVEDROWS - && bumpedItems == sourceModel()->rowCount(sourceModel()->index(0, 0))) - --folders; - return bumpedItems + folders; - } - - if (parent.internalId() == -1) { - if (parent.row() < bumpedRows()) - return 0; - } - - QModelIndex idx = mapToSource(parent); - int defaultCount = sourceModel()->rowCount(idx); - if (idx == sourceModel()->index(0, 0)) - return defaultCount - bumpedRows(); - return defaultCount; -} - -QModelIndex HistoryMenuModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - // currently not used or autotested - Q_ASSERT(false); - int sr = m_treeModel->mapToSource(sourceIndex).row(); - return createIndex(sourceIndex.row(), sourceIndex.column(), sr); -} - -QModelIndex HistoryMenuModel::mapToSource(const QModelIndex &proxyIndex) const -{ - if (!proxyIndex.isValid()) - return QModelIndex(); - - if (proxyIndex.internalId() == -1) { - int bumpedItems = bumpedRows(); - if (proxyIndex.row() < bumpedItems) - return m_treeModel->index(proxyIndex.row(), proxyIndex.column(), m_treeModel->index(0, 0)); - if (bumpedItems <= MOVEDROWS && bumpedItems == sourceModel()->rowCount(m_treeModel->index(0, 0))) - --bumpedItems; - return m_treeModel->index(proxyIndex.row() - bumpedItems, proxyIndex.column()); - } - - QModelIndex historyIndex = m_treeModel->sourceModel()->index(proxyIndex.internalId(), proxyIndex.column()); - QModelIndex treeIndex = m_treeModel->mapFromSource(historyIndex); - return treeIndex; -} - -QModelIndex HistoryMenuModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 - || column < 0 || column >= columnCount(parent) - || parent.column() > 0) - return QModelIndex(); - if (!parent.isValid()) - return createIndex(row, column, -1); - - QModelIndex treeIndexParent = mapToSource(parent); - - int bumpedItems = 0; - if (treeIndexParent == m_treeModel->index(0, 0)) - bumpedItems = bumpedRows(); - QModelIndex treeIndex = m_treeModel->index(row + bumpedItems, column, treeIndexParent); - QModelIndex historyIndex = m_treeModel->mapToSource(treeIndex); - int historyRow = historyIndex.row(); - if (historyRow == -1) - historyRow = treeIndex.row(); - return createIndex(row, column, historyRow); -} - -QModelIndex HistoryMenuModel::parent(const QModelIndex &index) const -{ - int offset = index.internalId(); - if (offset == -1 || !index.isValid()) - return QModelIndex(); - - QModelIndex historyIndex = m_treeModel->sourceModel()->index(index.internalId(), 0); - QModelIndex treeIndex = m_treeModel->mapFromSource(historyIndex); - QModelIndex treeIndexParent = treeIndex.parent(); - - int sr = m_treeModel->mapToSource(treeIndexParent).row(); - int bumpedItems = bumpedRows(); - if (bumpedItems <= MOVEDROWS && bumpedItems == sourceModel()->rowCount(sourceModel()->index(0, 0))) - --bumpedItems; - return createIndex(bumpedItems + treeIndexParent.row(), treeIndexParent.column(), sr); -} - - -HistoryMenu::HistoryMenu(QWidget *parent) - : ModelMenu(parent) - , m_history(0) -{ - connect(this, SIGNAL(activated(const QModelIndex &)), - this, SLOT(activated(const QModelIndex &))); - setHoverRole(HistoryModel::UrlStringRole); -} - -void HistoryMenu::activated(const QModelIndex &index) -{ - emit openUrl(index.data(HistoryModel::UrlRole).toUrl()); -} - -bool HistoryMenu::prePopulated() -{ - if (!m_history) { - m_history = BrowserApplication::historyManager(); - m_historyMenuModel = new HistoryMenuModel(m_history->historyTreeModel(), this); - setModel(m_historyMenuModel); - } - // initial actions - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); - if (!m_initialActions.isEmpty()) - addSeparator(); - setFirstSeparator(m_historyMenuModel->bumpedRows()); - - return false; -} - -void HistoryMenu::postPopulated() -{ - if (m_history->history().count() > 0) - addSeparator(); - - QAction *showAllAction = new QAction(tr("Show All History"), this); - connect(showAllAction, SIGNAL(triggered()), this, SLOT(showHistoryDialog())); - addAction(showAllAction); - - QAction *clearAction = new QAction(tr("Clear History"), this); - connect(clearAction, SIGNAL(triggered()), m_history, SLOT(clear())); - addAction(clearAction); -} - -void HistoryMenu::showHistoryDialog() -{ - HistoryDialog *dialog = new HistoryDialog(this); - connect(dialog, SIGNAL(openUrl(const QUrl&)), - this, SIGNAL(openUrl(const QUrl&))); - dialog->show(); -} - -void HistoryMenu::setInitialActions(QList actions) -{ - m_initialActions = actions; - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); -} - -TreeProxyModel::TreeProxyModel(QObject *parent) : QSortFilterProxyModel(parent) -{ - setSortRole(HistoryModel::DateTimeRole); - setFilterCaseSensitivity(Qt::CaseInsensitive); -} - -bool TreeProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const -{ - if (!source_parent.isValid()) - return true; - return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); -} - -HistoryDialog::HistoryDialog(QWidget *parent, HistoryManager *setHistory) : QDialog(parent) -{ - HistoryManager *history = setHistory; - if (!history) - history = BrowserApplication::historyManager(); - setupUi(this); - tree->setUniformRowHeights(true); - tree->setSelectionBehavior(QAbstractItemView::SelectRows); - tree->setTextElideMode(Qt::ElideMiddle); - QAbstractItemModel *model = history->historyTreeModel(); - TreeProxyModel *proxyModel = new TreeProxyModel(this); - connect(search, SIGNAL(textChanged(QString)), - proxyModel, SLOT(setFilterFixedString(QString))); - connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeOne())); - connect(removeAllButton, SIGNAL(clicked()), history, SLOT(clear())); - proxyModel->setSourceModel(model); - tree->setModel(proxyModel); - tree->setExpanded(proxyModel->index(0, 0), true); - tree->setAlternatingRowColors(true); - QFontMetrics fm(font()); - int header = fm.width(QLatin1Char('m')) * 40; - tree->header()->resizeSection(0, header); - tree->header()->setStretchLastSection(true); - connect(tree, SIGNAL(activated(const QModelIndex&)), - this, SLOT(open())); - tree->setContextMenuPolicy(Qt::CustomContextMenu); - connect(tree, SIGNAL(customContextMenuRequested(const QPoint &)), - this, SLOT(customContextMenuRequested(const QPoint &))); -} - -void HistoryDialog::customContextMenuRequested(const QPoint &pos) -{ - QMenu menu; - QModelIndex index = tree->indexAt(pos); - index = index.sibling(index.row(), 0); - if (index.isValid() && !tree->model()->hasChildren(index)) { - menu.addAction(tr("Open"), this, SLOT(open())); - menu.addSeparator(); - menu.addAction(tr("Copy"), this, SLOT(copy())); - } - menu.addAction(tr("Delete"), tree, SLOT(removeOne())); - menu.exec(QCursor::pos()); -} - -void HistoryDialog::open() -{ - QModelIndex index = tree->currentIndex(); - if (!index.parent().isValid()) - return; - emit openUrl(index.data(HistoryModel::UrlRole).toUrl()); -} - -void HistoryDialog::copy() -{ - QModelIndex index = tree->currentIndex(); - if (!index.parent().isValid()) - return; - QString url = index.data(HistoryModel::UrlStringRole).toString(); - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(url); -} - -HistoryFilterModel::HistoryFilterModel(QAbstractItemModel *sourceModel, QObject *parent) - : QAbstractProxyModel(parent), - m_loaded(false) -{ - setSourceModel(sourceModel); -} - -int HistoryFilterModel::historyLocation(const QString &url) const -{ - load(); - if (!m_historyHash.contains(url)) - return 0; - return sourceModel()->rowCount() - m_historyHash.value(url); -} - -QVariant HistoryFilterModel::data(const QModelIndex &index, int role) const -{ - return QAbstractProxyModel::data(index, role); -} - -void HistoryFilterModel::setSourceModel(QAbstractItemModel *newSourceModel) -{ - if (sourceModel()) { - disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), - this, SLOT(dataChanged(const QModelIndex &, const QModelIndex &))); - disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - } - - QAbstractProxyModel::setSourceModel(newSourceModel); - - if (sourceModel()) { - m_loaded = false; - connect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), - this, SLOT(sourceDataChanged(const QModelIndex &, const QModelIndex &))); - connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - } -} - -void HistoryFilterModel::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight)); -} - -QVariant HistoryFilterModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - return sourceModel()->headerData(section, orientation, role); -} - -void HistoryFilterModel::sourceReset() -{ - m_loaded = false; - reset(); -} - -int HistoryFilterModel::rowCount(const QModelIndex &parent) const -{ - load(); - if (parent.isValid()) - return 0; - return m_historyHash.count(); -} - -int HistoryFilterModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 2; -} - -QModelIndex HistoryFilterModel::mapToSource(const QModelIndex &proxyIndex) const -{ - load(); - int sourceRow = sourceModel()->rowCount() - proxyIndex.internalId(); - return sourceModel()->index(sourceRow, proxyIndex.column()); -} - -QModelIndex HistoryFilterModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - load(); - QString url = sourceIndex.data(HistoryModel::UrlStringRole).toString(); - if (!m_historyHash.contains(url)) - return QModelIndex(); - - // This can be done in a binary search, but we can't use qBinary find - // because it can't take: qBinaryFind(m_sourceRow.end(), m_sourceRow.begin(), v); - // so if this is a performance bottlneck then convert to binary search, until then - // the cleaner/easier to read code wins the day. - int realRow = -1; - int sourceModelRow = sourceModel()->rowCount() - sourceIndex.row(); - - for (int i = 0; i < m_sourceRow.count(); ++i) { - if (m_sourceRow.at(i) == sourceModelRow) { - realRow = i; - break; - } - } - if (realRow == -1) - return QModelIndex(); - - return createIndex(realRow, sourceIndex.column(), sourceModel()->rowCount() - sourceIndex.row()); -} - -QModelIndex HistoryFilterModel::index(int row, int column, const QModelIndex &parent) const -{ - load(); - if (row < 0 || row >= rowCount(parent) - || column < 0 || column >= columnCount(parent)) - return QModelIndex(); - - return createIndex(row, column, m_sourceRow[row]); -} - -QModelIndex HistoryFilterModel::parent(const QModelIndex &) const -{ - return QModelIndex(); -} - -void HistoryFilterModel::load() const -{ - if (m_loaded) - return; - m_sourceRow.clear(); - m_historyHash.clear(); - m_historyHash.reserve(sourceModel()->rowCount()); - for (int i = 0; i < sourceModel()->rowCount(); ++i) { - QModelIndex idx = sourceModel()->index(i, 0); - QString url = idx.data(HistoryModel::UrlStringRole).toString(); - if (!m_historyHash.contains(url)) { - m_sourceRow.append(sourceModel()->rowCount() - i); - m_historyHash[url] = sourceModel()->rowCount() - i; - } - } - m_loaded = true; -} - -void HistoryFilterModel::sourceRowsInserted(const QModelIndex &parent, int start, int end) -{ - Q_ASSERT(start == end && start == 0); - Q_UNUSED(end); - if (!m_loaded) - return; - QModelIndex idx = sourceModel()->index(start, 0, parent); - QString url = idx.data(HistoryModel::UrlStringRole).toString(); - if (m_historyHash.contains(url)) { - int sourceRow = sourceModel()->rowCount() - m_historyHash[url]; - int realRow = mapFromSource(sourceModel()->index(sourceRow, 0)).row(); - beginRemoveRows(QModelIndex(), realRow, realRow); - m_sourceRow.removeAt(realRow); - m_historyHash.remove(url); - endRemoveRows(); - } - beginInsertRows(QModelIndex(), 0, 0); - m_historyHash.insert(url, sourceModel()->rowCount() - start); - m_sourceRow.insert(0, sourceModel()->rowCount()); - endInsertRows(); -} - -void HistoryFilterModel::sourceRowsRemoved(const QModelIndex &, int start, int end) -{ - Q_UNUSED(start); - Q_UNUSED(end); - sourceReset(); -} - -/* - Removing a continuous block of rows will remove filtered rows too as this is - the users intention. -*/ -bool HistoryFilterModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (row < 0 || count <= 0 || row + count > rowCount(parent) || parent.isValid()) - return false; - int lastRow = row + count - 1; - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - beginRemoveRows(parent, row, lastRow); - int oldCount = rowCount(); - int start = sourceModel()->rowCount() - m_sourceRow.value(row); - int end = sourceModel()->rowCount() - m_sourceRow.value(lastRow); - sourceModel()->removeRows(start, end - start + 1); - endRemoveRows(); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - m_loaded = false; - if (oldCount - count != rowCount()) - reset(); - return true; -} - -HistoryCompletionModel::HistoryCompletionModel(QObject *parent) - : QAbstractProxyModel(parent) -{ -} - -QVariant HistoryCompletionModel::data(const QModelIndex &index, int role) const -{ - if (sourceModel() - && (role == Qt::EditRole || role == Qt::DisplayRole) - && index.isValid()) { - QModelIndex idx = mapToSource(index); - idx = idx.sibling(idx.row(), 1); - QString urlString = idx.data(HistoryModel::UrlStringRole).toString(); - if (index.row() % 2) { - QUrl url = urlString; - QString s = url.toString(QUrl::RemoveScheme - | QUrl::RemoveUserInfo - | QUrl::StripTrailingSlash); - return s.mid(2); // strip // from the front - } - return urlString; - } - return QAbstractProxyModel::data(index, role); -} - -int HistoryCompletionModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !sourceModel()) ? 0 : sourceModel()->rowCount(parent) * 2; -} - -int HistoryCompletionModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 1; -} - -QModelIndex HistoryCompletionModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - int row = sourceIndex.row() * 2; - return index(row, sourceIndex.column()); -} - -QModelIndex HistoryCompletionModel::mapToSource(const QModelIndex &proxyIndex) const -{ - if (!sourceModel()) - return QModelIndex(); - int row = proxyIndex.row() / 2; - return sourceModel()->index(row, proxyIndex.column()); -} - -QModelIndex HistoryCompletionModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 || row >= rowCount(parent) - || column < 0 || column >= columnCount(parent)) - return QModelIndex(); - return createIndex(row, column, 0); -} - -QModelIndex HistoryCompletionModel::parent(const QModelIndex &) const -{ - return QModelIndex(); -} - -void HistoryCompletionModel::setSourceModel(QAbstractItemModel *newSourceModel) -{ - if (sourceModel()) { - disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - } - - QAbstractProxyModel::setSourceModel(newSourceModel); - - if (newSourceModel) { - connect(newSourceModel, SIGNAL(modelReset()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - } - - reset(); -} - -void HistoryCompletionModel::sourceReset() -{ - reset(); -} - -HistoryTreeModel::HistoryTreeModel(QAbstractItemModel *sourceModel, QObject *parent) - : QAbstractProxyModel(parent) -{ - setSourceModel(sourceModel); -} - -QVariant HistoryTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - return sourceModel()->headerData(section, orientation, role); -} - -QVariant HistoryTreeModel::data(const QModelIndex &index, int role) const -{ - if ((role == Qt::EditRole || role == Qt::DisplayRole)) { - int start = index.internalId(); - if (start == 0) { - int offset = sourceDateRow(index.row()); - if (index.column() == 0) { - QModelIndex idx = sourceModel()->index(offset, 0); - QDate date = idx.data(HistoryModel::DateRole).toDate(); - if (date == QDate::currentDate()) - return tr("Earlier Today"); - return date.toString(QLatin1String("dddd, MMMM d, yyyy")); - } - if (index.column() == 1) { - return tr("%1 items").arg(rowCount(index.sibling(index.row(), 0))); - } - } - } - if (role == Qt::DecorationRole && index.column() == 0 && !index.parent().isValid()) - return QIcon(QLatin1String(":history.png")); - if (role == HistoryModel::DateRole && index.column() == 0 && index.internalId() == 0) { - int offset = sourceDateRow(index.row()); - QModelIndex idx = sourceModel()->index(offset, 0); - return idx.data(HistoryModel::DateRole); - } - - return QAbstractProxyModel::data(index, role); -} - -int HistoryTreeModel::columnCount(const QModelIndex &parent) const -{ - return sourceModel()->columnCount(mapToSource(parent)); -} - -int HistoryTreeModel::rowCount(const QModelIndex &parent) const -{ - if ( parent.internalId() != 0 - || parent.column() > 0 - || !sourceModel()) - return 0; - - // row count OF dates - if (!parent.isValid()) { - if (!m_sourceRowCache.isEmpty()) - return m_sourceRowCache.count(); - QDate currentDate; - int rows = 0; - int totalRows = sourceModel()->rowCount(); - - for (int i = 0; i < totalRows; ++i) { - QDate rowDate = sourceModel()->index(i, 0).data(HistoryModel::DateRole).toDate(); - if (rowDate != currentDate) { - m_sourceRowCache.append(i); - currentDate = rowDate; - ++rows; - } - } - Q_ASSERT(m_sourceRowCache.count() == rows); - return rows; - } - - // row count FOR a date - int start = sourceDateRow(parent.row()); - int end = sourceDateRow(parent.row() + 1); - return (end - start); -} - -// Translate the top level date row into the offset where that date starts -int HistoryTreeModel::sourceDateRow(int row) const -{ - if (row <= 0) - return 0; - - if (m_sourceRowCache.isEmpty()) - rowCount(QModelIndex()); - - if (row >= m_sourceRowCache.count()) { - if (!sourceModel()) - return 0; - return sourceModel()->rowCount(); - } - return m_sourceRowCache.at(row); -} - -QModelIndex HistoryTreeModel::mapToSource(const QModelIndex &proxyIndex) const -{ - int offset = proxyIndex.internalId(); - if (offset == 0) - return QModelIndex(); - int startDateRow = sourceDateRow(offset - 1); - return sourceModel()->index(startDateRow + proxyIndex.row(), proxyIndex.column()); -} - -QModelIndex HistoryTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 - || column < 0 || column >= columnCount(parent) - || parent.column() > 0) - return QModelIndex(); - - if (!parent.isValid()) - return createIndex(row, column, 0); - return createIndex(row, column, parent.row() + 1); -} - -QModelIndex HistoryTreeModel::parent(const QModelIndex &index) const -{ - int offset = index.internalId(); - if (offset == 0 || !index.isValid()) - return QModelIndex(); - return createIndex(offset - 1, 0, 0); -} - -bool HistoryTreeModel::hasChildren(const QModelIndex &parent) const -{ - QModelIndex grandparent = parent.parent(); - if (!grandparent.isValid()) - return true; - return false; -} - -Qt::ItemFlags HistoryTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::NoItemFlags; - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; -} - -bool HistoryTreeModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (row < 0 || count <= 0 || row + count > rowCount(parent)) - return false; - - if (parent.isValid()) { - // removing pages - int offset = sourceDateRow(parent.row()); - return sourceModel()->removeRows(offset + row, count); - } else { - // removing whole dates - for (int i = row + count - 1; i >= row; --i) { - QModelIndex dateParent = index(i, 0); - int offset = sourceDateRow(dateParent.row()); - if (!sourceModel()->removeRows(offset, rowCount(dateParent))) - return false; - } - } - return true; -} - -void HistoryTreeModel::setSourceModel(QAbstractItemModel *newSourceModel) -{ - if (sourceModel()) { - disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(layoutChanged()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - } - - QAbstractProxyModel::setSourceModel(newSourceModel); - - if (newSourceModel) { - connect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(layoutChanged()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - } - - reset(); -} - -void HistoryTreeModel::sourceReset() -{ - m_sourceRowCache.clear(); - reset(); -} - -void HistoryTreeModel::sourceRowsInserted(const QModelIndex &parent, int start, int end) -{ - Q_UNUSED(parent); // Avoid warnings when compiling release - Q_ASSERT(!parent.isValid()); - if (start != 0 || start != end) { - m_sourceRowCache.clear(); - reset(); - return; - } - - m_sourceRowCache.clear(); - QModelIndex treeIndex = mapFromSource(sourceModel()->index(start, 0)); - QModelIndex treeParent = treeIndex.parent(); - if (rowCount(treeParent) == 1) { - beginInsertRows(QModelIndex(), 0, 0); - endInsertRows(); - } else { - beginInsertRows(treeParent, treeIndex.row(), treeIndex.row()); - endInsertRows(); - } -} - -QModelIndex HistoryTreeModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - if (!sourceIndex.isValid()) - return QModelIndex(); - - if (m_sourceRowCache.isEmpty()) - rowCount(QModelIndex()); - - QList::iterator it; - it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), sourceIndex.row()); - if (*it != sourceIndex.row()) - --it; - int dateRow = qMax(0, it - m_sourceRowCache.begin()); - int row = sourceIndex.row() - m_sourceRowCache.at(dateRow); - return createIndex(row, sourceIndex.column(), dateRow + 1); -} - -void HistoryTreeModel::sourceRowsRemoved(const QModelIndex &parent, int start, int end) -{ - Q_UNUSED(parent); // Avoid warnings when compiling release - Q_ASSERT(!parent.isValid()); - if (m_sourceRowCache.isEmpty()) - return; - for (int i = end; i >= start;) { - QList::iterator it; - it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), i); - // playing it safe - if (it == m_sourceRowCache.end()) { - m_sourceRowCache.clear(); - reset(); - return; - } - - if (*it != i) - --it; - int row = qMax(0, it - m_sourceRowCache.begin()); - int offset = m_sourceRowCache[row]; - QModelIndex dateParent = index(row, 0); - // If we can remove all the rows in the date do that and skip over them - int rc = rowCount(dateParent); - if (i - rc + 1 == offset && start <= i - rc + 1) { - beginRemoveRows(QModelIndex(), row, row); - m_sourceRowCache.removeAt(row); - i -= rc + 1; - } else { - beginRemoveRows(dateParent, i - offset, i - offset); - ++row; - --i; - } - for (int j = row; j < m_sourceRowCache.count(); ++j) - --m_sourceRowCache[j]; - endRemoveRows(); - } -} - diff --git a/examples/gestures/browser/history.h b/examples/gestures/browser/history.h deleted file mode 100644 index 626e2f3..0000000 --- a/examples/gestures/browser/history.h +++ /dev/null @@ -1,350 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef HISTORY_H -#define HISTORY_H - -#include "modelmenu.h" - -#include -#include -#include -#include -#include - -#include - -#include - -class HistoryItem -{ -public: - HistoryItem() {} - HistoryItem(const QString &u, - const QDateTime &d = QDateTime(), const QString &t = QString()) - : title(t), url(u), dateTime(d) {} - - inline bool operator==(const HistoryItem &other) const - { return other.title == title - && other.url == url && other.dateTime == dateTime; } - - // history is sorted in reverse - inline bool operator <(const HistoryItem &other) const - { return dateTime > other.dateTime; } - - QString title; - QString url; - QDateTime dateTime; -}; - -class AutoSaver; -class HistoryModel; -class HistoryFilterModel; -class HistoryTreeModel; -class HistoryManager : public QWebHistoryInterface -{ - Q_OBJECT - Q_PROPERTY(int historyLimit READ historyLimit WRITE setHistoryLimit) - -signals: - void historyReset(); - void entryAdded(const HistoryItem &item); - void entryRemoved(const HistoryItem &item); - void entryUpdated(int offset); - -public: - HistoryManager(QObject *parent = 0); - ~HistoryManager(); - - bool historyContains(const QString &url) const; - void addHistoryEntry(const QString &url); - - void updateHistoryItem(const QUrl &url, const QString &title); - - int historyLimit() const; - void setHistoryLimit(int limit); - - QList history() const; - void setHistory(const QList &history, bool loadedAndSorted = false); - - // History manager keeps around these models for use by the completer and other classes - HistoryModel *historyModel() const; - HistoryFilterModel *historyFilterModel() const; - HistoryTreeModel *historyTreeModel() const; - -public slots: - void clear(); - void loadSettings(); - -private slots: - void save(); - void checkForExpired(); - -protected: - void addHistoryItem(const HistoryItem &item); - -private: - void load(); - - AutoSaver *m_saveTimer; - int m_historyLimit; - QTimer m_expiredTimer; - QList m_history; - QString m_lastSavedUrl; - - HistoryModel *m_historyModel; - HistoryFilterModel *m_historyFilterModel; - HistoryTreeModel *m_historyTreeModel; -}; - -class HistoryModel : public QAbstractTableModel -{ - Q_OBJECT - -public slots: - void historyReset(); - void entryAdded(); - void entryUpdated(int offset); - -public: - enum Roles { - DateRole = Qt::UserRole + 1, - DateTimeRole = Qt::UserRole + 2, - UrlRole = Qt::UserRole + 3, - UrlStringRole = Qt::UserRole + 4 - }; - - HistoryModel(HistoryManager *history, QObject *parent = 0); - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private: - HistoryManager *m_history; -}; - -/*! - Proxy model that will remove any duplicate entries. - Both m_sourceRow and m_historyHash store their offsets not from - the front of the list, but as offsets from the back. - */ -class HistoryFilterModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryFilterModel(QAbstractItemModel *sourceModel, QObject *parent = 0); - - inline bool historyContains(const QString &url) const - { load(); return m_historyHash.contains(url); } - int historyLocation(const QString &url) const; - - QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; - QModelIndex mapToSource(const QModelIndex &proxyIndex) const; - void setSourceModel(QAbstractItemModel *sourceModel); - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index= QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - -private slots: - void sourceReset(); - void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - void sourceRowsInserted(const QModelIndex &parent, int start, int end); - void sourceRowsRemoved(const QModelIndex &, int, int); - -private: - void load() const; - - mutable QList m_sourceRow; - mutable QHash m_historyHash; - mutable bool m_loaded; -}; - -/* - The history menu - - Removes the first twenty entries and puts them as children of the top level. - - If there are less then twenty entries then the first folder is also removed. - - The mapping is done by knowing that HistoryTreeModel is over a table - We store that row offset in our index's private data. -*/ -class HistoryMenuModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryMenuModel(HistoryTreeModel *sourceModel, QObject *parent = 0); - int columnCount(const QModelIndex &parent) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex mapFromSource(const QModelIndex & sourceIndex) const; - QModelIndex mapToSource(const QModelIndex & proxyIndex) const; - QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index = QModelIndex()) const; - - int bumpedRows() const; - -private: - HistoryTreeModel *m_treeModel; -}; - -// Menu that is dynamically populated from the history -class HistoryMenu : public ModelMenu -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - HistoryMenu(QWidget *parent = 0); - void setInitialActions(QList actions); - -protected: - bool prePopulated(); - void postPopulated(); - -private slots: - void activated(const QModelIndex &index); - void showHistoryDialog(); - -private: - HistoryManager *m_history; - HistoryMenuModel *m_historyMenuModel; - QList m_initialActions; -}; - -// proxy model for the history model that -// exposes each url http://www.foo.com and it url starting at the host www.foo.com -class HistoryCompletionModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryCompletionModel(QObject *parent = 0); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; - QModelIndex mapToSource(const QModelIndex &proxyIndex) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index= QModelIndex()) const; - void setSourceModel(QAbstractItemModel *sourceModel); - -private slots: - void sourceReset(); - -}; - -// proxy model for the history model that converts the list -// into a tree, one top level node per day. -// Used in the HistoryDialog. -class HistoryTreeModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryTreeModel(QAbstractItemModel *sourceModel, QObject *parent = 0); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; - QModelIndex mapToSource(const QModelIndex &proxyIndex) const; - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index= QModelIndex()) const; - bool hasChildren(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - void setSourceModel(QAbstractItemModel *sourceModel); - -private slots: - void sourceReset(); - void sourceRowsInserted(const QModelIndex &parent, int start, int end); - void sourceRowsRemoved(const QModelIndex &parent, int start, int end); - -private: - int sourceDateRow(int row) const; - mutable QList m_sourceRowCache; - -}; - -// A modified QSortFilterProxyModel that always accepts the root nodes in the tree -// so filtering is only done on the children. -// Used in the HistoryDialog -class TreeProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT - -public: - TreeProxyModel(QObject *parent = 0); - -protected: - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; -}; - -#include "ui_history.h" - -class HistoryDialog : public QDialog, public Ui_HistoryDialog -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - HistoryDialog(QWidget *parent = 0, HistoryManager *history = 0); - -private slots: - void customContextMenuRequested(const QPoint &pos); - void open(); - void copy(); - -}; - -#endif // HISTORY_H - diff --git a/examples/gestures/browser/history.ui b/examples/gestures/browser/history.ui deleted file mode 100644 index 0944940..0000000 --- a/examples/gestures/browser/history.ui +++ /dev/null @@ -1,106 +0,0 @@ - - HistoryDialog - - - - 0 - 0 - 758 - 450 - - - - History - - - - - - Qt::Horizontal - - - - 252 - 20 - - - - - - - - - - - - - - - - &Remove - - - - - - - Remove &All - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QDialogButtonBox::Ok - - - - - - - - - - SearchLineEdit - QLineEdit -
searchlineedit.h
-
- - EditTreeView - QTreeView -
edittreeview.h
-
-
- - - - buttonBox - accepted() - HistoryDialog - accept() - - - 472 - 329 - - - 461 - 356 - - - - -
diff --git a/examples/gestures/browser/htmls/htmls.qrc b/examples/gestures/browser/htmls/htmls.qrc deleted file mode 100644 index 03b256c..0000000 --- a/examples/gestures/browser/htmls/htmls.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - notfound.html - - diff --git a/examples/gestures/browser/htmls/notfound.html b/examples/gestures/browser/htmls/notfound.html deleted file mode 100644 index b04a9f8..0000000 --- a/examples/gestures/browser/htmls/notfound.html +++ /dev/null @@ -1,63 +0,0 @@ - - -%1 - - - -
- -

%2

-

When connecting to: %3.

-
    -
  • Check the address for errors such as ww.trolltech.com - instead of www.trolltech.com
  • -
  • If the address is correct, try checking the network - connection.
  • -
  • If your computer or network is protected by a firewall or - proxy, make sure that the browser demo is permitted to access - the network.
  • -
-

-
- - diff --git a/examples/gestures/browser/main.cpp b/examples/gestures/browser/main.cpp deleted file mode 100644 index b9e2830..0000000 --- a/examples/gestures/browser/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "browserapplication.h" - -int main(int argc, char **argv) -{ - Q_INIT_RESOURCE(data); - BrowserApplication application(argc, argv); - if (!application.isTheOnlyBrowser()) - return 0; - application.newMainWindow(); - return application.exec(); -} - diff --git a/examples/gestures/browser/modelmenu.cpp b/examples/gestures/browser/modelmenu.cpp deleted file mode 100644 index 2e81d0d..0000000 --- a/examples/gestures/browser/modelmenu.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "modelmenu.h" - -#include -#include - -ModelMenu::ModelMenu(QWidget * parent) - : QMenu(parent) - , m_maxRows(7) - , m_firstSeparator(-1) - , m_maxWidth(-1) - , m_hoverRole(0) - , m_separatorRole(0) - , m_model(0) -{ - connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); -} - -bool ModelMenu::prePopulated() -{ - return false; -} - -void ModelMenu::postPopulated() -{ -} - -void ModelMenu::setModel(QAbstractItemModel *model) -{ - m_model = model; -} - -QAbstractItemModel *ModelMenu::model() const -{ - return m_model; -} - -void ModelMenu::setMaxRows(int max) -{ - m_maxRows = max; -} - -int ModelMenu::maxRows() const -{ - return m_maxRows; -} - -void ModelMenu::setFirstSeparator(int offset) -{ - m_firstSeparator = offset; -} - -int ModelMenu::firstSeparator() const -{ - return m_firstSeparator; -} - -void ModelMenu::setRootIndex(const QModelIndex &index) -{ - m_root = index; -} - -QModelIndex ModelMenu::rootIndex() const -{ - return m_root; -} - -void ModelMenu::setHoverRole(int role) -{ - m_hoverRole = role; -} - -int ModelMenu::hoverRole() const -{ - return m_hoverRole; -} - -void ModelMenu::setSeparatorRole(int role) -{ - m_separatorRole = role; -} - -int ModelMenu::separatorRole() const -{ - return m_separatorRole; -} - -Q_DECLARE_METATYPE(QModelIndex) -void ModelMenu::aboutToShow() -{ - if (QMenu *menu = qobject_cast(sender())) { - QVariant v = menu->menuAction()->data(); - if (v.canConvert()) { - QModelIndex idx = qvariant_cast(v); - createMenu(idx, -1, menu, menu); - disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); - return; - } - } - - clear(); - if (prePopulated()) - addSeparator(); - int max = m_maxRows; - if (max != -1) - max += m_firstSeparator; - createMenu(m_root, max, this, this); - postPopulated(); -} - -void ModelMenu::createMenu(const QModelIndex &parent, int max, QMenu *parentMenu, QMenu *menu) -{ - if (!menu) { - QString title = parent.data().toString(); - menu = new QMenu(title, this); - QIcon icon = qvariant_cast(parent.data(Qt::DecorationRole)); - menu->setIcon(icon); - parentMenu->addMenu(menu); - QVariant v; - v.setValue(parent); - menu->menuAction()->setData(v); - connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); - return; - } - - int end = m_model->rowCount(parent); - if (max != -1) - end = qMin(max, end); - - connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*))); - connect(menu, SIGNAL(hovered(QAction*)), this, SLOT(hovered(QAction*))); - - for (int i = 0; i < end; ++i) { - QModelIndex idx = m_model->index(i, 0, parent); - if (m_model->hasChildren(idx)) { - createMenu(idx, -1, menu); - } else { - if (m_separatorRole != 0 - && idx.data(m_separatorRole).toBool()) - addSeparator(); - else - menu->addAction(makeAction(idx)); - } - if (menu == this && i == m_firstSeparator - 1) - addSeparator(); - } -} - -QAction *ModelMenu::makeAction(const QModelIndex &index) -{ - QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); - QAction *action = makeAction(icon, index.data().toString(), this); - QVariant v; - v.setValue(index); - action->setData(v); - return action; -} - -QAction *ModelMenu::makeAction(const QIcon &icon, const QString &text, QObject *parent) -{ - QFontMetrics fm(font()); - if (-1 == m_maxWidth) - m_maxWidth = fm.width(QLatin1Char('m')) * 30; - QString smallText = fm.elidedText(text, Qt::ElideMiddle, m_maxWidth); - return new QAction(icon, smallText, parent); -} - -void ModelMenu::triggered(QAction *action) -{ - QVariant v = action->data(); - if (v.canConvert()) { - QModelIndex idx = qvariant_cast(v); - emit activated(idx); - } -} - -void ModelMenu::hovered(QAction *action) -{ - QVariant v = action->data(); - if (v.canConvert()) { - QModelIndex idx = qvariant_cast(v); - QString hoveredString = idx.data(m_hoverRole).toString(); - if (!hoveredString.isEmpty()) - emit hovered(hoveredString); - } -} - diff --git a/examples/gestures/browser/modelmenu.h b/examples/gestures/browser/modelmenu.h deleted file mode 100644 index b44daa8..0000000 --- a/examples/gestures/browser/modelmenu.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MODELMENU_H -#define MODELMENU_H - -#include -#include - -// A QMenu that is dynamically populated from a QAbstractItemModel -class ModelMenu : public QMenu -{ - Q_OBJECT - -signals: - void activated(const QModelIndex &index); - void hovered(const QString &text); - -public: - ModelMenu(QWidget *parent = 0); - - void setModel(QAbstractItemModel *model); - QAbstractItemModel *model() const; - - void setMaxRows(int max); - int maxRows() const; - - void setFirstSeparator(int offset); - int firstSeparator() const; - - void setRootIndex(const QModelIndex &index); - QModelIndex rootIndex() const; - - void setHoverRole(int role); - int hoverRole() const; - - void setSeparatorRole(int role); - int separatorRole() const; - - QAction *makeAction(const QIcon &icon, const QString &text, QObject *parent); - -protected: - // add any actions before the tree, return true if any actions are added. - virtual bool prePopulated(); - // add any actions after the tree - virtual void postPopulated(); - // put all of the children of parent into menu up to max - void createMenu(const QModelIndex &parent, int max, QMenu *parentMenu = 0, QMenu *menu = 0); - -private slots: - void aboutToShow(); - void triggered(QAction *action); - void hovered(QAction *action); - -private: - QAction *makeAction(const QModelIndex &index); - int m_maxRows; - int m_firstSeparator; - int m_maxWidth; - int m_hoverRole; - int m_separatorRole; - QAbstractItemModel *m_model; - QPersistentModelIndex m_root; -}; - -#endif // MODELMENU_H - diff --git a/examples/gestures/browser/networkaccessmanager.cpp b/examples/gestures/browser/networkaccessmanager.cpp deleted file mode 100644 index 3a4598c..0000000 --- a/examples/gestures/browser/networkaccessmanager.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "networkaccessmanager.h" - -#include "browserapplication.h" -#include "browsermainwindow.h" -#include "ui_passworddialog.h" -#include "ui_proxy.h" - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -NetworkAccessManager::NetworkAccessManager(QObject *parent) - : QNetworkAccessManager(parent) -{ - connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), - SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - connect(this, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), - SLOT(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))); -#ifndef QT_NO_OPENSSL - connect(this, SIGNAL(sslErrors(QNetworkReply*, const QList&)), - SLOT(sslErrors(QNetworkReply*, const QList&))); -#endif - loadSettings(); - - QNetworkDiskCache *diskCache = new QNetworkDiskCache(this); - QString location = QDesktopServices::storageLocation(QDesktopServices::CacheLocation); - diskCache->setCacheDirectory(location); - setCache(diskCache); -} - -void NetworkAccessManager::loadSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("proxy")); - QNetworkProxy proxy; - if (settings.value(QLatin1String("enabled"), false).toBool()) { - if (settings.value(QLatin1String("type"), 0).toInt() == 0) - proxy = QNetworkProxy::Socks5Proxy; - else - proxy = QNetworkProxy::HttpProxy; - proxy.setHostName(settings.value(QLatin1String("hostName")).toString()); - proxy.setPort(settings.value(QLatin1String("port"), 1080).toInt()); - proxy.setUser(settings.value(QLatin1String("userName")).toString()); - proxy.setPassword(settings.value(QLatin1String("password")).toString()); - } - setProxy(proxy); -} - -void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthenticator *auth) -{ - BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); - - QDialog dialog(mainWindow); - dialog.setWindowFlags(Qt::Sheet); - - Ui::PasswordDialog passwordDialog; - passwordDialog.setupUi(&dialog); - - passwordDialog.iconLabel->setText(QString()); - passwordDialog.iconLabel->setPixmap(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow).pixmap(32, 32)); - - QString introMessage = tr("Enter username and password for \"%1\" at %2"); - introMessage = introMessage.arg(Qt::escape(reply->url().toString())).arg(Qt::escape(reply->url().toString())); - passwordDialog.introLabel->setText(introMessage); - passwordDialog.introLabel->setWordWrap(true); - - if (dialog.exec() == QDialog::Accepted) { - auth->setUser(passwordDialog.userNameLineEdit->text()); - auth->setPassword(passwordDialog.passwordLineEdit->text()); - } -} - -void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth) -{ - BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); - - QDialog dialog(mainWindow); - dialog.setWindowFlags(Qt::Sheet); - - Ui::ProxyDialog proxyDialog; - proxyDialog.setupUi(&dialog); - - proxyDialog.iconLabel->setText(QString()); - proxyDialog.iconLabel->setPixmap(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow).pixmap(32, 32)); - - QString introMessage = tr("Connect to proxy \"%1\" using:"); - introMessage = introMessage.arg(Qt::escape(proxy.hostName())); - proxyDialog.introLabel->setText(introMessage); - proxyDialog.introLabel->setWordWrap(true); - - if (dialog.exec() == QDialog::Accepted) { - auth->setUser(proxyDialog.userNameLineEdit->text()); - auth->setPassword(proxyDialog.passwordLineEdit->text()); - } -} - -#ifndef QT_NO_OPENSSL -void NetworkAccessManager::sslErrors(QNetworkReply *reply, const QList &error) -{ - // check if SSL certificate has been trusted already - QString replyHost = reply->url().host() + ":" + reply->url().port(); - if(! sslTrustedHostList.contains(replyHost)) { - BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); - - QStringList errorStrings; - for (int i = 0; i < error.count(); ++i) - errorStrings += error.at(i).errorString(); - QString errors = errorStrings.join(QLatin1String("\n")); - int ret = QMessageBox::warning(mainWindow, QCoreApplication::applicationName(), - tr("SSL Errors:\n\n%1\n\n%2\n\n" - "Do you want to ignore these errors for this host?").arg(reply->url().toString()).arg(errors), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No); - if (ret == QMessageBox::Yes) { - reply->ignoreSslErrors(); - sslTrustedHostList.append(replyHost); - } - } -} -#endif diff --git a/examples/gestures/browser/networkaccessmanager.h b/examples/gestures/browser/networkaccessmanager.h deleted file mode 100644 index d90a4d4..0000000 --- a/examples/gestures/browser/networkaccessmanager.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef NETWORKACCESSMANAGER_H -#define NETWORKACCESSMANAGER_H - -#include - -class NetworkAccessManager : public QNetworkAccessManager -{ - Q_OBJECT - -public: - NetworkAccessManager(QObject *parent = 0); - -private: - QList sslTrustedHostList; - -public slots: - void loadSettings(); - -private slots: - void authenticationRequired(QNetworkReply *reply, QAuthenticator *auth); - void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); -#ifndef QT_NO_OPENSSL - void sslErrors(QNetworkReply *reply, const QList &error); -#endif -}; - -#endif // NETWORKACCESSMANAGER_H diff --git a/examples/gestures/browser/passworddialog.ui b/examples/gestures/browser/passworddialog.ui deleted file mode 100644 index 7c16658..0000000 --- a/examples/gestures/browser/passworddialog.ui +++ /dev/null @@ -1,111 +0,0 @@ - - PasswordDialog - - - - 0 - 0 - 399 - 148 - - - - Authentication Required - - - - - - - - DUMMY ICON - - - - - - - - 0 - 0 - - - - INTRO TEXT DUMMY - - - - - - - - - Username: - - - - - - - - - - Password: - - - - - - - QLineEdit::Password - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - PasswordDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - PasswordDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/examples/gestures/browser/proxy.ui b/examples/gestures/browser/proxy.ui deleted file mode 100644 index 62a8be6..0000000 --- a/examples/gestures/browser/proxy.ui +++ /dev/null @@ -1,104 +0,0 @@ - - ProxyDialog - - - - 0 - 0 - 369 - 144 - - - - Proxy Authentication - - - - - - ICON - - - - - - - Connect to proxy - - - true - - - - - - - Username: - - - - - - - - - - Password: - - - - - - - QLineEdit::Password - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - ProxyDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - ProxyDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/examples/gestures/browser/searchlineedit.cpp b/examples/gestures/browser/searchlineedit.cpp deleted file mode 100644 index e04010d..0000000 --- a/examples/gestures/browser/searchlineedit.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "searchlineedit.h" - -#include -#include -#include -#include -#include - -ClearButton::ClearButton(QWidget *parent) - : QAbstractButton(parent) -{ - setCursor(Qt::ArrowCursor); - setToolTip(tr("Clear")); - setVisible(false); - setFocusPolicy(Qt::NoFocus); -} - -void ClearButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QPainter painter(this); - int height = this->height(); - - painter.setRenderHint(QPainter::Antialiasing, true); - QColor color = palette().color(QPalette::Mid); - painter.setBrush(isDown() - ? palette().color(QPalette::Dark) - : palette().color(QPalette::Mid)); - painter.setPen(painter.brush().color()); - int size = width(); - int offset = size / 5; - int radius = size - offset * 2; - painter.drawEllipse(offset, offset, radius, radius); - - painter.setPen(palette().color(QPalette::Base)); - int border = offset * 2; - painter.drawLine(border, border, width() - border, height - border); - painter.drawLine(border, height - border, width() - border, border); -} - -void ClearButton::textChanged(const QString &text) -{ - setVisible(!text.isEmpty()); -} - -/* - Search icon on the left hand side of the search widget - When a menu is set a down arrow appears - */ -class SearchButton : public QAbstractButton { -public: - SearchButton(QWidget *parent = 0); - void paintEvent(QPaintEvent *event); - QMenu *m_menu; - -protected: - void mousePressEvent(QMouseEvent *event); -}; - -SearchButton::SearchButton(QWidget *parent) - : QAbstractButton(parent), - m_menu(0) -{ - setObjectName(QLatin1String("SearchButton")); - setCursor(Qt::ArrowCursor); - setFocusPolicy(Qt::NoFocus); -} - -void SearchButton::mousePressEvent(QMouseEvent *event) -{ - if (m_menu && event->button() == Qt::LeftButton) { - QWidget *p = parentWidget(); - if (p) { - QPoint r = p->mapToGlobal(QPoint(0, p->height())); - m_menu->exec(QPoint(r.x() + height() / 2, r.y())); - } - event->accept(); - } - QAbstractButton::mousePressEvent(event); -} - -void SearchButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QPainterPath myPath; - - int radius = (height() / 5) * 2; - QRect circle(height() / 3 - 1, height() / 4, radius, radius); - myPath.addEllipse(circle); - - myPath.arcMoveTo(circle, 300); - QPointF c = myPath.currentPosition(); - int diff = height() / 7; - myPath.lineTo(qMin(width() - 2, (int)c.x() + diff), c.y() + diff); - - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setPen(QPen(Qt::darkGray, 2)); - painter.drawPath(myPath); - - if (m_menu) { - QPainterPath dropPath; - dropPath.arcMoveTo(circle, 320); - QPointF c = dropPath.currentPosition(); - c = QPointF(c.x() + 3.5, c.y() + 0.5); - dropPath.moveTo(c); - dropPath.lineTo(c.x() + 4, c.y()); - dropPath.lineTo(c.x() + 2, c.y() + 2); - dropPath.closeSubpath(); - painter.setPen(Qt::darkGray); - painter.setBrush(Qt::darkGray); - painter.setRenderHint(QPainter::Antialiasing, false); - painter.drawPath(dropPath); - } - painter.end(); -} - -/* - SearchLineEdit is an enhanced QLineEdit - - A Search icon on the left with optional menu - - When there is no text and doesn't have focus an "inactive text" is displayed - - When there is text a clear button is displayed on the right hand side - */ -SearchLineEdit::SearchLineEdit(QWidget *parent) : ExLineEdit(parent), - m_searchButton(new SearchButton(this)) -{ - connect(lineEdit(), SIGNAL(textChanged(const QString &)), - this, SIGNAL(textChanged(const QString &))); - setLeftWidget(m_searchButton); - m_inactiveText = tr("Search"); - - QSizePolicy policy = sizePolicy(); - setSizePolicy(QSizePolicy::Preferred, policy.verticalPolicy()); -} - -void SearchLineEdit::paintEvent(QPaintEvent *event) -{ - if (lineEdit()->text().isEmpty() && !hasFocus() && !m_inactiveText.isEmpty()) { - ExLineEdit::paintEvent(event); - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - QFontMetrics fm = fontMetrics(); - int horizontalMargin = lineEdit()->x(); - QRect lineRect(horizontalMargin + r.x(), r.y() + (r.height() - fm.height() + 1) / 2, - r.width() - 2 * horizontalMargin, fm.height()); - QPainter painter(this); - painter.setPen(palette().brush(QPalette::Disabled, QPalette::Text).color()); - painter.drawText(lineRect, Qt::AlignLeft|Qt::AlignVCenter, m_inactiveText); - } else { - ExLineEdit::paintEvent(event); - } -} - -void SearchLineEdit::resizeEvent(QResizeEvent *event) -{ - updateGeometries(); - ExLineEdit::resizeEvent(event); -} - -void SearchLineEdit::updateGeometries() -{ - int menuHeight = height(); - int menuWidth = menuHeight + 1; - if (!m_searchButton->m_menu) - menuWidth = (menuHeight / 5) * 4; - m_searchButton->resize(QSize(menuWidth, menuHeight)); -} - -QString SearchLineEdit::inactiveText() const -{ - return m_inactiveText; -} - -void SearchLineEdit::setInactiveText(const QString &text) -{ - m_inactiveText = text; -} - -void SearchLineEdit::setMenu(QMenu *menu) -{ - if (m_searchButton->m_menu) - m_searchButton->m_menu->deleteLater(); - m_searchButton->m_menu = menu; - updateGeometries(); -} - -QMenu *SearchLineEdit::menu() const -{ - if (!m_searchButton->m_menu) { - m_searchButton->m_menu = new QMenu(m_searchButton); - if (isVisible()) - (const_cast(this))->updateGeometries(); - } - return m_searchButton->m_menu; -} - diff --git a/examples/gestures/browser/searchlineedit.h b/examples/gestures/browser/searchlineedit.h deleted file mode 100644 index ad37dc7..0000000 --- a/examples/gestures/browser/searchlineedit.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SEARCHLINEEDIT_H -#define SEARCHLINEEDIT_H - -#include "urllineedit.h" - -#include -#include - -QT_BEGIN_NAMESPACE -class QMenu; -QT_END_NAMESPACE - -class SearchButton; - -/* - Clear button on the right hand side of the search widget. - Hidden by default - "A circle with an X in it" - */ -class ClearButton : public QAbstractButton -{ - Q_OBJECT - -public: - ClearButton(QWidget *parent = 0); - void paintEvent(QPaintEvent *event); - -public slots: - void textChanged(const QString &text); -}; - - -class SearchLineEdit : public ExLineEdit -{ - Q_OBJECT - Q_PROPERTY(QString inactiveText READ inactiveText WRITE setInactiveText) - -signals: - void textChanged(const QString &text); - -public: - SearchLineEdit(QWidget *parent = 0); - - QString inactiveText() const; - void setInactiveText(const QString &text); - - QMenu *menu() const; - void setMenu(QMenu *menu); - -protected: - void resizeEvent(QResizeEvent *event); - void paintEvent(QPaintEvent *event); - -private: - void updateGeometries(); - - SearchButton *m_searchButton; - QString m_inactiveText; -}; - -#endif // SEARCHLINEEDIT_H - diff --git a/examples/gestures/browser/settings.cpp b/examples/gestures/browser/settings.cpp deleted file mode 100644 index 2576449..0000000 --- a/examples/gestures/browser/settings.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "settings.h" - -#include "browserapplication.h" -#include "browsermainwindow.h" -#include "cookiejar.h" -#include "history.h" -#include "networkaccessmanager.h" -#include "webview.h" - -#include -#include -#include - -SettingsDialog::SettingsDialog(QWidget *parent) - : QDialog(parent) -{ - setupUi(this); - connect(exceptionsButton, SIGNAL(clicked()), this, SLOT(showExceptions())); - connect(setHomeToCurrentPageButton, SIGNAL(clicked()), this, SLOT(setHomeToCurrentPage())); - connect(cookiesButton, SIGNAL(clicked()), this, SLOT(showCookies())); - connect(standardFontButton, SIGNAL(clicked()), this, SLOT(chooseFont())); - connect(fixedFontButton, SIGNAL(clicked()), this, SLOT(chooseFixedFont())); - - loadDefaults(); - loadFromSettings(); -} - -void SettingsDialog::loadDefaults() -{ - QWebSettings *defaultSettings = QWebSettings::globalSettings(); - QString standardFontFamily = defaultSettings->fontFamily(QWebSettings::StandardFont); - int standardFontSize = defaultSettings->fontSize(QWebSettings::DefaultFontSize); - standardFont = QFont(standardFontFamily, standardFontSize); - standardLabel->setText(QString(QLatin1String("%1 %2")).arg(standardFont.family()).arg(standardFont.pointSize())); - - QString fixedFontFamily = defaultSettings->fontFamily(QWebSettings::FixedFont); - int fixedFontSize = defaultSettings->fontSize(QWebSettings::DefaultFixedFontSize); - fixedFont = QFont(fixedFontFamily, fixedFontSize); - fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(fixedFont.family()).arg(fixedFont.pointSize())); - - downloadsLocation->setText(QDesktopServices::storageLocation(QDesktopServices::DesktopLocation)); - - enableJavascript->setChecked(defaultSettings->testAttribute(QWebSettings::JavascriptEnabled)); - enablePlugins->setChecked(defaultSettings->testAttribute(QWebSettings::PluginsEnabled)); -} - -void SettingsDialog::loadFromSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("MainWindow")); - QString defaultHome = QLatin1String("http://qtsoftware.com"); - homeLineEdit->setText(settings.value(QLatin1String("home"), defaultHome).toString()); - settings.endGroup(); - - settings.beginGroup(QLatin1String("history")); - int historyExpire = settings.value(QLatin1String("historyExpire")).toInt(); - int idx = 0; - switch (historyExpire) { - case 1: idx = 0; break; - case 7: idx = 1; break; - case 14: idx = 2; break; - case 30: idx = 3; break; - case 365: idx = 4; break; - case -1: idx = 5; break; - default: - idx = 5; - } - expireHistory->setCurrentIndex(idx); - settings.endGroup(); - - settings.beginGroup(QLatin1String("downloadmanager")); - QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), downloadsLocation->text()).toString(); - downloadsLocation->setText(downloadDirectory); - settings.endGroup(); - - settings.beginGroup(QLatin1String("general")); - openLinksIn->setCurrentIndex(settings.value(QLatin1String("openLinksIn"), openLinksIn->currentIndex()).toInt()); - - settings.endGroup(); - - // Appearance - settings.beginGroup(QLatin1String("websettings")); - fixedFont = qVariantValue(settings.value(QLatin1String("fixedFont"), fixedFont)); - standardFont = qVariantValue(settings.value(QLatin1String("standardFont"), standardFont)); - - standardLabel->setText(QString(QLatin1String("%1 %2")).arg(standardFont.family()).arg(standardFont.pointSize())); - fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(fixedFont.family()).arg(fixedFont.pointSize())); - - enableJavascript->setChecked(settings.value(QLatin1String("enableJavascript"), enableJavascript->isChecked()).toBool()); - enablePlugins->setChecked(settings.value(QLatin1String("enablePlugins"), enablePlugins->isChecked()).toBool()); - userStyleSheet->setText(settings.value(QLatin1String("userStyleSheet")).toUrl().toString()); - settings.endGroup(); - - // Privacy - settings.beginGroup(QLatin1String("cookies")); - - CookieJar *jar = BrowserApplication::cookieJar(); - QByteArray value = settings.value(QLatin1String("acceptCookies"), QLatin1String("AcceptOnlyFromSitesNavigatedTo")).toByteArray(); - QMetaEnum acceptPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("AcceptPolicy")); - CookieJar::AcceptPolicy acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ? - CookieJar::AcceptOnlyFromSitesNavigatedTo : - static_cast(acceptPolicyEnum.keyToValue(value)); - switch(acceptCookies) { - case CookieJar::AcceptAlways: - acceptCombo->setCurrentIndex(0); - break; - case CookieJar::AcceptNever: - acceptCombo->setCurrentIndex(1); - break; - case CookieJar::AcceptOnlyFromSitesNavigatedTo: - acceptCombo->setCurrentIndex(2); - break; - } - - value = settings.value(QLatin1String("keepCookiesUntil"), QLatin1String("Expire")).toByteArray(); - QMetaEnum keepPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("KeepPolicy")); - CookieJar::KeepPolicy keepCookies = keepPolicyEnum.keyToValue(value) == -1 ? - CookieJar::KeepUntilExpire : - static_cast(keepPolicyEnum.keyToValue(value)); - switch(keepCookies) { - case CookieJar::KeepUntilExpire: - keepUntilCombo->setCurrentIndex(0); - break; - case CookieJar::KeepUntilExit: - keepUntilCombo->setCurrentIndex(1); - break; - case CookieJar::KeepUntilTimeLimit: - keepUntilCombo->setCurrentIndex(2); - break; - } - settings.endGroup(); - - - // Proxy - settings.beginGroup(QLatin1String("proxy")); - proxySupport->setChecked(settings.value(QLatin1String("enabled"), false).toBool()); - proxyType->setCurrentIndex(settings.value(QLatin1String("type"), 0).toInt()); - proxyHostName->setText(settings.value(QLatin1String("hostName")).toString()); - proxyPort->setValue(settings.value(QLatin1String("port"), 1080).toInt()); - proxyUserName->setText(settings.value(QLatin1String("userName")).toString()); - proxyPassword->setText(settings.value(QLatin1String("password")).toString()); - settings.endGroup(); -} - -void SettingsDialog::saveToSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("MainWindow")); - settings.setValue(QLatin1String("home"), homeLineEdit->text()); - settings.endGroup(); - - settings.beginGroup(QLatin1String("general")); - settings.setValue(QLatin1String("openLinksIn"), openLinksIn->currentIndex()); - settings.endGroup(); - - settings.beginGroup(QLatin1String("history")); - int historyExpire = expireHistory->currentIndex(); - int idx = -1; - switch (historyExpire) { - case 0: idx = 1; break; - case 1: idx = 7; break; - case 2: idx = 14; break; - case 3: idx = 30; break; - case 4: idx = 365; break; - case 5: idx = -1; break; - } - settings.setValue(QLatin1String("historyExpire"), idx); - settings.endGroup(); - - // Appearance - settings.beginGroup(QLatin1String("websettings")); - settings.setValue(QLatin1String("fixedFont"), fixedFont); - settings.setValue(QLatin1String("standardFont"), standardFont); - settings.setValue(QLatin1String("enableJavascript"), enableJavascript->isChecked()); - settings.setValue(QLatin1String("enablePlugins"), enablePlugins->isChecked()); - QString userStyleSheetString = userStyleSheet->text(); - if (QFile::exists(userStyleSheetString)) - settings.setValue(QLatin1String("userStyleSheet"), QUrl::fromLocalFile(userStyleSheetString)); - else - settings.setValue(QLatin1String("userStyleSheet"), QUrl(userStyleSheetString)); - settings.endGroup(); - - //Privacy - settings.beginGroup(QLatin1String("cookies")); - - CookieJar::KeepPolicy keepCookies; - switch(acceptCombo->currentIndex()) { - default: - case 0: - keepCookies = CookieJar::KeepUntilExpire; - break; - case 1: - keepCookies = CookieJar::KeepUntilExit; - break; - case 2: - keepCookies = CookieJar::KeepUntilTimeLimit; - break; - } - CookieJar *jar = BrowserApplication::cookieJar(); - QMetaEnum acceptPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("AcceptPolicy")); - settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(keepCookies))); - - CookieJar::KeepPolicy keepPolicy; - switch(keepUntilCombo->currentIndex()) { - default: - case 0: - keepPolicy = CookieJar::KeepUntilExpire; - break; - case 1: - keepPolicy = CookieJar::KeepUntilExit; - break; - case 2: - keepPolicy = CookieJar::KeepUntilTimeLimit; - break; - } - - QMetaEnum keepPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("KeepPolicy")); - settings.setValue(QLatin1String("keepCookiesUntil"), QLatin1String(keepPolicyEnum.valueToKey(keepPolicy))); - - settings.endGroup(); - - // proxy - settings.beginGroup(QLatin1String("proxy")); - settings.setValue(QLatin1String("enabled"), proxySupport->isChecked()); - settings.setValue(QLatin1String("type"), proxyType->currentIndex()); - settings.setValue(QLatin1String("hostName"), proxyHostName->text()); - settings.setValue(QLatin1String("port"), proxyPort->text()); - settings.setValue(QLatin1String("userName"), proxyUserName->text()); - settings.setValue(QLatin1String("password"), proxyPassword->text()); - settings.endGroup(); - - BrowserApplication::instance()->loadSettings(); - BrowserApplication::networkAccessManager()->loadSettings(); - BrowserApplication::cookieJar()->loadSettings(); - BrowserApplication::historyManager()->loadSettings(); -} - -void SettingsDialog::accept() -{ - saveToSettings(); - QDialog::accept(); -} - -void SettingsDialog::showCookies() -{ - CookiesDialog *dialog = new CookiesDialog(BrowserApplication::cookieJar(), this); - dialog->exec(); -} - -void SettingsDialog::showExceptions() -{ - CookiesExceptionsDialog *dialog = new CookiesExceptionsDialog(BrowserApplication::cookieJar(), this); - dialog->exec(); -} - -void SettingsDialog::chooseFont() -{ - bool ok; - QFont font = QFontDialog::getFont(&ok, standardFont, this); - if ( ok ) { - standardFont = font; - standardLabel->setText(QString(QLatin1String("%1 %2")).arg(font.family()).arg(font.pointSize())); - } -} - -void SettingsDialog::chooseFixedFont() -{ - bool ok; - QFont font = QFontDialog::getFont(&ok, fixedFont, this); - if ( ok ) { - fixedFont = font; - fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(font.family()).arg(font.pointSize())); - } -} - -void SettingsDialog::setHomeToCurrentPage() -{ - BrowserMainWindow *mw = static_cast(parent()); - WebView *webView = mw->currentTab(); - if (webView) - homeLineEdit->setText(webView->url().toString()); -} - diff --git a/examples/gestures/browser/settings.h b/examples/gestures/browser/settings.h deleted file mode 100644 index 900be7b..0000000 --- a/examples/gestures/browser/settings.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SETTINGS_H -#define SETTINGS_H - -#include -#include "ui_settings.h" - -class SettingsDialog : public QDialog, public Ui_Settings -{ - Q_OBJECT - -public: - SettingsDialog(QWidget *parent = 0); - void accept(); - -private slots: - void loadDefaults(); - void loadFromSettings(); - void saveToSettings(); - - void setHomeToCurrentPage(); - void showCookies(); - void showExceptions(); - - void chooseFont(); - void chooseFixedFont(); - -private: - QFont standardFont; - QFont fixedFont; -}; - -#endif // SETTINGS_H - diff --git a/examples/gestures/browser/settings.ui b/examples/gestures/browser/settings.ui deleted file mode 100644 index 3491ce0..0000000 --- a/examples/gestures/browser/settings.ui +++ /dev/null @@ -1,614 +0,0 @@ - - Settings - - - - 0 - 0 - 657 - 322 - - - - Settings - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - 0 - - - - - 0 - 0 - 627 - 243 - - - - General - - - - - - Home: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Set to current page - - - - - - - Qt::Horizontal - - - - 280 - 18 - - - - - - - - Remove history items: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - After one day - - - - - After one week - - - - - After two weeks - - - - - After one month - - - - - After one year - - - - - Manually - - - - - - - - Save downloads to: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Open links from applications: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - In a tab in the current window - - - - - In a new window - - - - - - - - Qt::Vertical - - - - 391 - 262 - - - - - - - - - - 0 - 0 - 627 - 243 - - - - Appearance - - - - - - Standard font: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - Times 16 - - - Qt::AlignCenter - - - - - - - Select... - - - - - - - Fixed-width font: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - QFrame::StyledPanel - - - Courier 13 - - - Qt::AlignCenter - - - - - - - Select... - - - - - - - Qt::Vertical - - - - 20 - 93 - - - - - - - - - - 0 - 0 - 627 - 243 - - - - Privacy - - - - - - Web Content - - - - - - Enable Plugins - - - true - - - - - - - Enable Javascript - - - true - - - - - - - - - - Cookies - - - - - - Accept Cookies: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - Always - - - - - Never - - - - - Only from sites you navigate to - - - - - - - - Exceptions... - - - - - - - Keep until: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - They expire - - - - - I exit the application - - - - - At most 90 days - - - - - - - - Cookies... - - - - - - - - - - Qt::Vertical - - - - 371 - 177 - - - - - - - - - - 0 - 0 - 627 - 243 - - - - Proxy - - - - - - Enable proxy - - - true - - - - - - Type: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - Socks5 - - - - - Http - - - - - - - - Host: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Port: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 10000 - - - 1080 - - - - - - - Qt::Horizontal - - - - 293 - 20 - - - - - - - - User Name: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Password: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - QLineEdit::Password - - - - - - - Qt::Vertical - - - - 20 - 8 - - - - - - - - - - - - Advanced - - - - - - Style Sheet: - - - - - - - - - - Qt::Vertical - - - - 20 - 176 - - - - - - - - - - - - - - buttonBox - accepted() - Settings - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Settings - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/examples/gestures/browser/squeezelabel.cpp b/examples/gestures/browser/squeezelabel.cpp deleted file mode 100644 index 3247330..0000000 --- a/examples/gestures/browser/squeezelabel.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "squeezelabel.h" - -SqueezeLabel::SqueezeLabel(QWidget *parent) : QLabel(parent) -{ -} - -void SqueezeLabel::paintEvent(QPaintEvent *event) -{ - QFontMetrics fm = fontMetrics(); - if (fm.width(text()) > contentsRect().width()) { - QString elided = fm.elidedText(text(), Qt::ElideMiddle, width()); - QString oldText = text(); - setText(elided); - QLabel::paintEvent(event); - setText(oldText); - } else { - QLabel::paintEvent(event); - } -} - diff --git a/examples/gestures/browser/squeezelabel.h b/examples/gestures/browser/squeezelabel.h deleted file mode 100644 index 550a275..0000000 --- a/examples/gestures/browser/squeezelabel.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SQUEEZELABEL_H -#define SQUEEZELABEL_H - -#include - -class SqueezeLabel : public QLabel -{ - Q_OBJECT - -public: - SqueezeLabel(QWidget *parent = 0); - -protected: - void paintEvent(QPaintEvent *event); - -}; - -#endif // SQUEEZELABEL_H - diff --git a/examples/gestures/browser/tabwidget.cpp b/examples/gestures/browser/tabwidget.cpp deleted file mode 100644 index 67714e4..0000000 --- a/examples/gestures/browser/tabwidget.cpp +++ /dev/null @@ -1,830 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "tabwidget.h" - -#include "browserapplication.h" -#include "browsermainwindow.h" -#include "history.h" -#include "urllineedit.h" -#include "webview.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -TabBar::TabBar(QWidget *parent) - : QTabBar(parent) -{ - setContextMenuPolicy(Qt::CustomContextMenu); - setAcceptDrops(true); - connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), - this, SLOT(contextMenuRequested(const QPoint &))); - - QString alt = QLatin1String("Alt+%1"); - for (int i = 1; i <= 10; ++i) { - int key = i; - if (key == 10) - key = 0; - QShortcut *shortCut = new QShortcut(alt.arg(key), this); - m_tabShortcuts.append(shortCut); - connect(shortCut, SIGNAL(activated()), this, SLOT(selectTabAction())); - } - setTabsClosable(true); - connect(this, SIGNAL(tabCloseRequested(int)), - this, SIGNAL(closeTab(int))); - setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); - setMovable(true); -} - -void TabBar::selectTabAction() -{ - if (QShortcut *shortCut = qobject_cast(sender())) { - int index = m_tabShortcuts.indexOf(shortCut); - if (index == 0) - index = 10; - setCurrentIndex(index); - } -} - -void TabBar::contextMenuRequested(const QPoint &position) -{ - QMenu menu; - menu.addAction(tr("New &Tab"), this, SIGNAL(newTab()), QKeySequence::AddTab); - int index = tabAt(position); - if (-1 != index) { - QAction *action = menu.addAction(tr("Clone Tab"), - this, SLOT(cloneTab())); - action->setData(index); - - menu.addSeparator(); - - action = menu.addAction(tr("&Close Tab"), - this, SLOT(closeTab()), QKeySequence::Close); - action->setData(index); - - action = menu.addAction(tr("Close &Other Tabs"), - this, SLOT(closeOtherTabs())); - action->setData(index); - - menu.addSeparator(); - - action = menu.addAction(tr("Reload Tab"), - this, SLOT(reloadTab()), QKeySequence::Refresh); - action->setData(index); - } else { - menu.addSeparator(); - } - menu.addAction(tr("Reload All Tabs"), this, SIGNAL(reloadAllTabs())); - menu.exec(QCursor::pos()); -} - -void TabBar::cloneTab() -{ - if (QAction *action = qobject_cast(sender())) { - int index = action->data().toInt(); - emit cloneTab(index); - } -} - -void TabBar::closeTab() -{ - if (QAction *action = qobject_cast(sender())) { - int index = action->data().toInt(); - emit closeTab(index); - } -} - -void TabBar::closeOtherTabs() -{ - if (QAction *action = qobject_cast(sender())) { - int index = action->data().toInt(); - emit closeOtherTabs(index); - } -} - -void TabBar::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - m_dragStartPos = event->pos(); - QTabBar::mousePressEvent(event); -} - -void TabBar::mouseMoveEvent(QMouseEvent *event) -{ - if (event->buttons() == Qt::LeftButton) { - int diffX = event->pos().x() - m_dragStartPos.x(); - int diffY = event->pos().y() - m_dragStartPos.y(); - if ((event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance() - && diffX < 3 && diffX > -3 - && diffY < -10) { - QDrag *drag = new QDrag(this); - QMimeData *mimeData = new QMimeData; - QList urls; - int index = tabAt(event->pos()); - QUrl url = tabData(index).toUrl(); - urls.append(url); - mimeData->setUrls(urls); - mimeData->setText(tabText(index)); - mimeData->setData(QLatin1String("action"), "tab-reordering"); - drag->setMimeData(mimeData); - drag->exec(); - } - } - QTabBar::mouseMoveEvent(event); -} - -// When index is -1 index chooses the current tab -void TabWidget::reloadTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - QWidget *widget = this->widget(index); - if (WebView *tab = qobject_cast(widget)) - tab->reload(); -} - -void TabBar::reloadTab() -{ - if (QAction *action = qobject_cast(sender())) { - int index = action->data().toInt(); - emit reloadTab(index); - } -} - -TabWidget::TabWidget(QWidget *parent) - : QTabWidget(parent) - , m_recentlyClosedTabsAction(0) - , m_newTabAction(0) - , m_closeTabAction(0) - , m_nextTabAction(0) - , m_previousTabAction(0) - , m_recentlyClosedTabsMenu(0) - , m_lineEditCompleter(0) - , m_lineEdits(0) - , m_tabBar(new TabBar(this)) -{ - setElideMode(Qt::ElideRight); - - connect(m_tabBar, SIGNAL(newTab()), this, SLOT(newTab())); - connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int))); - connect(m_tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int))); - connect(m_tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int))); - connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); - connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs())); - connect(m_tabBar, SIGNAL(tabMoved(int, int)), this, SLOT(moveTab(int, int))); - setTabBar(m_tabBar); - setDocumentMode(true); - - // Actions - m_newTabAction = new QAction(QIcon(QLatin1String(":addtab.png")), tr("New &Tab"), this); - m_newTabAction->setShortcuts(QKeySequence::AddTab); - m_newTabAction->setIconVisibleInMenu(false); - connect(m_newTabAction, SIGNAL(triggered()), this, SLOT(newTab())); - - m_closeTabAction = new QAction(QIcon(QLatin1String(":closetab.png")), tr("&Close Tab"), this); - m_closeTabAction->setShortcuts(QKeySequence::Close); - m_closeTabAction->setIconVisibleInMenu(false); - connect(m_closeTabAction, SIGNAL(triggered()), this, SLOT(closeTab())); - - m_nextTabAction = new QAction(tr("Show Next Tab"), this); - QList shortcuts; - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceRight)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageDown)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketRight)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Less)); - m_nextTabAction->setShortcuts(shortcuts); - connect(m_nextTabAction, SIGNAL(triggered()), this, SLOT(nextTab())); - - m_previousTabAction = new QAction(tr("Show Previous Tab"), this); - shortcuts.clear(); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceLeft)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageUp)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketLeft)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Greater)); - m_previousTabAction->setShortcuts(shortcuts); - connect(m_previousTabAction, SIGNAL(triggered()), this, SLOT(previousTab())); - - m_recentlyClosedTabsMenu = new QMenu(this); - connect(m_recentlyClosedTabsMenu, SIGNAL(aboutToShow()), - this, SLOT(aboutToShowRecentTabsMenu())); - connect(m_recentlyClosedTabsMenu, SIGNAL(triggered(QAction *)), - this, SLOT(aboutToShowRecentTriggeredAction(QAction *))); - m_recentlyClosedTabsAction = new QAction(tr("Recently Closed Tabs"), this); - m_recentlyClosedTabsAction->setMenu(m_recentlyClosedTabsMenu); - m_recentlyClosedTabsAction->setEnabled(false); - - connect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - - m_lineEdits = new QStackedWidget(this); -} - -void TabWidget::clear() -{ - // clear the recently closed tabs - m_recentlyClosedTabs.clear(); - // clear the line edit history - for (int i = 0; i < m_lineEdits->count(); ++i) { - QLineEdit *qLineEdit = lineEdit(i); - qLineEdit->setText(qLineEdit->text()); - } -} - -void TabWidget::moveTab(int fromIndex, int toIndex) -{ - QWidget *lineEdit = m_lineEdits->widget(fromIndex); - m_lineEdits->removeWidget(lineEdit); - m_lineEdits->insertWidget(toIndex, lineEdit); -} - -void TabWidget::addWebAction(QAction *action, QWebPage::WebAction webAction) -{ - if (!action) - return; - m_actions.append(new WebActionMapper(action, webAction, this)); -} - -void TabWidget::currentChanged(int index) -{ - WebView *webView = this->webView(index); - if (!webView) - return; - - Q_ASSERT(m_lineEdits->count() == count()); - - WebView *oldWebView = this->webView(m_lineEdits->currentIndex()); - if (oldWebView) { - disconnect(oldWebView, SIGNAL(statusBarMessage(const QString&)), - this, SIGNAL(showStatusBarMessage(const QString&))); - disconnect(oldWebView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), - this, SIGNAL(linkHovered(const QString&))); - disconnect(oldWebView, SIGNAL(loadProgress(int)), - this, SIGNAL(loadProgress(int))); - } - - connect(webView, SIGNAL(statusBarMessage(const QString&)), - this, SIGNAL(showStatusBarMessage(const QString&))); - connect(webView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), - this, SIGNAL(linkHovered(const QString&))); - connect(webView, SIGNAL(loadProgress(int)), - this, SIGNAL(loadProgress(int))); - - for (int i = 0; i < m_actions.count(); ++i) { - WebActionMapper *mapper = m_actions[i]; - mapper->updateCurrent(webView->page()); - } - emit setCurrentTitle(webView->title()); - m_lineEdits->setCurrentIndex(index); - emit loadProgress(webView->progress()); - emit showStatusBarMessage(webView->lastStatusBarText()); - if (webView->url().isEmpty()) - m_lineEdits->currentWidget()->setFocus(); - else - webView->setFocus(); -} - -QAction *TabWidget::newTabAction() const -{ - return m_newTabAction; -} - -QAction *TabWidget::closeTabAction() const -{ - return m_closeTabAction; -} - -QAction *TabWidget::recentlyClosedTabsAction() const -{ - return m_recentlyClosedTabsAction; -} - -QAction *TabWidget::nextTabAction() const -{ - return m_nextTabAction; -} - -QAction *TabWidget::previousTabAction() const -{ - return m_previousTabAction; -} - -QWidget *TabWidget::lineEditStack() const -{ - return m_lineEdits; -} - -QLineEdit *TabWidget::currentLineEdit() const -{ - return lineEdit(m_lineEdits->currentIndex()); -} - -WebView *TabWidget::currentWebView() const -{ - return webView(currentIndex()); -} - -QLineEdit *TabWidget::lineEdit(int index) const -{ - UrlLineEdit *urlLineEdit = qobject_cast(m_lineEdits->widget(index)); - if (urlLineEdit) - return urlLineEdit->lineEdit(); - return 0; -} - -WebView *TabWidget::webView(int index) const -{ - QWidget *widget = this->widget(index); - if (WebView *webView = qobject_cast(widget)) { - return webView; - } else { - // optimization to delay creating the first webview - if (count() == 1) { - TabWidget *that = const_cast(this); - that->setUpdatesEnabled(false); - that->newTab(); - that->closeTab(0); - that->setUpdatesEnabled(true); - return currentWebView(); - } - } - return 0; -} - -int TabWidget::webViewIndex(WebView *webView) const -{ - int index = indexOf(webView); - return index; -} - -WebView *TabWidget::newTab(bool makeCurrent) -{ - // line edit - UrlLineEdit *urlLineEdit = new UrlLineEdit; - QLineEdit *lineEdit = urlLineEdit->lineEdit(); - if (!m_lineEditCompleter && count() > 0) { - HistoryCompletionModel *completionModel = new HistoryCompletionModel(this); - completionModel->setSourceModel(BrowserApplication::historyManager()->historyFilterModel()); - m_lineEditCompleter = new QCompleter(completionModel, this); - // Should this be in Qt by default? - QAbstractItemView *popup = m_lineEditCompleter->popup(); - QListView *listView = qobject_cast(popup); - if (listView) - listView->setUniformItemSizes(true); - } - lineEdit->setCompleter(m_lineEditCompleter); - connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(lineEditReturnPressed())); - m_lineEdits->addWidget(urlLineEdit); - m_lineEdits->setSizePolicy(lineEdit->sizePolicy()); - - // optimization to delay creating the more expensive WebView, history, etc - if (count() == 0) { - QWidget *emptyWidget = new QWidget; - QPalette p = emptyWidget->palette(); - p.setColor(QPalette::Window, palette().color(QPalette::Base)); - emptyWidget->setPalette(p); - emptyWidget->setAutoFillBackground(true); - disconnect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - addTab(emptyWidget, tr("(Untitled)")); - connect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - return 0; - } - - // webview - WebView *webView = new WebView; - urlLineEdit->setWebView(webView); - connect(webView, SIGNAL(loadStarted()), - this, SLOT(webViewLoadStarted())); - connect(webView, SIGNAL(loadFinished(bool)), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(iconChanged()), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(titleChanged(const QString &)), - this, SLOT(webViewTitleChanged(const QString &))); - connect(webView, SIGNAL(urlChanged(const QUrl &)), - this, SLOT(webViewUrlChanged(const QUrl &))); - connect(webView->page(), SIGNAL(windowCloseRequested()), - this, SLOT(windowCloseRequested())); - connect(webView->page(), SIGNAL(geometryChangeRequested(const QRect &)), - this, SIGNAL(geometryChangeRequested(const QRect &))); - connect(webView->page(), SIGNAL(printRequested(QWebFrame *)), - this, SIGNAL(printRequested(QWebFrame *))); - connect(webView->page(), SIGNAL(menuBarVisibilityChangeRequested(bool)), - this, SIGNAL(menuBarVisibilityChangeRequested(bool))); - connect(webView->page(), SIGNAL(statusBarVisibilityChangeRequested(bool)), - this, SIGNAL(statusBarVisibilityChangeRequested(bool))); - connect(webView->page(), SIGNAL(toolBarVisibilityChangeRequested(bool)), - this, SIGNAL(toolBarVisibilityChangeRequested(bool))); - addTab(webView, tr("(Untitled)")); - if (makeCurrent) - setCurrentWidget(webView); - - // webview actions - for (int i = 0; i < m_actions.count(); ++i) { - WebActionMapper *mapper = m_actions[i]; - mapper->addChild(webView->page()->action(mapper->webAction())); - } - - if (count() == 1) - currentChanged(currentIndex()); - emit tabsChanged(); - return webView; -} - -void TabWidget::reloadAllTabs() -{ - for (int i = 0; i < count(); ++i) { - QWidget *tabWidget = widget(i); - if (WebView *tab = qobject_cast(tabWidget)) { - tab->reload(); - } - } -} - -void TabWidget::lineEditReturnPressed() -{ - if (QLineEdit *lineEdit = qobject_cast(sender())) { - emit loadPage(lineEdit->text()); - if (m_lineEdits->currentWidget() == lineEdit) - currentWebView()->setFocus(); - } -} - -void TabWidget::windowCloseRequested() -{ - WebPage *webPage = qobject_cast(sender()); - WebView *webView = qobject_cast(webPage->view()); - int index = webViewIndex(webView); - if (index >= 0) { - if (count() == 1) - webView->webPage()->mainWindow()->close(); - else - closeTab(index); - } -} - -void TabWidget::closeOtherTabs(int index) -{ - if (-1 == index) - return; - for (int i = count() - 1; i > index; --i) - closeTab(i); - for (int i = index - 1; i >= 0; --i) - closeTab(i); -} - -// When index is -1 index chooses the current tab -void TabWidget::cloneTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - WebView *tab = newTab(false); - tab->setUrl(webView(index)->url()); -} - -// When index is -1 index chooses the current tab -void TabWidget::closeTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - bool hasFocus = false; - if (WebView *tab = webView(index)) { - if (tab->isModified()) { - QMessageBox closeConfirmation(tab); - closeConfirmation.setWindowFlags(Qt::Sheet); - closeConfirmation.setWindowTitle(tr("Do you really want to close this page?")); - closeConfirmation.setInformativeText(tr("You have modified this page and when closing it you would lose the modification.\n" - "Do you really want to close this page?\n")); - closeConfirmation.setIcon(QMessageBox::Question); - closeConfirmation.addButton(QMessageBox::Yes); - closeConfirmation.addButton(QMessageBox::No); - closeConfirmation.setEscapeButton(QMessageBox::No); - if (closeConfirmation.exec() == QMessageBox::No) - return; - } - hasFocus = tab->hasFocus(); - - m_recentlyClosedTabsAction->setEnabled(true); - m_recentlyClosedTabs.prepend(tab->url()); - if (m_recentlyClosedTabs.size() >= TabWidget::m_recentlyClosedTabsSize) - m_recentlyClosedTabs.removeLast(); - } - QWidget *lineEdit = m_lineEdits->widget(index); - m_lineEdits->removeWidget(lineEdit); - lineEdit->deleteLater(); - QWidget *webView = widget(index); - removeTab(index); - webView->deleteLater(); - emit tabsChanged(); - if (hasFocus && count() > 0) - currentWebView()->setFocus(); - if (count() == 0) - emit lastTabClosed(); -} - -void TabWidget::webViewLoadStarted() -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - QIcon icon(QLatin1String(":loading.gif")); - setTabIcon(index, icon); - } -} - -void TabWidget::webViewIconChanged() -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - QIcon icon = BrowserApplication::instance()->icon(webView->url()); - setTabIcon(index, icon); - } -} - -void TabWidget::webViewTitleChanged(const QString &title) -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - setTabText(index, title); - } - if (currentIndex() == index) - emit setCurrentTitle(title); - BrowserApplication::historyManager()->updateHistoryItem(webView->url(), title); -} - -void TabWidget::webViewUrlChanged(const QUrl &url) -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - m_tabBar->setTabData(index, url); - } - emit tabsChanged(); -} - -void TabWidget::aboutToShowRecentTabsMenu() -{ - m_recentlyClosedTabsMenu->clear(); - for (int i = 0; i < m_recentlyClosedTabs.count(); ++i) { - QAction *action = new QAction(m_recentlyClosedTabsMenu); - action->setData(m_recentlyClosedTabs.at(i)); - QIcon icon = BrowserApplication::instance()->icon(m_recentlyClosedTabs.at(i)); - action->setIcon(icon); - action->setText(m_recentlyClosedTabs.at(i).toString()); - m_recentlyClosedTabsMenu->addAction(action); - } -} - -void TabWidget::aboutToShowRecentTriggeredAction(QAction *action) -{ - QUrl url = action->data().toUrl(); - loadUrlInCurrentTab(url); -} - -void TabWidget::mouseDoubleClickEvent(QMouseEvent *event) -{ - if (!childAt(event->pos()) - // Remove the line below when QTabWidget does not have a one pixel frame - && event->pos().y() < (tabBar()->y() + tabBar()->height())) { - newTab(); - return; - } - QTabWidget::mouseDoubleClickEvent(event); -} - -void TabWidget::contextMenuEvent(QContextMenuEvent *event) -{ - if (!childAt(event->pos())) { - m_tabBar->contextMenuRequested(event->pos()); - return; - } - QTabWidget::contextMenuEvent(event); -} - -void TabWidget::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::MidButton && !childAt(event->pos()) - // Remove the line below when QTabWidget does not have a one pixel frame - && event->pos().y() < (tabBar()->y() + tabBar()->height())) { - QUrl url(QApplication::clipboard()->text(QClipboard::Selection)); - if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) { - WebView *webView = newTab(); - webView->setUrl(url); - } - } -} - -void TabWidget::loadUrlInCurrentTab(const QUrl &url) -{ - WebView *webView = currentWebView(); - if (webView) { - webView->loadUrl(url); - webView->setFocus(); - } -} - -void TabWidget::nextTab() -{ - int next = currentIndex() + 1; - if (next == count()) - next = 0; - setCurrentIndex(next); -} - -void TabWidget::previousTab() -{ - int next = currentIndex() - 1; - if (next < 0) - next = count() - 1; - setCurrentIndex(next); -} - -static const qint32 TabWidgetMagic = 0xaa; - -QByteArray TabWidget::saveState() const -{ - int version = 1; - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - - stream << qint32(TabWidgetMagic); - stream << qint32(version); - - QStringList tabs; - for (int i = 0; i < count(); ++i) { - if (WebView *tab = qobject_cast(widget(i))) { - tabs.append(tab->url().toString()); - } else { - tabs.append(QString::null); - } - } - stream << tabs; - stream << currentIndex(); - return data; -} - -bool TabWidget::restoreState(const QByteArray &state) -{ - int version = 1; - QByteArray sd = state; - QDataStream stream(&sd, QIODevice::ReadOnly); - if (stream.atEnd()) - return false; - - qint32 marker; - qint32 v; - stream >> marker; - stream >> v; - if (marker != TabWidgetMagic || v != version) - return false; - - QStringList openTabs; - stream >> openTabs; - - for (int i = 0; i < openTabs.count(); ++i) { - if (i != 0) - newTab(); - loadPage(openTabs.at(i)); - } - - int currentTab; - stream >> currentTab; - setCurrentIndex(currentTab); - - return true; -} - -WebActionMapper::WebActionMapper(QAction *root, QWebPage::WebAction webAction, QObject *parent) - : QObject(parent) - , m_currentParent(0) - , m_root(root) - , m_webAction(webAction) -{ - if (!m_root) - return; - connect(m_root, SIGNAL(triggered()), this, SLOT(rootTriggered())); - connect(root, SIGNAL(destroyed(QObject *)), this, SLOT(rootDestroyed())); - root->setEnabled(false); -} - -void WebActionMapper::rootDestroyed() -{ - m_root = 0; -} - -void WebActionMapper::currentDestroyed() -{ - updateCurrent(0); -} - -void WebActionMapper::addChild(QAction *action) -{ - if (!action) - return; - connect(action, SIGNAL(changed()), this, SLOT(childChanged())); -} - -QWebPage::WebAction WebActionMapper::webAction() const -{ - return m_webAction; -} - -void WebActionMapper::rootTriggered() -{ - if (m_currentParent) { - QAction *gotoAction = m_currentParent->action(m_webAction); - gotoAction->trigger(); - } -} - -void WebActionMapper::childChanged() -{ - if (QAction *source = qobject_cast(sender())) { - if (m_root - && m_currentParent - && source->parent() == m_currentParent) { - m_root->setChecked(source->isChecked()); - m_root->setEnabled(source->isEnabled()); - } - } -} - -void WebActionMapper::updateCurrent(QWebPage *currentParent) -{ - if (m_currentParent) - disconnect(m_currentParent, SIGNAL(destroyed(QObject *)), - this, SLOT(currentDestroyed())); - - m_currentParent = currentParent; - if (!m_root) - return; - if (!m_currentParent) { - m_root->setEnabled(false); - m_root->setChecked(false); - return; - } - QAction *source = m_currentParent->action(m_webAction); - m_root->setChecked(source->isChecked()); - m_root->setEnabled(source->isEnabled()); - connect(m_currentParent, SIGNAL(destroyed(QObject *)), - this, SLOT(currentDestroyed())); -} - diff --git a/examples/gestures/browser/tabwidget.h b/examples/gestures/browser/tabwidget.h deleted file mode 100644 index ee7b226..0000000 --- a/examples/gestures/browser/tabwidget.h +++ /dev/null @@ -1,224 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TABWIDGET_H -#define TABWIDGET_H - -#include - -#include -/* - Tab bar with a few more features such as a context menu and shortcuts - */ -class TabBar : public QTabBar -{ - Q_OBJECT - -signals: - void newTab(); - void cloneTab(int index); - void closeTab(int index); - void closeOtherTabs(int index); - void reloadTab(int index); - void reloadAllTabs(); - void tabMoveRequested(int fromIndex, int toIndex); - -public: - TabBar(QWidget *parent = 0); - -protected: - void mousePressEvent(QMouseEvent* event); - void mouseMoveEvent(QMouseEvent* event); - -private slots: - void selectTabAction(); - void cloneTab(); - void closeTab(); - void closeOtherTabs(); - void reloadTab(); - void contextMenuRequested(const QPoint &position); - -private: - QList m_tabShortcuts; - friend class TabWidget; - - QPoint m_dragStartPos; - int m_dragCurrentIndex; -}; - -#include - -QT_BEGIN_NAMESPACE -class QAction; -QT_END_NAMESPACE -class WebView; -/*! - A proxy object that connects a single browser action - to one child webpage action at a time. - - Example usage: used to keep the main window stop action in sync with - the current tabs webview's stop action. - */ -class WebActionMapper : public QObject -{ - Q_OBJECT - -public: - WebActionMapper(QAction *root, QWebPage::WebAction webAction, QObject *parent); - QWebPage::WebAction webAction() const; - void addChild(QAction *action); - void updateCurrent(QWebPage *currentParent); - -private slots: - void rootTriggered(); - void childChanged(); - void rootDestroyed(); - void currentDestroyed(); - -private: - QWebPage *m_currentParent; - QAction *m_root; - QWebPage::WebAction m_webAction; -}; - -#include -#include -QT_BEGIN_NAMESPACE -class QCompleter; -class QLineEdit; -class QMenu; -class QStackedWidget; -QT_END_NAMESPACE -/*! - TabWidget that contains WebViews and a stack widget of associated line edits. - - Connects up the current tab's signals to this class's signal and uses WebActionMapper - to proxy the actions. - */ -class TabWidget : public QTabWidget -{ - Q_OBJECT - -signals: - // tab widget signals - void loadPage(const QString &url); - void tabsChanged(); - void lastTabClosed(); - - // current tab signals - void setCurrentTitle(const QString &url); - void showStatusBarMessage(const QString &message); - void linkHovered(const QString &link); - void loadProgress(int progress); - void geometryChangeRequested(const QRect &geometry); - void menuBarVisibilityChangeRequested(bool visible); - void statusBarVisibilityChangeRequested(bool visible); - void toolBarVisibilityChangeRequested(bool visible); - void printRequested(QWebFrame *frame); - -public: - TabWidget(QWidget *parent = 0); - void clear(); - void addWebAction(QAction *action, QWebPage::WebAction webAction); - - QAction *newTabAction() const; - QAction *closeTabAction() const; - QAction *recentlyClosedTabsAction() const; - QAction *nextTabAction() const; - QAction *previousTabAction() const; - - QWidget *lineEditStack() const; - QLineEdit *currentLineEdit() const; - WebView *currentWebView() const; - WebView *webView(int index) const; - QLineEdit *lineEdit(int index) const; - int webViewIndex(WebView *webView) const; - - QByteArray saveState() const; - bool restoreState(const QByteArray &state); - -protected: - void mouseDoubleClickEvent(QMouseEvent *event); - void contextMenuEvent(QContextMenuEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - -public slots: - void loadUrlInCurrentTab(const QUrl &url); - WebView *newTab(bool makeCurrent = true); - void cloneTab(int index = -1); - void closeTab(int index = -1); - void closeOtherTabs(int index); - void reloadTab(int index = -1); - void reloadAllTabs(); - void nextTab(); - void previousTab(); - -private slots: - void currentChanged(int index); - void aboutToShowRecentTabsMenu(); - void aboutToShowRecentTriggeredAction(QAction *action); - void webViewLoadStarted(); - void webViewIconChanged(); - void webViewTitleChanged(const QString &title); - void webViewUrlChanged(const QUrl &url); - void lineEditReturnPressed(); - void windowCloseRequested(); - void moveTab(int fromIndex, int toIndex); - -private: - QAction *m_recentlyClosedTabsAction; - QAction *m_newTabAction; - QAction *m_closeTabAction; - QAction *m_nextTabAction; - QAction *m_previousTabAction; - - QMenu *m_recentlyClosedTabsMenu; - static const int m_recentlyClosedTabsSize = 10; - QList m_recentlyClosedTabs; - QList m_actions; - - QCompleter *m_lineEditCompleter; - QStackedWidget *m_lineEdits; - TabBar *m_tabBar; -}; - -#endif // TABWIDGET_H - diff --git a/examples/gestures/browser/toolbarsearch.cpp b/examples/gestures/browser/toolbarsearch.cpp deleted file mode 100644 index 0fb5322..0000000 --- a/examples/gestures/browser/toolbarsearch.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "toolbarsearch.h" -#include "autosaver.h" - -#include -#include - -#include -#include -#include - -#include - -/* - ToolbarSearch is a very basic search widget that also contains a small history. - Searches are turned into urls that use Google to perform search - */ -ToolbarSearch::ToolbarSearch(QWidget *parent) - : SearchLineEdit(parent) - , m_autosaver(new AutoSaver(this)) - , m_maxSavedSearches(10) - , m_stringListModel(new QStringListModel(this)) -{ - QMenu *m = menu(); - connect(m, SIGNAL(aboutToShow()), this, SLOT(aboutToShowMenu())); - connect(m, SIGNAL(triggered(QAction*)), this, SLOT(triggeredMenuAction(QAction*))); - - QCompleter *completer = new QCompleter(m_stringListModel, this); - completer->setCompletionMode(QCompleter::InlineCompletion); - lineEdit()->setCompleter(completer); - - connect(lineEdit(), SIGNAL(returnPressed()), SLOT(searchNow())); - setInactiveText(tr("Google")); - load(); -} - -ToolbarSearch::~ToolbarSearch() -{ - m_autosaver->saveIfNeccessary(); -} - -void ToolbarSearch::save() -{ - QSettings settings; - settings.beginGroup(QLatin1String("toolbarsearch")); - settings.setValue(QLatin1String("recentSearches"), m_stringListModel->stringList()); - settings.setValue(QLatin1String("maximumSaved"), m_maxSavedSearches); - settings.endGroup(); -} - -void ToolbarSearch::load() -{ - QSettings settings; - settings.beginGroup(QLatin1String("toolbarsearch")); - QStringList list = settings.value(QLatin1String("recentSearches")).toStringList(); - m_maxSavedSearches = settings.value(QLatin1String("maximumSaved"), m_maxSavedSearches).toInt(); - m_stringListModel->setStringList(list); - settings.endGroup(); -} - -void ToolbarSearch::searchNow() -{ - QString searchText = lineEdit()->text(); - QStringList newList = m_stringListModel->stringList(); - if (newList.contains(searchText)) - newList.removeAt(newList.indexOf(searchText)); - newList.prepend(searchText); - if (newList.size() >= m_maxSavedSearches) - newList.removeLast(); - - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (!globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) { - m_stringListModel->setStringList(newList); - m_autosaver->changeOccurred(); - } - - QUrl url(QLatin1String("http://www.google.com/search")); - url.addQueryItem(QLatin1String("q"), searchText); - url.addQueryItem(QLatin1String("ie"), QLatin1String("UTF-8")); - url.addQueryItem(QLatin1String("oe"), QLatin1String("UTF-8")); - url.addQueryItem(QLatin1String("client"), QLatin1String("qtdemobrowser")); - emit search(url); -} - -void ToolbarSearch::aboutToShowMenu() -{ - lineEdit()->selectAll(); - QMenu *m = menu(); - m->clear(); - QStringList list = m_stringListModel->stringList(); - if (list.isEmpty()) { - m->addAction(tr("No Recent Searches")); - return; - } - - QAction *recent = m->addAction(tr("Recent Searches")); - recent->setEnabled(false); - for (int i = 0; i < list.count(); ++i) { - QString text = list.at(i); - m->addAction(text)->setData(text); - } - m->addSeparator(); - m->addAction(tr("Clear Recent Searches"), this, SLOT(clear())); -} - -void ToolbarSearch::triggeredMenuAction(QAction *action) -{ - QVariant v = action->data(); - if (v.canConvert()) { - QString text = v.toString(); - lineEdit()->setText(text); - searchNow(); - } -} - -void ToolbarSearch::clear() -{ - m_stringListModel->setStringList(QStringList()); - m_autosaver->changeOccurred();; -} - diff --git a/examples/gestures/browser/toolbarsearch.h b/examples/gestures/browser/toolbarsearch.h deleted file mode 100644 index 02c1871..0000000 --- a/examples/gestures/browser/toolbarsearch.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TOOLBARSEARCH_H -#define TOOLBARSEARCH_H - -#include "searchlineedit.h" - -QT_BEGIN_NAMESPACE -class QUrl; -class QAction; -class QStringListModel; -QT_END_NAMESPACE - -class AutoSaver; - -class ToolbarSearch : public SearchLineEdit -{ - Q_OBJECT - -signals: - void search(const QUrl &url); - -public: - ToolbarSearch(QWidget *parent = 0); - ~ToolbarSearch(); - -public slots: - void clear(); - void searchNow(); - -private slots: - void save(); - void aboutToShowMenu(); - void triggeredMenuAction(QAction *action); - -private: - void load(); - - AutoSaver *m_autosaver; - int m_maxSavedSearches; - QStringListModel *m_stringListModel; -}; - -#endif // TOOLBARSEARCH_H - diff --git a/examples/gestures/browser/urllineedit.cpp b/examples/gestures/browser/urllineedit.cpp deleted file mode 100644 index 70951d1..0000000 --- a/examples/gestures/browser/urllineedit.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "urllineedit.h" - -#include "browserapplication.h" -#include "searchlineedit.h" -#include "webview.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -ExLineEdit::ExLineEdit(QWidget *parent) - : QWidget(parent) - , m_leftWidget(0) - , m_lineEdit(new QLineEdit(this)) - , m_clearButton(0) -{ - setFocusPolicy(m_lineEdit->focusPolicy()); - setAttribute(Qt::WA_InputMethodEnabled); - setSizePolicy(m_lineEdit->sizePolicy()); - setBackgroundRole(m_lineEdit->backgroundRole()); - setMouseTracking(true); - setAcceptDrops(true); - setAttribute(Qt::WA_MacShowFocusRect, true); - QPalette p = m_lineEdit->palette(); - setPalette(p); - - // line edit - m_lineEdit->setFrame(false); - m_lineEdit->setFocusProxy(this); - m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false); - QPalette clearPalette = m_lineEdit->palette(); - clearPalette.setBrush(QPalette::Base, QBrush(Qt::transparent)); - m_lineEdit->setPalette(clearPalette); - - // clearButton - m_clearButton = new ClearButton(this); - connect(m_clearButton, SIGNAL(clicked()), - m_lineEdit, SLOT(clear())); - connect(m_lineEdit, SIGNAL(textChanged(const QString&)), - m_clearButton, SLOT(textChanged(const QString&))); -} - -void ExLineEdit::setLeftWidget(QWidget *widget) -{ - m_leftWidget = widget; -} - -QWidget *ExLineEdit::leftWidget() const -{ - return m_leftWidget; -} - -void ExLineEdit::resizeEvent(QResizeEvent *event) -{ - Q_ASSERT(m_leftWidget); - updateGeometries(); - QWidget::resizeEvent(event); -} - -void ExLineEdit::updateGeometries() -{ - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - QRect rect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - - int height = rect.height(); - int width = rect.width(); - - int m_leftWidgetHeight = m_leftWidget->height(); - m_leftWidget->setGeometry(rect.x() + 2, rect.y() + (height - m_leftWidgetHeight)/2, - m_leftWidget->width(), m_leftWidget->height()); - - int clearButtonWidth = this->height(); - m_lineEdit->setGeometry(m_leftWidget->x() + m_leftWidget->width(), 0, - width - clearButtonWidth - m_leftWidget->width(), this->height()); - - m_clearButton->setGeometry(this->width() - clearButtonWidth, 0, - clearButtonWidth, this->height()); -} - -void ExLineEdit::initStyleOption(QStyleOptionFrameV2 *option) const -{ - option->initFrom(this); - option->rect = contentsRect(); - option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this); - option->midLineWidth = 0; - option->state |= QStyle::State_Sunken; - if (m_lineEdit->isReadOnly()) - option->state |= QStyle::State_ReadOnly; -#ifdef QT_KEYPAD_NAVIGATION - if (hasEditFocus()) - option->state |= QStyle::State_HasEditFocus; -#endif - option->features = QStyleOptionFrameV2::None; -} - -QSize ExLineEdit::sizeHint() const -{ - m_lineEdit->setFrame(true); - QSize size = m_lineEdit->sizeHint(); - m_lineEdit->setFrame(false); - return size; -} - -void ExLineEdit::focusInEvent(QFocusEvent *event) -{ - m_lineEdit->event(event); - QWidget::focusInEvent(event); -} - -void ExLineEdit::focusOutEvent(QFocusEvent *event) -{ - m_lineEdit->event(event); - - if (m_lineEdit->completer()) { - connect(m_lineEdit->completer(), SIGNAL(activated(QString)), - m_lineEdit, SLOT(setText(QString))); - connect(m_lineEdit->completer(), SIGNAL(highlighted(QString)), - m_lineEdit, SLOT(_q_completionHighlighted(QString))); - } - QWidget::focusOutEvent(event); -} - -void ExLineEdit::keyPressEvent(QKeyEvent *event) -{ - m_lineEdit->event(event); -} - -bool ExLineEdit::event(QEvent *event) -{ - if (event->type() == QEvent::ShortcutOverride) - return m_lineEdit->event(event); - return QWidget::event(event); -} - -void ExLineEdit::paintEvent(QPaintEvent *) -{ - QPainter p(this); - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this); -} - -QVariant ExLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const -{ - return m_lineEdit->inputMethodQuery(property); -} - -void ExLineEdit::inputMethodEvent(QInputMethodEvent *e) -{ - m_lineEdit->event(e); -} - - -class UrlIconLabel : public QLabel -{ - -public: - UrlIconLabel(QWidget *parent); - - WebView *m_webView; - -protected: - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - -private: - QPoint m_dragStartPos; - -}; - -UrlIconLabel::UrlIconLabel(QWidget *parent) - : QLabel(parent) - , m_webView(0) -{ - setMinimumWidth(16); - setMinimumHeight(16); -} - -void UrlIconLabel::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - m_dragStartPos = event->pos(); - QLabel::mousePressEvent(event); -} - -void UrlIconLabel::mouseMoveEvent(QMouseEvent *event) -{ - if (event->buttons() == Qt::LeftButton - && (event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance() - && m_webView) { - QDrag *drag = new QDrag(this); - QMimeData *mimeData = new QMimeData; - mimeData->setText(QString::fromUtf8(m_webView->url().toEncoded())); - QList urls; - urls.append(m_webView->url()); - mimeData->setUrls(urls); - drag->setMimeData(mimeData); - drag->exec(); - } -} - -UrlLineEdit::UrlLineEdit(QWidget *parent) - : ExLineEdit(parent) - , m_webView(0) - , m_iconLabel(0) -{ - // icon - m_iconLabel = new UrlIconLabel(this); - m_iconLabel->resize(16, 16); - setLeftWidget(m_iconLabel); - m_defaultBaseColor = palette().color(QPalette::Base); - - webViewIconChanged(); -} - -void UrlLineEdit::setWebView(WebView *webView) -{ - Q_ASSERT(!m_webView); - m_webView = webView; - m_iconLabel->m_webView = webView; - connect(webView, SIGNAL(urlChanged(const QUrl &)), - this, SLOT(webViewUrlChanged(const QUrl &))); - connect(webView, SIGNAL(loadFinished(bool)), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(iconChanged()), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(loadProgress(int)), - this, SLOT(update())); -} - -void UrlLineEdit::webViewUrlChanged(const QUrl &url) -{ - m_lineEdit->setText(QString::fromUtf8(url.toEncoded())); - m_lineEdit->setCursorPosition(0); -} - -void UrlLineEdit::webViewIconChanged() -{ - QUrl url = (m_webView) ? m_webView->url() : QUrl(); - QIcon icon = BrowserApplication::instance()->icon(url); - QPixmap pixmap(icon.pixmap(16, 16)); - m_iconLabel->setPixmap(pixmap); -} - -QLinearGradient UrlLineEdit::generateGradient(const QColor &color) const -{ - QLinearGradient gradient(0, 0, 0, height()); - gradient.setColorAt(0, m_defaultBaseColor); - gradient.setColorAt(0.15, color.lighter(120)); - gradient.setColorAt(0.5, color); - gradient.setColorAt(0.85, color.lighter(120)); - gradient.setColorAt(1, m_defaultBaseColor); - return gradient; -} - -void UrlLineEdit::focusOutEvent(QFocusEvent *event) -{ - if (m_lineEdit->text().isEmpty() && m_webView) - m_lineEdit->setText(QString::fromUtf8(m_webView->url().toEncoded())); - ExLineEdit::focusOutEvent(event); -} - -void UrlLineEdit::paintEvent(QPaintEvent *event) -{ - QPalette p = palette(); - if (m_webView && m_webView->url().scheme() == QLatin1String("https")) { - QColor lightYellow(248, 248, 210); - p.setBrush(QPalette::Base, generateGradient(lightYellow)); - } else { - p.setBrush(QPalette::Base, m_defaultBaseColor); - } - setPalette(p); - ExLineEdit::paintEvent(event); - - QPainter painter(this); - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - QRect backgroundRect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - if (m_webView && !hasFocus()) { - int progress = m_webView->progress(); - QColor loadingColor = QColor(116, 192, 250); - painter.setBrush(generateGradient(loadingColor)); - painter.setPen(Qt::transparent); - int mid = backgroundRect.width() / 100 * progress; - QRect progressRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height()); - painter.drawRect(progressRect); - } -} diff --git a/examples/gestures/browser/urllineedit.h b/examples/gestures/browser/urllineedit.h deleted file mode 100644 index 0727e6a..0000000 --- a/examples/gestures/browser/urllineedit.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef URLLINEEDIT_H -#define URLLINEEDIT_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QLineEdit; -QT_END_NAMESPACE - -class ClearButton; -class ExLineEdit : public QWidget -{ - Q_OBJECT - -public: - ExLineEdit(QWidget *parent = 0); - - inline QLineEdit *lineEdit() const { return m_lineEdit; } - - void setLeftWidget(QWidget *widget); - QWidget *leftWidget() const; - - QSize sizeHint() const; - - QVariant inputMethodQuery(Qt::InputMethodQuery property) const; -protected: - void focusInEvent(QFocusEvent *event); - void focusOutEvent(QFocusEvent *event); - void keyPressEvent(QKeyEvent *event); - void paintEvent(QPaintEvent *event); - void resizeEvent(QResizeEvent *event); - void inputMethodEvent(QInputMethodEvent *e); - bool event(QEvent *event); - -protected: - void updateGeometries(); - void initStyleOption(QStyleOptionFrameV2 *option) const; - - QWidget *m_leftWidget; - QLineEdit *m_lineEdit; - ClearButton *m_clearButton; -}; - -class UrlIconLabel; -class WebView; -class UrlLineEdit : public ExLineEdit -{ - Q_OBJECT - -public: - UrlLineEdit(QWidget *parent = 0); - void setWebView(WebView *webView); - -protected: - void paintEvent(QPaintEvent *event); - void focusOutEvent(QFocusEvent *event); - -private slots: - void webViewUrlChanged(const QUrl &url); - void webViewIconChanged(); - -private: - QLinearGradient generateGradient(const QColor &color) const; - WebView *m_webView; - UrlIconLabel *m_iconLabel; - QColor m_defaultBaseColor; - -}; - - -#endif // URLLINEEDIT_H - diff --git a/examples/gestures/browser/webview.cpp b/examples/gestures/browser/webview.cpp deleted file mode 100644 index e50872f..0000000 --- a/examples/gestures/browser/webview.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "browserapplication.h" -#include "browsermainwindow.h" -#include "cookiejar.h" -#include "downloadmanager.h" -#include "networkaccessmanager.h" -#include "tabwidget.h" -#include "webview.h" - -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -WebPage::WebPage(QObject *parent) - : QWebPage(parent) - , m_keyboardModifiers(Qt::NoModifier) - , m_pressedButtons(Qt::NoButton) - , m_openInNewTab(false) -{ - setNetworkAccessManager(BrowserApplication::networkAccessManager()); - connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), - this, SLOT(handleUnsupportedContent(QNetworkReply *))); -} - -BrowserMainWindow *WebPage::mainWindow() -{ - QObject *w = this->parent(); - while (w) { - if (BrowserMainWindow *mw = qobject_cast(w)) - return mw; - w = w->parent(); - } - return BrowserApplication::instance()->mainWindow(); -} - -bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type) -{ - // ctrl open in new tab - // ctrl-shift open in new tab and select - // ctrl-alt open in new window - if (type == QWebPage::NavigationTypeLinkClicked - && (m_keyboardModifiers & Qt::ControlModifier - || m_pressedButtons == Qt::MidButton)) { - bool newWindow = (m_keyboardModifiers & Qt::AltModifier); - WebView *webView; - if (newWindow) { - BrowserApplication::instance()->newMainWindow(); - BrowserMainWindow *newMainWindow = BrowserApplication::instance()->mainWindow(); - webView = newMainWindow->currentTab(); - newMainWindow->raise(); - newMainWindow->activateWindow(); - webView->setFocus(); - } else { - bool selectNewTab = (m_keyboardModifiers & Qt::ShiftModifier); - webView = mainWindow()->tabWidget()->newTab(selectNewTab); - } - webView->load(request); - m_keyboardModifiers = Qt::NoModifier; - m_pressedButtons = Qt::NoButton; - return false; - } - if (frame == mainFrame()) { - m_loadingUrl = request.url(); - emit loadingUrl(m_loadingUrl); - } - return QWebPage::acceptNavigationRequest(frame, request, type); -} - -QWebPage *WebPage::createWindow(QWebPage::WebWindowType type) -{ - Q_UNUSED(type); - if (m_keyboardModifiers & Qt::ControlModifier || m_pressedButtons == Qt::MidButton) - m_openInNewTab = true; - if (m_openInNewTab) { - m_openInNewTab = false; - return mainWindow()->tabWidget()->newTab()->page(); - } - BrowserApplication::instance()->newMainWindow(); - BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); - return mainWindow->currentTab()->page(); -} - -#if !defined(QT_NO_UITOOLS) -QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) -{ - Q_UNUSED(url); - Q_UNUSED(paramNames); - Q_UNUSED(paramValues); - QUiLoader loader; - return loader.createWidget(classId, view()); -} -#endif // !defined(QT_NO_UITOOLS) - -void WebPage::handleUnsupportedContent(QNetworkReply *reply) -{ - if (reply->error() == QNetworkReply::NoError) { - BrowserApplication::downloadManager()->handleUnsupportedContent(reply); - return; - } - - QFile file(QLatin1String(":/notfound.html")); - bool isOpened = file.open(QIODevice::ReadOnly); - Q_ASSERT(isOpened); - QString title = tr("Error loading page: %1").arg(reply->url().toString()); - QString html = QString(QLatin1String(file.readAll())) - .arg(title) - .arg(reply->errorString()) - .arg(reply->url().toString()); - - QBuffer imageBuffer; - imageBuffer.open(QBuffer::ReadWrite); - QIcon icon = view()->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, view()); - QPixmap pixmap = icon.pixmap(QSize(32,32)); - if (pixmap.save(&imageBuffer, "PNG")) { - html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"), - QString(QLatin1String(imageBuffer.buffer().toBase64()))); - } - - QList frames; - frames.append(mainFrame()); - while (!frames.isEmpty()) { - QWebFrame *frame = frames.takeFirst(); - if (frame->url() == reply->url()) { - frame->setHtml(html, reply->url()); - return; - } - QList children = frame->childFrames(); - foreach(QWebFrame *frame, children) - frames.append(frame); - } - if (m_loadingUrl == reply->url()) { - mainFrame()->setHtml(html, reply->url()); - } -} - - -WebView::WebView(QWidget* parent) - : QWebView(parent) - , m_progress(0) - , m_page(new WebPage(this)) - , m_currentPanFrame(0) -{ - grabGesture(Qt::PanGesture); - setPage(m_page); - connect(page(), SIGNAL(statusBarMessage(const QString&)), - SLOT(setStatusBarText(const QString&))); - connect(this, SIGNAL(loadProgress(int)), - this, SLOT(setProgress(int))); - connect(this, SIGNAL(loadFinished(bool)), - this, SLOT(loadFinished())); - connect(page(), SIGNAL(loadingUrl(const QUrl&)), - this, SIGNAL(urlChanged(const QUrl &))); - connect(page(), SIGNAL(downloadRequested(const QNetworkRequest &)), - this, SLOT(downloadRequested(const QNetworkRequest &))); - page()->setForwardUnsupportedContent(true); - -} - -void WebView::contextMenuEvent(QContextMenuEvent *event) -{ - QWebHitTestResult r = page()->mainFrame()->hitTestContent(event->pos()); - if (!r.linkUrl().isEmpty()) { - QMenu menu(this); - menu.addAction(pageAction(QWebPage::OpenLinkInNewWindow)); - menu.addAction(tr("Open in New Tab"), this, SLOT(openLinkInNewTab())); - menu.addSeparator(); - menu.addAction(pageAction(QWebPage::DownloadLinkToDisk)); - // Add link to bookmarks... - menu.addSeparator(); - menu.addAction(pageAction(QWebPage::CopyLinkToClipboard)); - if (page()->settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled)) - menu.addAction(pageAction(QWebPage::InspectElement)); - menu.exec(mapToGlobal(event->pos())); - return; - } - QWebView::contextMenuEvent(event); -} - -void WebView::wheelEvent(QWheelEvent *event) -{ - if (QApplication::keyboardModifiers() & Qt::ControlModifier) { - int numDegrees = event->delta() / 8; - int numSteps = numDegrees / 15; - setTextSizeMultiplier(textSizeMultiplier() + numSteps * 0.1); - event->accept(); - return; - } - QWebView::wheelEvent(event); -} - -void WebView::openLinkInNewTab() -{ - m_page->m_openInNewTab = true; - pageAction(QWebPage::OpenLinkInNewWindow)->trigger(); -} - -void WebView::setProgress(int progress) -{ - m_progress = progress; -} - -void WebView::loadFinished() -{ - if (100 != m_progress) { - qWarning() << "Recieved finished signal while progress is still:" << progress() - << "Url:" << url(); - } - m_progress = 0; -} - -void WebView::loadUrl(const QUrl &url) -{ - m_initialUrl = url; - load(url); -} - -QString WebView::lastStatusBarText() const -{ - return m_statusBarText; -} - -QUrl WebView::url() const -{ - QUrl url = QWebView::url(); - if (!url.isEmpty()) - return url; - - return m_initialUrl; -} - -void WebView::mousePressEvent(QMouseEvent *event) -{ - m_page->m_pressedButtons = event->buttons(); - m_page->m_keyboardModifiers = event->modifiers(); - QWebView::mousePressEvent(event); -} - -void WebView::mouseReleaseEvent(QMouseEvent *event) -{ - QWebView::mouseReleaseEvent(event); - if (!event->isAccepted() && (m_page->m_pressedButtons & Qt::MidButton)) { - QUrl url(QApplication::clipboard()->text(QClipboard::Selection)); - if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) { - setUrl(url); - } - } -} - -void WebView::setStatusBarText(const QString &string) -{ - m_statusBarText = string; -} - -void WebView::downloadRequested(const QNetworkRequest &request) -{ - BrowserApplication::downloadManager()->download(request); -} - -bool WebView::event(QEvent *event) -{ - if (event->type() == QEvent::Gesture) - { - gestureEvent(static_cast(event)); - return true; - } - return QWebView::event(event); -} - -void WebView::gestureEvent(QGestureEvent *event) -{ - if (const QGesture *g = event->gesture(Qt::PanGesture)) { - if (g->state() == Qt::GestureUpdated) { - if (m_currentPanFrame) { - m_panSpeed = g->pos() - g->lastPos(); - m_currentPanFrame->scroll(-m_panSpeed.x(), -m_panSpeed.y()); - } - } else if (g->state() == Qt::GestureStarted) { - startTimer(20); - m_currentPanFrame = 0; - if (QWebFrame *frame = page()->mainFrame()) { - QWebHitTestResult result = frame->hitTestContent(g->startPos()); - if (!result.isNull()) - m_currentPanFrame = result.frame(); - while (m_currentPanFrame && - m_currentPanFrame->scrollBarMinimum(Qt::Vertical) == 0 && - m_currentPanFrame->scrollBarMaximum(Qt::Vertical) == 0 && - m_currentPanFrame->scrollBarMinimum(Qt::Horizontal) == 0 && - m_currentPanFrame->scrollBarMaximum(Qt::Horizontal) == 0) { - m_currentPanFrame = m_currentPanFrame->parentFrame(); - } - } - } else { - } - event->accept(); - } -} - -static QPoint deaccelerate(const QPoint &speed, int a = 1, int max = 64) -{ - int x = qBound(-max, speed.x(), max); - int y = qBound(-max, speed.y(), max); - x = (x == 0) ? x : (x > 0) ? qMax(0, x - a) : qMin(0, x + a); - y = (y == 0) ? y : (y > 0) ? qMax(0, y - a) : qMin(0, y + a); - return QPoint(x, y); -} - -void WebView::timerEvent(QTimerEvent *event) -{ - m_panSpeed = deaccelerate(m_panSpeed); - if (m_panSpeed.isNull()) - killTimer(event->timerId()); - if (m_currentPanFrame) - m_currentPanFrame->scroll(-m_panSpeed.x(), -m_panSpeed.y()); -} diff --git a/examples/gestures/browser/webview.h b/examples/gestures/browser/webview.h deleted file mode 100644 index 71aca1a..0000000 --- a/examples/gestures/browser/webview.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WEBVIEW_H -#define WEBVIEW_H - -#include - -QT_BEGIN_NAMESPACE -class QAuthenticator; -class QMouseEvent; -class QNetworkProxy; -class QNetworkReply; -class QSslError; -QT_END_NAMESPACE - -class BrowserMainWindow; -class WebPage : public QWebPage { - Q_OBJECT - -signals: - void loadingUrl(const QUrl &url); - -public: - WebPage(QObject *parent = 0); - BrowserMainWindow *mainWindow(); - -protected: - bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type); - QWebPage *createWindow(QWebPage::WebWindowType type); -#if !defined(QT_NO_UITOOLS) - QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); -#endif - -private slots: - void handleUnsupportedContent(QNetworkReply *reply); - -private: - friend class WebView; - - // set the webview mousepressedevent - Qt::KeyboardModifiers m_keyboardModifiers; - Qt::MouseButtons m_pressedButtons; - bool m_openInNewTab; - QUrl m_loadingUrl; -}; - -class WebView : public QWebView { - Q_OBJECT - -public: - WebView(QWidget *parent = 0); - WebPage *webPage() const { return m_page; } - - void loadUrl(const QUrl &url); - QUrl url() const; - - QString lastStatusBarText() const; - inline int progress() const { return m_progress; } - -protected: - bool event(QEvent *event); - void gestureEvent(QGestureEvent *event); - void timerEvent(QTimerEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void contextMenuEvent(QContextMenuEvent *event); - void wheelEvent(QWheelEvent *event); - -private slots: - void setProgress(int progress); - void loadFinished(); - void setStatusBarText(const QString &string); - void downloadRequested(const QNetworkRequest &request); - void openLinkInNewTab(); - -private: - QString m_statusBarText; - QUrl m_initialUrl; - int m_progress; - WebPage *m_page; - QPoint m_panSpeed; - QWebFrame *m_currentPanFrame; -}; - -#endif diff --git a/examples/gestures/browser/xbel.cpp b/examples/gestures/browser/xbel.cpp deleted file mode 100644 index 6145281..0000000 --- a/examples/gestures/browser/xbel.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "xbel.h" - -#include - -BookmarkNode::BookmarkNode(BookmarkNode::Type type, BookmarkNode *parent) : - expanded(false) - , m_parent(parent) - , m_type(type) -{ - if (parent) - parent->add(this); -} - -BookmarkNode::~BookmarkNode() -{ - if (m_parent) - m_parent->remove(this); - qDeleteAll(m_children); - m_parent = 0; - m_type = BookmarkNode::Root; -} - -bool BookmarkNode::operator==(const BookmarkNode &other) -{ - if (url != other.url - || title != other.title - || desc != other.desc - || expanded != other.expanded - || m_type != other.m_type - || m_children.count() != other.m_children.count()) - return false; - - for (int i = 0; i < m_children.count(); ++i) - if (!((*(m_children[i])) == (*(other.m_children[i])))) - return false; - return true; -} - -BookmarkNode::Type BookmarkNode::type() const -{ - return m_type; -} - -void BookmarkNode::setType(Type type) -{ - m_type = type; -} - -QList BookmarkNode::children() const -{ - return m_children; -} - -BookmarkNode *BookmarkNode::parent() const -{ - return m_parent; -} - -void BookmarkNode::add(BookmarkNode *child, int offset) -{ - Q_ASSERT(child->m_type != Root); - if (child->m_parent) - child->m_parent->remove(child); - child->m_parent = this; - if (-1 == offset) - offset = m_children.size(); - m_children.insert(offset, child); -} - -void BookmarkNode::remove(BookmarkNode *child) -{ - child->m_parent = 0; - m_children.removeAll(child); -} - - -XbelReader::XbelReader() -{ -} - -BookmarkNode *XbelReader::read(const QString &fileName) -{ - QFile file(fileName); - if (!file.exists()) { - return new BookmarkNode(BookmarkNode::Root); - } - file.open(QFile::ReadOnly); - return read(&file); -} - -BookmarkNode *XbelReader::read(QIODevice *device) -{ - BookmarkNode *root = new BookmarkNode(BookmarkNode::Root); - setDevice(device); - while (!atEnd()) { - readNext(); - if (isStartElement()) { - QString version = attributes().value(QLatin1String("version")).toString(); - if (name() == QLatin1String("xbel") - && (version.isEmpty() || version == QLatin1String("1.0"))) { - readXBEL(root); - } else { - raiseError(QObject::tr("The file is not an XBEL version 1.0 file.")); - } - } - } - return root; -} - -void XbelReader::readXBEL(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("xbel")); - - while (!atEnd()) { - readNext(); - if (isEndElement()) - break; - - if (isStartElement()) { - if (name() == QLatin1String("folder")) - readFolder(parent); - else if (name() == QLatin1String("bookmark")) - readBookmarkNode(parent); - else if (name() == QLatin1String("separator")) - readSeparator(parent); - else - skipUnknownElement(); - } - } -} - -void XbelReader::readFolder(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("folder")); - - BookmarkNode *folder = new BookmarkNode(BookmarkNode::Folder, parent); - folder->expanded = (attributes().value(QLatin1String("folded")) == QLatin1String("no")); - - while (!atEnd()) { - readNext(); - - if (isEndElement()) - break; - - if (isStartElement()) { - if (name() == QLatin1String("title")) - readTitle(folder); - else if (name() == QLatin1String("desc")) - readDescription(folder); - else if (name() == QLatin1String("folder")) - readFolder(folder); - else if (name() == QLatin1String("bookmark")) - readBookmarkNode(folder); - else if (name() == QLatin1String("separator")) - readSeparator(folder); - else - skipUnknownElement(); - } - } -} - -void XbelReader::readTitle(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("title")); - parent->title = readElementText(); -} - -void XbelReader::readDescription(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("desc")); - parent->desc = readElementText(); -} - -void XbelReader::readSeparator(BookmarkNode *parent) -{ - new BookmarkNode(BookmarkNode::Separator, parent); - // empty elements have a start and end element - readNext(); -} - -void XbelReader::readBookmarkNode(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("bookmark")); - BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark, parent); - bookmark->url = attributes().value(QLatin1String("href")).toString(); - while (!atEnd()) { - readNext(); - if (isEndElement()) - break; - - if (isStartElement()) { - if (name() == QLatin1String("title")) - readTitle(bookmark); - else if (name() == QLatin1String("desc")) - readDescription(bookmark); - else - skipUnknownElement(); - } - } - if (bookmark->title.isEmpty()) - bookmark->title = QObject::tr("Unknown title"); -} - -void XbelReader::skipUnknownElement() -{ - Q_ASSERT(isStartElement()); - - while (!atEnd()) { - readNext(); - - if (isEndElement()) - break; - - if (isStartElement()) - skipUnknownElement(); - } -} - - -XbelWriter::XbelWriter() -{ - setAutoFormatting(true); -} - -bool XbelWriter::write(const QString &fileName, const BookmarkNode *root) -{ - QFile file(fileName); - if (!root || !file.open(QFile::WriteOnly)) - return false; - return write(&file, root); -} - -bool XbelWriter::write(QIODevice *device, const BookmarkNode *root) -{ - setDevice(device); - - writeStartDocument(); - writeDTD(QLatin1String("")); - writeStartElement(QLatin1String("xbel")); - writeAttribute(QLatin1String("version"), QLatin1String("1.0")); - if (root->type() == BookmarkNode::Root) { - for (int i = 0; i < root->children().count(); ++i) - writeItem(root->children().at(i)); - } else { - writeItem(root); - } - - writeEndDocument(); - return true; -} - -void XbelWriter::writeItem(const BookmarkNode *parent) -{ - switch (parent->type()) { - case BookmarkNode::Folder: - writeStartElement(QLatin1String("folder")); - writeAttribute(QLatin1String("folded"), parent->expanded ? QLatin1String("no") : QLatin1String("yes")); - writeTextElement(QLatin1String("title"), parent->title); - for (int i = 0; i < parent->children().count(); ++i) - writeItem(parent->children().at(i)); - writeEndElement(); - break; - case BookmarkNode::Bookmark: - writeStartElement(QLatin1String("bookmark")); - if (!parent->url.isEmpty()) - writeAttribute(QLatin1String("href"), parent->url); - writeTextElement(QLatin1String("title"), parent->title); - if (!parent->desc.isEmpty()) - writeAttribute(QLatin1String("desc"), parent->desc); - writeEndElement(); - break; - case BookmarkNode::Separator: - writeEmptyElement(QLatin1String("separator")); - break; - default: - break; - } -} - diff --git a/examples/gestures/browser/xbel.h b/examples/gestures/browser/xbel.h deleted file mode 100644 index 20cbda6..0000000 --- a/examples/gestures/browser/xbel.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef XBEL_H -#define XBEL_H - -#include -#include - -class BookmarkNode -{ -public: - enum Type { - Root, - Folder, - Bookmark, - Separator - }; - - BookmarkNode(Type type = Root, BookmarkNode *parent = 0); - ~BookmarkNode(); - bool operator==(const BookmarkNode &other); - - Type type() const; - void setType(Type type); - QList children() const; - BookmarkNode *parent() const; - - void add(BookmarkNode *child, int offset = -1); - void remove(BookmarkNode *child); - - QString url; - QString title; - QString desc; - bool expanded; - -private: - BookmarkNode *m_parent; - Type m_type; - QList m_children; - -}; - -class XbelReader : public QXmlStreamReader -{ -public: - XbelReader(); - BookmarkNode *read(const QString &fileName); - BookmarkNode *read(QIODevice *device); - -private: - void skipUnknownElement(); - void readXBEL(BookmarkNode *parent); - void readTitle(BookmarkNode *parent); - void readDescription(BookmarkNode *parent); - void readSeparator(BookmarkNode *parent); - void readFolder(BookmarkNode *parent); - void readBookmarkNode(BookmarkNode *parent); -}; - -#include - -class XbelWriter : public QXmlStreamWriter -{ -public: - XbelWriter(); - bool write(const QString &fileName, const BookmarkNode *root); - bool write(QIODevice *device, const BookmarkNode *root); - -private: - void writeItem(const BookmarkNode *parent); -}; - -#endif // XBEL_H - diff --git a/examples/gestures/collidingmice/collidingmice.pro b/examples/gestures/collidingmice/collidingmice.pro deleted file mode 100644 index 15164ce..0000000 --- a/examples/gestures/collidingmice/collidingmice.pro +++ /dev/null @@ -1,18 +0,0 @@ -HEADERS += \ - mouse.h \ - gesturerecognizerlinjazax.h \ - linjazaxgesture.h - -SOURCES += \ - main.cpp \ - mouse.cpp \ - gesturerecognizerlinjazax.cpp - -RESOURCES += \ - mice.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/gestures/collidingmice -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS collidingmice.pro images -sources.path = $$[QT_INSTALL_EXAMPLES]/gestures/collidingmice -INSTALLS += target sources diff --git a/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp b/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp deleted file mode 100644 index 2070f6f..0000000 --- a/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "gesturerecognizerlinjazax.h" - -#include -#include - -static const int SIZE = 20; - -DirectionSimpleRecognizer::DirectionSimpleRecognizer() -{ -} - -Direction DirectionSimpleRecognizer::addPosition(const QPoint &pos) -{ - if (!directions.isEmpty()) { - const QPoint tmp = pos - directions.back().point; - if (tmp.manhattanLength() < 5) - return Direction(); - } - if (lastPoint.isNull()) { - lastPoint = pos; - return Direction(); - } - int dx = pos.x() - lastPoint.x(); - int dy = pos.y() - lastPoint.y(); - QString direction; - if (dx < 0) { - if (-1*dx >= SIZE/2) - direction = "4"; - } else { - if (dx >= SIZE/2) - direction = "6"; - } - if (dy < 0) { - if (-1*dy >= SIZE/2) - direction = "8"; - } else { - if (dy >= SIZE/2) - direction = "2"; - } - if (direction.isEmpty()) - return Direction(); - - lastPoint = pos; - directions.push_back(Direction(direction, pos)); - return Direction(direction, pos); -} - - -DirectionList DirectionSimpleRecognizer::getDirections() const -{ - return directions; -} - -void DirectionSimpleRecognizer::reset() -{ - directions.clear(); - lastPoint = QPoint(); -} - -/////////////////////////////////////////////////////////////////////////// - -GestureRecognizerLinjaZax::GestureRecognizerLinjaZax() - : QGestureRecognizer(QLatin1String("LinjaZax")), mousePressed(false), gestureFinished(false), - zoomState(LinjaZaxGesture::NoZoom) -{ -} - -QGestureRecognizer::Result GestureRecognizerLinjaZax::filterEvent(const QEvent *event) -{ - if (zoomState != LinjaZaxGesture::NoZoom && !lastDirections.isEmpty()) { - lastDirections = lastDirections.right(1); - zoomState = LinjaZaxGesture::NoZoom; - } - - if (event->type() == QEvent::MouseButtonPress) { - if (!currentDirection.isEmpty()) { - reset(); - return QGestureRecognizer::NotGesture; - } - mousePressed = true; - const QMouseEvent *ev = static_cast(event); - pressedPos = lastPos = currentPos = ev->pos(); - return QGestureRecognizer::MaybeGesture; - } else if (event->type() == QEvent::MouseButtonRelease) { - const QMouseEvent *ev = static_cast(event); - if (mousePressed && !currentDirection.isEmpty()) { - gestureFinished = true; - currentPos = ev->pos(); - internalReset(); - return QGestureRecognizer::GestureFinished; - } - reset(); - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseMove) { - if (!mousePressed) - return QGestureRecognizer::NotGesture; - lastPos = currentPos; - const QMouseEvent *ev = static_cast(event); - currentPos = ev->pos(); - QString direction = - simpleRecognizer.addPosition(ev->pos()).direction; - QGestureRecognizer::Result result = QGestureRecognizer::NotGesture; - if (currentDirection.isEmpty()) { - if (direction.isEmpty()) - result = QGestureRecognizer::MaybeGesture; - else - result = QGestureRecognizer::GestureStarted; - } else { - result = QGestureRecognizer::GestureStarted; - } - if (!direction.isEmpty()) { - lastDirections.append(direction); - currentDirection = direction; - if (lastDirections.length() > 5) - lastDirections.remove(0, 1); - if (lastDirections.contains("248") || lastDirections.contains("2448")) - zoomState = LinjaZaxGesture::ZoomingIn; - else if (lastDirections.contains("268") || lastDirections.contains("2668")) - zoomState = LinjaZaxGesture::ZoomingOut; - } - return result; - } - return QGestureRecognizer::NotGesture; -} - -static inline LinjaZaxGesture::DirectionType convertPanningDirection(const QString &direction) -{ - if (direction.length() == 1) { - if (direction == "4") - return LinjaZaxGesture::Left; - else if (direction == "6") - return LinjaZaxGesture::Right; - else if (direction == "8") - return LinjaZaxGesture::Up; - else if (direction == "2") - return LinjaZaxGesture::Down; - } - return LinjaZaxGesture::None; -} - -QGesture* GestureRecognizerLinjaZax::getGesture() -{ - LinjaZaxGesture::DirectionType dir = convertPanningDirection(currentDirection); - LinjaZaxGesture::DirectionType lastDir = convertPanningDirection(lastDirections.right(1)); - if (dir == LinjaZaxGesture::None) - return 0; - LinjaZaxGesture *g = - new LinjaZaxGesture(this, pressedPos, lastPos, currentPos, - QRect(), pressedPos, QDateTime(), 0, - gestureFinished ? Qt::GestureFinished : Qt::GestureStarted); - g->lastDirection_ = lastDir; - g->direction_ = dir; - g->zoomState_ = zoomState; - - return g; -} - -void GestureRecognizerLinjaZax::reset() -{ - mousePressed = false; - lastDirections.clear(); - currentDirection.clear(); - gestureFinished = false; - simpleRecognizer.reset(); - zoomState = LinjaZaxGesture::NoZoom; -} - -void GestureRecognizerLinjaZax::internalReset() -{ - mousePressed = false; - simpleRecognizer.reset(); -} diff --git a/examples/gestures/collidingmice/gesturerecognizerlinjazax.h b/examples/gestures/collidingmice/gesturerecognizerlinjazax.h deleted file mode 100644 index 79b2c2b..0000000 --- a/examples/gestures/collidingmice/gesturerecognizerlinjazax.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GESTURERECOGNIZERLINJAZAX_H -#define GESTURERECOGNIZERLINJAZAX_H - -#include -#include -#include -#include -#include - -#include "linjazaxgesture.h" - -struct Direction -{ - QString direction; - QPoint point; - - Direction(QString dir, const QPoint &pt) - : direction(dir), point(pt) { } - Direction() - : direction() { } - - inline bool isEmpty() const { return direction.isEmpty(); } - inline bool isNull() const { return direction.isEmpty(); } -}; -typedef QList DirectionList; - -class DirectionSimpleRecognizer -{ -public: - DirectionSimpleRecognizer(); - Direction addPosition(const QPoint &pos); - DirectionList getDirections() const; - void reset(); - -private: - QPoint lastPoint; - DirectionList directions; -}; - -class GestureRecognizerLinjaZax : public QGestureRecognizer -{ - Q_OBJECT -public: - GestureRecognizerLinjaZax(); - - QGestureRecognizer::Result filterEvent(const QEvent *event); - QGesture* getGesture(); - - void reset(); - -private: - void internalReset(); - - QPoint pressedPos; - QPoint lastPos; - QPoint currentPos; - bool mousePressed; - bool gestureFinished; - QString lastDirections; - QString currentDirection; - DirectionSimpleRecognizer simpleRecognizer; - LinjaZaxGesture::ZoomState zoomState; -}; - -#endif diff --git a/examples/gestures/collidingmice/images/cheese.jpg b/examples/gestures/collidingmice/images/cheese.jpg deleted file mode 100644 index dea5795..0000000 Binary files a/examples/gestures/collidingmice/images/cheese.jpg and /dev/null differ diff --git a/examples/gestures/collidingmice/linjazaxgesture.h b/examples/gestures/collidingmice/linjazaxgesture.h deleted file mode 100644 index 53b907e..0000000 --- a/examples/gestures/collidingmice/linjazaxgesture.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef LINJAZAXGESTURE_H -#define LINJAZAXGESTURE_H - -#include - -class LinjaZaxGesture : public QGesture -{ -public: - enum DirectionType - { - None = 0, - LeftDown = 1, - DownLeft = LeftDown, - Down = 2, - RightDown = 3, - DownRight = RightDown, - Left = 4, - Right = 6, - LeftUp = 7, - UpLeft = LeftUp, - Up = 8, - RightUp = 9, - UpRight = RightUp - }; - - enum ZoomState - { - NoZoom, - ZoomingIn, - ZoomingOut - }; - -public: - explicit LinjaZaxGesture(QObject *parent, - Qt::GestureState state = Qt::GestureStarted) - : QGesture(parent, QLatin1String("LinjaZax"), state), lastDirection_(None), - direction_(None), zoomState_(NoZoom) { } - LinjaZaxGesture(QObject *parent, const QPoint &startPos, - const QPoint &lastPos, const QPoint &pos, const QRect &rect, - const QPoint &hotSpot, const QDateTime &startTime, - uint duration, Qt::GestureState state) - : QGesture(parent, QLatin1String("LinjaZax"), startPos, lastPos, - pos, rect, hotSpot, startTime, duration, state) { } - ~LinjaZaxGesture() { } - - DirectionType lastDirection() const - { return lastDirection_; } - DirectionType direction() const - { return direction_; } - - ZoomState zoomState() const - { return zoomState_; } - -private: - DirectionType lastDirection_; - DirectionType direction_; - ZoomState zoomState_; - friend class GestureRecognizerLinjaZax; -}; - -#endif diff --git a/examples/gestures/collidingmice/main.cpp b/examples/gestures/collidingmice/main.cpp deleted file mode 100644 index 3638442..0000000 --- a/examples/gestures/collidingmice/main.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mouse.h" - -#include "gesturerecognizerlinjazax.h" -#include "linjazaxgesture.h" - -#include - -#include - -#define ZOOMING_ANIMATION -#ifdef ZOOMING_ANIMATION -static const int AnimationSteps = 10; -#endif - -static const int MouseCount = 7; - -class PannableGraphicsView : public QGraphicsView -{ - Q_OBJECT -public: - PannableGraphicsView(QGraphicsScene *scene, QWidget *parent = 0) - : QGraphicsView(scene, parent) - { - grabGesture(QLatin1String("LinjaZax")); -#ifdef ZOOMING_ANIMATION - timeline = new QTimeLine(700, this); - timeline->setFrameRange(0, AnimationSteps); - connect(timeline, SIGNAL(frameChanged(int)), this, SLOT(animationStep(int))); -#endif - } -protected: - bool event(QEvent *event) - { - if (event->type() == QEvent::Gesture) { - QGestureEvent *ge = static_cast(event); - const LinjaZaxGesture *g = static_cast(ge->gesture("LinjaZax")); - if (g) { - switch (g->zoomState()) { - case LinjaZaxGesture::ZoomingIn: -#ifdef ZOOMING_ANIMATION - scaleStep = 1. + 0.5/AnimationSteps; - timeline->stop(); - timeline->start(); -#else - scale(1.5, 1.5); -#endif - break; - case LinjaZaxGesture::ZoomingOut: -#ifdef ZOOMING_ANIMATION - scaleStep = 1. - 0.5/AnimationSteps; - timeline->stop(); - timeline->start(); -#else - scale(0.6, 0.6); -#endif - break; - default: - break; - }; - QPoint pt = g->pos() - g->lastPos(); - horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pt.x()); - verticalScrollBar()->setValue(verticalScrollBar()->value() - pt.y()); - event->accept(); - return true; - } - } - return QGraphicsView::event(event); - } -private slots: -#ifdef ZOOMING_ANIMATION - void animationStep(int step) - { - scale(scaleStep, scaleStep); - } -private: - qreal scaleStep; - QTimeLine *timeline; -#endif -}; - -//! [0] -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - app.addGestureRecognizer(new GestureRecognizerLinjaZax); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); -//! [0] - -//! [1] - QGraphicsScene scene; - scene.setSceneRect(-600, -600, 1200, 1200); -//! [1] //! [2] - scene.setItemIndexMethod(QGraphicsScene::NoIndex); -//! [2] - -//! [3] - for (int i = 0; i < MouseCount; ++i) { - Mouse *mouse = new Mouse; - mouse->setPos(::sin((i * 6.28) / MouseCount) * 200, - ::cos((i * 6.28) / MouseCount) * 200); - scene.addItem(mouse); - } -//! [3] - -//! [4] - PannableGraphicsView view(&scene); - view.setRenderHint(QPainter::Antialiasing); - view.setBackgroundBrush(QPixmap(":/images/cheese.jpg")); -//! [4] //! [5] - view.setCacheMode(QGraphicsView::CacheBackground); - view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); - //view.setDragMode(QGraphicsView::ScrollHandDrag); -//! [5] //! [6] - view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice")); - view.resize(400, 300); - view.show(); - - return app.exec(); -} -//! [6] - -#include "main.moc" diff --git a/examples/gestures/collidingmice/mice.qrc b/examples/gestures/collidingmice/mice.qrc deleted file mode 100644 index accdb4d..0000000 --- a/examples/gestures/collidingmice/mice.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - images/cheese.jpg - - diff --git a/examples/gestures/collidingmice/mouse.cpp b/examples/gestures/collidingmice/mouse.cpp deleted file mode 100644 index 256811a..0000000 --- a/examples/gestures/collidingmice/mouse.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mouse.h" - -#include -#include -#include - -#include - -static const double Pi = 3.14159265358979323846264338327950288419717; -static double TwoPi = 2.0 * Pi; - -static qreal normalizeAngle(qreal angle) -{ - while (angle < 0) - angle += TwoPi; - while (angle > TwoPi) - angle -= TwoPi; - return angle; -} - -//! [0] -Mouse::Mouse() - : angle(0), speed(0), mouseEyeDirection(0), - color(qrand() % 256, qrand() % 256, qrand() % 256) -{ - rotate(qrand() % (360 * 16)); - startTimer(1000 / 33); -} -//! [0] - -//! [1] -QRectF Mouse::boundingRect() const -{ - qreal adjust = 0.5; - return QRectF(-18 - adjust, -22 - adjust, - 36 + adjust, 60 + adjust); -} -//! [1] - -//! [2] -QPainterPath Mouse::shape() const -{ - QPainterPath path; - path.addRect(-10, -20, 20, 40); - return path; -} -//! [2] - -//! [3] -void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - // Body - painter->setBrush(color); - painter->drawEllipse(-10, -20, 20, 40); - - // Eyes - painter->setBrush(Qt::white); - painter->drawEllipse(-10, -17, 8, 8); - painter->drawEllipse(2, -17, 8, 8); - - // Nose - painter->setBrush(Qt::black); - painter->drawEllipse(QRectF(-2, -22, 4, 4)); - - // Pupils - painter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4)); - painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4)); - - // Ears - painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red); - painter->drawEllipse(-17, -12, 16, 16); - painter->drawEllipse(1, -12, 16, 16); - - // Tail - QPainterPath path(QPointF(0, 20)); - path.cubicTo(-5, 22, -5, 22, 0, 25); - path.cubicTo(5, 27, 5, 32, 0, 30); - path.cubicTo(-5, 32, -5, 42, 0, 35); - painter->setBrush(Qt::NoBrush); - painter->drawPath(path); -} -//! [3] - -//! [4] -void Mouse::timerEvent(QTimerEvent *) -{ -//! [4] - // Don't move too far away -//! [5] - QLineF lineToCenter(QPointF(0, 0), mapFromScene(0, 0)); - if (lineToCenter.length() > 150) { - qreal angleToCenter = ::acos(lineToCenter.dx() / lineToCenter.length()); - if (lineToCenter.dy() < 0) - angleToCenter = TwoPi - angleToCenter; - angleToCenter = normalizeAngle((Pi - angleToCenter) + Pi / 2); - - if (angleToCenter < Pi && angleToCenter > Pi / 4) { - // Rotate left - angle += (angle < -Pi / 2) ? 0.25 : -0.25; - } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) { - // Rotate right - angle += (angle < Pi / 2) ? 0.25 : -0.25; - } - } else if (::sin(angle) < 0) { - angle += 0.25; - } else if (::sin(angle) > 0) { - angle -= 0.25; -//! [5] //! [6] - } -//! [6] - - // Try not to crash with any other mice -//! [7] - QList dangerMice = scene()->items(QPolygonF() - << mapToScene(0, 0) - << mapToScene(-30, -50) - << mapToScene(30, -50)); - foreach (QGraphicsItem *item, dangerMice) { - if (item == this) - continue; - - QLineF lineToMouse(QPointF(0, 0), mapFromItem(item, 0, 0)); - qreal angleToMouse = ::acos(lineToMouse.dx() / lineToMouse.length()); - if (lineToMouse.dy() < 0) - angleToMouse = TwoPi - angleToMouse; - angleToMouse = normalizeAngle((Pi - angleToMouse) + Pi / 2); - - if (angleToMouse >= 0 && angleToMouse < Pi / 2) { - // Rotate right - angle += 0.5; - } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) { - // Rotate left - angle -= 0.5; -//! [7] //! [8] - } -//! [8] //! [9] - } -//! [9] - - // Add some random movement -//! [10] - if (dangerMice.size() > 1 && (qrand() % 10) == 0) { - if (qrand() % 1) - angle += (qrand() % 100) / 500.0; - else - angle -= (qrand() % 100) / 500.0; - } -//! [10] - -//! [11] - speed += (-50 + qrand() % 100) / 100.0; - - qreal dx = ::sin(angle) * 10; - mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5; - - rotate(dx); - setPos(mapToParent(0, -(3 + sin(speed) * 3))); -} -//! [11] diff --git a/examples/gestures/collidingmice/mouse.h b/examples/gestures/collidingmice/mouse.h deleted file mode 100644 index 6c8486f..0000000 --- a/examples/gestures/collidingmice/mouse.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MOUSE_H -#define MOUSE_H - -#include -#include - -//! [0] -class Mouse : public QObject, public QGraphicsItem -{ - Q_OBJECT - -public: - Mouse(); - - QRectF boundingRect() const; - QPainterPath shape() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - -protected: - void timerEvent(QTimerEvent *event); - -private: - qreal angle; - qreal speed; - qreal mouseEyeDirection; - QColor color; -}; -//! [0] - -#endif diff --git a/examples/gestures/gestures.pro b/examples/gestures/gestures.pro index d0735ae..09cd56a 100644 --- a/examples/gestures/gestures.pro +++ b/examples/gestures/gestures.pro @@ -1,14 +1,7 @@ TEMPLATE = \ subdirs SUBDIRS = \ - imageviewer \ - graphicsview \ - collidingmice - -contains(QT_CONFIG, webkit) { - SUBDIRS += pannablewebview - contains(QT_CONFIG, svg):SUBDIRS += browser -} + imageviewer # install target.path = $$[QT_INSTALL_EXAMPLES]/gestures diff --git a/examples/gestures/graphicsview/graphicsview.pro b/examples/gestures/graphicsview/graphicsview.pro deleted file mode 100644 index 9cef564..0000000 --- a/examples/gestures/graphicsview/graphicsview.pro +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES = main.cpp - diff --git a/examples/gestures/graphicsview/main.cpp b/examples/gestures/graphicsview/main.cpp deleted file mode 100644 index 12f4e75..0000000 --- a/examples/gestures/graphicsview/main.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -class PannableGraphicsView : public QGraphicsView -{ -public: - PannableGraphicsView() - { - grabGesture(Qt::PanGesture); - } -protected: - bool event(QEvent *event) - { - if (event->type() == QEvent::Gesture) { - QGestureEvent *gestureEvent = static_cast(event); - if (const QGesture *g = gestureEvent->gesture(Qt::PanGesture)) { - QPoint pt = g->pos() - g->lastPos(); - horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pt.x()); - verticalScrollBar()->setValue(verticalScrollBar()->value() - pt.y()); - event->accept(); - return true; - } - } - return QGraphicsView::event(event); - } -}; - -class ImageItem : public QGraphicsItem -{ -public: - ImageItem() - : colored(false) - { - grabGesture(Qt::DoubleTapGesture); - } - - QRectF boundingRect() const - { - return pixmap.isNull() ? QRectF(0, 0, 100, 100) - : QRectF(QPointF(0,0), QSizeF(pixmap.size())); - } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) - { - if (pixmap.isNull()) { - painter->setBrush(QBrush( colored ? Qt::green : Qt::white)); - painter->drawRect(0, 0, 100, 100); - painter->drawLine(0, 0, 100, 100); - painter->drawLine(0, 100, 100, 0); - return; - } - painter->drawPixmap(0, 0, pixmap); - } - - bool sceneEvent(QEvent *event) - { - if (event->type() == QEvent::GraphicsSceneGesture) { - QGraphicsSceneGestureEvent *gestureEvent = static_cast(event); - if (gestureEvent->gesture(Qt::DoubleTapGesture)) { - event->accept(); - colored = !colored; - update(); - return true; - } else { - qWarning("Item received unknown gesture"); - } - } - return QGraphicsItem::sceneEvent(event); - } - -private: - QPixmap pixmap; - bool colored; -}; - -class MainWidget : public QWidget -{ - Q_OBJECT - -public: - MainWidget(QWidget *parent = 0) - : QWidget(parent) - { - QVBoxLayout *l = new QVBoxLayout(this); - view = new PannableGraphicsView; - l->addWidget(view); - scene = new QGraphicsScene(0, 0, 1024, 768, view); - view->setScene(scene); - - ImageItem *item = new ImageItem; - scene->addItem(item); - item->setPos(scene->width()/3, scene->height()/3); - } - -signals: -public slots: -private: - QGraphicsView *view; - QGraphicsScene *scene; -}; - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - MainWidget w; - w.show(); - return app.exec(); -} - -#include "main.moc" diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index a4f3c9a..717bb09 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -46,6 +46,7 @@ ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent) { + setAttribute(Qt::WA_AcceptTouchEvents); setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_NoSystemBackground); @@ -61,9 +62,11 @@ ImageWidget::ImageWidget(QWidget *parent) horizontalOffset = 0; verticalOffset = 0; - grabGesture(Qt::DoubleTapGesture); - grabGesture(Qt::PanGesture); - grabGesture(Qt::TapAndHoldGesture); + panGesture = new QPanGesture(this); + connect(panGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); + + tapAndHoldGesture = new QTapAndHoldGesture(this); + connect(tapAndHoldGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); } void ImageWidget::paintEvent(QPaintEvent*) @@ -131,30 +134,33 @@ void ImageWidget::paintEvent(QPaintEvent*) p.restore(); } -bool ImageWidget::event(QEvent *event) +void ImageWidget::mousePressEvent(QMouseEvent *event) { - if (event->type() == QEvent::Gesture) { - gestureEvent(static_cast(event)); - return true; - } - return QWidget::event(event); + touchFeedback.tapped = true; + touchFeedback.position = event->pos(); +} + +void ImageWidget::mouseDoubleClickEvent(QMouseEvent *event) +{ + touchFeedback.doubleTapped = true; + const QPoint p = event->pos(); + touchFeedback.position = p; + horizontalOffset = p.x() - currentImage.width()*1.0*p.x()/width(); + verticalOffset = p.y() - currentImage.height()*1.0*p.y()/height(); + setZoomedIn(!zoomedIn); + zoomed = rotated = false; + updateImage(); + + feedbackFadeOutTimer.start(500, this); } -void ImageWidget::gestureEvent(QGestureEvent *event) +void ImageWidget::gestureTriggered() { + touchFeedback.tapped = false; touchFeedback.doubleTapped = false; - Q_ASSERT(event); - if (event->contains(Qt::TapGesture)) { - // - } else if (const QGesture *g = event->gesture(Qt::DoubleTapGesture)) { - touchFeedback.doubleTapped = true; - horizontalOffset = g->hotSpot().x() - currentImage.width()*1.0*g->hotSpot().x()/width(); - verticalOffset = g->hotSpot().y() - currentImage.height()*1.0*g->hotSpot().y()/height(); - setZoomedIn(!zoomedIn); - zoomed = rotated = false; - updateImage(); - } else if (const QGesture *g = event->gesture(Qt::PanGesture)) { + QGesture *g = qobject_cast(sender()); + if (sender() == panGesture) { if (zoomedIn) { // usual panning #ifndef QT_NO_CURSOR @@ -170,24 +176,22 @@ void ImageWidget::gestureEvent(QGestureEvent *event) update(); } else { // only slide gesture should be accepted - const QPanningGesture *pg = static_cast(g); - if (pg->direction() != pg->lastDirection()) { - // ###: event->cancel(); - } + const QPanGesture *pg = static_cast(g); if (g->state() == Qt::GestureFinished) { touchFeedback.sliding = false; zoomed = rotated = false; - if (pg->direction() == Qt::RightDirection) { + if (pg->totalOffset().width() > 0) { qDebug() << "slide right"; goNextImage(); - } else if (pg->direction() == Qt::LeftDirection) { + } else { qDebug() << "slide left"; goPrevImage(); } updateImage(); } } - } else if (const QGesture *g = event->gesture(Qt::TapAndHoldGesture)) { + feedbackFadeOutTimer.start(500, this); + } else if (sender() == tapAndHoldGesture) { if (g->state() == Qt::GestureFinished) { qDebug() << "tap and hold detected"; touchFeedback.reset(); @@ -197,13 +201,20 @@ void ImageWidget::gestureEvent(QGestureEvent *event) menu.addAction("Action 1"); menu.addAction("Action 2"); menu.addAction("Action 3"); - menu.exec(mapToGlobal(g->hotSpot())); + menu.exec(mapToGlobal(g->pos())); } - } else { - qDebug() << "unknown gesture"; + feedbackFadeOutTimer.start(500, this); } - feedbackFadeOutTimer.start(500, this); - event->accept(); +} + +void ImageWidget::gestureFinished() +{ + qDebug() << "gesture finished" << sender(); +} + +void ImageWidget::gestureCancelled() +{ + qDebug() << "gesture cancelled" << sender(); } void ImageWidget::resizeEvent(QResizeEvent*) @@ -345,3 +356,5 @@ void ImageWidget::timerEvent(QTimerEvent *event) } update(); } + +#include "moc_imagewidget.cpp" diff --git a/examples/gestures/imageviewer/imagewidget.h b/examples/gestures/imageviewer/imagewidget.h index 7ec73a7..e12634d 100644 --- a/examples/gestures/imageviewer/imagewidget.h +++ b/examples/gestures/imageviewer/imagewidget.h @@ -50,17 +50,24 @@ class ImageWidget : public QWidget { + Q_OBJECT + public: ImageWidget(QWidget *parent = 0); void openDirectory(const QString &path); protected: - bool event(QEvent *event); void paintEvent(QPaintEvent*); - void gestureEvent(QGestureEvent *event); void resizeEvent(QResizeEvent*); void timerEvent(QTimerEvent*); + void mousePressEvent(QMouseEvent*); + void mouseDoubleClickEvent(QMouseEvent*); + +private slots: + void gestureTriggered(); + void gestureFinished(); + void gestureCancelled(); private: void updateImage(); @@ -71,6 +78,9 @@ private: void goPrevImage(); void goToImage(int index); + QPanGesture *panGesture; + QTapAndHoldGesture *tapAndHoldGesture; + QString path; QStringList files; int position; diff --git a/examples/gestures/pannablewebview/main.cpp b/examples/gestures/pannablewebview/main.cpp deleted file mode 100644 index 89c1fce..0000000 --- a/examples/gestures/pannablewebview/main.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -class PannableWebView : public QWebView -{ -public: - PannableWebView(QWidget *parent = 0) - : QWebView(parent) - { -#if 0 - QPushButton *btn = new QPushButton("Some test button", this); - btn->resize(300, 200); - btn->move(40, 300); -#endif - grabGesture(Qt::PanGesture); - } -protected: - bool event(QEvent *event) - { - if (event->type() == QEvent::Gesture) - { - QGestureEvent *ev = static_cast(event); - if (const QGesture *g = ev->gesture(Qt::PanGesture)) { - if (QWebFrame *frame = page()->mainFrame()) { - QPoint offset = g->pos() - g->lastPos(); - frame->setScrollPosition(frame->scrollPosition() - offset); - } - event->accept(); - } - return true; - } - return QWebView::event(event); - } -}; - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - QGraphicsScene scene; - QGraphicsView w(&scene); - - QWebView *wv = new PannableWebView; - wv->resize(480, 800); - wv->setUrl(QUrl("http://www.trolltech.com")); - scene.addWidget(wv); - w.show(); - - return app.exec(); -} diff --git a/examples/gestures/pannablewebview/pannablewebview.pro b/examples/gestures/pannablewebview/pannablewebview.pro deleted file mode 100644 index 07d8f91..0000000 --- a/examples/gestures/pannablewebview/pannablewebview.pro +++ /dev/null @@ -1,4 +0,0 @@ -SOURCES += \ - main.cpp - -QT += webkit diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 0006026..e0584e5 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1562,18 +1562,6 @@ public: }; Q_DECLARE_FLAGS(TouchPointStates, TouchPointState) - enum GestureType - { - UnknownGesture, - TapGesture, - DoubleTapGesture, - TrippleTapGesture, - TapAndHoldGesture, - PanGesture, - PinchGesture - }; - - enum GestureState { NoGesture, @@ -1582,23 +1570,6 @@ public: GestureFinished = 3 }; - enum DirectionType - { - NoDirection = 0, - LeftDownDirection = 1, - DownLeftDirection = LeftDownDirection, - DownDirection = 2, - RightDownDirection = 3, - DownRightDirection = RightDownDirection, - LeftDirection = 4, - RightDirection = 6, - LeftUpDirection = 7, - UpLeftDirection = LeftUpDirection, - UpDirection = 8, - RightUpDirection = 9, - UpRightDirection = RightUpDirection - }; - } #ifdef Q_MOC_RUN ; diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 504ae84..c636716 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -225,8 +225,6 @@ QT_BEGIN_NAMESPACE \value TouchBegin Beginning of a sequence of touch-screen and/or track-pad events (QTouchEvent) \value TouchUpdate Touch-screen event (QTouchEvent) \value TouchEnd End of touch-event sequence (QTouchEvent) - \value Gesture A gesture has occured. - \value GraphicsSceneGesture A gesture has occured on a graphics scene. User events should have values between \c User and \c{MaxUser}: @@ -271,6 +269,7 @@ QT_BEGIN_NAMESPACE \omitvalue CocoaRequestModal \omitvalue Wrapped \omitvalue Signal + \omitvalue WinGesture */ /*! diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 4929c51..1d86f47 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -276,8 +276,7 @@ public: TouchUpdate = 195, TouchEnd = 196, - Gesture = 197, - GraphicsSceneGesture = 198, + WinGesture = 197, // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 2223f5d..c82c2e5 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -574,7 +574,6 @@ #include #include #include -#include #ifdef Q_WS_X11 #include @@ -615,8 +614,6 @@ public: }; Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore) -QString qt_getStandardGestureTypeName(Qt::GestureType type); - /*! \internal @@ -1131,7 +1128,6 @@ QGraphicsItem::~QGraphicsItem() { d_ptr->inDestructor = 1; d_ptr->removeExtraItemCache(); - d_ptr->removeExtraGestures(); clearFocus(); if (!d_ptr->children.isEmpty()) { @@ -6251,104 +6247,6 @@ QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const } /*! - \since 4.6 - - Subscribes the graphics item to the specified \a gesture type. - - Returns the id of the gesture. - - \sa releaseGesture(), setGestureEnabled() -*/ -int QGraphicsItem::grabGesture(Qt::GestureType gesture) -{ - /// TODO: if we are QGraphicsProxyWidget we should subscribe the widget to gesture as well. - return grabGesture(qt_getStandardGestureTypeName(gesture)); -} - -/*! - \since 4.6 - - Subscribes the graphics item to the specified \a gesture type. - - Returns the id of the gesture. - - \sa releaseGesture(), setGestureEnabled() -*/ -int QGraphicsItem::grabGesture(const QString &gesture) -{ - int id = QGestureManager::instance()->makeGestureId(gesture); - d_ptr->grabGesture(id); - return id; -} - -void QGraphicsItemPrivate::grabGesture(int id) -{ - Q_Q(QGraphicsItem); - extraGestures()->gestures << id; - if (scene) - scene->d_func()->grabGesture(q, id); -} - -bool QGraphicsItemPrivate::releaseGesture(int id) -{ - Q_Q(QGraphicsItem); - QGestureExtraData *extra = maybeExtraGestures(); - if (extra && extra->gestures.contains(id)) { - if (scene) - scene->d_func()->releaseGesture(q, id); - extra->gestures.remove(id); - return true; - } - return false; -} - -/*! - \since 4.6 - - Unsubscribes the graphics item from a gesture, which is specified - by the \a gestureId. - - \sa grabGesture(), setGestureEnabled() -*/ -void QGraphicsItem::releaseGesture(int gestureId) -{ - /// TODO: if we are QGraphicsProxyWidget we should unsubscribe the widget from gesture as well. - if (d_ptr->releaseGesture(gestureId)) - QGestureManager::instance()->releaseGestureId(gestureId); -} - -/*! - \since 4.6 - - If \a enable is true, the gesture with the given \a gestureId is - enabled; otherwise the gesture is disabled. - - The id of the gesture is returned by the grabGesture(). - - \sa grabGesture(), releaseGesture() -*/ -void QGraphicsItem::setGestureEnabled(int gestureId, bool enable) -{ - Q_UNUSED(gestureId); - Q_UNUSED(enable); - //### -} - -bool QGraphicsItemPrivate::hasGesture(const QString &name) const -{ - if (QGestureExtraData *extra = maybeExtraGestures()) { - QGestureManager *gm = QGestureManager::instance(); - QSet::const_iterator it = extra->gestures.begin(), - e = extra->gestures.end(); - for (; it != e; ++it) { - if (gm->gestureNameFromId(*it) == name) - return true; - } - } - return false; -} - -/*! This virtual function is called by QGraphicsItem to notify custom items that some part of the item's state changes. By reimplementing this function, your can react to a change, and in some cases, (depending on \a @@ -6372,23 +6270,6 @@ bool QGraphicsItemPrivate::hasGesture(const QString &name) const QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value) { Q_UNUSED(change); - if (change == QGraphicsItem::ItemSceneChange) { - QGestureExtraData *extra = d_ptr->maybeExtraGestures(); - if (!qVariantValue(value) && extra) { - // the item has been removed from a scene, unsubscribe gestures. - Q_ASSERT(d_ptr->scene); - foreach(int id, extra->gestures) - d_ptr->scene->d_func()->releaseGesture(this, id); - } - } else if (change == QGraphicsItem::ItemSceneHasChanged) { - QGraphicsScene *scene = qVariantValue(value); - QGestureExtraData *extra = d_ptr->maybeExtraGestures(); - if (scene && extra) { - // item has been added to the scene - foreach(int id, extra->gestures) - scene->d_func()->grabGesture(this, id); - } - } return value; } diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 3a3d1a1..b0571c2 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -379,11 +379,6 @@ public: QVariant data(int key) const; void setData(int key, const QVariant &value); - int grabGesture(Qt::GestureType gesture); - int grabGesture(const QString &gesture); - void releaseGesture(int gestureId); - void setGestureEnabled(int gestureId, bool enable = true); - enum { Type = 1, UserType = 65536 diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index a0d061b..a977e1e 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -93,12 +93,6 @@ public: void purge(); }; -class QGestureExtraData -{ -public: - QSet gestures; -}; - class Q_AUTOTEST_EXPORT QGraphicsItemPrivate { Q_DECLARE_PUBLIC(QGraphicsItem) @@ -108,8 +102,7 @@ public: ExtraCursor, ExtraCacheData, ExtraMaxDeviceCoordCacheSize, - ExtraBoundingRegionGranularity, - ExtraGestures + ExtraBoundingRegionGranularity }; enum AncestorFlag { @@ -394,30 +387,6 @@ public: int index; int depth; - inline QGestureExtraData* extraGestures() const - { - QGestureExtraData *c = (QGestureExtraData *)qVariantValue(extra(ExtraGestures)); - if (!c) { - QGraphicsItemPrivate *that = const_cast(this); - c = new QGestureExtraData; - that->setExtra(ExtraGestures, qVariantFromValue(c)); - } - return c; - } - QGestureExtraData* maybeExtraGestures() const - { - return (QGestureExtraData *)qVariantValue(extra(ExtraGestures)); - } - inline void removeExtraGestures() - { - QGestureExtraData *c = (QGestureExtraData *)qVariantValue(extra(ExtraGestures)); - delete c; - unsetExtra(ExtraGestures); - } - bool hasGesture(const QString &gesture) const; - void grabGesture(int id); - bool releaseGesture(int id); - // Packed 32 bytes quint32 acceptedMouseButtons : 5; quint32 visible : 1; diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index f081222..0b421ad 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -48,7 +48,6 @@ #include "private/qgraphicsproxywidget_p.h" #include "private/qwidget_p.h" #include "private/qapplication_p.h" -#include "private/qgesturemanager_p.h" #include #include @@ -649,9 +648,6 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto q->setAttribute(Qt::WA_OpaquePaintEvent); widget = newWidget; - foreach(int gestureId, widget->d_func()->gestures) { - grabGesture(gestureId); - } // Changes only go from the widget to the proxy. enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode; @@ -875,15 +871,6 @@ bool QGraphicsProxyWidget::event(QEvent *event) } break; } - case QEvent::GraphicsSceneGesture: { - qDebug() << "QGraphicsProxyWidget: graphicsscenegesture"; - if (d->widget && d->widget->isVisible()) { - //### TODO: widget->childAt(): decompose gesture event and find widget under hotspots. - //QGestureManager::instance()->sendGestureEvent(d->widget, ge->gestures().toSet(), ge->cancelledGestures()); - return true; - } - break; - } default: break; } diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e50ee94..c3f72e6 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -247,8 +247,6 @@ #ifdef Q_WS_X11 #include #endif -#include -#include QT_BEGIN_NAMESPACE @@ -4018,47 +4016,6 @@ bool QGraphicsScene::event(QEvent *event) // geometries that do not have an explicit style set. update(); break; - case QEvent::GraphicsSceneGesture: { - QGraphicsSceneGestureEvent *ev = static_cast(event); - QGraphicsView *view = qobject_cast(ev->widget()); - if (!view) { - qWarning("QGraphicsScene::event: gesture event was received without a view"); - break; - } - - // get a list of gestures that just started. - QSet startedGestures; - QList gestures = ev->gestures(); - for(QList::const_iterator it = gestures.begin(), e = gestures.end(); - it != e; ++it) { - QGesture *g = *it; - QGesturePrivate *gd = g->d_func(); - if (g->state() == Qt::GestureStarted || gd->singleshot) { - startedGestures.insert(g); - } - } - if (!startedGestures.isEmpty()) { - // find a target for each started gesture. - for(QSet::const_iterator it = startedGestures.begin(), e = startedGestures.end(); - it != e; ++it) { - QGesture *g = *it; - QGesturePrivate *gd = g->d_func(); - gd->graphicsItem = 0; - QList itemsInGestureArea = items(g->hotSpot()); - const QString gestureName = g->type(); - foreach(QGraphicsItem *item, itemsInGestureArea) { - if (item->d_func()->hasGesture(gestureName)) { - Q_ASSERT(gd->graphicsItem == 0); - gd->graphicsItem = item; - d->itemsWithGestures[item].insert(g); - break; - } - } - } - } - d->sendGestureEvent(ev->gestures().toSet(), ev->cancelledGestures()); - } - break; case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: @@ -4080,69 +4037,6 @@ bool QGraphicsScene::event(QEvent *event) return true; } -void QGraphicsScenePrivate::sendGestureEvent(const QSet &gestures, const QSet &cancelled) -{ - Q_Q(QGraphicsScene); - typedef QMap > ItemGesturesMap; - ItemGesturesMap itemGestures; - QSet startedGestures; - for(QSet::const_iterator it = gestures.begin(), e = gestures.end(); - it != e; ++it) { - QGesture *g = *it; - Q_ASSERT(g != 0); - QGesturePrivate *gd = g->d_func(); - if (gd->graphicsItem != 0) { - itemGestures[gd->graphicsItem].insert(g); - if (g->state() == Qt::GestureStarted || gd->singleshot) - startedGestures.insert(g); - } - } - - QSet ignoredGestures; - for(ItemGesturesMap::const_iterator it = itemGestures.begin(), e = itemGestures.end(); - it != e; ++it) { - QGraphicsItem *receiver = it.key(); - Q_ASSERT(receiver != 0); - QGraphicsSceneGestureEvent event; - event.setGestures(it.value()); - event.setCancelledGestures(cancelled); - bool processed = sendEvent(receiver, &event); - QSet started = startedGestures.intersect(it.value()); - if (event.isAccepted()) - foreach(QGesture *g, started) - g->accept(); - if (!started.isEmpty() && !(processed && event.isAccepted())) { - // there are started gestures event that weren't - // accepted, so propagating each gesture independently. - QSet::const_iterator it = started.begin(), - e = started.end(); - for(; it != e; ++it) { - QGesture *g = *it; - if (processed && g->isAccepted()) { - continue; - } - QGesturePrivate *gd = g->d_func(); - gd->graphicsItem = 0; - - //### THIS IS BS, DONT FORGET TO REWRITE THIS CODE - // need to make sure we try to deliver event just once to each widget - const QString gestureType = g->type(); - QList itemsUnderGesture = q->items(g->hotSpot()); - for (int i = 0; i < itemsUnderGesture.size(); ++i) { - QGraphicsItem *item = itemsUnderGesture.at(i); - if (item != receiver && item->d_func()->hasGesture(gestureType)) { - ignoredGestures.insert(g); - gd->graphicsItem = item; - break; - } - } - } - } - } - if (!ignoredGestures.isEmpty()) - sendGestureEvent(ignoredGestures, cancelled); -} - /*! \reimp @@ -6018,32 +5912,11 @@ bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event) void QGraphicsScenePrivate::addView(QGraphicsView *view) { views << view; - foreach(int gestureId, grabbedGestures) - view->d_func()->grabGesture(gestureId); } void QGraphicsScenePrivate::removeView(QGraphicsView *view) { views.removeAll(view); - foreach(int gestureId, grabbedGestures) - view->releaseGesture(gestureId); -} - -void QGraphicsScenePrivate::grabGesture(QGraphicsItem *item, int gestureId) -{ - if (!grabbedGestures.contains(gestureId)) { - foreach(QGraphicsView *view, views) - view->d_func()->grabGesture(gestureId); - } - (void)itemsWithGestures[item]; - grabbedGestures << gestureId; -} - -void QGraphicsScenePrivate::releaseGesture(QGraphicsItem *item, int gestureId) -{ - Q_UNUSED(gestureId); - itemsWithGestures.remove(item); - //### } void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent) diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index c8b147f..6aaeb91 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -79,7 +79,6 @@ class QGraphicsSceneHelpEvent; class QGraphicsSceneHoverEvent; class QGraphicsSceneMouseEvent; class QGraphicsSceneWheelEvent; -class QGraphicsSceneGestureEvent; class QGraphicsSimpleTextItem; class QGraphicsTextItem; class QGraphicsView; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 3c3a811..d2d603a 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -78,7 +78,6 @@ QT_BEGIN_NAMESPACE class QGraphicsView; class QGraphicsWidget; -class QGesture; class QGraphicsScenePrivate : public QObjectPrivate { @@ -309,13 +308,6 @@ public: QStyleOptionGraphicsItem styleOptionTmp; - // items with gestures -> list of started gestures. - QMap > itemsWithGestures; - QSet grabbedGestures; - void grabGesture(QGraphicsItem *item, int gestureId); - void releaseGesture(QGraphicsItem *item, int gestureId); - void sendGestureEvent(const QSet &gestures, const QSet &cancelled); - QMap sceneCurrentTouchPoints; QMap itemForTouchPointId; static void updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent); diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 27a2d7e..53019f2 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -275,8 +275,6 @@ QT_BEGIN_NAMESPACE -QString qt_getStandardGestureTypeName(Qt::GestureType type); - class QGraphicsSceneEventPrivate { public: @@ -1679,253 +1677,6 @@ void QGraphicsSceneMoveEvent::setNewPos(const QPointF &pos) d->newPos = pos; } -/*! - \class QGraphicsSceneGestureEvent - \brief The QGraphicsSceneGestureEvent class provides gesture events for - the graphics view framework. - \since 4.6 - \ingroup multimedia - \ingroup graphicsview-api - - QGraphicsSceneGestureEvent extends information provided by - QGestureEvent by adding some convenience functions like - \l{QGraphicsSceneEvent::}{widget()} to get a widget that received - original gesture event, and convenience functions mapToScene(), - mapToItem() for converting positions of the gesture into - QGraphicsScene and QGraphicsItem coordinate system respectively. - - The scene sends the event to the first QGraphicsItem under the - mouse cursor that accepts gestures; a graphics item is set to accept - gestures with \l{QGraphicsItem::}{grabGesture()}. - - \sa QGestureEvent -*/ - -/*! - Constructs a QGraphicsSceneGestureEvent. -*/ -QGraphicsSceneGestureEvent::QGraphicsSceneGestureEvent() - : QGraphicsSceneEvent(QEvent::GraphicsSceneGesture) -{ - setAccepted(false); -} - -/*! - Destroys a QGraphicsSceneGestureEvent. -*/ -QGraphicsSceneGestureEvent::~QGraphicsSceneGestureEvent() -{ -} - -/*! - Returns true if the gesture event contains gesture of specific \a - type; returns false otherwise. -*/ -bool QGraphicsSceneGestureEvent::contains(const QString &type) const -{ - return gesture(type) != 0; -} - -/*! - Returns true if the gesture event contains gesture of specific \a - type; returns false otherwise. -*/ -bool QGraphicsSceneGestureEvent::contains(Qt::GestureType type) const -{ - return contains(qt_getStandardGestureTypeName(type)); -} - -/*! - Returns a list of gesture names that this event contains. -*/ -QList QGraphicsSceneGestureEvent::gestureTypes() const -{ - return m_gestures.keys(); -} - -/*! - Returns extended information about a gesture of specific \a type. -*/ -const QGesture* QGraphicsSceneGestureEvent::gesture(const QString &type) const -{ - return m_gestures.value(type, 0); -} - -/*! - Returns extended information about a gesture of specific \a type. -*/ -const QGesture* QGraphicsSceneGestureEvent::gesture(Qt::GestureType type) const -{ - return gesture(qt_getStandardGestureTypeName(type)); -} - -/*! - Returns extended information about all gestures in the event. -*/ -QList QGraphicsSceneGestureEvent::gestures() const -{ - return m_gestures.values(); -} - -/*! - Returns a set of gesture names that used to be executed, but were - cancelled (i.e. they were not finished properly). -*/ -QSet QGraphicsSceneGestureEvent::cancelledGestures() const -{ - return m_cancelledGestures; -} - -/*! - Sets a list of gesture names \a cancelledGestures that used to be - executed, but were cancelled (i.e. they were not finished - properly). -*/ -void QGraphicsSceneGestureEvent::setCancelledGestures(const QSet &cancelledGestures) -{ - m_cancelledGestures = cancelledGestures; -} - -/*! - Maps the point \a point, which is in a view coordinate system, to - scene coordinate system, and returns the mapped coordinate. - - A \a point is in coordinate system of the widget that received - gesture event. - - \sa mapToItem(), {The Graphics View Coordinate System} -*/ -QPointF QGraphicsSceneGestureEvent::mapToScene(const QPoint &point) const -{ - if (QGraphicsView *view = qobject_cast(widget())) - return view->mapToScene(point); - return QPointF(); -} - -/*! - Maps the rectangular \a rect, which is in a view coordinate system, to - scene coordinate system, and returns the mapped coordinate. - - A \a rect is in coordinate system of the widget that received - gesture event. - - \sa mapToItem(), {The Graphics View Coordinate System} -*/ -QPolygonF QGraphicsSceneGestureEvent::mapToScene(const QRect &rect) const -{ - if (QGraphicsView *view = qobject_cast(widget())) - return view->mapToScene(rect); - return QPolygonF(); -} - -/*! - Maps the point \a point, which is in a view coordinate system, to - item's \a item coordinate system, and returns the mapped coordinate. - - If \a item is 0, this function returns the same as mapToScene(). - - \sa mapToScene(), {The Graphics View Coordinate System} -*/ -QPointF QGraphicsSceneGestureEvent::mapToItem(const QPoint &point, QGraphicsItem *item) const -{ - if (item) { - if (QGraphicsView *view = qobject_cast(widget())) - return item->mapFromScene(view->mapToScene(point)); - } else { - return mapToScene(point); - } - return QPointF(); -} - -/*! - Maps the rectangualar \a rect, which is in a view coordinate system, to - item's \a item coordinate system, and returns the mapped coordinate. - - If \a item is 0, this function returns the same as mapToScene(). - - \sa mapToScene(), {The Graphics View Coordinate System} -*/ -QPolygonF QGraphicsSceneGestureEvent::mapToItem(const QRect &rect, QGraphicsItem *item) const -{ - if (item) { - if (QGraphicsView *view = qobject_cast(widget())) - return item->mapFromScene(view->mapToScene(rect)); - } else { - return mapToScene(rect); - } - return QPolygonF(); -} - -/*! - Set a list of gesture objects containing extended information about \a gestures. -*/ -void QGraphicsSceneGestureEvent::setGestures(const QList &gestures) -{ - foreach(QGesture *g, gestures) - m_gestures.insert(g->type(), g); -} - -/*! - Set a list of gesture objects containing extended information about \a gestures. -*/ -void QGraphicsSceneGestureEvent::setGestures(const QSet &gestures) -{ - foreach(QGesture *g, gestures) - m_gestures.insert(g->type(), g); -} - -/*! - Sets the accept flag of the all gestures for the event object. - This is the equivalent of calling \l{QEvent::accept()} {accept()} - or \l{QEvent::setAccepted()}{setAccepted(true)}. - - Setting the accept flag indicates that the event receiver wants - the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGraphicsSceneGestureEvent::acceptAll() -{ - QHash::iterator it = m_gestures.begin(), - e = m_gestures.end(); - for(; it != e; ++it) - it.value()->accept(); - setAccepted(true); -} - -/*! \fn void QGraphicsSceneGestureEvent::accept() - Calls QEvent::accept(). -*/ - -/*! - Sets the accept flag of the gesture specified by \a type. This is - equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> - \l{QGesture::accept()}{accept()} - - Setting the accept flag indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGraphicsSceneGestureEvent::accept(Qt::GestureType type) -{ - if (QGesture *g = m_gestures.value(qt_getStandardGestureTypeName(type), 0)) - g->accept(); -} - -/*! - - Sets the accept flag of the gesture specified by \a type. This is - equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> - \l{QGesture::accept()}{accept()} - - Setting the accept flag indicates that the event receiver wants the - gesture. Unwanted gestures might be propagated to the parent widget. -*/ -void QGraphicsSceneGestureEvent::accept(const QString &type) -{ - if (QGesture *g = m_gestures.value(type, 0)) - g->accept(); -} - QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicssceneevent.h b/src/gui/graphicsview/qgraphicssceneevent.h index 8a30bb8..b38e757 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.h +++ b/src/gui/graphicsview/qgraphicssceneevent.h @@ -306,49 +306,6 @@ public: void setNewPos(const QPointF &pos); }; -class QGesture; -class QGraphicsItem; -class QGraphicsSceneGestureEventPrivate; -class Q_GUI_EXPORT QGraphicsSceneGestureEvent : public QGraphicsSceneEvent -{ - Q_DECLARE_PRIVATE(QGraphicsSceneGestureEvent) -public: - QGraphicsSceneGestureEvent(); - ~QGraphicsSceneGestureEvent(); - - bool contains(const QString &type) const; - bool contains(Qt::GestureType type) const; - - QList gestureTypes() const; - - const QGesture* gesture(Qt::GestureType type) const; - const QGesture* gesture(const QString &type) const; - QList gestures() const; - void setGestures(const QList &gestures); - void setGestures(const QSet &gestures); - - QSet cancelledGestures() const; - void setCancelledGestures(const QSet &cancelledGestures); - - void acceptAll(); -#ifndef Q_NO_USING_KEYWORD - using QEvent::accept; -#else - inline void accept() { QEvent::accept(); } -#endif - void accept(Qt::GestureType type); - void accept(const QString &type); - - QPointF mapToScene(const QPoint &point) const; - QPolygonF mapToScene(const QRect &rect) const; - QPointF mapToItem(const QPoint &point, QGraphicsItem *item) const; - QPolygonF mapToItem(const QRect &rect, QGraphicsItem *item) const; - -protected: - QHash m_gestures; - QSet m_cancelledGestures; -}; - #endif // QT_NO_GRAPHICSVIEW QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index a2adf82..56a69f7 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2658,9 +2658,6 @@ bool QGraphicsView::event(QEvent *event) } } break; - case QEvent::Gesture: - viewportEvent(event); - return true; default: break; } @@ -2742,17 +2739,6 @@ bool QGraphicsView::viewportEvent(QEvent *event) d->scene->d_func()->updateAll = false; } break; - case QEvent::Gesture: { - QGraphicsSceneGestureEvent gestureEvent; - gestureEvent.setWidget(this); - QGestureEvent *ev = static_cast(event); - gestureEvent.setGestures(ev->gestures()); - gestureEvent.setCancelledGestures(ev->cancelledGestures()); - QApplication::sendEvent(d->scene, &gestureEvent); - event->setAccepted(gestureEvent.isAccepted()); - return true; - } - break; case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 2917592..e6eff6e 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -44,12 +44,8 @@ HEADERS += \ kernel/qkeymapper_p.h \ kernel/qgesture.h \ kernel/qgesture_p.h \ - kernel/qgesturemanager_p.h \ - kernel/qgesturerecognizer_p.h \ - kernel/qgesturerecognizer.h \ - kernel/qgesturestandardrecognizers_p.h \ - kernel/qdirectionrecognizer_p.h \ - kernel/qdirectionsimplificator_p.h + kernel/qstandardgestures.h \ + kernel/qstandardgestures_p.h SOURCES += \ kernel/qaction.cpp \ @@ -80,10 +76,7 @@ SOURCES += \ kernel/qwidgetaction.cpp \ kernel/qkeymapper.cpp \ kernel/qgesture.cpp \ - kernel/qgesturemanager.cpp \ - kernel/qgesturerecognizer.cpp \ - kernel/qgesturestandardrecognizers.cpp \ - kernel/qdirectionrecognizer.cpp + kernel/qstandardgestures.cpp win32 { DEFINES += QT_NO_DIRECTDRAW diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index a7b7a0a..0e8978f 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -90,8 +90,6 @@ #include "qapplication.h" -#include - #ifdef Q_WS_WINCE #include "qdatetime.h" #include "qguifunctions_wince.h" @@ -137,14 +135,6 @@ int QApplicationPrivate::autoMaximizeThreshold = -1; bool QApplicationPrivate::autoSipEnabled = false; #endif -QGestureManager* QGestureManager::instance() -{ - QApplicationPrivate *d = qApp->d_func(); - if (!d->gestureManager) - d->gestureManager = new QGestureManager(qApp); - return d->gestureManager; -} - QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type) : QCoreApplicationPrivate(argc, argv) { @@ -168,8 +158,6 @@ QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::T directPainters = 0; #endif - gestureManager = 0; - if (!self) self = this; } @@ -3595,14 +3583,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e) #endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT } - if (!d->grabbedGestures.isEmpty() && e->spontaneous() && receiver->isWidgetType()) { - const QEvent::Type t = e->type(); - if (t != QEvent::Gesture && t != QEvent::GraphicsSceneGesture) { - if (QGestureManager::instance()->filterEvent(static_cast(receiver), e)) - return true; - } - } - // User input and window activation makes tooltips sleep switch (e->type()) { case QEvent::Wheel: @@ -4061,6 +4041,19 @@ bool QApplication::notify(QObject *receiver, QEvent *e) touchEvent->setAccepted(eventAccepted); break; } + case QEvent::WinGesture: + { + // only propagate the first gesture event (after the GID_BEGIN) + QWidget *w = static_cast(receiver); + while (w) { + e->ignore(); + res = d->notify_helper(w, e); + if ((res && e->isAccepted()) || w->isWindow()) + break; + w = w->parentWidget(); + } + break; + } default: res = d->notify_helper(receiver, e); break; @@ -5057,57 +5050,6 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy) return true; } -/*! - \since 4.6 - - Adds custom gesture \a recognizer object. - - Qt takes ownership of the provided \a recognizer. - - \sa QGestureEvent -*/ -void QApplication::addGestureRecognizer(QGestureRecognizer *recognizer) -{ - QGestureManager::instance()->addRecognizer(recognizer); -} - -/*! - \since 4.6 - - Removes custom gesture \a recognizer object. - - \sa QGestureEvent -*/ -void QApplication::removeGestureRecognizer(QGestureRecognizer *recognizer) -{ - Q_D(QApplication); - if (!d->gestureManager) - return; - d->gestureManager->removeRecognizer(recognizer); -} - -/*! - \property QApplication::eventDeliveryDelayForGestures - \since 4.6 - - Specifies the \a delay before input events are delivered to the - gesture enabled widgets. - - The delay allows to postpone widget's input event handling until - gestures framework can successfully recognize a gesture. - - \sa QWidget::grabGesture() -*/ -void QApplication::setEventDeliveryDelayForGestures(int delay) -{ - QGestureManager::instance()->setEventDeliveryDelay(delay); -} - -int QApplication::eventDeliveryDelayForGestures() -{ - return QGestureManager::instance()->eventDeliveryDelay(); -} - /*! \fn QDecoration &QApplication::qwsDecoration() Return the QWSDecoration used for decorating windows. diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 954f824..19ae085 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -71,7 +71,6 @@ class QStyle; class QEventLoop; class QIcon; class QInputContext; -class QGestureRecognizer; template class QList; class QLocale; #if defined(Q_WS_QWS) @@ -107,7 +106,6 @@ class Q_GUI_EXPORT QApplication : public QCoreApplication Q_PROPERTY(int autoMaximizeThreshold READ autoMaximizeThreshold WRITE setAutoMaximizeThreshold) Q_PROPERTY(bool autoSipEnabled READ autoSipEnabled WRITE setAutoSipEnabled) #endif - Q_PROPERTY(int eventDeliveryDelayForGestures READ eventDeliveryDelayForGestures WRITE setEventDeliveryDelayForGestures) public: enum Type { Tty, GuiClient, GuiServer }; @@ -268,12 +266,6 @@ public: static bool keypadNavigationEnabled(); #endif - void addGestureRecognizer(QGestureRecognizer *recognizer); - void removeGestureRecognizer(QGestureRecognizer *recognizer); - - void setEventDeliveryDelayForGestures(int delay); - int eventDeliveryDelayForGestures(); - Q_SIGNALS: void lastWindowClosed(); void focusChanged(QWidget *old, QWidget *now); @@ -382,7 +374,6 @@ private: friend class QDirectPainter; friend class QDirectPainterPrivate; #endif - friend class QGestureManager; #if defined(Q_WS_WIN) friend QApplicationPrivate* getQApplicationPrivateInternal(); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 4b2bf15..db77b07 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -193,7 +193,109 @@ extern "C" { typedef BOOL (WINAPI *qt_RegisterTouchWindowPtr)(HWND, ULONG); typedef BOOL (WINAPI *qt_GetTouchInputInfoPtr)(HANDLE, UINT, PVOID, int); typedef BOOL (WINAPI *qt_CloseTouchInputHandlePtr)(HANDLE); -#endif + +#ifndef WM_GESTURE + +#define WM_GESTURE 0x0119 +#define WM_GESTURE_NOTIFY 0x011A + +DECLARE_HANDLE(HGESTUREINFO); + +#define GF_BEGIN 0x00000001 +#define GF_INERTIA 0x00000002 +#define GF_END 0x00000004 + +/* + * Gesture IDs + */ +#define GID_BEGIN 1 +#define GID_END 2 +#define GID_ZOOM 3 +#define GID_PAN 4 +#define GID_ROTATE 5 +#define GID_TWOFINGERTAP 6 +#define GID_ROLLOVER 7 + +typedef struct tagGESTUREINFO { + UINT cbSize; // size, in bytes, of this structure (including variable length Args field) + DWORD dwFlags; // see GF_* flags + DWORD dwID; // gesture ID, see GID_* defines + HWND hwndTarget; // handle to window targeted by this gesture + POINTS ptsLocation; // current location of this gesture + DWORD dwInstanceID; // internally used + DWORD dwSequenceID; // internally used + ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES + UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture +} GESTUREINFO, *PGESTUREINFO; +typedef GESTUREINFO const * PCGESTUREINFO; + +typedef struct tagGESTURENOTIFYSTRUCT { + UINT cbSize; // size, in bytes, of this structure + DWORD dwFlags; // unused + HWND hwndTarget; // handle to window targeted by the gesture + POINTS ptsLocation; // starting location + DWORD dwInstanceID; // internally used +} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT; + +/* + * Gesture argument helpers + * - Angle should be a double in the range of -2pi to +2pi + * - Argument should be an unsigned 16-bit value + */ +#define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0)) +#define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265) + +typedef struct tagGESTURECONFIG { + DWORD dwID; // gesture ID + DWORD dwWant; // settings related to gesture ID that are to be turned on + DWORD dwBlock; // settings related to gesture ID that are to be turned off +} GESTURECONFIG, *PGESTURECONFIG; + +#define GC_ALLGESTURES 0x00000001 +#define GC_ZOOM 0x00000001 +#define GC_PAN 0x00000001 +#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002 +#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004 +#define GC_PAN_WITH_GUTTER 0x00000008 +#define GC_PAN_WITH_INERTIA 0x00000010 +#define GC_ROTATE 0x00000001 +#define GC_TWOFINGERTAP 0x00000001 +#define GC_ROLLOVER 0x00000001 +#define GESTURECONFIGMAXCOUNT 256 // Maximum number of gestures that can be included + // in a single call to SetGestureConfig / GetGestureConfig + + + +#define GCF_INCLUDE_ANCESTORS 0x00000001 // If specified, GetGestureConfig returns consolidated configuration + // for the specified window and it's parent window chain + +typedef BOOL (*PtrGetGestureInfo)(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo); +typedef BOOL (*PtrGetGestureExtraArgs)(HGESTUREINFO hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); +typedef BOOL (*PtrCloseGestureInfoHandle)(HGESTUREINFO hGestureInfo); +typedef BOOL (*PtrSetGestureConfig)(HWND hwnd, DWORD dwReserved, UINT cIDs, + PGESTURECONFIG pGestureConfig, + UINT cbSize); +typedef BOOL (*PtrGetGestureConfig)(HWND hwnd, DWORD dwReserved, + DWORD dwFlags, PUINT pcIDs, + PGESTURECONFIG pGestureConfig, + UINT cbSize); + +typedef BOOL (*PtrBeginPanningFeedback)(HWND hwnd); +typedef BOOL (*PtrUpdatePanningFeedback)(HWND hwnd, LONG, LONG, BOOL); +typedef BOOL (*PtrEndPanningFeedback)(HWND hwnd, BOOL); + +#endif // WM_GESTURE +#endif // Q_WS_WIN + +class QPanGesture; +class QPinchGesture; +struct StandardGestures +{ + QPanGesture *pan; + QPinchGesture *pinch; + StandardGestures() : pan(0), pinch(0) { } +}; + class QScopedLoopLevelCounter { @@ -439,10 +541,6 @@ public: void sendSyntheticEnterLeave(QWidget *widget); #endif - QGestureManager *gestureManager; - // map number of widget subscribed to it> - QMap grabbedGestures; - QMap widgetForTouchPointId; QMap appCurrentTouchPoints; static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent); @@ -465,6 +563,19 @@ public: QHash touchInputIDToTouchPointID; QList appAllTouchPoints; bool translateTouchEvent(const MSG &msg); + + typedef QMap WidgetStandardGesturesMap; + WidgetStandardGesturesMap widgetGestures; + ulong lastGestureId; + + PtrGetGestureInfo GetGestureInfo; + PtrGetGestureExtraArgs GetGestureExtraArgs; + PtrCloseGestureInfoHandle CloseGestureInfoHandle; + PtrSetGestureConfig SetGestureConfig; + PtrGetGestureConfig GetGestureConfig; + PtrBeginPanningFeedback BeginPanningFeedback; + PtrUpdatePanningFeedback UpdatePanningFeedback; + PtrEndPanningFeedback EndPanningFeedback; #endif #ifdef QT_RX71_MULTITOUCH diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index e1af0f7..13f19a3 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -89,6 +89,8 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c #include #include #include "qevent_p.h" +#include "qstandardgestures.h" +#include "qstandardgestures_p.h" //#define ALIEN_DEBUG @@ -451,6 +453,7 @@ public: bool translateConfigEvent(const MSG &msg); bool translateCloseEvent(const MSG &msg); bool translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets); + bool translateGestureEvent(const MSG &msg); void repolishStyle(QStyle &style); inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); } inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); } @@ -809,6 +812,33 @@ void qt_init(QApplicationPrivate *priv, int) QLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware")) ptrSetProcessDPIAware(); #endif + + priv->lastGestureId = 0; + + priv->GetGestureInfo = + (PtrGetGestureInfo)QLibrary::resolve(QLatin1String("user32"), + "GetGestureInfo"); + priv->GetGestureExtraArgs = + (PtrGetGestureExtraArgs)QLibrary::resolve(QLatin1String("user32"), + "GetGestureExtraArgs"); + priv->CloseGestureInfoHandle = + (PtrCloseGestureInfoHandle)QLibrary::resolve(QLatin1String("user32"), + "CloseGestureInfoHandle"); + priv->SetGestureConfig = + (PtrSetGestureConfig)QLibrary::resolve(QLatin1String("user32"), + "SetGestureConfig"); + priv->GetGestureConfig = + (PtrGetGestureConfig)QLibrary::resolve(QLatin1String("user32"), + "GetGestureConfig"); + priv->BeginPanningFeedback = + (PtrBeginPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "BeginPanningFeedback"); + priv->UpdatePanningFeedback = + (PtrUpdatePanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "UpdatePanningFeedback"); + priv->EndPanningFeedback = + (PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "EndPanningFeedback"); } /***************************************************************************** @@ -2469,6 +2499,10 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } result = false; break; + case WM_GESTURE: + widget->translateGestureEvent(msg); + result = true; + break; default: result = false; // event was not processed break; @@ -3649,6 +3683,60 @@ bool QETWidget::translateCloseEvent(const MSG &) return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); } +bool QETWidget::translateGestureEvent(const MSG &msg) +{ + GESTUREINFO gi; + gi.cbSize = sizeof(GESTUREINFO); + gi.dwFlags = 0; + gi.ptsLocation.x = 0; + gi.ptsLocation.y = 0; + gi.dwID = 0; + gi.dwInstanceID = 0; + gi.dwSequenceID = 0; + + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + BOOL bResult = qAppPriv->GetGestureInfo((HGESTUREINFO)msg.lParam, &gi); + + const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); + QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); + if (alienWidget && alienWidget->internalWinId()) + alienWidget = 0; + QWidget *widget = alienWidget ? alienWidget : this; + + QWinGestureEvent event; + event.sequenceId = gi.dwSequenceID; + event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); + if (bResult) { + switch (gi.dwID) { + case GID_BEGIN: + // we are not interested in this type of event. + break; + case GID_END: + event.gestureType = QWinGestureEvent::GestureEnd; + break; + case GID_ZOOM: + event.gestureType = QWinGestureEvent::Pinch; + break; + case GID_PAN: + event.gestureType = QWinGestureEvent::Pan; + break; + case GID_ROTATE: + case GID_TWOFINGERTAP: + case GID_ROLLOVER: + default: + break; + } + if (event.gestureType != QWinGestureEvent::None) + qt_sendSpontaneousEvent(widget, &event); + } else { + DWORD dwErr = GetLastError(); + if (dwErr > 0) + qWarning() << "translateGestureEvent: error = " << dwErr; + } + qAppPriv->CloseGestureInfoHandle((HGESTUREINFO)msg.lParam); + return true; +} + void QApplication::setCursorFlashTime(int msecs) { @@ -3830,6 +3918,7 @@ void QSessionManager::cancel() #endif //QT_NO_SESSIONMANAGER + qt_RegisterTouchWindowPtr QApplicationPrivate::RegisterTouchWindow = 0; qt_GetTouchInputInfoPtr QApplicationPrivate::GetTouchInputInfo = 0; qt_CloseTouchInputHandlePtr QApplicationPrivate::CloseTouchInputHandle = 0; diff --git a/src/gui/kernel/qdirectionrecognizer.cpp b/src/gui/kernel/qdirectionrecognizer.cpp deleted file mode 100644 index a1bc5b1..0000000 --- a/src/gui/kernel/qdirectionrecognizer.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdirectionrecognizer_p.h" - -#include - -#ifndef M_PI -#define M_PI 3.141592653589793238462643 -#endif - -QT_BEGIN_NAMESPACE - -enum { - DistanceDelta = 20 -}; - -QDirectionSimpleRecognizer::QDirectionSimpleRecognizer() -{ -} - -Direction QDirectionSimpleRecognizer::addPosition(const QPoint &pos) -{ - if (!directions.isEmpty()) { - const QPoint tmp = pos - directions.back().point; - if (tmp.manhattanLength() < 5) - return Direction(); - } - if (lastPoint.isNull()) { - lastPoint = pos; - return Direction(); - } - int dx = pos.x() - lastPoint.x(); - int dy = pos.y() - lastPoint.y(); - Qt::DirectionType direction = Qt::NoDirection; - if (dx < 0) { - if (-1*dx >= DistanceDelta/2) - direction = Qt::LeftDirection; - } else { - if (dx >= DistanceDelta/2) - direction = Qt::RightDirection; - } - if (dy < 0) { - if (-1*dy >= DistanceDelta/2) - direction = Qt::UpDirection; - } else { - if (dy >= DistanceDelta/2) - direction = Qt::DownDirection; - } - if (direction == Qt::NoDirection) - return Direction(); - - lastPoint = pos; - directions.push_back(Direction(direction, pos)); - return Direction(direction, pos); -} - - -DirectionList QDirectionSimpleRecognizer::getDirections() const -{ - return directions; -} - -void QDirectionSimpleRecognizer::reset() -{ - directions.clear(); - lastPoint = QPoint(); -} - - -/// QDirectionDiagonalRecognizer - -QDirectionDiagonalRecognizer::QDirectionDiagonalRecognizer() -{ -} - -Direction QDirectionDiagonalRecognizer::addPosition(const QPoint &pos) -{ - if (!directions.isEmpty()) { - const QPoint tmp = pos - directions.back().point; - if (tmp.manhattanLength() < 5) - return Direction(); - } - if (lastPoint.isNull()) { - lastPoint = pos; - return Direction(); - } - int dx = pos.x() - lastPoint.x(); - int dy = pos.y() - lastPoint.y(); - int distance = sqrt(static_cast(dx*dx + dy*dy)); - if (distance < DistanceDelta/2) - return Direction(); - - Qt::DirectionType direction = Qt::NoDirection; - double angle = atan(1.0*qAbs(lastPoint.y() - pos.y())/qAbs(pos.x() - lastPoint.x())) * 180. / M_PI; - if (dx < 0 && dy <= 0) { - angle = 180 - angle; - } else if (dx <= 0 && dy > 0) { - angle += 180; - } else if (dx > 0 && dy > 0) { - angle = 360-angle; - } - if (angle < 0) - angle += 360; - if (angle <= 20) - direction = Qt::RightDirection; - else if (angle <= 65) - direction = Qt::RightUpDirection; - else if (angle <= 110) - direction = Qt::UpDirection; - else if (angle <= 155) - direction = Qt::LeftUpDirection; - else if (angle <= 200) - direction = Qt::LeftDirection; - else if (angle <= 245) - direction = Qt::LeftDownDirection; - else if (angle <= 290) - direction = Qt::DownDirection; - else if (angle <= 335) - direction = Qt::RightDownDirection; - else - direction = Qt::RightDirection; - - if (direction == Qt::NoDirection) - return Direction(); - - lastPoint = pos; - directions.push_back(Direction(direction, pos)); - return Direction(direction, pos); -} - - -DirectionList QDirectionDiagonalRecognizer::getDirections() const -{ - return directions; -} - -void QDirectionDiagonalRecognizer::reset() -{ - directions.clear(); - lastPoint = QPoint(); -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qdirectionrecognizer_p.h b/src/gui/kernel/qdirectionrecognizer_p.h deleted file mode 100644 index 12307c6..0000000 --- a/src/gui/kernel/qdirectionrecognizer_p.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDIRECTIONRECOGNIZER_P_H -#define QDIRECTIONRECOGNIZER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qpoint.h" -#include "qlist.h" - -QT_BEGIN_NAMESPACE - -struct Direction -{ - Qt::DirectionType direction; - QPoint point; - - Direction(Qt::DirectionType dir, const QPoint &pt) - : direction(dir), point(pt) { } - Direction() - : direction(Qt::NoDirection) { } - - inline bool isEmpty() const { return direction == Qt::NoDirection; } - inline bool isNull() const { return direction == Qt::NoDirection; } -}; - -typedef QList DirectionList; - -class QDirectionSimpleRecognizer -{ -public: - QDirectionSimpleRecognizer(); - Direction addPosition(const QPoint &pos); - DirectionList getDirections() const; - void reset(); - -private: - QPoint lastPoint; - DirectionList directions; -}; - -class QDirectionDiagonalRecognizer -{ -public: - QDirectionDiagonalRecognizer(); - Direction addPosition(const QPoint &pos); - DirectionList getDirections() const; - void reset(); - -private: - QPoint lastPoint; - DirectionList directions; -}; - -QT_END_NAMESPACE - -#endif // QDIRECTIONRECOGNIZER_P_H diff --git a/src/gui/kernel/qdirectionsimplificator_p.h b/src/gui/kernel/qdirectionsimplificator_p.h deleted file mode 100644 index d7491dc..0000000 --- a/src/gui/kernel/qdirectionsimplificator_p.h +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDIRECTIONSIMPLIFICATOR_P_H -#define QDIRECTIONSIMPLIFICATOR_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "private/qdirectionrecognizer_p.h" - -QT_BEGIN_NAMESPACE - -class QDirectionSimplificator -{ -public: - QDirectionSimplificator(const DirectionList &dir); - - bool simplify(DirectionList *result); - -private: - DirectionList directions; - DirectionList lastResult; - enum State { - None, - Trim, // remove first and last element - AccidentalMoves, // 66866 => 6666 - ComplexAccidentalMoves, // 778788 => 777888 (swapping elements without changing direction) - ShortMoves, // (moves of length 1) - } state; - - struct SimplifyTrim - { - SimplifyTrim() : state(0) { } - bool operator()(DirectionList &directions) - { - if (state == 0) { - directions.removeFirst(); - state = 1; - } else if (state == 1) { - directions.removeLast(); - state = 2; - } else if (state == 2 && directions.size() >= 2) { - directions.removeFirst(); - directions.removeLast(); - state = 3; - } else { - return false; - } - return true; - } - int state; - }; - struct SimplifyAccidentalMoves - { - SimplifyAccidentalMoves() : state(0) { } - bool operator()(DirectionList &directions) - { - return false; - } - int state; - }; - struct SimplifyComplexAccidentalMoves - { - SimplifyComplexAccidentalMoves() : state(0) { } - bool operator()(DirectionList &directions) - { - return false; - } - int state; - }; - - SimplifyTrim trim; - SimplifyAccidentalMoves accidentalMoves; - SimplifyComplexAccidentalMoves complexAccidentalMoves; - //SimplifyShortMoves shortMoves; -}; - -QDirectionSimplificator::QDirectionSimplificator(const DirectionList &dir) - : directions(dir), state(None) -{ -} - -bool QDirectionSimplificator::simplify(DirectionList *result) -{ - if (directions.isEmpty() || !result) - return false; - *result = directions; - switch(state) { - case None: - state = Trim; - trim = SimplifyTrim(); - case Trim: - if (trim(*result)) - break; - *result = lastResult; - state = AccidentalMoves; - accidentalMoves = SimplifyAccidentalMoves(); - case AccidentalMoves: - if (accidentalMoves(*result)) - break; - *result = lastResult; - state = ComplexAccidentalMoves; - complexAccidentalMoves = SimplifyComplexAccidentalMoves(); - case ComplexAccidentalMoves: - if (complexAccidentalMoves(*result)) - break; - *result = lastResult; - // state = ShortMoves; - // shortMoves = SimplifyShortMoves(); - // case ShortMoves: - // if (shortMoves(*result)) - // break; - // state = None; - default: - return false; - } - lastResult = *result; - if (lastResult.isEmpty()) - return false; - return true; -} - -QT_END_NAMESPACE - -#endif // QDIRECTIONSIMPLIFICATOR_P_H diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index a7a7f2d..bef7ee1 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -53,8 +53,6 @@ QT_BEGIN_NAMESPACE -QString qt_getStandardGestureTypeName(Qt::GestureType type); - /*! \class QInputEvent \ingroup events @@ -3332,9 +3330,6 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::ChildRemoved: n = n ? n : "ChildRemoved"; dbg.nospace() << "QChildEvent(" << n << ", " << (static_cast(e))->child(); return dbg.space(); - case QEvent::Gesture: - n = "Gesture"; - break; default: dbg.nospace() << "QEvent(" << (const void *)e << ", type = " << e->type() << ')'; return dbg.space(); @@ -3531,157 +3526,6 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) #endif -/*! - \class QGestureEvent - \since 4.6 - \ingroup events - - \brief The QGestureEvent class provides the parameters used for - gesture recognition. - - The QGestureEvent class contains a list of gestures that are being - executed right now (\l{QGestureEvent::}{gestureTypes()}) and a - list of gestures that are cancelled (the gesture might be - cancelled because the window lost focus, or because of timeout, - etc). - - \sa QGesture -*/ - -/*! - Creates new QGestureEvent containing a list of \a gestures that - are being executed and a list of gesture that were cancelled (\a - cancelledGestures). -*/ -QGestureEvent::QGestureEvent(const QSet &gestures, - const QSet &cancelledGestures) - : QEvent(QEvent::Gesture), m_cancelledGestures(cancelledGestures) -{ - setAccepted(false); - foreach(QGesture *r, gestures) - m_gestures.insert(r->type(), r); -} - -/*! - Destroys the QGestureEvent object. -*/ -QGestureEvent::~QGestureEvent() -{ -} - -/*! - Returns true if the gesture event contains gesture of specific \a - type; returns false otherwise. -*/ -bool QGestureEvent::contains(Qt::GestureType type) const -{ - return contains(qt_getStandardGestureTypeName(type)); -} - -/*! - Returns true if the gesture event contains gesture of specific \a - type; returns false otherwise. -*/ -bool QGestureEvent::contains(const QString &type) const -{ - return gesture(type) != 0; -} - -/*! - Returns a list of gesture names that this event contains. -*/ -QList QGestureEvent::gestureTypes() const -{ - return m_gestures.keys(); -} - -/*! - Returns extended information about a gesture of specific \a type. -*/ -const QGesture* QGestureEvent::gesture(Qt::GestureType type) const -{ - return gesture(qt_getStandardGestureTypeName(type)); -} - -/*! - Returns extended information about a gesture of specific \a type. -*/ -const QGesture* QGestureEvent::gesture(const QString &type) const -{ - return m_gestures.value(type, 0); -} - -/*! - Returns extended information about all gestures in the event. -*/ -QList QGestureEvent::gestures() const -{ - return m_gestures.values(); -} - -/*! - Returns a set of gesture names that used to be executed, but were - cancelled (i.e. they were not finished properly). -*/ -QSet QGestureEvent::cancelledGestures() const -{ - return m_cancelledGestures; -} - -/*! \fn void QGestureEvent::accept() - Calls QEvent::accept(). -*/ - -/*! - Sets the accept flag of the all gestures inside the event object, - the equivalent of calling \l{QEvent::accept()}{accept()} or - \l{QEvent::setAccepted()}{setAccepted(true)}. - - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGestureEvent::acceptAll() -{ - QHash::iterator it = m_gestures.begin(), - e = m_gestures.end(); - for(; it != e; ++it) - it.value()->accept(); - setAccepted(true); -} - -/*! - Sets the accept flag of the gesture specified by \a type. - This is equivalent to calling - \l{QGestureEvent::gesture()}{gesture(type)}-> - \l{QGesture::accept()}{accept()} - - Setting the accept flag indicates that the event receiver wants - the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGestureEvent::accept(Qt::GestureType type) -{ - if (QGesture *g = m_gestures.value(qt_getStandardGestureTypeName(type), 0)) - g->accept(); -} - -/*! - Sets the accept flag of the gesture specified by \a type. - This is equivalent to calling - \l{QGestureEvent::gesture()}{gesture(type)}-> - \l{QGesture::accept()}{accept()} - - Setting the accept flag indicates that the event receiver wants - the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGestureEvent::accept(const QString &type) -{ - if (QGesture *g = m_gestures.value(type, 0)) - g->accept(); -} - /*! \class QTouchEvent \brief The QTouchEvent class contains parameters that describe a touch event . diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 136dd7f..11843cb 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -714,41 +714,6 @@ private: }; #endif -class Q_GUI_EXPORT QGestureEvent : public QEvent -{ -public: - QGestureEvent(const QSet &gestures, - const QSet &cancelledGestures = QSet()); - ~QGestureEvent(); - - bool contains(Qt::GestureType type) const; - bool contains(const QString &type) const; - - QList gestureTypes() const; - - const QGesture* gesture(Qt::GestureType type) const; - const QGesture* gesture(const QString &type) const; - QList gestures() const; - - QSet cancelledGestures() const; - - void acceptAll(); -#ifndef Q_NO_USING_KEYWORD - using QEvent::accept; -#else - inline void accept() { QEvent::accept(); } -#endif - void accept(Qt::GestureType type); - void accept(const QString &type); - -protected: - QHash m_gestures; - QSet m_cancelledGestures; - - friend class QApplication; - friend class QGestureManager; -}; - #ifndef QT_NO_DEBUG_STREAM Q_GUI_EXPORT QDebug operator<<(QDebug, const QEvent *); #endif diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 8a2bb05..67441ea 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -119,6 +119,22 @@ public: qreal pressure; }; +class QWinGestureEvent : public QEvent +{ +public: + enum Type { + None, + GestureEnd, + Pan, + Pinch + }; + + QWinGestureEvent() : QEvent(QEvent::WinGesture), gestureType(None), sequenceId(0) { } + Type gestureType; + QPoint position; + ulong sequenceId; +}; + QT_END_NAMESPACE #endif // QEVENT_P_H diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index ff369e2..32a219c 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -41,190 +41,166 @@ #include "qgesture.h" #include +#include "qgraphicsitem.h" QT_BEGIN_NAMESPACE -QString qt_getStandardGestureTypeName(Qt::GestureType type); + +class QEventFilterProxyGraphicsItem : public QGraphicsItem +{ +public: + QEventFilterProxyGraphicsItem(QGesture *g) + : gesture(g) + { + } + bool sceneEventFilter(QGraphicsItem *, QEvent *event) + { + return gesture ? gesture->filterEvent(event) : false; + } + QRectF boundingRect() const { return QRectF(); } + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) { } + +private: + QGesture *gesture; +}; /*! \class QGesture \since 4.6 - \brief The QGesture class represents a gesture, containing all - properties that describe a gesture. - - The widget receives a QGestureEvent with a list of QGesture - objects that represent gestures that are occuring on it. The class - has a list of properties that can be queried by the user to get - some gesture-specific arguments (i.e. position of the tap in the - DoubleTap gesture). - - When creating custom gesture recognizers, they might add new - properties to the gesture object, or custom gesture developers - might subclass the QGesture objects to provide some extended - information. However, if the gesture developer wants to add a new - property to the gesture object that describe coordinate (like a - QPoint or QRect), it is required to subclass the QGesture and - re-implement the \l{QGesture::}{translate()} function to make sure - the coordinates are translated properly when the gesture event is - propagated to parent widgets. - - \sa QGestureEvent, QGestureRecognizer -*/ + \brief The QGesture class is the base class for implementing custom + gestures. -/*! - Creates a new gesture object of type \a type in a \a state and - marks it as a child of \a parent. + This class represents both an object that recognizes a gesture out of a set + of input events (a gesture recognizer), and a gesture object itself that + can be used to get extended information about the triggered gesture. - Usually QGesture objects should only be contructed by the - QGestureRecognizer classes. -*/ -QGesture::QGesture(QObject *parent, const QString &type, Qt::GestureState state) - : QObject(*new QGesturePrivate, parent), m_accept(0) -{ - Q_D(QGesture); - d->type = type; - d->state = state; -} + The class has a list of properties that can be queried by the user to get + some gesture-specific parameters (for example, an offset of a Pan gesture). -/*! - Creates a new gesture object of type \a type in a \a state and - marks it as a child of \a parent. - - This constructor also fills some basic information about the - gesture like a \a startPos which describes the start point of the - gesture, \a lastPos - last point where the gesture happened, \a - pos - a current point, \a rect - a bounding rect of the gesture, - \a hotSpot - a center point of the gesture, \a startTime - a time - when the gesture has started, \a duration - how long the gesture - is going on. - - Usually QGesture objects should only be contructed by the - QGestureRecognizer classes. -*/ -QGesture::QGesture(QObject *parent, const QString &type, const QPoint &startPos, - const QPoint &lastPos, const QPoint &pos, const QRect &rect, - const QPoint &hotSpot, const QDateTime &startTime, - uint duration, Qt::GestureState state) - : QObject(*new QGesturePrivate, parent) -{ - Q_D(QGesture); - d->type = type; - d->state = state; - d->init(startPos, lastPos, pos, rect, hotSpot, startTime, duration); -} + Usually gesture recognizer implements a state machine, storing its state + internally in the recognizer object. The recognizer receives input events + through the \l{QGesture::}{filterEvent()} virtual function and decides + whether the event should change the state of the recognizer by emitting an + appropriate signal. -/*! \internal + Input events should be either fed to the recognizer one by one with a + filterEvent() function, or the gesture recognizer should be attached to an + object it filters events for by specifying it as a parent object. The + QGesture object installs itself as an event filter to the parent object + automatically, the unsetObject() function should be used to remove an event + filter from the parent object. To make a + gesture that operates on a QGraphicsItem, both the appropriate QGraphicsView + should be passed as a parent object and setGraphicsItem() functions should + be used to attach a gesture to a graphics item. + + This is a base class, to create a custom gesture type, you should subclass + it and implement its pure virtual functions. + + \sa QPanGesture, QTapAndHoldGesture */ -QGesture::QGesture(QGesturePrivate &dd, QObject *parent, const QString &type, - Qt::GestureState state) - : QObject(dd, parent) -{ - Q_D(QGesture); - d->type = type; - d->state = state; -} -/*! - Destroys the gesture object. +/*! \fn bool QGesture::filterEvent(QEvent *event) + + Parses input \a event and emits a signal when detects a gesture. + + In your reimplementation of this function, if you want to filter the \a + event out, i.e. stop it being handled further, return true; otherwise + return false; + + This is a pure virtual function that needs to be implemented in subclasses. */ -QGesture::~QGesture() -{ -} -/*! - \property QGesture::type +/*! \fn void QGesture::started() - \brief The type of the gesture. + The signal is emitted when the gesture is started. Extended information + about the gesture is contained in the signal sender object. + + In addition to started(), a triggered() signal should also be emitted. */ -QString QGesture::type() const -{ - return d_func()->type; -} +/*! \fn void QGesture::triggered() -/*! - \property QGesture::state + The signal is emitted when the gesture is detected. Extended information + about the gesture is contained in the signal sender object. +*/ - \brief The current state of the gesture. +/*! \fn void QGesture::finished() + + The signal is emitted when the gesture is finished. Extended information + about the gesture is contained in the signal sender object. */ -Qt::GestureState QGesture::state() const -{ - return d_func()->state; -} -/*! - Translates the internal gesture properties that represent - coordinates by \a offset. +/*! \fn void QGesture::cancelled() - Custom gesture recognizer developer have to re-implement this - function if they want to store custom properties that represent - coordinates. + The signal is emitted when the gesture is cancelled, for example the reset() + function is called while the gesture was in the process of emitting a + triggered() signal. Extended information about the gesture is contained in + the sender object. */ -void QGesture::translate(const QPoint &offset) -{ - Q_D(QGesture); - d->rect.translate(offset); - d->hotSpot += offset; - d->startPos += offset; - d->lastPos += offset; - d->pos += offset; -} + /*! - \property QGesture::rect + Creates a new gesture handler object and marks it as a child of \a parent. + + The \a parent object is also the default event source for the gesture, + meaning that the gesture installs itself as an event filter for the \a + parent. - \brief The bounding rect of a gesture. + \sa setGraphicsItem() */ -QRect QGesture::rect() const +QGesture::QGesture(QObject *parent) + : QObject(*new QGesturePrivate, parent) { - return d_func()->rect; + if (parent) + installEventFilter(parent); } -void QGesture::setRect(const QRect &rect) +/*! \internal + */ +QGesture::QGesture(QGesturePrivate &dd, QObject *parent) + : QObject(dd, parent) { - d_func()->rect = rect; + if (parent) + installEventFilter(parent); } /*! - \property QGesture::hotSpot - - \brief The center point of a gesture. + Destroys the gesture object. */ -QPoint QGesture::hotSpot() const +QGesture::~QGesture() { - return d_func()->hotSpot; } -void QGesture::setHotSpot(const QPoint &point) +/*! \internal + */ +bool QGesture::eventFilter(QObject *receiver, QEvent *event) { - d_func()->hotSpot = point; + Q_D(QGesture); + if (d->graphicsItem && receiver == parent()) + return false; + return filterEvent(event); } /*! - \property QGesture::startTime + \property QGesture::state - \brief The time when the gesture has started. + \brief The current state of the gesture. */ -QDateTime QGesture::startTime() const +Qt::GestureState QGesture::state() const { - return d_func()->startTime; + return d_func()->state; } -/*! - \property QGesture::duration - - \brief The duration time of a gesture. -*/ -uint QGesture::duration() const +void QGesture::setState(Qt::GestureState state) { - return d_func()->duration; + d_func()->state = state; } /*! \property QGesture::startPos - \brief The start position of the pointer. + \brief The start position of the gesture (if relevant). */ QPoint QGesture::startPos() const { @@ -239,7 +215,7 @@ void QGesture::setStartPos(const QPoint &point) /*! \property QGesture::lastPos - \brief The last recorded position of the pointer. + \brief The last recorded position of the gesture (if relevant). */ QPoint QGesture::lastPos() const { @@ -254,7 +230,7 @@ void QGesture::setLastPos(const QPoint &point) /*! \property QGesture::pos - \brief The current position of the pointer. + \brief The current position of the gesture (if relevant). */ QPoint QGesture::pos() const { @@ -266,66 +242,48 @@ void QGesture::setPos(const QPoint &point) d_func()->pos = point; } -/*! \fn void QGesture::setAccepted(bool accepted) - Marks the gesture with the value of \a accepted. - */ - -/*! \fn bool QGesture::isAccepted() const - Returns true if the gesture is marked accepted. - */ - -/*! \fn void QGesture::accept() - Marks the gesture accepted. -*/ - -/*! \fn void QGesture::ignore() - Marks the gesture ignored. -*/ - /*! - \class QPanningGesture - \since 4.6 + Sets the \a graphicsItem the gesture is filtering events for. - \brief The QPanningGesture class represents a Pan gesture, - providing additional information related to panning. + The gesture will install an event filter to the \a graphicsItem and + redirect them to the filterEvent() function. - This class is provided for convenience, panning direction - information is also contained in the QGesture object in it's - properties. + \sa graphicsItem() */ - -/*! \internal -*/ -QPanningGesture::QPanningGesture(QObject *parent) - : QGesture(*new QPanningGesturePrivate, parent, - qt_getStandardGestureTypeName(Qt::PanGesture)) -{ -} - -/*! \internal -*/ -QPanningGesture::~QPanningGesture() +void QGesture::setGraphicsItem(QGraphicsItem *graphicsItem) { + Q_D(QGesture); + if (d->graphicsItem && d->eventFilterProxyGraphicsItem) + d->graphicsItem->removeSceneEventFilter(d->eventFilterProxyGraphicsItem); + d->graphicsItem = graphicsItem; + if (!d->eventFilterProxyGraphicsItem) + d->eventFilterProxyGraphicsItem = new QEventFilterProxyGraphicsItem(this); + if (graphicsItem) + graphicsItem->installSceneEventFilter(d->eventFilterProxyGraphicsItem); } /*! - \property QPanningGesture::lastDirection + Returns the graphics item the gesture is filtering events for. - \brief The last recorded direction of panning. + \sa setGraphicsItem() */ -Qt::DirectionType QPanningGesture::lastDirection() const +QGraphicsItem* QGesture::graphicsItem() const { - return d_func()->lastDirection; + return d_func()->graphicsItem; } -/*! - \property QPanningGesture::direction +/*! \fn void QGesture::reset() - \brief The current direction of panning. + Resets the internal state of the gesture. This function might be called by + the filterEvent() implementation in a derived class, or by the user to + cancel a gesture. The base class implementation emits the cancelled() + signal if the state() of the gesture wasn't empty. */ -Qt::DirectionType QPanningGesture::direction() const +void QGesture::reset() { - return d_func()->direction; + if (state() != Qt::NoGesture) + emit cancelled(); + setState(Qt::NoGesture); } QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index f3c95cc..b5abdd2 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -55,50 +55,32 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) +class QGraphicsItem; class QGesturePrivate; class Q_GUI_EXPORT QGesture : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QGesture) - Q_PROPERTY(QString type READ type) Q_PROPERTY(Qt::GestureState state READ state) - Q_PROPERTY(QDateTime startTime READ startTime) - Q_PROPERTY(uint duration READ duration) - - Q_PROPERTY(QRect rect READ rect WRITE setRect) - Q_PROPERTY(QPoint hotSpot READ hotSpot WRITE setHotSpot) Q_PROPERTY(QPoint startPos READ startPos WRITE setStartPos) Q_PROPERTY(QPoint lastPos READ lastPos WRITE setLastPos) Q_PROPERTY(QPoint pos READ pos WRITE setPos) public: - QGesture(QObject *parent, const QString &type, - Qt::GestureState state = Qt::GestureStarted); - QGesture(QObject *parent, - const QString &type, const QPoint &startPos, - const QPoint &lastPos, const QPoint &pos, const QRect &rect, - const QPoint &hotSpot, const QDateTime &startTime, - uint duration, Qt::GestureState state); - virtual ~QGesture(); - - inline void setAccepted(bool accepted) { m_accept = accepted; } - inline bool isAccepted() const { return m_accept; } - - inline void accept() { m_accept = true; } - inline void ignore() { m_accept = false; } - - QString type() const; - Qt::GestureState state() const; + explicit QGesture(QObject *parent = 0); + ~QGesture(); + + virtual bool filterEvent(QEvent *event) = 0; + + void setGraphicsItem(QGraphicsItem *); + QGraphicsItem *graphicsItem() const; - QDateTime startTime() const; - uint duration() const; + virtual void reset(); - QRect rect() const; - void setRect(const QRect &rect); - QPoint hotSpot() const; - void setHotSpot(const QPoint &point); + Qt::GestureState state() const; + void setState(Qt::GestureState state); QPoint startPos() const; void setStartPos(const QPoint &point); @@ -108,45 +90,19 @@ public: void setPos(const QPoint &point); protected: - QGesture(QGesturePrivate &dd, QObject *parent, const QString &type, - Qt::GestureState state = Qt::GestureStarted); - virtual void translate(const QPoint &offset); + QGesture(QGesturePrivate &dd, QObject *parent); + bool eventFilter(QObject*, QEvent*); -private: - ushort m_accept : 1; - - friend class QGestureManager; - friend class QApplication; - friend class QGraphicsScene; - friend class QGraphicsScenePrivate; - friend class QGestureRecognizerPan; - friend class QDoubleTapGestureRecognizer; - friend class QTapAndHoldGestureRecognizer; -}; - -class QPanningGesturePrivate; -class Q_GUI_EXPORT QPanningGesture : public QGesture -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QPanningGesture) - - Q_PROPERTY(Qt::DirectionType lastDirection READ lastDirection) - Q_PROPERTY(Qt::DirectionType direction READ direction) - -public: - Qt::DirectionType lastDirection() const; - Qt::DirectionType direction() const; +signals: + void started(); + void triggered(); + void finished(); + void cancelled(); private: - QPanningGesture(QObject *parent = 0); - ~QPanningGesture(); - - friend class QGestureRecognizerPan; + friend class QWidget; }; -Q_DECLARE_METATYPE(Qt::DirectionType) -Q_DECLARE_METATYPE(Qt::GestureState) - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index caf851e..99f572f 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -56,10 +56,12 @@ #include "qrect.h" #include "qpoint.h" #include "qdatetime.h" +#include "qgesture.h" #include "private/qobject_p.h" QT_BEGIN_NAMESPACE +class QObject; class QGraphicsItem; class QGesturePrivate : public QObjectPrivate { @@ -67,47 +69,28 @@ class QGesturePrivate : public QObjectPrivate public: QGesturePrivate() - : state(Qt::NoGesture), graphicsItem(0), singleshot(0), duration(0) { } + : graphicsItem(0), eventFilterProxyGraphicsItem(0), state(Qt::NoGesture) + { + } void init(const QPoint &startPos, const QPoint &lastPos, - const QPoint &pos, const QRect &rect, - const QPoint &hotSpot, const QDateTime &startTime, - uint duration) + const QPoint &pos) { - this->rect = rect; - this->hotSpot = hotSpot; - this->startTime = startTime; - this->duration = duration; this->startPos = startPos; this->lastPos = lastPos; this->pos = pos; } - QString type; - Qt::GestureState state; - - QPointer widget; QGraphicsItem *graphicsItem; - uint singleshot:1; + QGraphicsItem *eventFilterProxyGraphicsItem; + + Qt::GestureState state; - QRect rect; - QPoint hotSpot; - QDateTime startTime; - uint duration; QPoint startPos; QPoint lastPos; QPoint pos; }; -class QPanningGesturePrivate : public QGesturePrivate -{ - Q_DECLARE_PUBLIC(QPanningGesture) - -public: - Qt::DirectionType lastDirection; - Qt::DirectionType direction; -}; - QT_END_NAMESPACE #endif // QGESTURE_P_H diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp deleted file mode 100644 index 20abda9..0000000 --- a/src/gui/kernel/qgesturemanager.cpp +++ /dev/null @@ -1,644 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgesturemanager_p.h" -#include "qgesture.h" -#include "qgesture_p.h" -#include "qevent.h" - -#include "qapplication.h" -#include "qapplication_p.h" -#include "qwidget.h" -#include "qwidget_p.h" - -#include "qgesturestandardrecognizers_p.h" - -#include "qdebug.h" - -// #define GESTURE_DEBUG -#ifndef GESTURE_DEBUG -# define DEBUG if (0) qDebug -#else -# define DEBUG qDebug -#endif - -QT_BEGIN_NAMESPACE - -bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); - -static const unsigned int MaximumGestureRecognitionTimeout = 2000; - -QGestureManager::QGestureManager(QObject *parent) - : QObject(parent), eventDeliveryDelayTimeout(300), - delayedPressTimer(0), lastMousePressReceiver(0), lastMousePressEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0), - lastGestureId(0), state(NotGesture) -{ - qRegisterMetaType(); - qRegisterMetaType(); - - recognizers << new QDoubleTapGestureRecognizer(this); - recognizers << new QTapAndHoldGestureRecognizer(this); - recognizers << new QGestureRecognizerPan(this); - - foreach(QGestureRecognizer *r, recognizers) - connect(r, SIGNAL(stateChanged(QGestureRecognizer::Result)), - this, SLOT(recognizerStateChanged(QGestureRecognizer::Result))); -} - -void QGestureManager::addRecognizer(QGestureRecognizer *recognizer) -{ - recognizer->setParent(this); - recognizers << recognizer; -} - -void QGestureManager::removeRecognizer(QGestureRecognizer *recognizer) -{ - recognizers.remove(recognizer); -} - -bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) -{ - QPoint currentPos; - switch (event->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::MouseMove: - currentPos = static_cast(event)->pos(); break; - default: break; - } - - const QMap &grabbedGestures = qApp->d_func()->grabbedGestures; - - bool ret = false; - QSet startedGestures; - QSet finishedGestures; - QSet newMaybeGestures; - QSet cancelledGestures; - QSet notGestures; - if (state == NotGesture || state == MaybeGesture) { - DEBUG() << "QGestureManager: current event processing state: " - << (state == NotGesture ? "NotGesture" : "MaybeGesture"); - - QSet stillMaybeGestures; - // try other recognizers. - foreach(QGestureRecognizer *r, recognizers) { - if (grabbedGestures.value(r->gestureType(), 0) <= 0) - continue; - QGestureRecognizer::Result result = r->filterEvent(event); - if (result == QGestureRecognizer::GestureStarted) { - DEBUG() << "QGestureManager: gesture started: " << r; - startedGestures << r; - } else if (result == QGestureRecognizer::GestureFinished) { - DEBUG() << "QGestureManager: gesture finished: " << r; - finishedGestures << r; - } else if (result == QGestureRecognizer::MaybeGesture) { - DEBUG() << "QGestureManager: maybe gesture: " << r; - newMaybeGestures << r; - } else if (result == QGestureRecognizer::NotGesture) { - // if it was maybe gesture, but isn't a gesture anymore. - DEBUG() << "QGestureManager: not gesture: " << r; - notGestures << r; - } - } - Q_ASSERT(activeGestures.isEmpty()); - activeGestures += startedGestures; - for(QMap::iterator it = maybeGestures.begin(); - it != maybeGestures.end();) { - QGestureRecognizer *r = it.key(); - if (startedGestures.contains(r) || finishedGestures.contains(r) || - notGestures.contains(r)) { - killTimer(it.value()); - it = maybeGestures.erase(it); - } else { - ++it; - } - } - foreach(QGestureRecognizer *r, newMaybeGestures) { - if (!maybeGestures.contains(r)) { - int timerId = startTimer(MaximumGestureRecognitionTimeout); - if (!timerId) - qWarning("QGestureManager: couldn't start timer!"); - maybeGestures.insert(r, timerId); - } - } - if (!finishedGestures.isEmpty() || !startedGestures.isEmpty()) { - // gesture found! - ret = true; - QSet started; - foreach(QGestureRecognizer *r, finishedGestures) { - if (QGesture *gesture = r->getGesture()) { - started << gesture; - gesture->d_func()->singleshot = true; - } - } - foreach(QGestureRecognizer *r, startedGestures) { - if (QGesture *gesture = r->getGesture()) { - started << gesture; - gesture->d_func()->singleshot = false; - } - } - - if (!activeGestures.isEmpty()) { - DEBUG() << "QGestureManager: new state = Gesture"; - state = Gesture; - } else if (!maybeGestures.isEmpty()) { - DEBUG() << "QGestureManager: new state = Maybe"; - state = MaybeGesture; - } else { - DEBUG() << "QGestureManager: new state = NotGesture"; - state = NotGesture; - } - - Q_ASSERT(!started.isEmpty()); - ret = sendGestureEvent(receiver, started, QSet()); - } else if (!maybeGestures.isEmpty()) { - if (state != MaybeGesture) { - // We got a new set of events that look like a start - // of some gesture, so we switch to state MaybeGesture - // and wait for more events. - DEBUG() << "QGestureManager: new state = Maybe. Waiting for events"; - state = MaybeGesture; - // start gesture timer - } else { - // we still not sure if it is a gesture or not. - } - } else if (state == MaybeGesture) { - // last time we thought it looks like gesture, but now we - // know for sure that it isn't. - DEBUG() << "QGestureManager: new state = NotGesture"; - state = NotGesture; - } - foreach(QGestureRecognizer *r, finishedGestures) - r->reset(); - foreach(QGestureRecognizer *r, cancelledGestures) - r->reset(); - foreach(QGestureRecognizer *r, notGestures) - r->reset(); - } else if (state == Gesture) { - DEBUG() << "QGestureManager: current event processing state: Gesture"; - Q_ASSERT(!activeGestures.isEmpty()); - - foreach(QGestureRecognizer *r, recognizers) { - if (grabbedGestures.value(r->gestureType(), 0) <= 0) - continue; - QGestureRecognizer::Result result = r->filterEvent(event); - if (result == QGestureRecognizer::GestureStarted) { - DEBUG() << "QGestureManager: gesture started: " << r; - startedGestures << r; - } else if (result == QGestureRecognizer::GestureFinished) { - DEBUG() << "QGestureManager: gesture finished: " << r; - finishedGestures << r; - } else if (result == QGestureRecognizer::MaybeGesture) { - DEBUG() << "QGestureManager: maybe gesture: " << r; - newMaybeGestures << r; - } else if (result == QGestureRecognizer::NotGesture) { - // if it was an active gesture, but isn't a gesture anymore. - if (activeGestures.contains(r)) { - DEBUG() << "QGestureManager: cancelled gesture: " << r; - cancelledGestures << r; - } else { - DEBUG() << "QGestureManager: not gesture: " << r; - notGestures << r; - } - } - } - - for(QMap::iterator it = maybeGestures.begin(); - it != maybeGestures.end();) { - QGestureRecognizer *r = it.key(); - if (startedGestures.contains(r) || finishedGestures.contains(r) || - notGestures.contains(r)) { - killTimer(it.value()); - it = maybeGestures.erase(it); - } else { - ++it; - } - } - foreach(QGestureRecognizer *r, newMaybeGestures) { - if (!maybeGestures.contains(r)) { - int timerId = startTimer(MaximumGestureRecognitionTimeout); - if (!timerId) - qWarning("QGestureManager: couldn't start timer!"); - maybeGestures.insert(r, timerId); - } - } - QSet started, updated; - if (!finishedGestures.isEmpty() || !startedGestures.isEmpty()) { - // another gesture found! - ret = true; - foreach(QGestureRecognizer *r, finishedGestures) { - if (QGesture *gesture = r->getGesture()) { - gesture->d_func()->singleshot = !activeGestures.contains(r); - if (gesture->d_func()->singleshot) - started << gesture; - else - updated << gesture; - } - } - foreach(QGestureRecognizer *r, startedGestures) { - if (QGesture *gesture = r->getGesture()) { - gesture->d_func()->singleshot = !activeGestures.contains(r); - if (gesture->d_func()->singleshot) - started << gesture; - else - updated << gesture; - } - } - } - activeGestures -= newMaybeGestures; - activeGestures -= cancelledGestures; - activeGestures += startedGestures; - activeGestures -= finishedGestures; - QSet cancelledGestureNames; - foreach(QGestureRecognizer *r, cancelledGestures) - cancelledGestureNames << r->gestureType(); - ret = sendGestureEvent(receiver, started, updated, cancelledGestureNames); - - foreach(QGestureRecognizer *r, finishedGestures) - r->reset(); - foreach(QGestureRecognizer *r, cancelledGestures) - r->reset(); - foreach(QGestureRecognizer *r, notGestures) - r->reset(); - if (!activeGestures.isEmpty()) { - // nothing changed, we are still handling a gesture - } else if (!maybeGestures.isEmpty()) { - DEBUG() << "QGestureManager: new state = Maybe. Waiting for events: " << maybeGestures; - state = MaybeGesture; - } else { - DEBUG() << "QGestureManager: new state = NotGesture"; - state = NotGesture; - } - } - - if (delayedPressTimer && state == Gesture) { - DEBUG() << "QGestureManager: gesture started. Forgetting about postponed mouse press event"; - killTimer(delayedPressTimer); - delayedPressTimer = 0; - lastMousePressReceiver = 0; - } else if (delayedPressTimer && (state == NotGesture || - event->type() == QEvent::MouseButtonRelease)) { - // not a gesture or released button too fast, so replay press - // event back. - DEBUG() << "QGestureManager: replaying mouse press event"; - QMap::const_iterator it = maybeGestures.begin(), - e = maybeGestures.end();; - for (; it != e; ++it) { - it.key()->reset(); - killTimer(it.value()); - } - maybeGestures.clear(); - state = NotGesture; - - if (lastMousePressReceiver) { - QApplication::sendEvent(lastMousePressReceiver, &lastMousePressEvent); - if (event->type() == QEvent::MouseButtonRelease) { - QMouseEvent *me = static_cast(event); - QMouseEvent move(QEvent::MouseMove, me->pos(), me->globalPos(), me->button(), - me->buttons(), me->modifiers()); - QApplication::sendEvent(lastMousePressReceiver, &move); - ret = false; - } - lastMousePressReceiver = 0; - } - lastMousePressReceiver = 0; - killTimer(delayedPressTimer); - delayedPressTimer = 0; - } else if (state == MaybeGesture && event->type() == QEvent::MouseButtonPress - && eventDeliveryDelayTimeout) { - // postpone the press event delivery until we know for - // sure whether it is a gesture. - DEBUG() << "QGestureManager: postponing mouse press event"; - QMouseEvent *me = static_cast(event); - lastMousePressReceiver = receiver; - lastMousePressEvent = QMouseEvent(QEvent::MouseButtonPress, me->pos(), - me->globalPos(), me->button(), - me->buttons(), me->modifiers()); - Q_ASSERT(delayedPressTimer == 0); - delayedPressTimer = startTimer(eventDeliveryDelayTimeout); - if (!delayedPressTimer) - qWarning("QGestureManager: couldn't start delayed press timer!"); - ret = true; - } - if (delayedPressTimer && event->type() == QEvent::MouseMove) { - // if we have postponed a mouse press event, postpone all - // subsequent mouse move events as well. - ret = true; - } - - lastPos = currentPos; - return ret; -} - -void QGestureManager::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == delayedPressTimer) { - DEBUG() << "QGestureManager: replaying mouse press event due to timeout"; - // sanity checks - Q_ASSERT(state != Gesture); - - QMap::const_iterator it = maybeGestures.begin(), - e = maybeGestures.end();; - for (; it != e; ++it) { - it.key()->reset(); - killTimer(it.value()); - } - maybeGestures.clear(); - state = NotGesture; - - if (lastMousePressReceiver) { - // we neither received a mouse release event nor gesture - // started, so we replay stored mouse press event. - QApplication::sendEvent(lastMousePressReceiver, &lastMousePressEvent); - lastMousePressReceiver = 0; - } - - lastMousePressReceiver = 0; - killTimer(delayedPressTimer); - delayedPressTimer = 0; - } else { - // sanity checks, remove later - Q_ASSERT((state == Gesture && !activeGestures.isEmpty()) || (state != Gesture && activeGestures.isEmpty())); - - typedef QMap MaybeGestureMap; - for (MaybeGestureMap::iterator it = maybeGestures.begin(), e = maybeGestures.end(); - it != e; ++it) { - if (it.value() == event->timerId()) { - DEBUG() << "QGestureManager: gesture timeout."; - QGestureRecognizer *r = it.key(); - r->reset(); - maybeGestures.erase(it); - killTimer(event->timerId()); - break; - } - } - - if (state == MaybeGesture && maybeGestures.isEmpty()) { - DEBUG() << "QGestureManager: new state = NotGesture because of timeout"; - state = NotGesture; - } - } -} - -bool QGestureManager::inGestureMode() -{ - return state == Gesture; -} - -void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result) -{ - QGestureRecognizer *recognizer = qobject_cast(sender()); - if (!recognizer) - return; - if (qApp->d_func()->grabbedGestures.value(recognizer->gestureType(), 0) <= 0) { - recognizer->reset(); - return; - } - - switch (result) { - case QGestureRecognizer::GestureStarted: - case QGestureRecognizer::GestureFinished: { - if (result == QGestureRecognizer::GestureStarted) { - DEBUG() << "QGestureManager: gesture started: " << recognizer; - activeGestures << recognizer; - DEBUG() << "QGestureManager: new state = Gesture"; - state = Gesture; - } else { - DEBUG() << "QGestureManager: gesture finished: " << recognizer; - } - if (maybeGestures.contains(recognizer)) { - killTimer(maybeGestures.value(recognizer)); - maybeGestures.remove(recognizer); - } - QSet gestures; - if (QGesture *gesture = recognizer->getGesture()) - gestures << gesture; - if(!gestures.isEmpty()) { - //FIXME: sendGestureEvent(targetWidget, gestures); - } - if (result == QGestureRecognizer::GestureFinished) - recognizer->reset(); - } - break; - case QGestureRecognizer::MaybeGesture: { - DEBUG() << "QGestureManager: maybe gesture: " << recognizer; - if (activeGestures.contains(recognizer)) { - //FIXME: sendGestureEvent(targetWidget, QSet(), QSet() << recognizer->gestureType()); - } - if (!maybeGestures.contains(recognizer)) { - int timerId = startTimer(MaximumGestureRecognitionTimeout); - if (!timerId) - qWarning("QGestureManager: couldn't start timer!"); - maybeGestures.insert(recognizer, timerId); - } - } - break; - case QGestureRecognizer::NotGesture: - DEBUG() << "QGestureManager: not gesture: " << recognizer; - if (maybeGestures.contains(recognizer)) { - killTimer(maybeGestures.value(recognizer)); - maybeGestures.remove(recognizer); - } - recognizer->reset(); - break; - default: - Q_ASSERT(false); - } - - if (delayedPressTimer && state == Gesture) { - killTimer(delayedPressTimer); - delayedPressTimer = 0; - } -} - -bool QGestureManager::sendGestureEvent(QWidget *receiver, - const QSet &startedGestures, - const QSet &updatedGestures, - const QSet &cancelled) -{ - DEBUG() << "QGestureManager::sendGestureEvent: sending to" << receiver - << "gestures:" << startedGestures << "," << updatedGestures - << "cancelled:" << cancelled; - // grouping gesture objects by receiver widgets. - typedef QMap > WidgetGesturesMap; - WidgetGesturesMap widgetGestures; - for(QSet::const_iterator it = startedGestures.begin(), e = startedGestures.end(); - it != e; ++it) { - QGesture *g = *it; - QGesturePrivate *gd = g->d_func(); - if (receiver) { - // find the target widget - gd->widget = 0; - gd->graphicsItem = 0; - QWidget *w = receiver; - QPoint offset; - const QString gestureType = g->type(); - while (w) { - if (w->d_func()->hasGesture(gestureType)) - break; - if (w->isWindow()) { - w = 0; - break; - } - offset += w->pos(); - w = w->parentWidget(); - } - if (w && w != gd->widget) { - DEBUG() << "QGestureManager::sendGestureEvent:" << g << "propagating to widget" << w << "offset" << offset; - g->translate(offset); - } - gd->widget = w; - } - if (!gd->widget) { - DEBUG() << "QGestureManager: didn't find a widget to send gesture event (" - << g->type() << ") for tree:" << receiver; - // TODO: maybe we should reset gesture recognizers when nobody interested in its gestures. - continue; - } - widgetGestures[gd->widget].insert(g); - } - - QSet ignoredGestures; - bool ret = false; - for(WidgetGesturesMap::const_iterator it = widgetGestures.begin(), e = widgetGestures.end(); - it != e; ++it) { - QWidget *receiver = it.key(); - Q_ASSERT(receiver != 0 /*should be taken care above*/); - QSet gestures = it.value(); - // mark all gestures as ignored by default - for(QSet::iterator it = gestures.begin(), e = gestures.end(); it != e; ++it) - (*it)->ignore(); - // TODO: send cancelled gesture event to the widget that received the original gesture! - QGestureEvent event(gestures, cancelled); - DEBUG() << "QGestureManager::sendGestureEvent: sending now to" << receiver - << "gestures" << gestures; - bool processed = qt_sendSpontaneousEvent(receiver, &event); - QSet started = startedGestures & gestures; - DEBUG() << "QGestureManager::sendGestureEvent:" << - (event.isAccepted() ? "" : "not") << "all gestures were accepted"; - if (!started.isEmpty() && !(processed && event.isAccepted())) { - // there are started gestures events that weren't - // accepted, so propagating each gesture independently. - if (event.isAccepted()) { - foreach(QGesture *g, started) - g->accept(); - } - QSet::const_iterator it = started.begin(), - e = started.end(); - for(; it != e; ++it) { - QGesture *g = *it; - if (processed && g->isAccepted()) { - ret = true; - continue; - } - // if it wasn't accepted, find the first parent widget - // that is subscribed to the gesture. - QGesturePrivate *gd = g->d_func(); - QWidget *w = gd->widget; - gd->widget = 0; - - if (w && !w->isWindow()) { - g->translate(w->pos()); - w = w->parentWidget(); - QPoint offset; - const QString gestureType = g->type(); - while (w) { - if (w->d_func()->hasGesture(gestureType)) { - DEBUG() << "QGestureManager::sendGestureEvent:" << receiver - << "didn't accept gesture" << g << "propagating to" << w; - ignoredGestures.insert(g); - gd->widget = w; - break; - } - if (w->isWindow()) { - w = 0; - break; - } - offset += w->pos(); - w = w->parentWidget(); - } - if (w) { - g->translate(offset); - } else { - DEBUG() << "QGestureManager::sendGestureEvent:" << receiver - << "didn't accept gesture" << g << "and nobody wants it"; - } - } - } - } - } - if (ignoredGestures.isEmpty()) - return ret; - // try to send all gestures that were ignored to the next parent - return sendGestureEvent(0, ignoredGestures, QSet(), cancelled) || ret; -} - -int QGestureManager::eventDeliveryDelay() const -{ - return eventDeliveryDelayTimeout; -} - -void QGestureManager::setEventDeliveryDelay(int ms) -{ - eventDeliveryDelayTimeout = ms; -} - -int QGestureManager::makeGestureId(const QString &name) -{ - gestureIdMap[++lastGestureId] = name; - return lastGestureId; -} - -void QGestureManager::releaseGestureId(int gestureId) -{ - gestureIdMap.remove(gestureId); -} - -QString QGestureManager::gestureNameFromId(int gestureId) const -{ - return gestureIdMap.value(gestureId); -} - -QT_END_NAMESPACE - -#include "moc_qgesturemanager_p.cpp" - diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h deleted file mode 100644 index 8656590..0000000 --- a/src/gui/kernel/qgesturemanager_p.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGESTUREMANAGER_P_H -#define QGESTUREMANAGER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qlist.h" -#include "qset.h" -#include "qevent.h" -#include "qbasictimer.h" -#include "qpointer.h" - -#include "qgesturerecognizer.h" - -QT_BEGIN_NAMESPACE - -class QWidget; -class Q_AUTOTEST_EXPORT QGestureManager : public QObject -{ - Q_OBJECT -public: - QGestureManager(QObject *parent); - - int eventDeliveryDelay() const; - void setEventDeliveryDelay(int ms); - - void addRecognizer(QGestureRecognizer *recognizer); - void removeRecognizer(QGestureRecognizer *recognizer); - - bool filterEvent(QWidget *receiver, QEvent *event); - bool inGestureMode(); - - int makeGestureId(const QString &name); - void releaseGestureId(int gestureId); - QString gestureNameFromId(int gestureId) const; - - // declared in qapplication.cpp - static QGestureManager* instance(); - - bool sendGestureEvent(QWidget *receiver, - const QSet &startedGestures, - const QSet &updatedGestures, - const QSet &cancelled = QSet()); - -protected: - void timerEvent(QTimerEvent *event); - -private slots: - void recognizerStateChanged(QGestureRecognizer::Result); - -private: - QSet activeGestures; - QMap maybeGestures; - QSet recognizers; - - QPoint lastPos; - - int eventDeliveryDelayTimeout; - int delayedPressTimer; - QPointer lastMousePressReceiver; - QMouseEvent lastMousePressEvent; - - QMap gestureIdMap; - int lastGestureId; - - enum State { - Gesture, - NotGesture, - MaybeGesture // that mean timers are up and waiting for some - // more events, and input events are handled by - // gesture recognizer explicitely - } state; -}; - -QT_END_NAMESPACE - -#endif // QGESTUREMANAGER_P_H diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp deleted file mode 100644 index 30889d7..0000000 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgesturerecognizer.h" -#include "qgesture.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -QString qt_getStandardGestureTypeName(Qt::GestureType gestureType); - -/*! - \class QGestureRecognizer - \since 4.6 - - \brief The QGestureRecognizer class is the base class for - implementing custom gestures. - - This is a base class, to create a custom gesture type, you should - subclass it and implement its pure virtual functions. - - Usually gesture recognizer implements state machine, storing its - state internally in the recognizer object. The recognizer receives - input events through the \l{QGestureRecognizer::}{filterEvent()} - virtual function and decides whether the parsed event should - change the state of the recognizer - i.e. if the event starts or - ends a gesture or if it isn't related to gesture at all. -*/ - -/*! - \enum QGestureRecognizer::Result - \since 4.6 - - This enum type defines the state of the gesture recognizer. - - \value Ignore Gesture recognizer ignores the event. - - \value NotGesture Not a gesture. - - \value GestureStarted The continuous gesture has started. When the - recognizer is in this state, a \l{QGestureEvent}{gesture event} - containing QGesture objects returned by the - \l{QGestureRecognizer::}{getGesture()} will be sent to a widget. - - \value GestureFinished The gesture has ended. A - \l{QGestureEvent}{gesture event} will be sent to a widget. - - \value MaybeGesture Gesture recognizer hasn't decided yet if a - gesture has started, but it might start soon after the following - events are received by the recognizer. This means that gesture - manager shouldn't reset() the internal state of the gesture - recognizer. -*/ - -/*! \fn QGestureRecognizer::Result QGestureRecognizer::filterEvent(const QEvent *event) - - This is a pure virtual function that needs to be implemented in - subclasses. - - Parses input \a event and returns the result, which specifies - whether the event sequence is a gesture or not. -*/ - -/*! \fn QGesture* QGestureRecognizer::getGesture() - - Returns a gesture object that will be send to the widget. This - function is called when the gesture recognizer changed its state - to QGestureRecognizer::GestureStarted or - QGestureRecognizer::GestureFinished. - - The returned QGesture object must point to the same object in a - single gesture sequence. - - The gesture object is owned by the recognizer itself. -*/ - -/*! \fn void QGestureRecognizer::reset() - - Resets the internal state of the gesture recognizer. -*/ - -/*! \fn void QGestureRecognizer::stateChanged(QGestureRecognizer::Result result) - - The gesture recognizer might emit the stateChanged() signal when - the gesture state changes asynchronously, i.e. without any event - being filtered through filterEvent(). \a result specifies whether - the event sequence is a gesture or not. -*/ - -QGestureRecognizerPrivate::QGestureRecognizerPrivate() - : gestureType(Qt::UnknownGesture) -{ -} - -/*! - Creates a new gesture recognizer object that handles gestures of - the specific \a gestureType as a child of \a parent. - - \sa QApplication::addGestureRecognizer(), - QApplication::removeGestureRecognizer(), -*/ -QGestureRecognizer::QGestureRecognizer(const QString &gestureType, QObject *parent) - : QObject(*new QGestureRecognizerPrivate, parent) -{ - Q_D(QGestureRecognizer); - d->customGestureType = gestureType; -} - -/*! - Returns the name of the gesture that is handled by the recognizer. -*/ -QString QGestureRecognizer::gestureType() const -{ - Q_D(const QGestureRecognizer); - if (d->gestureType == Qt::UnknownGesture) - return d->customGestureType; - return qt_getStandardGestureTypeName(d->gestureType); -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h deleted file mode 100644 index 2c1c61b..0000000 --- a/src/gui/kernel/qgesturerecognizer.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGESTURERECOGNIZER_H -#define QGESTURERECOGNIZER_H - -#include "qevent.h" -#include "qlist.h" -#include "qset.h" - -QT_BEGIN_NAMESPACE - -class QGesture; -class QGestureRecognizerPrivate; -class Q_GUI_EXPORT QGestureRecognizer : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QGestureRecognizer) - -public: - enum Result - { - Ignore, - NotGesture, - GestureStarted, //TODO: rename to just Gesture? - GestureFinished, - MaybeGesture - }; - - explicit QGestureRecognizer(const QString &gestureType, QObject *parent = 0); - - QString gestureType() const; - - virtual QGestureRecognizer::Result filterEvent(const QEvent* event) = 0; - virtual QGesture* getGesture() = 0; - virtual void reset() = 0; - -signals: - void stateChanged(QGestureRecognizer::Result result); - -private: - friend class QDoubleTapGestureRecognizer; - friend class QTapAndHoldGestureRecognizer; - friend class QGestureRecognizerPan; -}; - -QT_END_NAMESPACE - -#endif // QGESTURERECOGNIZER_P_H diff --git a/src/gui/kernel/qgesturerecognizer_p.h b/src/gui/kernel/qgesturerecognizer_p.h deleted file mode 100644 index e250201..0000000 --- a/src/gui/kernel/qgesturerecognizer_p.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGESTURERECOGNIZER_P_H -#define QGESTURERECOGNIZER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -class QGestureRecognizerPrivate : public QObjectPrivate -{ -public: - QGestureRecognizerPrivate(); - -public: - Qt::GestureType gestureType; - QString customGestureType; -}; - -QT_END_NAMESPACE - -#endif // QGESTURERECOGNIZER_P_H diff --git a/src/gui/kernel/qgesturestandardrecognizers.cpp b/src/gui/kernel/qgesturestandardrecognizers.cpp deleted file mode 100644 index b108994..0000000 --- a/src/gui/kernel/qgesturestandardrecognizers.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgesturestandardrecognizers_p.h" -#include "qgesture_p.h" -#include "qgesturerecognizer_p.h" - -// #define GESTURE_RECOGNIZER_DEBUG -#ifndef GESTURE_RECOGNIZER_DEBUG -# define DEBUG if (0) qDebug -#else -# define DEBUG qDebug -#endif - -QT_BEGIN_NAMESPACE - -QString qt_getStandardGestureTypeName(Qt::GestureType gestureType) -{ - switch (gestureType) { - case Qt::TapGesture: - return QLatin1String("__QTapGesture"); - case Qt::DoubleTapGesture: - return QLatin1String("__QDoubleTapGesture"); - case Qt::TrippleTapGesture: - return QLatin1String("__QTrippleTapGesture"); - case Qt::TapAndHoldGesture: - return QLatin1String("__QTapAndHoldGesture"); - case Qt::PanGesture: - return QLatin1String("__QPanGesture"); - case Qt::PinchGesture: - return QLatin1String("__QPinchGesture"); - case Qt::UnknownGesture: - break; - } - qFatal("QGestureRecognizer::gestureType: got an unhandled gesture type."); - return QLatin1String("__unknown_gesture"); -} - -// -// QGestureRecognizerPan -// - -QGestureRecognizerPan::QGestureRecognizerPan(QObject *parent) - : QGestureRecognizer(QString(), parent), - mousePressed(false), gestureState(Qt::NoGesture), - lastDirection(Qt::NoDirection), currentDirection(Qt::NoDirection) -{ - Q_D(QGestureRecognizer); - d->gestureType = Qt::PanGesture; -} - -QGestureRecognizer::Result QGestureRecognizerPan::filterEvent(const QEvent *event) -{ - if (event->type() == QEvent::MouseButtonPress) { - const QMouseEvent *ev = static_cast(event); - if (currentDirection != Qt::NoDirection) { - DEBUG() << "Pan: MouseButtonPress: fail. another press during pan"; - reset(); - return QGestureRecognizer::NotGesture; - } - if (ev->button() != Qt::LeftButton) { - return QGestureRecognizer::NotGesture; - } - DEBUG() << "Pan: MouseButtonPress: maybe gesture started"; - mousePressed = true; - pressedPos = lastPos = currentPos = ev->pos(); - return QGestureRecognizer::MaybeGesture; - } else if (event->type() == QEvent::MouseButtonRelease) { - const QMouseEvent *ev = static_cast(event); - if (mousePressed && currentDirection != Qt::NoDirection - && ev->button() == Qt::LeftButton) { - DEBUG() << "Pan: MouseButtonRelease: pan detected"; - gestureState = Qt::GestureFinished; - currentPos = ev->pos(); - internalReset(); - return QGestureRecognizer::GestureFinished; - } - DEBUG() << "Pan: MouseButtonRelease: some weird release detected, ignoring"; - reset(); - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseMove) { - if (!mousePressed) - return QGestureRecognizer::NotGesture; - const QMouseEvent *ev = static_cast(event); - lastPos = currentPos; - currentPos = ev->pos(); - Qt::DirectionType newDirection = - simpleRecognizer.addPosition(ev->pos()).direction; - DEBUG() << "Pan: MouseMove: simplerecognizer result = " << newDirection; - QGestureRecognizer::Result result = QGestureRecognizer::NotGesture; - if (currentDirection == Qt::NoDirection) { - if (newDirection == Qt::NoDirection) { - result = QGestureRecognizer::MaybeGesture; - } else { - result = QGestureRecognizer::GestureStarted; - gestureState = Qt::GestureStarted; - } - } else { - result = QGestureRecognizer::GestureStarted; - gestureState = Qt::GestureUpdated; - } - if (newDirection != Qt::NoDirection) { - if (currentDirection != newDirection) - lastDirection = currentDirection; - currentDirection = newDirection; - } - return result; - } - return QGestureRecognizer::Ignore; -} - -QGesture* QGestureRecognizerPan::getGesture() -{ - if (currentDirection == Qt::NoDirection) - return 0; - QPanningGesturePrivate *d = gesture.d_func(); - d->startPos = pressedPos; - d->lastPos = lastPos; - d->pos = currentPos; - d->hotSpot = pressedPos; - d->state = gestureState; - d->lastDirection = lastDirection; - d->direction = currentDirection; - - return &gesture; -} - -void QGestureRecognizerPan::reset() -{ - mousePressed = false; - lastDirection = Qt::NoDirection; - currentDirection = Qt::NoDirection; - gestureState = Qt::NoGesture; - diagonalRecognizer.reset(); - simpleRecognizer.reset(); -} - -void QGestureRecognizerPan::internalReset() -{ - mousePressed = false; - diagonalRecognizer.reset(); - simpleRecognizer.reset(); -} - - -// -// QDoubleTapGestureRecognizer -// -QDoubleTapGestureRecognizer::QDoubleTapGestureRecognizer(QObject *parent) - : QGestureRecognizer(QString(), parent), - gesture(0, qt_getStandardGestureTypeName(Qt::DoubleTapGesture)) -{ - Q_D(QGestureRecognizer); - d->gestureType = Qt::DoubleTapGesture; -} - -QGestureRecognizer::Result QDoubleTapGestureRecognizer::filterEvent(const QEvent *event) -{ - if (event->type() == QEvent::MouseButtonPress) { - const QMouseEvent *ev = static_cast(event); - if (pressedPosition.isNull()) { - pressedPosition = ev->pos(); - return QGestureRecognizer::MaybeGesture; - } else if ((pressedPosition - ev->pos()).manhattanLength() < 10) { - return QGestureRecognizer::GestureFinished; - } - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseButtonRelease) { - const QMouseEvent *ev = static_cast(event); - if (!pressedPosition.isNull() && (pressedPosition - ev->pos()).manhattanLength() < 10) - return QGestureRecognizer::MaybeGesture; - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseButtonDblClick) { - const QMouseEvent *ev = static_cast(event); - pressedPosition = ev->pos(); - return QGestureRecognizer::GestureFinished; - } - return QGestureRecognizer::NotGesture; -} - -QGesture* QDoubleTapGestureRecognizer::getGesture() -{ - QGesturePrivate *d = gesture.d_func(); - d->startPos = pressedPosition; - d->lastPos = pressedPosition; - d->pos = pressedPosition; - d->hotSpot = pressedPosition; - d->state = Qt::GestureFinished; - return &gesture; -} - -void QDoubleTapGestureRecognizer::reset() -{ - pressedPosition = QPoint(); -} - -// -// QTapAndHoldGestureRecognizer -// -const int QTapAndHoldGestureRecognizer::iterationCount = 40; -const int QTapAndHoldGestureRecognizer::iterationTimeout = 50; - -QTapAndHoldGestureRecognizer::QTapAndHoldGestureRecognizer(QObject *parent) - : QGestureRecognizer(QString(), parent), - gesture(0, qt_getStandardGestureTypeName(Qt::TapAndHoldGesture)), - iteration(0) -{ - Q_D(QGestureRecognizer); - d->gestureType = Qt::TapAndHoldGesture; -} - -QGestureRecognizer::Result QTapAndHoldGestureRecognizer::filterEvent(const QEvent *event) -{ - if (event->type() == QEvent::MouseButtonPress) { - const QMouseEvent *ev = static_cast(event); - if (timer.isActive()) - timer.stop(); - timer.start(QTapAndHoldGestureRecognizer::iterationTimeout, this); - pressedPosition = ev->pos(); - return QGestureRecognizer::MaybeGesture; - } else if (event->type() == QEvent::MouseMove) { - const QMouseEvent *ev = static_cast(event); - if ((pressedPosition - ev->pos()).manhattanLength() < 15) - return QGestureRecognizer::GestureStarted; - else - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseButtonRelease) { - timer.stop(); - return QGestureRecognizer::NotGesture; - } - return QGestureRecognizer::Ignore; -} - -void QTapAndHoldGestureRecognizer::timerEvent(QTimerEvent *event) -{ - if (event->timerId() != timer.timerId()) - return; - if (iteration == QTapAndHoldGestureRecognizer::iterationCount) { - timer.stop(); - emit stateChanged(QGestureRecognizer::GestureFinished); - } else { - emit stateChanged(QGestureRecognizer::GestureStarted); - } - ++iteration; -} - -QGesture* QTapAndHoldGestureRecognizer::getGesture() -{ - QGesturePrivate *d = gesture.d_func(); - d->startPos = pressedPosition; - d->lastPos = pressedPosition; - d->pos = pressedPosition; - d->hotSpot = pressedPosition; - if (iteration >= QTapAndHoldGestureRecognizer::iterationCount) - d->state = Qt::GestureFinished; - else - d->state = iteration == 0 ? Qt::GestureStarted : Qt::GestureUpdated; - return &gesture; -} - -void QTapAndHoldGestureRecognizer::reset() -{ - pressedPosition = QPoint(); - timer.stop(); - iteration = 0; -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesturestandardrecognizers_p.h b/src/gui/kernel/qgesturestandardrecognizers_p.h deleted file mode 100644 index 8abc1fb..0000000 --- a/src/gui/kernel/qgesturestandardrecognizers_p.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGESTURESTANDARDRECOGNIZERS_P_H -#define QGESTURESTANDARDRECOGNIZERS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qevent.h" -#include "qbasictimer.h" -#include "qdebug.h" - -#include "qgesture.h" -#include "qgesturerecognizer.h" -#include "private/qdirectionrecognizer_p.h" - -QT_BEGIN_NAMESPACE - -class QGestureRecognizerPan : public QGestureRecognizer -{ - Q_OBJECT -public: - QGestureRecognizerPan(QObject *parent); - - QGestureRecognizer::Result filterEvent(const QEvent *event); - QGesture* getGesture(); - void reset(); - -private: - void internalReset(); - - QPanningGesture gesture; - - QPoint pressedPos; - QPoint lastPos; - QPoint currentPos; - bool mousePressed; - Qt::GestureState gestureState; - Qt::DirectionType lastDirection; - Qt::DirectionType currentDirection; - QDirectionDiagonalRecognizer diagonalRecognizer; - QDirectionSimpleRecognizer simpleRecognizer; -}; - -class QDoubleTapGestureRecognizer : public QGestureRecognizer -{ - Q_OBJECT -public: - QDoubleTapGestureRecognizer(QObject *parent); - - QGestureRecognizer::Result filterEvent(const QEvent *event); - QGesture* getGesture(); - void reset(); - -private: - QGesture gesture; - QPoint pressedPosition; -}; - -class QTapAndHoldGestureRecognizer : public QGestureRecognizer -{ - Q_OBJECT -public: - QTapAndHoldGestureRecognizer(QObject *parent); - - QGestureRecognizer::Result filterEvent(const QEvent *event); - QGesture* getGesture(); - void reset(); - -protected: - void timerEvent(QTimerEvent *event); - -private: - QGesture gesture; - QPoint pressedPosition; - QBasicTimer timer; - int iteration; - static const int iterationCount; - static const int iterationTimeout; -}; - -QT_END_NAMESPACE - -#endif // QGESTURESTANDARDRECOGNIZERS_P_H diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp new file mode 100644 index 0000000..c8b11c5 --- /dev/null +++ b/src/gui/kernel/qstandardgestures.cpp @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstandardgestures.h" +#include "qstandardgestures_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QPanGesture + \since 4.6 + + \brief The QPanGesture class represents a Pan gesture, + providing additional information related to panning. +*/ + +/*! + Creates a new Pan gesture handler object and marks it as a child of \a + parent. + + On some platform like Windows it's necessary to provide a non-null widget + as \a parent to get native gesture support. +*/ +QPanGesture::QPanGesture(QWidget *parent) + : QGesture(*new QPanGesturePrivate, parent) +{ +#ifdef Q_WS_WIN + if (parent) { + QApplicationPrivate* getQApplicationPrivateInternal(); + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + qAppPriv->widgetGestures[parent].pan = this; + } +#endif +} + +/*! \internal */ +bool QPanGesture::event(QEvent *event) +{ +#ifdef Q_WS_WIN + QApplicationPrivate* getQApplicationPrivateInternal(); + switch (event->type()) { + case QEvent::ParentAboutToChange: + if (QWidget *w = qobject_cast(parent())) + getQApplicationPrivateInternal()->widgetGestures[w].pan = 0; + break; + case QEvent::ParentChange: + if (QWidget *w = qobject_cast(parent())) + getQApplicationPrivateInternal()->widgetGestures[w].pan = this; + break; + default: + break; + } +#endif + return QObject::event(event); +} + +/*! \internal */ +bool QPanGesture::filterEvent(QEvent *event) +{ + Q_D(QPanGesture); + if (!event->spontaneous()) + return false; + const QTouchEvent *ev = static_cast(event); + if (event->type() == QEvent::TouchBegin) { + d->touchPoints = ev->touchPoints(); + const QPoint p = ev->touchPoints().at(0).pos().toPoint(); + setStartPos(p); + setLastPos(p); + setPos(p); + return false; + } else if (event->type() == QEvent::TouchEnd) { + if (state() != Qt::NoGesture) { + setState(Qt::GestureFinished); + setLastPos(pos()); + setPos(ev->touchPoints().at(0).pos().toPoint()); + emit triggered(); + emit finished(); + } + setState(Qt::NoGesture); + reset(); + } else if (event->type() == QEvent::TouchUpdate) { + d->touchPoints = ev->touchPoints(); + QPointF pt = d->touchPoints.at(0).pos() - d->touchPoints.at(0).startPos(); + setLastPos(pos()); + setPos(ev->touchPoints().at(0).pos().toPoint()); + if (pt.x() > 10 || pt.y() > 10 || pt.x() < -10 || pt.y() < -10) { + if (state() == Qt::NoGesture) + setState(Qt::GestureStarted); + else + setState(Qt::GestureUpdated); + emit triggered(); + } + } + return false; +} + +/*! \internal */ +void QPanGesture::reset() +{ + Q_D(QPanGesture); + d->touchPoints.clear(); +} + +/*! + \property QPanGesture::totalOffset + + Specifies a total pan offset since the start of the gesture. +*/ +QSize QPanGesture::totalOffset() const +{ + QPoint pt = pos() - startPos(); + return QSize(pt.x(), pt.y()); +} + +/*! + \property QPanGesture::lastOffset + + Specifies a pan offset since the last time the gesture was + triggered. +*/ +QSize QPanGesture::lastOffset() const +{ + QPoint pt = pos() - lastPos(); + return QSize(pt.x(), pt.y()); +} + +/*! + \class QTapAndHoldGesture + \since 4.6 + + \brief The QTapAndHoldGesture class represents a Tap-and-Hold gesture, + providing additional information. +*/ + +const int QTapAndHoldGesturePrivate::iterationCount = 40; +const int QTapAndHoldGesturePrivate::iterationTimeout = 50; + +/*! + Creates a new Tap and Hold gesture handler object and marks it as a child + of \a parent. + + On some platforms like Windows there is a system-wide tap and hold gesture + that cannot be overriden, hence the gesture might never trigger and default + context menu will be shown instead. +*/ +QTapAndHoldGesture::QTapAndHoldGesture(QWidget *parent) + : QGesture(*new QTapAndHoldGesturePrivate, parent) +{ +} + +/*! \internal */ +bool QTapAndHoldGesture::filterEvent(QEvent *event) +{ + Q_D(QTapAndHoldGesture); + if (!event->spontaneous()) + return false; + const QTouchEvent *ev = static_cast(event); + switch (event->type()) { + case QEvent::TouchBegin: { + if (d->timer.isActive()) + d->timer.stop(); + d->timer.start(QTapAndHoldGesturePrivate::iterationTimeout, this); + const QPoint p = ev->touchPoints().at(0).pos().toPoint(); + setStartPos(p); + setLastPos(p); + setPos(p); + break; + } + case QEvent::TouchUpdate: + if (ev->touchPoints().size() != 1) + reset(); + else if ((startPos() - ev->touchPoints().at(0).pos().toPoint()).manhattanLength() > 15) + reset(); + break; + case QEvent::TouchEnd: + reset(); + break; + default: + break; + } + return false; +} + +/*! \internal */ +void QTapAndHoldGesture::timerEvent(QTimerEvent *event) +{ + Q_D(QTapAndHoldGesture); + if (event->timerId() != d->timer.timerId()) + return; + if (d->iteration == QTapAndHoldGesturePrivate::iterationCount) { + d->timer.stop(); + setState(Qt::GestureFinished); + emit triggered(); + } else { + setState(Qt::GestureStarted); + emit triggered(); + } + ++d->iteration; +} + +/*! \internal */ +void QTapAndHoldGesture::reset() +{ + Q_D(QTapAndHoldGesture); + if (state() != Qt::NoGesture) + emit cancelled(); + setState(Qt::NoGesture); + d->timer.stop(); + d->iteration = 0; +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h new file mode 100644 index 0000000..db96ef6 --- /dev/null +++ b/src/gui/kernel/qstandardgestures.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTANDARDGESTURES_H +#define QSTANDARDGESTURES_H + +#include "qevent.h" +#include "qbasictimer.h" +#include "qdebug.h" + +#include "qgesture.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QPanGesturePrivate; +class Q_GUI_EXPORT QPanGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QPanGesture) + + Q_PROPERTY(QSize totalOffset READ totalOffset) + Q_PROPERTY(QSize lastOffset READ lastOffset) + +public: + QPanGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + + QSize totalOffset() const; + QSize lastOffset() const; + +protected: + bool event(QEvent *event); + +private: + friend class QWidget; +}; + +class QTapAndHoldGesturePrivate; +class Q_GUI_EXPORT QTapAndHoldGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QTapAndHoldGesture) + +public: + QTapAndHoldGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + +protected: + void timerEvent(QTimerEvent *event); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSTANDARDGESTURES_H diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h new file mode 100644 index 0000000..bb11c9f --- /dev/null +++ b/src/gui/kernel/qstandardgestures_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTANDARDGESTURES_P_H +#define QSTANDARDGESTURES_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qevent.h" +#include "qbasictimer.h" +#include "qdebug.h" + +#include "qgesture.h" +#include "qgesture_p.h" + +QT_BEGIN_NAMESPACE + +class QPanGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QPanGesture) + +public: + QPanGesturePrivate() { } + + QList touchPoints; +}; + +class QTapAndHoldGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QTapAndHoldGesture) + +public: + QTapAndHoldGesturePrivate() + : iteration(0) { } + + QBasicTimer timer; + int iteration; + static const int iterationCount; + static const int iterationTimeout; +}; + +QT_END_NAMESPACE + +#endif // QSTANDARDGESTURES_P_H diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 9a834aa..611cb44 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -82,6 +82,8 @@ #include "private/qstyle_p.h" #include "private/qinputcontext_p.h" #include "qfileinfo.h" +#include "qstandardgestures.h" +#include "qstandardgestures_p.h" #if defined (Q_WS_WIN) # include @@ -107,9 +109,9 @@ #include "private/qgraphicsproxywidget_p.h" #include "QtGui/qabstractscrollarea.h" #include "private/qabstractscrollarea_p.h" +#include "private/qevent_p.h" #include "private/qgraphicssystem_p.h" -#include "private/qgesturemanager_p.h" // widget/widget data creation count //#define QWIDGET_EXTRA_DEBUG @@ -128,8 +130,6 @@ Q_GUI_EXPORT void qt_x11_set_global_double_buffer(bool enable) } #endif -QString qt_getStandardGestureTypeName(Qt::GestureType); - static inline bool qRectIntersects(const QRect &r1, const QRect &r2) { return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) && @@ -7484,8 +7484,6 @@ bool QWidget::event(QEvent *event) #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: #endif - case QEvent::Gesture: - return false; default: break; } @@ -7880,9 +7878,6 @@ bool QWidget::event(QEvent *event) d->needWindowChange = false; break; #endif - case QEvent::Gesture: - event->ignore(); - break; case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: @@ -7920,6 +7915,59 @@ bool QWidget::event(QEvent *event) (void) QApplication::sendEvent(this, &mouseEvent); break; } +#ifdef Q_WS_WIN + case QEvent::WinGesture: { + QWinGestureEvent *ev = static_cast(event); + QApplicationPrivate *qAppPriv = qApp->d_func(); + QApplicationPrivate::WidgetStandardGesturesMap::iterator it; + it = qAppPriv->widgetGestures.find(this); + if (it != qAppPriv->widgetGestures.end()) { + Qt::GestureState state = Qt::GestureUpdated; + if (qAppPriv->lastGestureId == 0) + state = Qt::GestureStarted; + QWinGestureEvent::Type type = ev->gestureType; + if (ev->gestureType == QWinGestureEvent::GestureEnd) { + type = (QWinGestureEvent::Type)qAppPriv->lastGestureId; + state = Qt::GestureFinished; + } + + QGesture *gesture = 0; + switch (type) { + case QWinGestureEvent::Pan: { + QPanGesture *pan = it.value().pan; + gesture = pan; + if (state == Qt::GestureStarted) { + gesture->setStartPos(ev->position); + gesture->setLastPos(ev->position); + } else { + gesture->setLastPos(gesture->pos()); + } + gesture->setPos(ev->position); + break; + } + case QWinGestureEvent::Pinch: + break; + default: + break; + } + if (gesture) { + gesture->setState(state); + if (state == Qt::GestureStarted) + emit gesture->started(); + emit gesture->triggered(); + if (state == Qt::GestureFinished) + emit gesture->finished(); + event->accept(); + } + if (ev->gestureType == QWinGestureEvent::GestureEnd) { + qAppPriv->lastGestureId = 0; + } else { + qAppPriv->lastGestureId = type; + } + } + break; + } +#endif #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast(event)->propertyName(); @@ -11016,105 +11064,6 @@ QWindowSurface *QWidget::windowSurface() const return bs ? bs->windowSurface : 0; } -/*! - \since 4.6 - - Subscribes the widget to the specified \a gesture type. - - Returns the id of the gesture. - - \sa releaseGesture(), setGestureEnabled() -*/ -int QWidget::grabGesture(const QString &gesture) -{ - Q_D(QWidget); - int id = d->grabGesture(QGestureManager::instance()->makeGestureId(gesture)); - if (d->extra && d->extra->proxyWidget) - d->extra->proxyWidget->QGraphicsItem::d_ptr->grabGesture(id); - return id; -} - -int QWidgetPrivate::grabGesture(int gestureId) -{ - gestures << gestureId; - ++qApp->d_func()->grabbedGestures[QGestureManager::instance()->gestureNameFromId(gestureId)]; - return gestureId; -} - -bool QWidgetPrivate::releaseGesture(int gestureId) -{ - QApplicationPrivate *qAppPriv = qApp->d_func(); - if (gestures.contains(gestureId)) { - QString name = QGestureManager::instance()->gestureNameFromId(gestureId); - Q_ASSERT(qAppPriv->grabbedGestures[name] > 0); - --qAppPriv->grabbedGestures[name]; - gestures.remove(gestureId); - return true; - } - return false; -} - -bool QWidgetPrivate::hasGesture(const QString &name) const -{ - QGestureManager *gm = QGestureManager::instance(); - QSet::const_iterator it = gestures.begin(), - e = gestures.end(); - for (; it != e; ++it) { - if (gm->gestureNameFromId(*it) == name) - return true; - } - return false; -} - -/*! - \since 4.6 - - Subscribes the widget to the specified \a gesture type. - - Returns the id of the gesture. - - \sa releaseGesture(), setGestureEnabled() -*/ -int QWidget::grabGesture(Qt::GestureType gesture) -{ - return grabGesture(qt_getStandardGestureTypeName(gesture)); -} - -/*! - \since 4.6 - - Unsubscribes the widget from a gesture, which is specified by the - \a gestureId. - - \sa grabGesture(), setGestureEnabled() -*/ -void QWidget::releaseGesture(int gestureId) -{ - Q_D(QWidget); - if (d->releaseGesture(gestureId)) { - if (d->extra && d->extra->proxyWidget) - d->extra->proxyWidget->QGraphicsItem::d_ptr->releaseGesture(gestureId); - QGestureManager::instance()->releaseGestureId(gestureId); - } -} - -/*! - \since 4.6 - - If \a enable is true, the gesture with the given \a gestureId is - enabled; otherwise the gesture is disabled. - - The id of the gesture is returned by the grabGesture(). - - \sa grabGesture(), releaseGesture() -*/ -void QWidget::setGestureEnabled(int gestureId, bool enable) -{ - Q_UNUSED(gestureId); - Q_UNUSED(enable); - //### -} - void QWidgetPrivate::getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const { if (left) diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 1667275..bc9952c 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -90,7 +90,6 @@ class QDragLeaveEvent; class QDropEvent; class QShowEvent; class QHideEvent; -class QGestureEvent; class QInputContext; class QIcon; class QWindowSurface; @@ -612,11 +611,6 @@ public: void setWindowSurface(QWindowSurface *surface); QWindowSurface *windowSurface() const; - int grabGesture(const QString &gesture); - int grabGesture(Qt::GestureType gesture); - void releaseGesture(int gestureId); - void setGestureEnabled(int gestureId, bool enable = true); - Q_SIGNALS: void customContextMenuRequested(const QPoint &pos); @@ -752,7 +746,6 @@ private: friend bool isWidgetOpaque(const QWidget *); friend class QGLWidgetPrivate; #endif - friend class QGestureManager; #ifdef Q_WS_X11 friend void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp); friend void qt_net_remove_user_time(QWidget *tlw); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 7385e83..626950e 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -523,11 +523,6 @@ public: QList actions; #endif - QSet gestures; - int grabGesture(int gestureId); - bool releaseGesture(int gestureId); - bool hasGesture(const QString &type) const; - // Bit fields. uint high_attributes[3]; // the low ones are in QWidget::widget_attributes QPalette::ColorRole fg_role : 8; diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index e1beb98..66572b8 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -51,10 +51,13 @@ #include "qdebug.h" #include "qboxlayout.h" #include "qpainter.h" +#include "qstandardgestures.h" #include "qabstractscrollarea_p.h" #include +#include + #ifdef Q_WS_MAC #include #include @@ -157,6 +160,9 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate() :hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded), viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0), xoffset(0), yoffset(0), viewportFilter(0) +#ifdef Q_WS_WIN + , singleFingerPanEnabled(false) +#endif { } @@ -290,6 +296,31 @@ void QAbstractScrollAreaPrivate::init() layoutChildren(); } +void QAbstractScrollAreaPrivate::setupGestures() +{ +#ifdef Q_OS_WIN + if (!viewport) + return; + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn + || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum())); + + bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn + || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); + if (qAppPriv->SetGestureConfig && (needh || needv)) { + GESTURECONFIG gc[1]; + gc[0].dwID = GID_PAN; + gc[0].dwWant = GC_PAN; + gc[0].dwBlock = 0; + if (needv && singleFingerPanEnabled) + gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; + if (needh && singleFingerPanEnabled) + gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; + qAppPriv->SetGestureConfig(viewport->winId(), 0, 1, gc, sizeof(gc)); + } +#endif // Q_OS_WIN +} + void QAbstractScrollAreaPrivate::layoutChildren() { Q_Q(QAbstractScrollArea); @@ -909,8 +940,6 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::DragMove: case QEvent::DragLeave: #endif - case QEvent::Gesture: - return false; case QEvent::StyleChange: case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: @@ -1239,6 +1268,7 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y) void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars() { layoutChildren(); + setupGestures(); } QPoint QAbstractScrollAreaPrivate::contentsOffset() const diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 71a83cc..5d3494b 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -99,6 +99,11 @@ public: inline bool viewportEvent(QEvent *event) { return q_func()->viewportEvent(event); } QObject *viewportFilter; + +#ifdef Q_WS_WIN + bool singleFingerPanEnabled; +#endif + void setupGestures(); }; class QAbstractScrollAreaFilter : public QObject diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index bab6b89..c9d1d6e 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -66,6 +66,8 @@ #include #include +#include + #include #ifndef QT_NO_TEXTEDIT @@ -726,6 +728,9 @@ QPlainTextEditPrivate::QPlainTextEditPrivate() backgroundVisible = false; centerOnScroll = false; inDrag = false; +#ifdef Q_WS_WIN + singleFingerPanEnabled = true; +#endif } @@ -781,6 +786,9 @@ void QPlainTextEditPrivate::init(const QString &txt) #ifndef QT_NO_CURSOR viewport->setCursor(Qt::IBeamCursor); #endif + originalOffsetY = 0; + panGesture = new QPanGesture(q); + QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); } void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect) @@ -2899,6 +2907,30 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons (\a available is true) or unavailable (\a available is false). */ +void QPlainTextEditPrivate::_q_gestureTriggered() +{ + Q_Q(QPlainTextEdit); + QPanGesture *g = qobject_cast(q->sender()); + if (!g) + return; + QScrollBar *hBar = q->horizontalScrollBar(); + QScrollBar *vBar = q->verticalScrollBar(); + if (g->state() == Qt::GestureStarted) + originalOffsetY = vBar->value(); + QSize totalOffset = g->totalOffset(); + if (!totalOffset.isNull()) { + if (QApplication::isRightToLeft()) + totalOffset.rwidth() *= -1; + // QPlainTextEdit scrolls by lines only in vertical direction + QFontMetrics fm(q->document()->defaultFont()); + int lineHeight = fm.height(); + int newX = hBar->value() - g->lastOffset().width(); + int newY = originalOffsetY - totalOffset.height()/lineHeight; + hbar->setValue(newX); + vbar->setValue(newY); + } +} + QT_END_NAMESPACE #include "moc_qplaintextedit.cpp" diff --git a/src/gui/widgets/qplaintextedit.h b/src/gui/widgets/qplaintextedit.h index dc0851b..35bbc37 100644 --- a/src/gui/widgets/qplaintextedit.h +++ b/src/gui/widgets/qplaintextedit.h @@ -269,6 +269,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars()) Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int)) Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered()) friend class QPlainTextEditControl; }; diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h index 5075fc4..ae584e0 100644 --- a/src/gui/widgets/qplaintextedit_p.h +++ b/src/gui/widgets/qplaintextedit_p.h @@ -72,6 +72,7 @@ class QMimeData; class QPlainTextEdit; class ExtraArea; +class QPanGesture; class QPlainTextEditControl : public QTextControl { @@ -173,6 +174,10 @@ public: void _q_cursorPositionChanged(); void _q_modificationChanged(bool); + + void _q_gestureTriggered(); + int originalOffsetY; + QPanGesture *panGesture; }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index c8d8d04..e80df92 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -67,6 +67,8 @@ #include #include +#include + #include #endif @@ -111,6 +113,9 @@ QTextEditPrivate::QTextEditPrivate() preferRichText = false; showCursorOnInitialShow = true; inDrag = false; +#ifdef Q_WS_WIN + singleFingerPanEnabled = true; +#endif } void QTextEditPrivate::createAutoBulletList() @@ -178,6 +183,8 @@ void QTextEditPrivate::init(const QString &html) #ifndef QT_NO_CURSOR viewport->setCursor(Qt::IBeamCursor); #endif + panGesture = new QPanGesture(q); + QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); } void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect) @@ -2610,6 +2617,25 @@ void QTextEdit::ensureCursorVisible() d->control->ensureCursorVisible(); } +void QTextEditPrivate::_q_gestureTriggered() +{ + Q_Q(QTextEdit); + QPanGesture *g = qobject_cast(q->sender()); + if (!g) + return; + QScrollBar *hBar = q->horizontalScrollBar(); + QScrollBar *vBar = q->verticalScrollBar(); + QPoint delta = g->pos() - (g->lastPos().isNull() ? g->pos() : g->lastPos()); + if (!delta.isNull()) { + if (QApplication::isRightToLeft()) + delta.rx() *= -1; + int newX = hBar->value() - delta.x(); + int newY = vBar->value() - delta.y(); + hbar->setValue(newX); + vbar->setValue(newY); + } +} + /*! \enum QTextEdit::KeyboardAction diff --git a/src/gui/widgets/qtextedit.h b/src/gui/widgets/qtextedit.h index 617822a..9e10e07 100644 --- a/src/gui/widgets/qtextedit.h +++ b/src/gui/widgets/qtextedit.h @@ -414,6 +414,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_currentCharFormatChanged(const QTextCharFormat &)) Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars()) Q_PRIVATE_SLOT(d_func(), void _q_ensureVisible(const QRectF &)) + Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered()) friend class QTextEditControl; friend class QTextDocument; friend class QTextControl; diff --git a/src/gui/widgets/qtextedit_p.h b/src/gui/widgets/qtextedit_p.h index e7609d6..249331e 100644 --- a/src/gui/widgets/qtextedit_p.h +++ b/src/gui/widgets/qtextedit_p.h @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_TEXTEDIT class QMimeData; - +class QPanGesture; class QTextEditPrivate : public QAbstractScrollAreaPrivate { Q_DECLARE_PUBLIC(QTextEdit) @@ -129,6 +129,9 @@ public: QString anchorToScrollToWhenVisible; + void _q_gestureTriggered(); + QPanGesture *panGesture; + #ifdef QT_KEYPAD_NAVIGATION QBasicTimer deleteAllTimer; #endif diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 6d3bc0a..d2ef64a 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -140,6 +140,13 @@ struct GestureState last.secondfinger.lastPoint = TouchPoint(); last.secondfinger.point = TouchPoint(); last.secondfinger.offset = QPoint(); + last.pan.delivered = false; + last.pan.startPoints[0] = TouchPoint(); + last.pan.startPoints[1] = TouchPoint(); + last.pan.lastPoints[0] = TouchPoint(); + last.pan.lastPoints[1] = TouchPoint(); + last.pan.points[0] = TouchPoint(); + last.pan.points[1] = TouchPoint(); last.cancelled.clear(); } }; @@ -760,7 +767,8 @@ void tst_Gestures::simpleGraphicsItem() scene.addItem(item); QApplication::processEvents(); - SingleshotEvent event(50, 80); + QPoint pt = view.mapFromScene(item->mapToScene(30, 30)); + SingleshotEvent event(pt.x(), pt.y()); sendSpontaneousEvent(&view, &event); QVERIFY(item->gesture.seenGestureEvent); QVERIFY(scene.gesture.seenGestureEvent); @@ -771,7 +779,9 @@ void tst_Gestures::simpleGraphicsItem() mainWidget->reset(); item->shouldAcceptSingleshotGesture = false; - SingleshotEvent event2(20, 40); + // outside of the graphicsitem + pt = view.mapFromScene(item->mapToScene(-10, -10)); + SingleshotEvent event2(pt.x(), pt.y()); sendSpontaneousEvent(&view, &event2); QVERIFY(!item->gesture.seenGestureEvent); QVERIFY(scene.gesture.seenGestureEvent); @@ -790,9 +800,11 @@ void tst_Gestures::overlappingGraphicsItems() scene.addItem(item); GraphicsItem *subitem1 = new GraphicsItem(50, 70); subitem1->setPos(70, 70); + subitem1->setZValue(1); scene.addItem(subitem1); GraphicsItem *subitem2 = new GraphicsItem(50, 70); subitem2->setPos(250, 70); + subitem2->setZValue(1); scene.addItem(subitem2); QApplication::processEvents(); @@ -802,13 +814,14 @@ void tst_Gestures::overlappingGraphicsItems() subitem1->grabSingleshotGesture(); subitem2->grabSecondFingerGesture(); - SingleshotEvent event(100, 100); + QPoint pt = view.mapFromScene(subitem1->mapToScene(20, 20)); + SingleshotEvent event(pt.x(), pt.y()); sendSpontaneousEvent(&view, &event); - QVERIFY(subitem1->gesture.seenGestureEvent); + QVERIFY(scene.gesture.seenGestureEvent); QVERIFY(!subitem2->gesture.seenGestureEvent); QVERIFY(!item->gesture.seenGestureEvent); - QVERIFY(scene.gesture.seenGestureEvent); QVERIFY(!mainWidget->gesture.seenGestureEvent); + QVERIFY(subitem1->gesture.seenGestureEvent); QVERIFY(subitem1->gesture.last.singleshot.delivered); item->reset(); @@ -818,12 +831,12 @@ void tst_Gestures::overlappingGraphicsItems() mainWidget->reset(); subitem1->shouldAcceptSingleshotGesture = false; - SingleshotEvent event2(100, 100); + SingleshotEvent event2(pt.x(), pt.y()); sendSpontaneousEvent(&view, &event2); - QVERIFY(subitem1->gesture.seenGestureEvent); + QVERIFY(scene.gesture.seenGestureEvent); QVERIFY(!subitem2->gesture.seenGestureEvent); + QVERIFY(subitem1->gesture.seenGestureEvent); QVERIFY(item->gesture.seenGestureEvent); - QVERIFY(scene.gesture.seenGestureEvent); QVERIFY(!mainWidget->gesture.seenGestureEvent); QVERIFY(subitem1->gesture.last.singleshot.delivered); QVERIFY(item->gesture.last.singleshot.delivered); -- cgit v0.12 From 69b4be80a445985bdb8632dab4104236fe9b054d Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Tue, 30 Jun 2009 11:42:02 +0200 Subject: Benchmark test for quaternion multiplication. Reviewed-by: Rhys Weatherley --- tests/benchmarks/qquaternion/qquaternion.pro | 6 ++ tests/benchmarks/qquaternion/tst_qquaternion.cpp | 124 +++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 tests/benchmarks/qquaternion/qquaternion.pro create mode 100644 tests/benchmarks/qquaternion/tst_qquaternion.cpp diff --git a/tests/benchmarks/qquaternion/qquaternion.pro b/tests/benchmarks/qquaternion/qquaternion.pro new file mode 100644 index 0000000..cd68423 --- /dev/null +++ b/tests/benchmarks/qquaternion/qquaternion.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qquaternion + +SOURCES += tst_qquaternion.cpp + diff --git a/tests/benchmarks/qquaternion/tst_qquaternion.cpp b/tests/benchmarks/qquaternion/tst_qquaternion.cpp new file mode 100644 index 0000000..eaacf74 --- /dev/null +++ b/tests/benchmarks/qquaternion/tst_qquaternion.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +//TESTED_FILES= + +class tst_QQuaternion : public QObject +{ + Q_OBJECT + +public: + tst_QQuaternion(); + virtual ~tst_QQuaternion(); + +public slots: + void init(); + void cleanup(); + +private slots: + void multiply_data(); + void multiply(); +}; + +tst_QQuaternion::tst_QQuaternion() +{ +} + +tst_QQuaternion::~tst_QQuaternion() +{ +} + +void tst_QQuaternion::init() +{ +} + +void tst_QQuaternion::cleanup() +{ +} + +void tst_QQuaternion::multiply_data() +{ + QTest::addColumn("x1"); + QTest::addColumn("y1"); + QTest::addColumn("z1"); + QTest::addColumn("w1"); + QTest::addColumn("x2"); + QTest::addColumn("y2"); + QTest::addColumn("z2"); + QTest::addColumn("w2"); + + QTest::newRow("null") + << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f + << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; + + QTest::newRow("unitvec") + << (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f + << (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << (qreal)1.0f; + + QTest::newRow("complex") + << (qreal)1.0f << (qreal)2.0f << (qreal)3.0f << (qreal)7.0f + << (qreal)4.0f << (qreal)5.0f << (qreal)6.0f << (qreal)8.0f; +} + +void tst_QQuaternion::multiply() +{ + QFETCH(qreal, x1); + QFETCH(qreal, y1); + QFETCH(qreal, z1); + QFETCH(qreal, w1); + QFETCH(qreal, x2); + QFETCH(qreal, y2); + QFETCH(qreal, z2); + QFETCH(qreal, w2); + + QQuaternion q1(w1, x1, y1, z1); + QQuaternion q2(w2, x2, y2, z2); + + QBENCHMARK { + QQuaternion q3 = q1 * q2; + } +} + +QTEST_MAIN(tst_QQuaternion) +#include "tst_qquaternion.moc" -- cgit v0.12 From 8f7ed011e38021f19f50b22d8a5c00d8ccd366ed Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 2 Jul 2009 15:55:19 +0200 Subject: QPlainTextEdit pixel dust redrawing problem on clear() With document margins, the mapping from content-coordinates to visual coordinates went wrong. --- src/gui/widgets/qplaintextedit.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index c9d1d6e..82026d4 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -252,7 +252,7 @@ QPlainTextDocumentLayoutPrivate *QPlainTextDocumentLayout::priv() const */ void QPlainTextDocumentLayout::requestUpdate() { - emit update(QRectF(0., -4., 1000000000., 1000000000.)); + emit update(QRectF(0., -document()->documentMargin(), 1000000000., 1000000000.)); } @@ -347,8 +347,7 @@ void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, i } if (!d->blockUpdate) - emit update(); // optimization potential - + emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential } -- cgit v0.12 From 9c64e8f7a5e19e241deaa7e426534dc6761a6890 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 2 Jul 2009 11:47:10 -0700 Subject: Better debug output for QDirectFBPaintEngine Add unsupportedCompositionMode to the output. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index e4ce230..df341fb 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -81,7 +81,7 @@ template <> inline const bool* ptr(const bool &) { return 0; } template static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, int scale, bool matrixRotShear, bool simplePen, - bool dfbHandledClip, + bool dfbHandledClip, bool unsupportedCompositionMode, const char *nameOne, const T1 &one, const char *nameTwo, const T2 &two, const char *nameThree, const T3 &three) @@ -98,7 +98,8 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * dbg << "scale" << scale << "matrixRotShear" << matrixRotShear << "simplePen" << simplePen - << "dfbHandledClip" << dfbHandledClip; + << "dfbHandledClip" << dfbHandledClip + << "unsupportedCompositionMode" << unsupportedCompositionMode; const T1 *t1 = ptr(one); const T2 *t2 = ptr(two); @@ -124,6 +125,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * __FUNCTION__, state()->painter->device(), \ d_func()->scale, d_func()->matrixRotShear, \ d_func()->simplePen, d_func()->dfbCanHandleClip(), \ + d_func()->unsupportedCompositionMode, \ #one, one, #two, two, #three, three); \ if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS)) \ return; @@ -138,6 +140,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * __FUNCTION__, state()->painter->device(), \ d_func()->scale, d_func()->matrixRotShear, \ d_func()->simplePen, d_func()->dfbCanHandleClip(), \ + d_func()->unsupportedCompositionMode, \ #one, one, #two, two, #three, three); #else #define RASTERFALLBACK(op, one, two, three) -- cgit v0.12 From b0f18119b4559a2b425222c2d63671422c014783 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 2 Jul 2009 18:25:03 -0700 Subject: QDirectFBPaintEngine return if destRect is null Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index df341fb..947cc76 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -1062,6 +1062,8 @@ void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s, { const QRect sr = src.toRect(); const QRect dr = transform.mapRect(dest).toRect(); + if (dr.isEmpty()) + return; const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; DFBResult result; -- cgit v0.12 From 1866485e46039d51ea78a6d672b678aa02f68eef Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Fri, 3 Jul 2009 11:51:49 +1000 Subject: Fixed compile of QtCore with some exotic GNU toolchains. Fixes: corelib/kernel/qcore_unix_p.h:127: error: `O_CLOEXEC' undeclared Some toolchains claim to provide glibc >= 2.4 but do not define O_CLOEXEC. An alternative fix might be to define O_CLOEXEC ourselves as we do with some of the system call numbers. --- src/corelib/kernel/qcore_unix_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 1f3fe39..61d8401 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -71,7 +71,7 @@ struct sockaddr; QT_BEGIN_NAMESPACE -#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 +#if defined(Q_OS_LINUX) && defined(O_CLOEXEC) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 // Linux supports thread-safe FD_CLOEXEC # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 -- cgit v0.12 From 5b701c1bbbbf4993117bd0311717b73fafae02fd Mon Sep 17 00:00:00 2001 From: Bill King Date: Fri, 3 Jul 2009 13:08:17 +1000 Subject: Fixes invalid length for numeric fields in oracle. When the precisionpolicy is high, and the field is numeric, it was getting confused as a string field and pulling the wrong length value. --- src/sql/drivers/oci/qsql_oci.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index 8d34dd8..1ffd999 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -611,7 +611,7 @@ static QSqlField qFromOraInf(const OraFieldInfo &ofi) QSqlField f(ofi.name, ofi.type); f.setRequired(ofi.oraIsNull == 0); - if (ofi.type == QVariant::String) + if (ofi.type == QVariant::String && ofi.oraType != SQLT_NUM && ofi.oraType != SQLT_VNU) f.setLength(ofi.oraFieldLength); else f.setLength(ofi.oraPrecision == 0 ? 38 : int(ofi.oraPrecision)); -- cgit v0.12 From e0912dad8095adb8da4bd27128a5baacfda59eb5 Mon Sep 17 00:00:00 2001 From: Bill King Date: Fri, 3 Jul 2009 15:31:54 +1000 Subject: Fixes ::record for dialect 3 named tables in interbase/firebird. The comparison was mistakenly only uppercasing one side, so mixed case table names were reporting back as if they weren't found for both QSqlDatabase::record() and QSqlDatabase::primaryIndex() --- src/sql/drivers/ibase/qsql_ibase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp index 0033418..5e94c81 100644 --- a/src/sql/drivers/ibase/qsql_ibase.cpp +++ b/src/sql/drivers/ibase/qsql_ibase.cpp @@ -1583,7 +1583,7 @@ QSqlRecord QIBaseDriver::record(const QString& tablename) const "b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG " "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b " "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE " - "AND a.RDB$RELATION_NAME = '") + tablename.toUpper() + QLatin1String("' " + "AND UPPER(a.RDB$RELATION_NAME) = '") + tablename.toUpper() + QLatin1String("' " "ORDER BY a.RDB$FIELD_POSITION")); while (q.next()) { @@ -1616,7 +1616,7 @@ QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const q.exec(QLatin1String("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE, d.RDB$FIELD_SCALE " "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d " "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' " - "AND a.RDB$RELATION_NAME = '") + table.toUpper() + + "AND UPPER(a.RDB$RELATION_NAME) = '") + table.toUpper() + QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME " "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME " "AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME " -- cgit v0.12 From 238c5e3025d8f48dd73f1c4060d08701444eac0d Mon Sep 17 00:00:00 2001 From: Bill King Date: Fri, 3 Jul 2009 15:34:44 +1000 Subject: Fix up two more qsqldatabase autotests. --- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 28a2191..21064c3 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -188,7 +188,7 @@ private slots: void oci_fieldLength_data() { generic_data("QOCI"); } void oci_fieldLength(); - void sqlite_bindAndFetchUInt_data() { generic_data("QSQLITE3"); } + void sqlite_bindAndFetchUInt_data() { generic_data("QSQLITE"); } void sqlite_bindAndFetchUInt(); void sqlStatementUseIsNull_189093_data() { generic_data(); } @@ -1526,6 +1526,7 @@ void tst_QSqlDatabase::psql_escapedIdentifiers() QString field1Name = QString("fIeLdNaMe"); QString field2Name = QString("ZuLu"); + q.exec(QString("DROP SCHEMA \"%1\" CASCADE").arg(schemaName)); QString createSchema = QString("CREATE SCHEMA \"%1\"").arg(schemaName); QVERIFY_SQL(q, exec(createSchema)); QString createTable = QString("CREATE TABLE \"%1\".\"%2\" (\"%3\" int PRIMARY KEY, \"%4\" varchar(20))").arg(schemaName).arg(tableName).arg(field1Name).arg(field2Name); @@ -1681,6 +1682,8 @@ void tst_QSqlDatabase::precisionPolicy() q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt32); QVERIFY_SQL(q, exec(query)); + if(db.driverName().startsWith("QOCI")) + QEXPECT_FAIL("", "Oracle fails to move to next when data columns are oversize", Abort); QVERIFY_SQL(q, next()); QCOMPARE(q.value(0).type(), QVariant::Invalid); } @@ -2262,6 +2265,10 @@ void tst_QSqlDatabase::sqlite_bindAndFetchUInt() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + if (db.driverName().startsWith("QSQLITE2")) { + QSKIP("SQLite3 specific test", SkipSingle); + return; + } QSqlQuery q(db); QString tableName = qTableName("uint_test"); -- cgit v0.12 From 1752e03a97cc16dd653d68d5a4bcf24024c59980 Mon Sep 17 00:00:00 2001 From: Keith Isdale Date: Fri, 3 Jul 2009 16:46:54 +1000 Subject: Do not specify the output file when generating Visual Studio Project Files files with qmake. The correct file extension for generated file is best left to qmake to decide. --- doc/src/snippets/code/doc_src_qmake-manual.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/snippets/code/doc_src_qmake-manual.qdoc b/doc/src/snippets/code/doc_src_qmake-manual.qdoc index edb66bc..82c710d 100644 --- a/doc/src/snippets/code/doc_src_qmake-manual.qdoc +++ b/doc/src/snippets/code/doc_src_qmake-manual.qdoc @@ -689,7 +689,7 @@ qmake -o Makefile hello.pro //! [115] -qmake -tp vc -o hello.dsp hello.pro +qmake -tp vc hello.pro //! [115] -- cgit v0.12 From 012d133b2093e0949872263297c23277d0ce30d9 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Fri, 3 Jul 2009 16:47:56 +1000 Subject: Fixed dead code possibly leading to crash. Looks like this `&&' was meant to be `||'. QNetworkProxy::FtpCachingProxy is 5 so it's clearly impossible for type to be less than 0 and greater than QNetworkProxy::FtpCachingProxy. Reviewed-by: Aaron Kennedy --- src/network/kernel/qnetworkproxy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index c2743ef..103b948 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -366,7 +366,7 @@ static QNetworkProxy::Capabilities defaultCapabilitiesForType(QNetworkProxy::Pro int(QNetworkProxy::HostNameLookupCapability)), }; - if (int(type) < 0 && int(type) > int(QNetworkProxy::FtpCachingProxy)) + if (int(type) < 0 || int(type) > int(QNetworkProxy::FtpCachingProxy)) type = QNetworkProxy::DefaultProxy; return QNetworkProxy::Capabilities(defaults[int(type)]); } -- cgit v0.12 From 95e4c95d28be9bc9d94685f7a13e36cbf57bf74e Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 3 Jul 2009 10:08:25 +0200 Subject: doc: Corrected several qdoc warnings. --- doc/src/qmake-manual.qdoc | 5 +++-- src/corelib/tools/qsharedpointer.cpp | 6 +++--- src/dbus/qdbuserror.cpp | 10 +++++++++- src/gui/kernel/qgesture.cpp | 7 +++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index 42921db..5b261ab 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -1037,8 +1037,9 @@ (see \l{LibDepend}{Library Dependencies} for more info). \endtable - Please note that \c create_prl is required when \i {building} a static library, - while \c link_prl is required when \i {using} a static library. + Please note that \c create_prl is required when \e {building} a + static library, while \c link_prl is required when \e {using} a + static library. On Windows (or if Qt is configured with \c{-debug_and_release}, adding the \c build_all option to the \c CONFIG variable makes this rule the default diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 71bf318..fe3d9e0 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -342,7 +342,7 @@ /*! \fn QSharedPointer QSharedPointer::objectCast() const - Performs a \ref qobject_cast from this pointer's type to \tt X and + Performs a \l qobject_cast() from this pointer's type to \tt X and returns a QSharedPointer that shares the reference. If this function is used to up-cast, then QSharedPointer will perform a \tt qobject_cast, which means that if the object being pointed by this @@ -739,7 +739,7 @@ \relates QSharedPointer Returns a shared pointer to the pointer held by \a other, using a - \ref qobject_cast to type \tt X to obtain an internal pointer of the + \l qobject_cast() to type \tt X to obtain an internal pointer of the appropriate type. If the \tt qobject_cast fails, the object returned will be null. @@ -756,7 +756,7 @@ \relates QWeakPointer Returns a shared pointer to the pointer held by \a other, using a - \ref qobject_cast to type \tt X to obtain an internal pointer of the + \l qobject_cast() to type \tt X to obtain an internal pointer of the appropriate type. If the \tt qobject_cast fails, the object returned will be null. diff --git a/src/dbus/qdbuserror.cpp b/src/dbus/qdbuserror.cpp index b2d21ec..caa2437 100644 --- a/src/dbus/qdbuserror.cpp +++ b/src/dbus/qdbuserror.cpp @@ -225,8 +225,16 @@ static inline QDBusError::ErrorType get(const char *name) \value UnknownInterface The interface is not known \value InternalError An internal error occurred (\c com.trolltech.QtDBus.Error.InternalError) - \value UnknownObject The remote object could not be found. + \value InvalidObjectPath The object path provided is invalid. + + \value InvalidService The service requested is invalid. + + \value InvalidMember The member is invalid. + + \value InvalidInterface The interface is invalid. + + \value UnknownObject The remote object could not be found. */ /*! diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 32a219c..d53b419 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -187,11 +187,18 @@ bool QGesture::eventFilter(QObject *receiver, QEvent *event) \brief The current state of the gesture. */ + +/*! + Returns the gesture recognition state. + */ Qt::GestureState QGesture::state() const { return d_func()->state; } +/*! + Sets this gesture's recognition state to \a state. + */ void QGesture::setState(Qt::GestureState state) { d_func()->state = state; -- cgit v0.12 From d64d961c7242d22a4d71b376e9dcbbb3a7061a9e Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 3 Jul 2009 11:21:58 +0200 Subject: QToolBar: avoid repaints when entering/leaving a toolbar HoverEnter/Leave now do nothing. Task-number: 256103 --- src/gui/widgets/qtoolbar.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index 3414b4f..b249915 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -1145,6 +1145,10 @@ bool QToolBar::event(QEvent *event) if (d->mouseReleaseEvent(static_cast(event))) return true; break; + case QEvent::HoverEnter: + case QEvent::HoverLeave: + // there's nothing special to do here and we don't want to update the whole widget + return true; case QEvent::HoverMove: { #ifndef QT_NO_CURSOR QHoverEvent *e = static_cast(event); -- cgit v0.12 From 88a0857ac76c803d4f88204fe74448e140bbf300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Riku=20Palom=C3=A4ki?= Date: Fri, 3 Jul 2009 11:28:07 +0200 Subject: Fix QX11Embed* with x86_64 by reading prop_return as long. Even though the _XEMBED_INFO property uses 32 bit values, prop_return has 64-bit padded values in 64-bit applications, see man XChangeProperty. Without this fix the XEMBED client will read XEMBED_MAPPED wrong and unmap (hide) itself. Merge-request: 797 Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qx11embed_x11.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/gui/kernel/qx11embed_x11.cpp index 3ddde1b..659331f 100644 --- a/src/gui/kernel/qx11embed_x11.cpp +++ b/src/gui/kernel/qx11embed_x11.cpp @@ -826,7 +826,7 @@ bool QX11EmbedWidget::x11Event(XEvent *event) &actual_format_return, &nitems_return, &bytes_after_return, &prop_return) == Success) { if (nitems_return > 1) { - if (((int * )prop_return)[1] & XEMBED_MAPPED) { + if (((long * )prop_return)[1] & XEMBED_MAPPED) { XMapWindow(x11Info().display(), internalWinId()); } else { XUnmapWindow(x11Info().display(), internalWinId()); @@ -1670,9 +1670,9 @@ void QX11EmbedContainerPrivate::acceptClient(WId window) // Clients with the _XEMBED_INFO property are XEMBED clients. clientIsXEmbed = true; - unsigned int *p = (unsigned int *)prop_return; + long *p = (long *)prop_return; if (nitems_return >= 2) - clientversion = p[0]; + clientversion = (unsigned int)p[0]; } XFree(prop_return); -- cgit v0.12 From 9b4234d567804e8f503951e8d0c96e95f5dbec48 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 3 Jul 2009 13:45:49 +0200 Subject: Enabled double buffering of window surfaces on Windows. Without this, QWindowSurface::flush() doesn't work. Reviewed-by: Samuel --- src/opengl/qwindowsurface_gl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 3a7a07e..eec725e 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -171,7 +171,7 @@ QGLGraphicsSystem::QGLGraphicsSystem() } } #elif defined(Q_WS_WIN) - QGLWindowSurface::surfaceFormat.setDoubleBuffer(false); + QGLWindowSurface::surfaceFormat.setDoubleBuffer(true); qt_win_owndc_required = true; #endif -- cgit v0.12 From 460e204c5b96cb67244bd9463ca0dfa56ad02564 Mon Sep 17 00:00:00 2001 From: Trond Kjernaasen Date: Fri, 3 Jul 2009 13:29:43 +0200 Subject: Replace usage of the old, obsolete PrintDlg with PrintDlgEx. Since we don't support Windows versions < Win 2000, we can just go ahead and replace usage of the old compat dialog. Task-number: 222417 Reviewed-by: Prasanth --- src/gui/dialogs/qprintdialog_win.cpp | 79 +++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/src/gui/dialogs/qprintdialog_win.cpp b/src/gui/dialogs/qprintdialog_win.cpp index 6022a66..115cd8d 100644 --- a/src/gui/dialogs/qprintdialog_win.cpp +++ b/src/gui/dialogs/qprintdialog_win.cpp @@ -77,14 +77,10 @@ public: QWin32PrintEnginePrivate *ep; }; -static PRINTDLG* qt_win_make_PRINTDLG(QWidget *parent, - QPrintDialog *pdlg, - QPrintDialogPrivate *d, HGLOBAL *tempDevNames) +static void qt_win_setup_PRINTDLGEX(PRINTDLGEX *pd, QWidget *parent, + QPrintDialog *pdlg, + QPrintDialogPrivate *d, HGLOBAL *tempDevNames) { - PRINTDLG *pd = new PRINTDLG; - memset(pd, 0, sizeof(PRINTDLG)); - pd->lStructSize = sizeof(PRINTDLG); - DEVMODE *devMode = d->ep->devMode; if (devMode) { @@ -125,31 +121,31 @@ static PRINTDLG* qt_win_make_PRINTDLG(QWidget *parent, if (pd->nMinPage==0 && pd->nMaxPage==0) pd->Flags |= PD_NOPAGENUMS; + // we don't have a 'current page' notion in the QPrinter API yet. + // Neither do we support more than one page range, so limit those + // options + pd->Flags |= PD_NOCURRENTPAGE; + pd->nStartPage = START_PAGE_GENERAL; + pd->nPageRanges = 1; + pd->nMaxPageRanges = 1; + if (d->ep->printToFile) pd->Flags |= PD_PRINTTOFILE; Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created)); pd->hwndOwner = parent ? parent->winId() : 0; - pd->nFromPage = qMax(pdlg->fromPage(), pdlg->minPage()); - pd->nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1; + pd->lpPageRanges[0].nFromPage = qMax(pdlg->fromPage(), pdlg->minPage()); + pd->lpPageRanges[0].nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1; pd->nCopies = d->ep->num_copies; - - return pd; -} - -static void qt_win_clean_up_PRINTDLG(PRINTDLG **pd) -{ - delete *pd; - *pd = 0; } -static void qt_win_read_back_PRINTDLG(PRINTDLG *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d) +static void qt_win_read_back_PRINTDLGEX(PRINTDLGEX *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d) { if (pd->Flags & PD_SELECTION) { pdlg->setPrintRange(QPrintDialog::Selection); pdlg->setFromTo(0, 0); } else if (pd->Flags & PD_PAGENUMS) { pdlg->setPrintRange(QPrintDialog::PageRange); - pdlg->setFromTo(pd->nFromPage, pd->nToPage); + pdlg->setFromTo(pd->lpPageRanges[0].nFromPage, pd->lpPageRanges[0].nToPage); } else { pdlg->setPrintRange(QPrintDialog::AllPages); pdlg->setFromTo(0, 0); @@ -223,19 +219,35 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() HGLOBAL *tempDevNames = ep->createDevNames(); - bool result; bool done; - PRINTDLG *pd = qt_win_make_PRINTDLG(parent, q, this, tempDevNames); + bool result; + bool doPrinting; + + PRINTPAGERANGE pageRange; + PRINTDLGEX pd; + memset(&pd, 0, sizeof(PRINTDLGEX)); + pd.lStructSize = sizeof(PRINTDLGEX); + pd.lpPageRanges = &pageRange; + qt_win_setup_PRINTDLGEX(&pd, parent, q, this, tempDevNames); do { done = true; - result = PrintDlg(pd); - if ((pd->Flags & PD_PAGENUMS) && (pd->nFromPage > pd->nToPage)) - done = false; - if (result && pd->hDC == 0) - result = false; - else if (!result) - done = true; + doPrinting = false; + result = (PrintDlgEx(&pd) == S_OK); + if (result && (pd.dwResultAction == PD_RESULT_PRINT + || pd.dwResultAction == PD_RESULT_APPLY)) + { + doPrinting = (pd.dwResultAction == PD_RESULT_PRINT); + if ((pd.Flags & PD_PAGENUMS) + && (pd.lpPageRanges[0].nFromPage > pd.lpPageRanges[0].nToPage)) + { + pd.lpPageRanges[0].nFromPage = 1; + pd.lpPageRanges[0].nToPage = 1; + done = false; + } + if (pd.hDC == 0) + result = false; + } if (!done) { QMessageBox::warning(0, QPrintDialog::tr("Print"), @@ -249,9 +261,10 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() qt_win_eatMouseMove(); // write values back... - if (result) { - qt_win_read_back_PRINTDLG(pd, q, this); - qt_win_clean_up_PRINTDLG(&pd); + if (result && (pd.dwResultAction == PD_RESULT_PRINT + || pd.dwResultAction == PD_RESULT_APPLY)) + { + qt_win_read_back_PRINTDLGEX(&pd, q, this); // update printer validity printer->d_func()->validPrinter = !ep->name.isEmpty(); } @@ -259,9 +272,9 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() // Cleanup... GlobalFree(tempDevNames); - q->done(result); + q->done(result && doPrinting); - return result; + return result && doPrinting; } void QPrintDialog::setVisible(bool visible) -- cgit v0.12 From b43cbebc5353b7e6b2a3812046a23f327a12c4dc Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Fri, 3 Jul 2009 13:46:22 +0200 Subject: Drag leave event is delivered, after re-entering the widget. This happens only for widgets with focus frames. Since the mouse location at the time of this event will be outside of the focus frame, we cannot use it to identify the widget. Instead, use the QDragManager's currentTarget() to deliver the drag leave event. Task-number: 252088 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qdnd_mac.mm | 4 ++-- src/gui/kernel/qwidget_mac.mm | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qdnd_mac.mm b/src/gui/kernel/qdnd_mac.mm index b244d84..99399da 100644 --- a/src/gui/kernel/qdnd_mac.mm +++ b/src/gui/kernel/qdnd_mac.mm @@ -405,12 +405,12 @@ bool QWidgetPrivate::qt_mac_dnd_event(uint kind, DragRef dragRef) SetDragDropAction(dragRef, qt_mac_dnd_map_qt_actions(qDEEvent.dropAction())); if (!qDEEvent.isAccepted()) - // The widget is simply not interrested in this + // The widget is simply not interested in this // drag. So tell carbon this by returning 'false'. We will then // not receive any further move, drop or leave events for this widget. return false; else { - // Documentation states that a drag move event is sendt immidiatly after + // Documentation states that a drag move event is sent immediately after // a drag enter event. So we do that. This will honor widgets overriding // 'dragMoveEvent' only, and not 'dragEnterEvent' QDragMoveEvent qDMEvent(q->mapFromGlobal(QPoint(mouse.h, mouse.v)), qtAllowed, dropdata, diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 250cc35..d1e4230 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -1369,6 +1369,14 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event, // Set dropWidget to zero, so qt_mac_dnd_event // doesn't get called a second time below: dropWidget = 0; + } else if (ekind == kEventControlDragLeave) { + dropWidget = QDragManager::self()->currentTarget(); + if (dropWidget) { + dropWidget->d_func()->qt_mac_dnd_event(kEventControlDragLeave, drag); + } + // Set dropWidget to zero, so qt_mac_dnd_event + // doesn't get called a second time below: + dropWidget = 0; } } } -- cgit v0.12 From 468bbd8fd5c40e29b50e6c38b3f2c3450aad2e67 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 3 Jul 2009 15:18:16 +0200 Subject: signals -> Q_SIGNALS --- src/gui/kernel/qgesture.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index b5abdd2..cc46916 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -93,7 +93,7 @@ protected: QGesture(QGesturePrivate &dd, QObject *parent); bool eventFilter(QObject*, QEvent*); -signals: +Q_SIGNALS: void started(); void triggered(); void finished(); -- cgit v0.12 From 7bc98d7bd7aabc6086e5cd27a167769d7aa71d83 Mon Sep 17 00:00:00 2001 From: jasplin Date: Fri, 3 Jul 2009 15:40:20 +0200 Subject: Improved the support for input methods in Graphics View. This patch improves the graphics view support for input methods in several ways: * A new ItemAcceptsInputMethod flag is introduced to serve the same purpose for graphics items as WA_InputMethodEnabled does for widgets: Input method support can be controlled individually for each item. * The input method sensitivity of a view (i.e. the value of the WA_InputMethodEnabled flag) is updated dynamically whenever the input method support of the current focus item may change. * Input contexts are reset whenever an item that supports input methods loses focus. Reviewed-by: janarve Task-number: 254492 --- src/gui/graphicsview/qgraphicsitem.cpp | 13 +++ src/gui/graphicsview/qgraphicsitem.h | 3 +- src/gui/graphicsview/qgraphicsitem_p.h | 4 +- src/gui/graphicsview/qgraphicsproxywidget.cpp | 22 +++- src/gui/graphicsview/qgraphicsproxywidget_p.h | 2 + src/gui/graphicsview/qgraphicsscene.cpp | 33 +++++- src/gui/graphicsview/qgraphicsscene_p.h | 2 + src/gui/graphicsview/qgraphicsview.cpp | 20 ++++ src/gui/graphicsview/qgraphicsview_p.h | 1 + .../tst_qgraphicsproxywidget.cpp | 46 +++++++- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 58 ++++++++++ tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 118 +++++++++++++++++++++ 12 files changed, 310 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c82c2e5..a5ee7e6 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -323,6 +323,10 @@ performance reasons, these notifications are disabled by default. You must enable this flag to receive notifications for position and transform changes. This flag was introduced in Qt 4.6. + + \value ItemAcceptsInputMethod The item supports input methods typically + used for Asian languages. + This flag was introduced in Qt 4.6. */ /*! @@ -1486,6 +1490,12 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->scene->d_func()->needSortTopLevelItems = 1; } + if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) { + // Update input method sensitivity in any views. + if (d_ptr->scene) + d_ptr->scene->d_func()->updateInputMethodSensitivityInViews(); + } + if (d_ptr->scene) { d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, @@ -9840,6 +9850,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag) case QGraphicsItem::ItemSendsGeometryChanges: str = "ItemSendsGeometryChanges"; break; + case QGraphicsItem::ItemAcceptsInputMethod: + str = "ItemAcceptsInputMethod"; + break; } debug << str; return debug; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index b0571c2..d26110a 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -98,7 +98,8 @@ public: ItemStacksBehindParent = 0x100, ItemUsesExtendedStyleOption = 0x200, ItemHasNoContents = 0x400, - ItemSendsGeometryChanges = 0x800 + ItemSendsGeometryChanges = 0x800, + ItemAcceptsInputMethod = 0x1000 // NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag. }; Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index a977e1e..46ec6fe 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -415,7 +415,7 @@ public: quint32 fullUpdatePending : 1; // New 32 bits - quint32 flags : 12; + quint32 flags : 13; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; quint32 dirtySceneTransform : 1; @@ -426,7 +426,7 @@ public: quint32 ignoreOpacity : 1; quint32 acceptTouchEvents : 1; quint32 acceptedTouchBeginEvent : 1; - quint32 unused : 10; // feel free to use + quint32 unused : 9; // feel free to use // Optional stacking order int globalStackingOrder; diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 0b421ad..5fac6cf 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -451,6 +451,22 @@ void QGraphicsProxyWidgetPrivate::updateProxyGeometryFromWidget() /*! \internal +*/ +void QGraphicsProxyWidgetPrivate::updateProxyInputMethodAcceptanceFromWidget() +{ + Q_Q(QGraphicsProxyWidget); + if (!widget) + return; + + QWidget *focusWidget = widget->focusWidget(); + if (!focusWidget) + focusWidget = widget; + q->setFlag(QGraphicsItem::ItemAcceptsInputMethod, + focusWidget->testAttribute(Qt::WA_InputMethodEnabled)); +} + +/*! + \internal Embeds \a subWin as a subwindow of this proxy widget. \a subWin must be a top-level widget and a descendant of the widget managed by this proxy. A separate subproxy @@ -690,6 +706,8 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto updateProxyGeometryFromWidget(); + updateProxyInputMethodAcceptanceFromWidget(); + // Hook up the event filter to keep the state up to date. newWidget->installEventFilter(q); QObject::connect(newWidget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot())); @@ -1303,8 +1321,8 @@ void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event) if (d->widget && d->widget->focusWidget()) { d->widget->focusWidget()->setFocus(event->reason()); return; - } - break; + } + break; } } diff --git a/src/gui/graphicsview/qgraphicsproxywidget_p.h b/src/gui/graphicsview/qgraphicsproxywidget_p.h index ec5400a..fbc9f6c 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget_p.h +++ b/src/gui/graphicsview/qgraphicsproxywidget_p.h @@ -102,6 +102,8 @@ public: void updateWidgetGeometryFromProxy(); void updateProxyGeometryFromWidget(); + void updateProxyInputMethodAcceptanceFromWidget(); + QPointF mapToReceiver(const QPointF &pos, const QWidget *receiver) const; enum ChangeMode { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c3f72e6..0c3abd4 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -242,6 +242,7 @@ #include #include #include +#include #include #include #ifdef Q_WS_X11 @@ -3175,6 +3176,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Deliver post-change notification item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant); + + d->updateInputMethodSensitivityInViews(); } /*! @@ -3450,6 +3453,8 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) // Deliver post-change notification item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant); + + d->updateInputMethodSensitivityInViews(); } /*! @@ -3504,6 +3509,17 @@ void QGraphicsScene::setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReas d->lastFocusItem = d->focusItem; d->focusItem = 0; d->sendEvent(d->lastFocusItem, &event); + + if (d->lastFocusItem + && (d->lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { + // Reset any visible preedit text + QInputMethodEvent imEvent; + d->sendEvent(d->lastFocusItem, &imEvent); + + // Close any external input method panel + for (int i = 0; i < d->views.size(); ++i) + d->views.at(i)->inputContext()->reset(); + } } if (item) { @@ -3516,6 +3532,8 @@ void QGraphicsScene::setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReas QFocusEvent event(QEvent::FocusIn, focusReason); d->sendEvent(item, &event); } + + d->updateInputMethodSensitivityInViews(); } /*! @@ -3699,7 +3717,7 @@ void QGraphicsScene::setForegroundBrush(const QBrush &brush) QVariant QGraphicsScene::inputMethodQuery(Qt::InputMethodQuery query) const { Q_D(const QGraphicsScene); - if (!d->focusItem) + if (!d->focusItem || !(d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) return QVariant(); const QTransform matrix = d->focusItem->sceneTransform(); QVariant value = d->focusItem->inputMethodQuery(query); @@ -4662,16 +4680,16 @@ void QGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent) subclass to receive input method events for the scene. The default implementation forwards the event to the focusItem(). - If no item currently has focus, this function does nothing. + If no item currently has focus or the current focus item does not + accept input methods, this function does nothing. \sa QGraphicsItem::inputMethodEvent() */ void QGraphicsScene::inputMethodEvent(QInputMethodEvent *event) { Q_D(QGraphicsScene); - if (!d->focusItem) - return; - d->sendEvent(d->focusItem, event); + if (d->focusItem && (d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) + d->sendEvent(d->focusItem, event); } /*! @@ -6128,6 +6146,11 @@ void QGraphicsScenePrivate::enableTouchEventsOnViews() view->viewport()->setAttribute(Qt::WA_AcceptTouchEvents, true); } +void QGraphicsScenePrivate::updateInputMethodSensitivityInViews() +{ + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->updateInputMethodSensitivity(); +} QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index d2d603a..dc720a7 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -316,6 +316,8 @@ public: bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent); bool allItemsIgnoreTouchEvents; void enableTouchEventsOnViews(); + + void updateInputMethodSensitivityInViews(); }; QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 56a69f7..3b29552 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -280,6 +280,7 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < #include #include #include +#include #ifdef Q_WS_X11 #include #endif @@ -1017,6 +1018,22 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg } /*! + \internal + + Enables input methods for the view if and only if the current focus item of + the scene accepts input methods. Call function whenever that condition has + potentially changed. +*/ +void QGraphicsViewPrivate::updateInputMethodSensitivity() +{ + Q_Q(QGraphicsView); + q->setAttribute( + Qt::WA_InputMethodEnabled, + scene && scene->focusItem() + && scene->focusItem()->flags() & QGraphicsItem::ItemAcceptsInputMethod); +} + +/*! Constructs a QGraphicsView. \a parent is passed to QWidget's constructor. */ QGraphicsView::QGraphicsView(QWidget *parent) @@ -1538,6 +1555,8 @@ void QGraphicsView::setScene(QGraphicsScene *scene) } else { d->recalculateContentSize(); } + + d->updateInputMethodSensitivity(); } /*! @@ -2929,6 +2948,7 @@ void QGraphicsView::dragMoveEvent(QDragMoveEvent *event) void QGraphicsView::focusInEvent(QFocusEvent *event) { Q_D(QGraphicsView); + d->updateInputMethodSensitivity(); QAbstractScrollArea::focusInEvent(event); if (d->scene) QApplication::sendEvent(d->scene, event); diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 8c62f73..09d842d 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -181,6 +181,7 @@ public: QPointF mapToScene(const QPointF &point) const; QRectF mapToScene(const QRectF &rect) const; static void translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent); + void updateInputMethodSensitivity(); }; QT_END_NAMESPACE diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 0b1d5cf..dbc4339 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -178,6 +178,7 @@ private slots: void windowFlags_data(); void windowFlags(); void comboboxWindowFlags(); + void inputMethod(); }; // Subclass that exposes the protected functions. @@ -1572,7 +1573,7 @@ void tst_QGraphicsProxyWidget::resize_simple() QGraphicsProxyWidget proxy; QWidget *widget = new QWidget; - widget->setGeometry(0, 0, size.width(), size.height()); + widget->setGeometry(0, 0, (int)size.width(), (int)size.height()); proxy.setWidget(widget); widget->show(); QCOMPARE(widget->pos(), QPoint()); @@ -3217,10 +3218,51 @@ void tst_QGraphicsProxyWidget::comboboxWindowFlags() QVERIFY((static_cast(popupProxy)->windowFlags() & Qt::Popup) == Qt::Popup); } +class InputMethod_LineEdit : public QLineEdit +{ + bool event(QEvent *e) + { + if (e->type() == QEvent::InputMethod) + ++inputMethodEvents; + return QLineEdit::event(e); + } +public: + int inputMethodEvents; +}; + +void tst_QGraphicsProxyWidget::inputMethod() +{ + QGraphicsScene scene; + + // check that the proxy is initialized with the correct input method sensitivity + for (int i = 0; i < 2; ++i) + { + QLineEdit *lineEdit = new QLineEdit; + lineEdit->setAttribute(Qt::WA_InputMethodEnabled, !!i); + QGraphicsProxyWidget *proxy = scene.addWidget(lineEdit); + QCOMPARE(!!(proxy->flags() & QGraphicsItem::ItemAcceptsInputMethod), !!i); + } + + // check that input method events are only forwarded to widgets with focus + for (int i = 0; i < 2; ++i) + { + InputMethod_LineEdit *lineEdit = new InputMethod_LineEdit; + lineEdit->setAttribute(Qt::WA_InputMethodEnabled, true); + QGraphicsProxyWidget *proxy = scene.addWidget(lineEdit); + + if (i) + lineEdit->setFocus(); + + lineEdit->inputMethodEvents = 0; + QInputMethodEvent event; + qApp->sendEvent(proxy, &event); + QCOMPARE(lineEdit->inputMethodEvents, i); + } +} + QTEST_MAIN(tst_QGraphicsProxyWidget) #include "tst_qgraphicsproxywidget.moc" #else // QT_NO_STYLE_CLEANLOOKS QTEST_NOOP_MAIN #endif - diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 4247cca..d325f0f 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -252,6 +252,8 @@ private slots: void stickyFocus_data(); void stickyFocus(); void sendEvent(); + void inputMethod_data(); + void inputMethod(); // task specific tests below me void task139710_bspTreeCrash(); @@ -3614,5 +3616,61 @@ void tst_QGraphicsScene::sendEvent() QCOMPARE(spy->count(), 1); } +void tst_QGraphicsScene::inputMethod_data() +{ + QTest::addColumn("flags"); + QTest::addColumn("callFocusItem"); + QTest::newRow("0") << 0 << false; + QTest::newRow("1") << (int)QGraphicsItem::ItemAcceptsInputMethod << false; + QTest::newRow("2") << (int)QGraphicsItem::ItemIsFocusable << false; + QTest::newRow("3") << + (int)(QGraphicsItem::ItemAcceptsInputMethod|QGraphicsItem::ItemIsFocusable) << true; +} + +class InputMethodTester : public QGraphicsRectItem +{ + void inputMethodEvent(QInputMethodEvent *) { ++eventCalls; } + QVariant inputMethodQuery(Qt::InputMethodQuery) const { ++queryCalls; return QVariant(); } +public: + int eventCalls; + mutable int queryCalls; +}; + +void tst_QGraphicsScene::inputMethod() +{ + QFETCH(int, flags); + QFETCH(bool, callFocusItem); + + InputMethodTester *item = new InputMethodTester; + item->setFlags((QGraphicsItem::GraphicsItemFlags)flags); + + QGraphicsScene scene; + scene.addItem(item); + QInputMethodEvent event; + + scene.setFocusItem(item); + QCOMPARE(!!(item->flags() & QGraphicsItem::ItemIsFocusable), scene.focusItem() == item); + + item->eventCalls = 0; + qApp->sendEvent(&scene, &event); + QCOMPARE(item->eventCalls, callFocusItem ? 1 : 0); + + item->queryCalls = 0; + scene.inputMethodQuery((Qt::InputMethodQuery)0); + QCOMPARE(item->queryCalls, callFocusItem ? 1 : 0); + + scene.setFocusItem(0); + QCOMPARE(item->eventCalls, callFocusItem ? 2 : 0); // verify correct delivery of "reset" event + QCOMPARE(item->queryCalls, callFocusItem ? 1 : 0); // verify that value is unaffected + + item->eventCalls = 0; + qApp->sendEvent(&scene, &event); + QCOMPARE(item->eventCalls, 0); + + item->queryCalls = 0; + scene.inputMethodQuery((Qt::InputMethodQuery)0); + QCOMPARE(item->queryCalls, 0); +} + QTEST_MAIN(tst_QGraphicsScene) #include "tst_qgraphicsscene.moc" diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index d24e437..8b4ca4c 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -63,6 +63,7 @@ #include #include #include +#include //TESTED_CLASS= //TESTED_FILES= @@ -195,6 +196,8 @@ private slots: void mouseTracking2(); void render(); void exposeRegion(); + void inputMethodSensitivity(); + void inputContextReset(); // task specific tests below me void task172231_untransformableItems(); @@ -3357,6 +3360,121 @@ void tst_QGraphicsView::exposeRegion() QCOMPARE(item->paints, 0); } +void tst_QGraphicsView::inputMethodSensitivity() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + + QGraphicsRectItem *item = new QGraphicsRectItem; + + view.setAttribute(Qt::WA_InputMethodEnabled, true); + + scene.addItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.removeItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + item->setFlag(QGraphicsItem::ItemAcceptsInputMethod); + scene.addItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.removeItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.addItem(item); + scene.setFocusItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.removeItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + item->setFlag(QGraphicsItem::ItemIsFocusable); + scene.addItem(item); + scene.setFocusItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + + item->setFlag(QGraphicsItem::ItemAcceptsInputMethod, false); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + item->setFlag(QGraphicsItem::ItemAcceptsInputMethod, true); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + + // introduce another item that is focusable but does not accept input methods + QGraphicsRectItem *item2 = new QGraphicsRectItem; + item2->setFlag(QGraphicsItem::ItemIsFocusable); + scene.addItem(item2); + scene.setFocusItem(item2); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.setFocusItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + + view.setScene(0); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + view.setScene(&scene); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + + scene.setFocusItem(item2); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + view.setScene(0); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.setFocusItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + view.setScene(&scene); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); +} + +class InputContextTester : public QInputContext +{ + QString identifierName() { return QString(); } + bool isComposing() const { return false; } + QString language() { return QString(); } + void reset() { ++resets; } +public: + int resets; +}; + +void tst_QGraphicsView::inputContextReset() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + + InputContextTester inputContext; + view.setInputContext(&inputContext); + + QGraphicsItem *item1 = new QGraphicsRectItem; + item1->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod); + + inputContext.resets = 0; + scene.addItem(item1); + QCOMPARE(inputContext.resets, 0); + + inputContext.resets = 0; + scene.setFocusItem(item1); + QCOMPARE(inputContext.resets, 0); + + inputContext.resets = 0; + scene.setFocusItem(0); + QCOMPARE(inputContext.resets, 1); + + // introduce another item that is focusable but does not accept input methods + QGraphicsItem *item2 = new QGraphicsRectItem; + item1->setFlags(QGraphicsItem::ItemIsFocusable); + + inputContext.resets = 0; + scene.setFocusItem(item2); + QCOMPARE(inputContext.resets, 0); + + inputContext.resets = 0; + scene.setFocusItem(item1); + QCOMPARE(inputContext.resets, 0); +} + void tst_QGraphicsView::task253415_reconnectUpdateSceneOnSceneChanged() { QGraphicsView view; -- cgit v0.12 From 208bba0abd8a417cf8fdfd61295682738df3bc67 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 3 Jul 2009 16:40:32 +0200 Subject: QHeaderView: fixed the sizeHint with hidden sections We used to check the 100 first sections and 100 last sections Now we make sure we check 100 visible sections Task-number: 255574 --- src/gui/itemviews/qheaderview.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index aea288b..a73f85a 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -528,20 +528,24 @@ QSize QHeaderView::sizeHint() const return d->cachedSizeHint; int width = 0; int height = 0; + d->executePostedLayout(); + // get size hint for the first n sections - int c = qMin(count(), 100); - for (int i = 0; i < c; ++i) { + int i = 0; + for (int checked = 0; checked < 100 && i < d->sectionCount; ++i) { if (isSectionHidden(i)) continue; + checked++; QSize hint = sectionSizeFromContents(i); width = qMax(hint.width(), width); height = qMax(hint.height(), height); } // get size hint for the last n sections - c = qMax(count() - 100, c); - for (int j = count() - 1; j >= c; --j) { + i = qMax(i, d->sectionCount - 100 ); + for (int j = d->sectionCount - 1, checked = 0; j > i && checked < 100; --j) { if (isSectionHidden(j)) continue; + checked++; QSize hint = sectionSizeFromContents(j); width = qMax(hint.width(), width); height = qMax(hint.height(), height); -- cgit v0.12 From 108f549a446e13a3be7ee6753be9eb74260547d7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 3 Jul 2009 16:44:51 +0200 Subject: QHeaderView: code cleanup in sizehint calculation --- src/gui/itemviews/qheaderview.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index a73f85a..57e44c7 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -522,12 +522,9 @@ int QHeaderView::length() const QSize QHeaderView::sizeHint() const { Q_D(const QHeaderView); - if (count() < 1) - return QSize(0, 0); if (d->cachedSizeHint.isValid()) return d->cachedSizeHint; - int width = 0; - int height = 0; + d->cachedSizeHint = QSize(0, 0); d->executePostedLayout(); // get size hint for the first n sections @@ -537,8 +534,7 @@ QSize QHeaderView::sizeHint() const continue; checked++; QSize hint = sectionSizeFromContents(i); - width = qMax(hint.width(), width); - height = qMax(hint.height(), height); + d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); } // get size hint for the last n sections i = qMax(i, d->sectionCount - 100 ); @@ -547,10 +543,8 @@ QSize QHeaderView::sizeHint() const continue; checked++; QSize hint = sectionSizeFromContents(j); - width = qMax(hint.width(), width); - height = qMax(hint.height(), height); + d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); } - d->cachedSizeHint = QSize(width, height); return d->cachedSizeHint; } -- cgit v0.12 From 84bbac2a4d7b663e57b74094cbebf8fca16e0ed8 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 3 Jul 2009 17:25:40 +0200 Subject: Moved uniform enum to QGLEngineShaderManager. Simplified caching of uniform locations. Reviewed-by: Samuel --- .../gl2paintengineex/qglengineshadermanager.cpp | 40 ++++++++------ .../gl2paintengineex/qglengineshadermanager_p.h | 26 +++++++-- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 61 ++++++++-------------- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 25 +-------- 4 files changed, 69 insertions(+), 83 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 4b73ca9..27636f4 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -190,27 +190,33 @@ QGLEngineShaderManager::~QGLEngineShaderManager() //### } - -uint QGLEngineShaderManager::getUniformIdentifier(const char *uniformName) -{ - uniformIdentifiers << uniformName; - return uniformIdentifiers.size() - 1; -} - -uint QGLEngineShaderManager::getUniformLocation(uint id) +uint QGLEngineShaderManager::getUniformLocation(Uniform id) { QVector &uniformLocations = currentShaderProg->uniformLocations; - uint oldSize = uniformLocations.size(); - if (oldSize <= id) { - uint newSize = id + 1; - uniformLocations.resize(newSize); - - for (uint i = oldSize; i < newSize; ++i) - uniformLocations[i] = GLuint(-1); - } + if (uniformLocations.isEmpty()) + uniformLocations.fill(GLuint(-1), NumUniforms); + + static const char *uniformNames[] = { + "imageTexture", + "patternColor", + "globalOpacity", + "depth", + "pmvMatrix", + "maskTexture", + "fragmentColor", + "linearData", + "angle", + "halfViewportSize", + "fmp", + "fmp2_m_radius2", + "inverse_2_fmp2_m_radius2", + "invertedTextureSize", + "brushTransform", + "brushTexture" + }; if (uniformLocations.at(id) == GLuint(-1)) - uniformLocations[id] = currentShaderProg->program->uniformLocation(uniformIdentifiers.at(id)); + uniformLocations[id] = currentShaderProg->program->uniformLocation(uniformNames[id]); return uniformLocations.at(id); } diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 34f0768..442edfe 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -274,6 +274,26 @@ public: TextureSrcWithPattern = Qt::TexturePattern+4 }; + enum Uniform { + ImageTexture, + PatternColor, + GlobalOpacity, + Depth, + PmvMatrix, + MaskTexture, + FragmentColor, + LinearData, + Angle, + HalfViewportSize, + Fmp, + Fmp2MRadius2, + Inverse2Fmp2MRadius2, + InvertedTextureSize, + BrushTransform, + BrushTexture, + NumUniforms + }; + // There are optimisations we can do, depending on the brush transform: // 1) May not have to apply perspective-correction // 2) Can use lower precision for matrix @@ -285,8 +305,7 @@ public: void setMaskType(MaskType); void setCompositionMode(QPainter::CompositionMode); - uint getUniformIdentifier(const char *uniformName); - uint getUniformLocation(uint id); + uint getUniformLocation(Uniform id); void setDirty(); // someone has manually changed the current shader program bool useCorrectShaderProg(); // returns true if the shader program needed to be changed @@ -352,6 +371,7 @@ public: TotalShaderCount, InvalidShaderName }; + /* // These allow the ShaderName enum to be used as a cache key const int mainVertexOffset = 0; @@ -391,8 +411,6 @@ private: void compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type); static const char* qglEngineShaderSourceCode[TotalShaderCount]; - - QVector uniformIdentifiers; }; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index f261ca2..bcff29b 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -393,7 +393,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() if (style == Qt::SolidPattern) { QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(FragmentColor), col); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::FragmentColor), col); } else { // All other brushes have a transform and thus need the translation point: @@ -404,10 +404,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(PatternColor), col); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::LinearGradientPattern) { const QLinearGradient *g = static_cast(currentBrush->gradient()); @@ -424,10 +424,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() 1.0f / (l.x() * l.x() + l.y() * l.y()) ); - shaderManager->currentProgram()->setUniformValue(location(LinearData), linearData); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::LinearData), linearData); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::ConicalGradientPattern) { const QConicalGradient *g = static_cast(currentBrush->gradient()); @@ -435,10 +435,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() GLfloat angle = -(g->angle() * 2 * Q_PI) / 360.0; - shaderManager->currentProgram()->setUniformValue(location(Angle), angle); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Angle), angle); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::RadialGradientPattern) { const QRadialGradient *g = static_cast(currentBrush->gradient()); @@ -448,15 +448,15 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() translationPoint = realFocal; QPointF fmp = realCenter - realFocal; - shaderManager->currentProgram()->setUniformValue(location(Fmp), fmp); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Fmp), fmp); GLfloat fmp2_m_radius2 = -fmp.x() * fmp.x() - fmp.y() * fmp.y() + realRadius*realRadius; - shaderManager->currentProgram()->setUniformValue(location(Fmp2MRadius2), fmp2_m_radius2); - shaderManager->currentProgram()->setUniformValue(location(Inverse2Fmp2MRadius2), + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Fmp2MRadius2), fmp2_m_radius2); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Inverse2Fmp2MRadius2), GLfloat(1.0 / (2.0*fmp2_m_radius2))); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::TexturePattern) { translationPoint = q->state()->brushOrigin; @@ -465,14 +465,14 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() if (qHasPixmapTexture(*currentBrush) && currentBrush->texture().isQBitmap()) { QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(PatternColor), col); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); } QSizeF invertedTextureSize( 1.0 / texPixmap.width(), 1.0 / texPixmap.height() ); - shaderManager->currentProgram()->setUniformValue(location(InvertedTextureSize), invertedTextureSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::InvertedTextureSize), invertedTextureSize); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else qWarning("QGL2PaintEngineEx: Unimplemented fill style"); @@ -481,8 +481,8 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QTransform gl_to_qt(1, 0, 0, -1, 0, height); QTransform inv_matrix = gl_to_qt * (brushQTransform * q->state()->matrix).inverted() * translate; - shaderManager->currentProgram()->setUniformValue(location(BrushTransform), inv_matrix); - shaderManager->currentProgram()->setUniformValue(location(BrushTexture), QT_BRUSH_TEXTURE_UNIT); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BrushTransform), inv_matrix); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BrushTexture), QT_BRUSH_TEXTURE_UNIT); } brushUniformsDirty = false; } @@ -620,11 +620,11 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s shaderManager->setSrcPixelType(pattern ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); shaderManager->setTextureCoordsEnabled(true); if (prepareForDraw(opaque)) - shaderManager->currentProgram()->setUniformValue(location(ImageTexture), QT_IMAGE_TEXTURE_UNIT); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); if (pattern) { QColor col = premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(PatternColor), col); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); } GLfloat dx = 1.0 / textureSize.width(); @@ -873,17 +873,17 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) updateBrushUniforms(); if (shaderMatrixUniformDirty) { - shaderManager->currentProgram()->setUniformValue(location(PmvMatrix), pmvMatrix); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PmvMatrix), pmvMatrix); shaderMatrixUniformDirty = false; } if (depthUniformDirty) { - shaderManager->currentProgram()->setUniformValue(location(Depth), (GLfloat)q->state()->currentDepth); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Depth), (GLfloat)q->state()->currentDepth); depthUniformDirty = false; } if (useGlobalOpacityUniform && opacityUniformDirty) { - shaderManager->currentProgram()->setUniformValue(location(GlobalOpacity), (GLfloat)q->state()->opacity); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity); opacityUniformDirty = false; } @@ -1166,7 +1166,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte prepareForDraw(false); // Text always causes src pixels to be transparent - shaderManager->currentProgram()->setUniformValue(location(MaskTexture), QT_MASK_TEXTURE_UNIT); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::MaskTexture), QT_MASK_TEXTURE_UNIT); if (vertexCoordinateArray.data() != oldVertexCoordinateDataPtr) glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); @@ -1210,23 +1210,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->shaderManager->setDirty(); } else { d->shaderManager = new QGLEngineShaderManager(d->ctx); - - d->uniformIdentifiers[QGL2PaintEngineExPrivate::ImageTexture] = d->shaderManager->getUniformIdentifier("imageTexture"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::PatternColor] = d->shaderManager->getUniformIdentifier("patternColor"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::GlobalOpacity] = d->shaderManager->getUniformIdentifier("globalOpacity"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Depth] = d->shaderManager->getUniformIdentifier("depth"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::PmvMatrix] = d->shaderManager->getUniformIdentifier("pmvMatrix"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::MaskTexture] = d->shaderManager->getUniformIdentifier("maskTexture"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::FragmentColor] = d->shaderManager->getUniformIdentifier("fragmentColor"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::LinearData] = d->shaderManager->getUniformIdentifier("linearData"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Angle] = d->shaderManager->getUniformIdentifier("angle"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::HalfViewportSize] = d->shaderManager->getUniformIdentifier("halfViewportSize"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Fmp] = d->shaderManager->getUniformIdentifier("fmp"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Fmp2MRadius2] = d->shaderManager->getUniformIdentifier("fmp2_m_radius2"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Inverse2Fmp2MRadius2] = d->shaderManager->getUniformIdentifier("inverse_2_fmp2_m_radius2"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::InvertedTextureSize] = d->shaderManager->getUniformIdentifier("invertedTextureSize"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::BrushTransform] = d->shaderManager->getUniformIdentifier("brushTransform"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::BrushTexture] = d->shaderManager->getUniformIdentifier("brushTexture"); } glViewport(0, 0, d->width, d->height); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 0d28a49..ec447a3 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -221,32 +221,11 @@ public: void systemStateChanged(); uint use_system_clip : 1; - enum Uniform { - ImageTexture, - PatternColor, - GlobalOpacity, - Depth, - PmvMatrix, - MaskTexture, - FragmentColor, - LinearData, - Angle, - HalfViewportSize, - Fmp, - Fmp2MRadius2, - Inverse2Fmp2MRadius2, - InvertedTextureSize, - BrushTransform, - BrushTexture, - NumUniforms - }; - - uint location(Uniform uniform) + uint location(QGLEngineShaderManager::Uniform uniform) { - return shaderManager->getUniformLocation(uniformIdentifiers[uniform]); + return shaderManager->getUniformLocation(uniform); } - uint uniformIdentifiers[NumUniforms]; GLuint lastTexture; bool needsSync; -- cgit v0.12 From 8fa9744b1b18f97b98fc434b8b8057434118e3db Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 6 Jul 2009 12:30:32 +1000 Subject: Fix precision autotest for SqlServer Sql Server can't count. Reduce the expected length of string when we're on sql server. --- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index 91533dd..812c862 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -155,11 +155,9 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase db ) } if (tst_Databases::isMSAccess(db)) { - QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 number)")); - } else if (db.driverName().startsWith("QIBASE")) { - QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 numeric(15, 14))")); + QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 number)")); } else { - QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 numeric(15, 14))")); + QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 numeric(15, 14))")); } } @@ -555,7 +553,7 @@ void tst_Q3SqlCursor::unicode() void tst_Q3SqlCursor::precision() { - static const QString precStr = "1.23456789012345"; + static const QString precStr = QLatin1String("1.23456789012345"); static const double precDbl = 2.23456789012345; QFETCH( QString, dbName ); @@ -574,7 +572,10 @@ void tst_Q3SqlCursor::precision() QVERIFY_SQL(cur, select()); QVERIFY( cur.next() ); - QCOMPARE( cur.value( 0 ).asString(), QString( precStr ) ); + if(!tst_Databases::isSqlServer(db)) + QCOMPARE( cur.value( 0 ).asString(), precStr ); + else + QCOMPARE( cur.value( 0 ).asString(), precStr.left(precStr.size()-1) ); QVERIFY( cur.next() ); QCOMPARE( cur.value( 0 ).asDouble(), precDbl ); } -- cgit v0.12 From 8915977e56b58c4631dfb2b8616585b664e55f38 Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 6 Jul 2009 15:57:41 +1000 Subject: Fix more sql autotest failures. Sql server fails at numeric field calculations. (Confirmed by running against MySql via odbc). Also, quote fields properly. The drivers know how to do it correctly, so let them handle it. --- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index 812c862..360c3b7 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -575,7 +575,7 @@ void tst_Q3SqlCursor::precision() if(!tst_Databases::isSqlServer(db)) QCOMPARE( cur.value( 0 ).asString(), precStr ); else - QCOMPARE( cur.value( 0 ).asString(), precStr.left(precStr.size()-1) ); + QCOMPARE( cur.value( 0 ).asString(), precStr.left(precStr.size()-1) ); // Sql server fails at counting. QVERIFY( cur.next() ); QCOMPARE( cur.value( 0 ).asDouble(), precDbl ); } @@ -759,8 +759,9 @@ void tst_Q3SqlCursor::insertFieldNameContainsWS() { QSqlQuery q(db); q.exec(QString("DROP TABLE %1").arg(tableName)); - QString query = QString("CREATE TABLE %1 (id int, \"first Name\" varchar(20), " - "lastName varchar(20))"); + QString query = "CREATE TABLE %1 (id int, " + + db.driver()->escapeIdentifier("first Name", QSqlDriver::FieldName) + + " varchar(20), lastName varchar(20))"; QVERIFY_SQL(q, exec(query.arg(tableName))); Q3SqlCursor cur(QString("%1").arg(tableName), true, db); -- cgit v0.12 From d3de6acd72b42ebe99bba104c83cfbfda538cc33 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 09:15:15 +0200 Subject: qdoc: Added missing CR to help message. --- tools/qdoc3/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp index 5a98275..6425765 100644 --- a/tools/qdoc3/main.cpp +++ b/tools/qdoc3/main.cpp @@ -128,7 +128,7 @@ static void printHelp() " -D " "Define as a macro while parsing sources\n" " -slow " - "Turn on features that slow down qdoc" + "Turn on features that slow down qdoc\n" " -showinternal " "Include stuff marked internal") ); } -- cgit v0.12 From bf5112c6673d32cbaad33c388d38690264adf107 Mon Sep 17 00:00:00 2001 From: ck Date: Mon, 6 Jul 2009 10:20:02 +0200 Subject: Fixed race condition in search module. Task-number: 257441 Reviewed-by: kh --- tools/assistant/lib/qhelpsearchengine.cpp | 10 ++++------ .../lib/qhelpsearchindexreader_clucene.cpp | 21 +++++++++++++++------ .../lib/qhelpsearchindexreader_clucene_p.h | 5 ++--- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/tools/assistant/lib/qhelpsearchengine.cpp b/tools/assistant/lib/qhelpsearchengine.cpp index 9faafe0..15f7f9e 100644 --- a/tools/assistant/lib/qhelpsearchengine.cpp +++ b/tools/assistant/lib/qhelpsearchengine.cpp @@ -96,6 +96,7 @@ private: delete indexWriter; } + int hitsCount() const { int count = 0; @@ -107,12 +108,9 @@ private: QList hits(int start, int end) const { - QList returnValue; - if (indexReader) { - for (int i = start; i < end && i < hitsCount(); ++i) - returnValue.append(indexReader->hit(i)); - } - return returnValue; + return indexReader ? + indexReader->hits(start, end) : + QList(); } void updateIndex(bool reindex = false) diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp index 227e558..867e060 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp @@ -86,8 +86,8 @@ void QHelpSearchIndexReader::cancelSearching() void QHelpSearchIndexReader::search(const QString &collectionFile, const QString &indexFilesFolder, const QList &queryList) { - QMutexLocker lock(&mutex); - + wait(); + this->hitList.clear(); this->m_cancel = false; this->m_query = queryList; @@ -99,12 +99,18 @@ void QHelpSearchIndexReader::search(const QString &collectionFile, const QString int QHelpSearchIndexReader::hitsCount() const { + QMutexLocker lock(&mutex); return hitList.count(); } -QHelpSearchEngine::SearchHit QHelpSearchIndexReader::hit(int index) const +QList QHelpSearchIndexReader::hits(int start, + int end) const { - return hitList.at(index); + QList hits; + QMutexLocker lock(&mutex); + for (int i = start; i < end && i < hitList.count(); ++i) + hits.append(hitList.at(i)); + return hits; } void QHelpSearchIndexReader::run() @@ -135,7 +141,7 @@ void QHelpSearchIndexReader::run() if(QCLuceneIndexReader::indexExists(indexPath)) { mutex.lock(); if (m_cancel) { - mutex.unlock(); + mutex.unlock(); return; } mutex.unlock(); @@ -213,7 +219,9 @@ void QHelpSearchIndexReader::run() #if !defined(QT_NO_EXCEPTIONS) } catch(...) { + mutex.lock(); hitList.clear(); + mutex.unlock(); emit searchingFinished(0); } #endif @@ -416,8 +424,9 @@ void QHelpSearchIndexReader::boostSearchHits(const QHelpEngineCore &engine, boostedList.append(it.value()); } while (it != hitMap.constBegin()); boostedList += hitList.mid(count, hitList.count()); - + mutex.lock(); hitList = boostedList; + mutex.unlock(); } } diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h index 47af43f..e7ac0eb 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h @@ -85,9 +85,8 @@ public: void search(const QString &collectionFile, const QString &indexFilesFolder, const QList &queryList); - int hitsCount() const; - QHelpSearchEngine::SearchHit hit(int index) const; + QList hits(int start, int end) const; signals: void searchingStarted(); @@ -105,7 +104,7 @@ private: const QList &queryList); private: - QMutex mutex; + mutable QMutex mutex; QList hitList; QWaitCondition waitCondition; -- cgit v0.12 From 18a717b3f2e6a19a5ad631b68b26d09ba934bece Mon Sep 17 00:00:00 2001 From: ck Date: Mon, 6 Jul 2009 10:24:37 +0200 Subject: Removed superfluous code in assistant's search module. Reviewed-by: kh --- tools/assistant/lib/qhelpsearchengine.cpp | 19 ++++++------------- .../assistant/lib/qhelpsearchindexreader_clucene.cpp | 1 - .../assistant/lib/qhelpsearchindexreader_clucene_p.h | 2 -- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/tools/assistant/lib/qhelpsearchengine.cpp b/tools/assistant/lib/qhelpsearchengine.cpp index 15f7f9e..2a41d04 100644 --- a/tools/assistant/lib/qhelpsearchengine.cpp +++ b/tools/assistant/lib/qhelpsearchengine.cpp @@ -84,14 +84,12 @@ private: , resultWidget(0) , helpEngine(helpEngine) { - hitList.clear(); indexReader = 0; indexWriter = 0; } ~QHelpSearchEnginePrivate() { - hitList.clear(); delete indexReader; delete indexWriter; } @@ -129,11 +127,9 @@ private: connect(indexWriter, SIGNAL(indexingFinished()), this, SLOT(optimizeIndex())); } - if (indexWriter) { - indexWriter->cancelIndexing(); - indexWriter->updateIndex(helpEngine->collectionFile(), - indexFilesFolder(), reindex); - } + indexWriter->cancelIndexing(); + indexWriter->updateIndex(helpEngine->collectionFile(), + indexFilesFolder(), reindex); } void cancelIndexing() @@ -157,11 +153,9 @@ private: connect(indexReader, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int))); } - if (indexReader) { - m_queryList = queryList; - indexReader->cancelSearching(); - indexReader->search(helpEngine->collectionFile(), indexFilesFolder(), queryList); - } + m_queryList = queryList; + indexReader->cancelSearching(); + indexReader->search(helpEngine->collectionFile(), indexFilesFolder(), queryList); } void cancelSearching() @@ -202,7 +196,6 @@ private: QHelpSearchIndexWriter *indexWriter; QPointer helpEngine; - QList hitList; QList m_queryList; }; diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp index 867e060..89d6040 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp @@ -70,7 +70,6 @@ QHelpSearchIndexReader::~QHelpSearchIndexReader() { mutex.lock(); this->m_cancel = true; - waitCondition.wakeOne(); mutex.unlock(); wait(); diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h index e7ac0eb..8876d80 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h @@ -106,8 +106,6 @@ private: private: mutable QMutex mutex; QList hitList; - QWaitCondition waitCondition; - bool m_cancel; QString m_collectionFile; QList m_query; -- cgit v0.12 From cb78e8165bd9e210b336a59065f710d24cae5dd2 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 10:34:16 +0200 Subject: doc: Added note about qmake not building to two targets simultaneously Task-number: 256486 --- doc/src/qmake-manual.qdoc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index 5b261ab..049f30c 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -829,6 +829,29 @@ Note that, if a project is later moved on the disk, \c qmake must be run again to process the project file and create a new Xcode project file. + \section2 On supporting two build targets simultaneously + + Implementing this is currently not feasible, because the XCode + concept of Active Build Configurations is conceptually different + from the qmake idea of build targets. + + The XCode Active Build Configurations settings are for modifying + xcode configurations, compiler flags and similar build + options. Unlike Visual Studio, XCode does not allow for the + selection of specific library files based on whether debug or + release build configurations are selected. The qmake debug and + release settings control which library files are linked to the + executable. + + It is currently not possible to set files in XCode configuration + settings from the qmake generated xcode project file. The way the + libraries are linked in the "Frameworks & Libraries" phase in the + XCode build system. + + Furthermore, The selected "Active Build Configuration" is stored + in a .pbxuser file, which is generated by xcode on first load, not + created by qmake. + \section1 Windows Features specific to this platform include support for creating Visual -- cgit v0.12 From 1737e24412ba3becd9b4a86bff3656281767564c Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 10:48:04 +0200 Subject: doc: Removed specific reference to Mac OS X. Task-number: 256452 --- src/gui/dialogs/qfiledialog.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index f6a8602..849f4b3 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -209,25 +209,30 @@ Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook /*! \enum QFileDialog::Option - \value ShowDirsOnly Only show directories in the file dialog. By default both files and - directories are shown. (Valid only in the \l Directory file mode.) - \value DontResolveSymlinks Don't resolve symlinks in the file dialog. By default symlinks - are resolved. - \value DontConfirmOverwrite Don't ask for confirmation if an existing file is selected. - By default confirmation is requested. - \value DontUseNativeDialog Don't use the native file dialog. By default on Mac OS X, - the native file dialog is used unless you use a subclass of QFileDialog that contains the - Q_OBJECT macro. + \value ShowDirsOnly Only show directories in the file dialog. By + default both files and directories are shown. (Valid only in the + \l Directory file mode.) + + \value DontResolveSymlinks Don't resolve symlinks in the file + dialog. By default symlinks are resolved. + + \value DontConfirmOverwrite Don't ask for confirmation if an + existing file is selected. By default confirmation is requested. + + \value DontUseNativeDialog Don't use the native file dialog. By + default, the native file dialog is used unless you use a subclass + of QFileDialog that contains the Q_OBJECT macro. + \value ReadOnly Indicates that the model is readonly. - \value HideNameFilterDetails Indicates if the is hidden or not. + \value HideNameFilterDetails Indicates if the is hidden or not. This value is obsolete and does nothing since Qt 4.5: - \value DontUseSheet In previous versions of Qt, the static functions would - create a sheet by default if the static function was given a parent. This - is no longer supported in Qt 4.5, The static functions will always be an - application modal dialog. If you want to use sheets, use - QFileDialog::open() instead. + \value DontUseSheet In previous versions of Qt, the static + functions would create a sheet by default if the static function + was given a parent. This is no longer supported in Qt 4.5, The + static functions will always be an application modal dialog. If + you want to use sheets, use QFileDialog::open() instead. */ -- cgit v0.12 From 423d40c56f090f3619c8df5667dcfcb0c0a0dc32 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 11:24:21 +0200 Subject: doc: Added not about Mac OS X. On Mac OS X, QMenuBar::clear() does not remove menu items that have been merged into the system menu bar. Task-number: 255222 --- src/gui/widgets/qmenubar.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index e1d41de..caacc58 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -956,6 +956,13 @@ void QMenuBar::setActiveAction(QAction *act) /*! Removes all the actions from the menu bar. + \note On Mac OS X, menu items that have been merged to the system + menu bar are not removed by this function. One way to handle this + would be to remove the extra actions yourself. You can set the + \l{QAction::MenuRole}{menu role} on the different menus, so that + you know ahead of time which menu items get merged and which do + not. Then decide what to recreate or remove yourself. + \sa removeAction() */ void QMenuBar::clear() -- cgit v0.12 From c4b7fab9e8296915fff700704db26161bac8df0c Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Mon, 6 Jul 2009 10:19:01 +0200 Subject: Fix to paint big widgets in a scroll area If a big widget is inside a scroll area, and this widget is in the limits of XCOORD_MAX, its child might not be inside the limits. The child is then limited to wrect, but wrect might not be on the screen because the parent is scrolled. To avoid this problem, the widgets position should not influence whether wrect is used or not. Task-number: 144779 Reviewed-by: nrc --- src/gui/kernel/qwidget_mac.mm | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index d1e4230..b0531ec 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3823,7 +3823,6 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) Qt coordinate system for parent X coordinate system for parent (relative to parent's wrect). */ - QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX); QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX); QRect wrect; //xrect is the X geometry of my X widget. (starts out in parent's Qt coord sys, and ends up in parent's X coord sys) @@ -3901,7 +3900,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) } } - if (!validRange.contains(xrect)) { + if (xrect.height() > XCOORD_MAX || xrect.width() > XCOORD_MAX) { // we are too big, and must clip xrect &=wrectRange; wrect = xrect; @@ -3949,10 +3948,9 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) qt_mac_update_widget_posisiton(q, oldRect, xrect); - if (jump) { - updateSystemBackground(); + if (jump) q->update(); - } + if (mapWindow && !dontShow) { q->setAttribute(Qt::WA_Mapped); #ifndef QT_MAC_USE_COCOA -- cgit v0.12 From f0cd15365d683ad1998a32aab305cbcf69c3140e Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 13:11:42 +0200 Subject: doc: Corrected comment about effect of deleting a QObject from a thread. Task-number: 151180 --- doc/src/threads.qdoc | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/doc/src/threads.qdoc b/doc/src/threads.qdoc index c9d0904..9f7f857 100644 --- a/doc/src/threads.qdoc +++ b/doc/src/threads.qdoc @@ -428,20 +428,22 @@ an object and its children (the object cannot be moved if it has a parent). - Calling \c delete on a QObject from another thread than the - thread where it is created (or accessing the object in other - ways) is unsafe unless you can guarantee that the object isn't - processing events at the same moment. Use QObject::deleteLater() - instead; it will post a - \l{QEvent::DeferredDelete}{DeferredDelete} event, which the - event loop of the object's thread will eventually pick up. + Calling \c delete on a QObject from a thread other than the one + that \e owns the object (or accessing the object in other ways) is + unsafe, unless you guarantee that the object isn't processing + events at that moment. Use QObject::deleteLater() instead, and a + \l{QEvent::DeferredDelete}{DeferredDelete} event will be posted, + which the event loop of the object's thread will eventually pick + up. By default, the thread that \e owns a QObject is the thread + that \e creates the QObject, but not after QObject::moveToThread() + has been called. If no event loop is running, events won't be delivered to the - object. For example, if you create a QTimer object in a thread - but never call \l{QThread::exec()}{exec()}, the QTimer will never emit its - \l{QTimer::timeout()}{timeout()} signal. Calling - \l{QObject::deleteLater()}{deleteLater()} won't work either. (These - restrictions apply to the main thread as well.) + object. For example, if you create a QTimer object in a thread but + never call \l{QThread::exec()}{exec()}, the QTimer will never emit + its \l{QTimer::timeout()}{timeout()} signal. Calling + \l{QObject::deleteLater()}{deleteLater()} won't work + either. (These restrictions apply to the main thread as well.) You can manually post events to any object in any thread at any time using the thread-safe function -- cgit v0.12 From e446729d99bebaf7fac0110fcf22fc867d7229cb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 3 Jul 2009 11:55:06 +0200 Subject: remove arbitrary string length limits --- tools/linguist/lupdate/cpp.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index b1d2d01..35b41d4 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -58,10 +58,6 @@ QT_BEGIN_NAMESPACE static const char MagicComment[] = "TRANSLATOR "; -static const int yyIdentMaxLen = 128; -static const int yyCommentMaxLen = 65536; -static const int yyStringMaxLen = 65536; - #define STRINGIFY_INTERNAL(x) #x #define STRINGIFY(x) STRINGIFY_INTERNAL(x) #define STRING(s) static QString str##s(QLatin1String(STRINGIFY(s))) @@ -668,14 +664,9 @@ uint CppParser::getToken() yyCh = getChar(); if (yyCh == EOF || yyCh == '\n') break; - if (yyString.size() < yyStringMaxLen) { - yyString.append(QLatin1Char('\\')); - yyString.append(yyCh); - } - } else { - if (yyString.size() < yyStringMaxLen) - yyString.append(yyCh); + yyString.append(QLatin1Char('\\')); } + yyString.append(yyCh); yyCh = getChar(); } -- cgit v0.12 From 20d73ef1bf23569b09ca862f6c5e5971098613d6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 3 Jul 2009 13:28:16 +0200 Subject: support for id-based translations unlike in an earlier attempt, ids are textual this time. the developer is able to provide a template for the string. when lupdate and lrelease are integrated into the build process, this makes it possible to avoid a round-trip to a dedicated string designer during the early development stage. Requirement-id: QT-435 --- .../snippets/code/src_corelib_global_qglobal.cpp | 24 ++++++++ src/corelib/global/qglobal.cpp | 56 +++++++++++++++++ src/corelib/global/qglobal.h | 12 ++++ src/corelib/kernel/qcoreapplication.cpp | 6 ++ tests/auto/linguist/lrelease/tst_lrelease.cpp | 13 ++++ .../lupdate/testdata/good/parsecpp/main.cpp | 12 ++++ .../testdata/good/parsecpp/project.ts.result | 18 ++++++ tools/linguist/lrelease/main.cpp | 19 ++++-- tools/linguist/lupdate/cpp.cpp | 70 +++++++++++++++++++++- tools/linguist/shared/qm.cpp | 52 ++++++++++++---- tools/linguist/shared/translator.h | 2 + 11 files changed, 267 insertions(+), 17 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_global_qglobal.cpp b/doc/src/snippets/code/src_corelib_global_qglobal.cpp index 287181a..50052c3 100644 --- a/doc/src/snippets/code/src_corelib_global_qglobal.cpp +++ b/doc/src/snippets/code/src_corelib_global_qglobal.cpp @@ -358,6 +358,30 @@ QString global_greeting(int type) //! [36] +//! [qttrid] + //% "%n fooish bar(s) found.\n" + //% "Do you want to continue?" + QString text = qtTrId("qtn_foo_bar", n); +//! [qttrid] + + +//! [qttrid_noop] +static const char * const ids[] = { + //% "This is the first text." + QT_TRID_NOOP("qtn_1st_text"), + //% "This is the second text." + QT_TRID_NOOP("qtn_2nd_text"), + 0 +}; + +void TheClass::addLabels() +{ + for (int i = 0; ids[i]; ++i) + new QLabel(qtTrId(ids[i]), this); +} +//! [qttrid_noop] + + //! [37] qWarning("%s: %s", qPrintable(key), qPrintable(value)); //! [37] diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index f7a97e1..ad4868d 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2459,6 +2459,62 @@ int qrand() */ /*! + \fn QString qtTrId(const char *id, int n = -1) + \relates + \reentrant + \since 4.6 + + Returns a translated string identified by \a id. + If no matching string is found, the id itself is returned. This + should not happen under normal conditions. + + If \a n >= 0, all occurrences of \c %n in the resulting string + are replaced with a decimal representation of \a n. In addition, + depending on \a n's value, the translation text may vary. + + Meta data and comments can be passed as documented for QObject::tr(). + In addition, it is possible to supply a source string template like that: + + \tt{//% } + + or + + \tt{\begincomment% \endcomment} + + Example: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp qttrid + + Creating QM files suitable for use with this function requires passing + the \c -idbased option to the \c lrelease tool. + + \warning This method is reentrant only if all translators are + installed \e before calling this method. Installing or removing + translators while performing translations is not supported. Doing + so will probably result in crashes or other undesirable behavior. + + \sa QObject::tr(), QCoreApplication::translate(), {Internationalization with Qt} +*/ + +/*! + \macro QT_TRID_NOOP(id) + \relates + \since 4.6 + + Marks \a id for dynamic translation. + The only purpose of this macro is to provide an anchor for attaching + meta data like to qtTrId(). + + The macro expands to \a id. + + Example: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp qttrid_noop + + \sa qtTrId(), {Internationalization with Qt} +*/ + +/*! \macro QT_POINTER_SIZE \relates diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index a522bcf..a139a55 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2198,6 +2198,18 @@ inline const QForeachContainer *qForeachContainer(const QForeachContainerBase #define QT_TRANSLATE_NOOP_UTF8(scope, x) (x) #define QT_TRANSLATE_NOOP3(scope, x, comment) {x, comment} #define QT_TRANSLATE_NOOP3_UTF8(scope, x, comment) {x, comment} + +#ifndef QT_NO_TRANSLATION // ### This should enclose the NOOPs above + +// Defined in qcoreapplication.cpp +// The better name qTrId() is reserved for an upcoming function which would +// return a much more powerful QStringFormatter instead of a QString. +Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1); + +#define QT_TRID_NOOP(id) id + +#endif // QT_NO_TRANSLATION + #define QDOC_PROPERTY(text) /* diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e2708c3..054be70 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1675,6 +1675,12 @@ QString QCoreApplication::translate(const char *context, const char *sourceText, return result; } +// Declared in qglobal.h +QString qtTrId(const char *id, int n) +{ + return QCoreApplication::translate(0, id, 0, QCoreApplication::UnicodeUTF8, n); +} + bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator) { return QCoreApplication::self diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp index 512987d..ff90b3c 100644 --- a/tests/auto/linguist/lrelease/tst_lrelease.cpp +++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp @@ -55,6 +55,7 @@ private slots: void translate(); void mixedcodecs(); void compressed(); + void idbased(); void dupes(); private: @@ -191,6 +192,18 @@ void tst_lrelease::compressed() } +void tst_lrelease::idbased() +{ + QVERIFY(!QProcess::execute("lrelease -idbased testdata/idbased.ts")); + + QTranslator translator; + QVERIFY(translator.load("testdata/idbased.qm")); + qApp->installTranslator(&translator); + + QCOMPARE(qtTrId("test_id"), QString::fromAscii("This is a test string.")); + QCOMPARE(qtTrId("untranslated_id"), QString::fromAscii("This has no translation.")); +} + void tst_lrelease::dupes() { QProcess proc; diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp index 9fb43fe..735e4cd 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp @@ -175,3 +175,15 @@ class TestingTake17 : QObject { tr("even more cool"); } }; + + + + +//: again an extra comment, this time for id-based NOOP +//% "This is supposed\tto be quoted \" newline\n" +//% "backslashed \\ stuff." +QT_TRID_NOOP("this_a_id") + +//~ some thing +//% "This needs to be here. Really." +QString test = qtTrId("this_another_id", n); diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result index 5bd7525..97d3bce 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result @@ -2,6 +2,24 @@ + + + + This is supposed to be quoted " newline +backslashed \ stuff. + again an extra comment, this time for id-based NOOP + + + + + This needs to be here. Really. + + + + thing + + + Dialog2 diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index 86b7866..5fbecac 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -70,6 +70,8 @@ static void printUsage() "format into the 'compiled' .qm format used by QTranslator objects.\n\n" "Options:\n" " -help Display this information and exit\n" + " -idbased\n" + " Use IDs instead of source strings for message keying\n" " -compress\n" " Compress the .qm files\n" " -nounfinished\n" @@ -99,7 +101,7 @@ static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbo static bool releaseTranslator(Translator &tor, const QString &qmFileName, bool verbose, bool ignoreUnfinished, - bool removeIdentical, TranslatorSaveMode mode) + bool removeIdentical, bool idBased, TranslatorSaveMode mode) { Translator::reportDuplicates(tor.resolveDuplicates(), qmFileName, verbose); @@ -121,6 +123,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName, ConversionData cd; cd.m_verbose = verbose; cd.m_ignoreUnfinished = ignoreUnfinished; + cd.m_idBased = idBased; cd.m_saveMode = mode; bool ok = tor.release(&file, cd); file.close(); @@ -136,7 +139,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName, } static bool releaseTsFile(const QString& tsFileName, bool verbose, - bool ignoreUnfinished, bool removeIdentical, TranslatorSaveMode mode) + bool ignoreUnfinished, bool removeIdentical, bool idBased, TranslatorSaveMode mode) { Translator tor; if (!loadTsFile(tor, tsFileName, verbose)) @@ -151,7 +154,7 @@ static bool releaseTsFile(const QString& tsFileName, bool verbose, } qmFileName += QLatin1String(".qm"); - return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, mode); + return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, idBased, mode); } int main(int argc, char **argv) @@ -164,6 +167,7 @@ int main(int argc, char **argv) bool verbose = true; // the default is true starting with Qt 4.2 bool ignoreUnfinished = false; + bool idBased = false; // the default mode is SaveEverything starting with Qt 4.2 TranslatorSaveMode mode = SaveEverything; bool removeIdentical = false; @@ -175,6 +179,9 @@ int main(int argc, char **argv) if (args[i] == QLatin1String("-compress")) { mode = SaveStripped; continue; + } else if (args[i] == QLatin1String("-idbased")) { + idBased = true; + continue; } else if (args[i] == QLatin1String("-nocompress")) { mode = SaveEverything; continue; @@ -232,7 +239,7 @@ int main(int argc, char **argv) qPrintable(args[i])); } else { foreach (const QString &trans, translations) - if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, mode)) + if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, idBased, mode)) return 1; } } else { @@ -243,7 +250,7 @@ int main(int argc, char **argv) } } else { if (outputFile.isEmpty()) { - if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, mode)) + if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, idBased, mode)) return 1; } else { if (!loadTsFile(tor, args[i], verbose)) @@ -254,7 +261,7 @@ int main(int argc, char **argv) if (!outputFile.isEmpty()) return releaseTranslator(tor, outputFile, verbose, ignoreUnfinished, - removeIdentical, mode) ? 0 : 1; + removeIdentical, idBased, mode) ? 0 : 1; return 0; } diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 35b41d4..58e094b 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -199,7 +199,7 @@ private: enum { Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return, - Tok_tr = 10, Tok_trUtf8, Tok_translate, Tok_translateUtf8, + Tok_tr = 10, Tok_trUtf8, Tok_translate, Tok_translateUtf8, Tok_trid, Tok_Q_OBJECT = 20, Tok_Q_DECLARE_TR_FUNCTIONS, Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon, Tok_Equals, @@ -553,6 +553,8 @@ uint CppParser::getToken() return Tok_Q_DECLARE_TR_FUNCTIONS; if (yyIdent == QLatin1String("QT_TR_NOOP")) return Tok_tr; + if (yyIdent == QLatin1String("QT_TRID_NOOP")) + return Tok_trid; if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP")) return Tok_translate; if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP3")) @@ -588,6 +590,10 @@ uint CppParser::getToken() if (yyIdent == QLatin1String("namespace")) return Tok_namespace; break; + case 'q': + if (yyIdent == QLatin1String("qtTrId")) + return Tok_trid; + break; case 'r': if (yyIdent == QLatin1String("return")) return Tok_return; @@ -1328,6 +1334,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) QString comment; QString extracomment; QString msgid; + QString sourcetext; TranslatorMessage::ExtraData extra; QString prefix; #ifdef DIAGNOSE_RETRANSLATABILITY @@ -1514,6 +1521,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) case Tok_trUtf8: if (!results->tor) goto case_default; + if (!sourcetext.isEmpty()) + qWarning("%s:%d: //%% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n", + qPrintable(yyFileName), yyLineNo); utf8 = (yyTok == Tok_trUtf8); line = yyLineNo; yyTok = getToken(); @@ -1611,6 +1621,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) case Tok_translate: if (!results->tor) goto case_default; + if (!sourcetext.isEmpty()) + qWarning("%s:%d: //%% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n", + qPrintable(yyFileName), yyLineNo); utf8 = (yyTok == Tok_translateUtf8); line = yyLineNo; yyTok = getToken(); @@ -1660,6 +1673,27 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) msgid.clear(); extra.clear(); break; + case Tok_trid: + if (!results->tor) + goto case_default; + if (!sourcetext.isEmpty()) { + if (!msgid.isEmpty()) + qWarning("%s:%d: //= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n", + qPrintable(yyFileName), yyLineNo); + //utf8 = false; // Maybe use //%% or something like that + line = yyLineNo; + yyTok = getToken(); + if (match(Tok_LeftParen) && matchString(&msgid) && !msgid.isEmpty()) { + bool plural = match(Tok_Comma); + recordMessage(line, QString(), sourcetext, QString(), extracomment, + msgid, extra, false, plural); + } + sourcetext.clear(); + } + extracomment.clear(); + msgid.clear(); + extra.clear(); + break; case Tok_Q_DECLARE_TR_FUNCTIONS: case Tok_Q_OBJECT: namespaces.last()->hasTrFunctions = true; @@ -1689,6 +1723,40 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) int k = yyComment.indexOf(QLatin1Char(' ')); if (k > -1) extra.insert(yyComment.left(k), yyComment.mid(k + 1).trimmed()); + } else if (yyComment.startsWith(QLatin1Char('%'))) { + int p = 1, c; + forever { + if (p >= yyComment.length()) + break; + c = yyComment.unicode()[p++].unicode(); + if (isspace(c)) + continue; + if (c != '"') { + qWarning("%s:%d: Unexpected character in meta string\n", + qPrintable(yyFileName), yyLineNo); + break; + } + forever { + if (p >= yyComment.length()) { + whoops: + qWarning("%s:%d: Unterminated meta string\n", + qPrintable(yyFileName), yyLineNo); + break; + } + c = yyComment.unicode()[p++].unicode(); + if (c == '"') + break; + if (c == '\\') { + if (p >= yyComment.length()) + goto whoops; + c = yyComment.unicode()[p++].unicode(); + if (c == '\n') + goto whoops; + sourcetext.append(QLatin1Char('\\')); + } + sourcetext.append(c); + } + } } else { comment = yyComment.simplified(); if (comment.startsWith(QLatin1String(MagicComment))) { diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index ec61cb6..05d8e12 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -173,6 +173,7 @@ public: bool save(QIODevice *iod); void insert(const TranslatorMessage &msg, bool forceComment); + void insertIdBased(const TranslatorMessage &message); void squeeze(TranslatorSaveMode mode); @@ -436,6 +437,16 @@ void Releaser::insert(const TranslatorMessage &message, bool forceComment) insertInternal(message, forceComment, false); } +void Releaser::insertIdBased(const TranslatorMessage &message) +{ + QStringList tlns = message.translations(); + for (int i = 0; i < tlns.size(); ++i) + if (tlns.at(i).isEmpty()) + tlns[i] = message.sourceText(); + ByteTranslatorMessage bmsg("", originalBytes(message.id(), false), "", tlns); + m_messages.insert(bmsg, 0); +} + void Releaser::setNumerusRules(const QByteArray &rules) { m_numerusRules = rules; @@ -689,11 +700,17 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData int finished = 0; int unfinished = 0; int untranslated = 0; + int missingIds = 0; + int droppedData = 0; for (int i = 0; i != translator.messageCount(); ++i) { const TranslatorMessage &msg = translator.message(i); TranslatorMessage::Type typ = msg.type(); if (typ != TranslatorMessage::Obsolete) { + if (cd.m_idBased && msg.id().isEmpty()) { + ++missingIds; + continue; + } if (typ == TranslatorMessage::Unfinished) { if (msg.translation().isEmpty()) { ++untranslated; @@ -706,19 +723,34 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData } else { ++finished; } - // 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); + if (cd.m_idBased) { + if (!msg.context().isEmpty() || !msg.comment().isEmpty()) + ++droppedData; + releaser.insertIdBased(msg); + } else { + // 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); + } } } + if (missingIds) + cd.appendError(QCoreApplication::translate("LRelease", + "Dropped %n message(s) which had no ID.", 0, + QCoreApplication::CodecForTr, missingIds)); + if (droppedData) + cd.appendError(QCoreApplication::translate("LRelease", + "Excess context/disambiguation dropped from %n message(s).", 0, + QCoreApplication::CodecForTr, droppedData)); + releaser.squeeze(cd.m_saveMode); bool saved = releaser.save(&dev); if (saved && cd.isVerbose()) { diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index ac824f3..fb17fd1 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -65,6 +65,7 @@ public: m_ignoreUnfinished(false), m_sortContexts(false), m_noUiLines(false), + m_idBased(false), m_saveMode(SaveEverything) {} @@ -97,6 +98,7 @@ public: bool m_ignoreUnfinished; bool m_sortContexts; bool m_noUiLines; + bool m_idBased; TranslatorSaveMode m_saveMode; }; -- cgit v0.12 From a59fbee567571827c3a1505b125b9dfb3788c79e Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Mon, 6 Jul 2009 13:45:28 +0200 Subject: update German translation - unification - typos Merge-request: 823 Reviewed-by: Oswald Buddenhagen --- translations/assistant_de.ts | 100 +++++++++++----------- translations/linguist_de.ts | 194 +++++++++++++++++++++---------------------- 2 files changed, 150 insertions(+), 144 deletions(-) diff --git a/translations/assistant_de.ts b/translations/assistant_de.ts index 72b24b6..f702465 100644 --- a/translations/assistant_de.ts +++ b/translations/assistant_de.ts @@ -14,7 +14,7 @@ Warning - Warnung + Achtung @@ -68,12 +68,12 @@ Delete Folder - Verzeichnis löschen + Ordner löschen Rename Folder - Verzeichnis umbenennen + Ordner umbenennen @@ -91,7 +91,7 @@ You are going to delete a Folder, this will also<br>remove it's content. Are you sure to continue? - Wenn Sie dieses Verzeichnis löschen, wird auch<br>dessen kompletter Inhalt gelöscht! Fortfahren? + Wenn Sie diesen Ordner löschen, wird auch<br>dessen kompletter Inhalt gelöscht. Möchten Sie wirklich fortfahren? @@ -123,12 +123,12 @@ Delete Folder - Verzeichnis löschen + Ordner löschen Rename Folder - Verzeichnis umbenennen + Ordner umbenennen @@ -201,7 +201,7 @@ Add Bookmark for this Page... - Lesezeichen für diese Seite hinzufügen... + Lesezeichen für diese Seite hinzufügen ... @@ -236,7 +236,7 @@ Filter Name: - Filter Name: + Filtername: @@ -244,22 +244,22 @@ Previous - Vorherige + Zurück Next - Nächste + Weiter Case Sensitive - Gross/ Kleinschreibung beachten + Groß-/Kleinschreibung beachten Whole words - Gesamte Worte + Ganze Wörter @@ -316,12 +316,12 @@ <title>Error 404...</title><div align="center"><br><br><h1>The page could not be found</h1><br><h3>'%1'</h3></div> - <title>Fehler 404...</title><div align="center"><br><br><h1>Die Seite konnte nicht gefunden werden!</h1><br><h3>'%1'</h3></div> + <title>Fehler 404 ...</title><div align="center"><br><br><h1>Die Seite kann nicht gefunden werden.</h1><br><h3>'%1'</h3></div> Copy &Link Location - &Link Adresse kopieren + &Link-Adresse kopieren @@ -346,7 +346,7 @@ &Look for: - Suche &nach: + Suchen &nach: @@ -370,7 +370,7 @@ Downloading documentation info... - Dokumentationsinformation herunterladen... + Dokumentationsinformation herunterladen ... @@ -387,12 +387,12 @@ The file %1 already exists. Do you want to overwrite it? - Die Datei %1 existiert bereits. Überschreiben? + Die Datei %1 existiert bereits. Möchten Sie sie überschreiben? Unable to save the file %1: %2. - Die Datei %1 konnte nicht gespeichert werden! Ursache: %2 + Die Datei %1 kann nicht gespeichert werden: %2. @@ -404,7 +404,7 @@ Download failed: %1. - Herunterladen fehlgeschlagen: %1 + Herunterladen fehlgeschlagen: %1. @@ -431,7 +431,7 @@ Available Documentation: - Verfügbare Dokumentationen: + Verfügbare Dokumentation: @@ -451,7 +451,7 @@ Installation Path: - Installationsverzeichnis: + Installationsordner: @@ -504,17 +504,17 @@ Page Set&up... - S&eite einrichten... + S&eite einrichten ... Print Preview... - Druckvorschau... + Druckvorschau ... &Print... - &Drucken... + &Drucken ... CTRL+P @@ -523,7 +523,7 @@ New &Tab - Neue &Seite + Neuer &Tab CTRL+T @@ -532,7 +532,7 @@ &Close Tab - &Seite schließen + Tab &schließen CTRL+W @@ -555,7 +555,7 @@ &Copy selected Text - &Kopieren + Ausgewählten Text &kopieren Ctrl+C @@ -564,7 +564,7 @@ &Find in Text... - &Textsuche... + &Textsuche ... Ctrl+F @@ -591,7 +591,7 @@ Preferences... - Einstellungen... + Einstellungen ... View @@ -656,7 +656,7 @@ Ctrl+Home - Strg+Pos1 + Ctrl+Home @@ -671,7 +671,7 @@ Sync with Table of Contents - Seite mit Inhalt Tab syncronisieren + Seite mit Inhalt-Tab abgleichen @@ -696,7 +696,7 @@ Add Bookmark... - Lesezeichen hinzufügen... + Lesezeichen hinzufügen ... CTRL+B @@ -709,7 +709,7 @@ About... - Über... + Über ... @@ -775,7 +775,7 @@ Looking for Qt Documentation... - Suche nach Qt-Dokumentation... + Suche nach Qt-Dokumentation ... @@ -790,7 +790,7 @@ Ctrl+M - CTRL+M + Ctrl+M @@ -823,7 +823,7 @@ &Go - &Gehe + &Gehe zu @@ -869,12 +869,12 @@ Qt Compressed Help Files (*.qch) - Komprimierte Hilfe-Dateien (*.qch) + Komprimierte Hilfedateien (*.qch) The specified file is not a valid Qt Help File! - Die angegebene Datei ist keine Qt-Hilfe-Datei. + Die angegebene Datei ist keine Qt-Hilfedatei. @@ -889,7 +889,7 @@ Some documents currently opened in Assistant reference the documentation you are attempting to remove. Removing the documentation will close those documents. - Einige der gegenwärtig geöffneten Dokumente stammen aus der Dokumentation, die Sie gerade zu löschen versuchen. Sie werden beim Löschen geschlossen. + Einige der derzeit geöffneten Dokumente stammen aus der Dokumentation, die Sie gerade zu löschen versuchen. Sie werden beim Löschen geschlossen. @@ -904,7 +904,7 @@ Use custom settings - Benutze erweiterte Einstellungen + Benutzerdefinierte Einstellungen verwenden @@ -972,12 +972,12 @@ Registered Documentation: - Registrierte Dokumentationen: + Registrierte Dokumentation: Add... - Hinzufügen... + Hinzufügen ... Network @@ -1008,7 +1008,7 @@ Restore to default - Vorgabe wiederherstellen + Voreinstellung wiederherstellen @@ -1035,7 +1035,7 @@ Invalid URL! - Unbekannte URL. + Ungültige URL. @@ -1091,7 +1091,10 @@ Reason: %2 - Could not register documentation file%1Reason:%2 + Dokumentationsdatei %1 kann nicht registriert werden + +Grund: +%2 @@ -1105,7 +1108,10 @@ Reason: Reason: %2 - Could not unregister documentation file%1Reason:%2 + Registrierung der Dokumentationsdatei %1 kann nicht aufgehoben werden + +Grund: +%2 @@ -1152,7 +1158,7 @@ Reason: Copy &Link Location - &Link Adresse kopieren + &Link-Adresse kopieren diff --git a/translations/linguist_de.ts b/translations/linguist_de.ts index 5e9712c..48f1f2e 100644 --- a/translations/linguist_de.ts +++ b/translations/linguist_de.ts @@ -34,7 +34,7 @@ Searching, please wait... - Suche, bitte warten... + Suche, bitte warten ... @@ -67,7 +67,7 @@ Set translated entries to finished - Markiere Übersetzung als erledigt + Übersetzung als erledigt markieren @@ -77,7 +77,7 @@ Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked. - Beachten Sie, dass die geänderten Einträge in den Status 'unerledigt' zurückgesetzt werden, wenn 'Markiere Übersetzung als erledigt' deaktiviert ist. + Beachten Sie, dass die geänderten Einträge in den Status 'unerledigt' zurückgesetzt werden, wenn 'Übersetzung als erledigt markieren' deaktiviert ist. @@ -215,17 +215,17 @@ Es wird mit einer einfachen Universalform gearbeitet. Accelerator possibly superfluous in translation. - Zusätzliche Kurztaste im Übersetzungstext. + Möglicherweise überflüssiger Kurzbefehl im Übersetzungstext. Accelerator possibly missing in translation. - Kurztaste fehlt im Übersetzungstext. + Kurzbefehl fehlt im Übersetzungstext. Translation does not end with the same punctuation as the source text. - Interpunktion am Ende des Übersetzungstextes unterscheidet sich von Interpunktion im Quelltext. + Interpunktion am Ende des Übersetzungstextes unterscheidet sich von Interpunktion des Ursprungstextes. @@ -235,7 +235,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Translation does not refer to the same place markers as in the source text. - Platzhalter im Übersetzungstext und Quelltext unterscheiden sich. + Platzhalter im Übersetzungstext und Ursprungstext unterscheiden sich. @@ -276,7 +276,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Source texts are searched when checked. - Wenn aktiviert, wird in dem Ursprungstexten gesucht. + Wenn aktiviert, wird in den Ursprungstexten gesucht. Source texts @@ -322,7 +322,7 @@ Es wird mit einer einfachen Universalform gearbeitet. &Source texts - &Quelltexte + &Ursprungstexte @@ -347,7 +347,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Click here to find the next occurrence of the text you typed in. - Hier klicken für das nächste Vorkommen des Suchtextes. + Klicken Sie hier, um zum nächsten Vorkommen des Suchtextes zu springen. @@ -357,7 +357,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Click here to close this window. - Klicken Sie hier um das Fenster zu schließen. + Klicken Sie hier, um das Fenster zu schließen. @@ -510,12 +510,12 @@ p, li { white-space: pre-wrap; } &Edit Phrase Book - Wörterbuch &Editieren + Wörterbuch &bearbeiten &Print Phrase Book - Wörterbuch &Drucken + Wörterbuch &drucken @@ -572,7 +572,7 @@ p, li { white-space: pre-wrap; } &Open... - Ö&ffnen... + Ö&ffnen ... @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Previous unfinished item. - Vorherige Unerledigte + Vorheriger unerledigter Eintrag. @@ -623,7 +623,7 @@ p, li { white-space: pre-wrap; } Next unfinished item. - Nächste Unerledigte + Nächster unerledigter Eintrag. @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Copy from source text - &Ursprungstext übernehmen + Ursprungstext übernehmen @@ -698,17 +698,17 @@ p, li { white-space: pre-wrap; } Toggle the validity check of place markers, i.e. whether %1, %2, ... are used consistently in the source text and translation text. If the check fails, a message is shown in the warnings window. - Die Prüfung der Platzhalter, das heißt, ob %1, %2 usw. in Quelltext und Übersetzung übereinstimmend verwendet werden, ein- bzw. ausschalten. Bei Fehlschlag wird eine Warnung im Hinweis-Fenster angezeigt. + Die Prüfung der Platzhalter, das heißt, ob %1, %2 usw. in Ursprungstext und Übersetzung übereinstimmend verwendet werden, ein- bzw. ausschalten. Bei Fehlschlag wird eine Warnung im Hinweis-Fenster angezeigt. Open Read-O&nly... - Schr&eibgeschützt öffnen... + Schr&eibgeschützt öffnen ... &Save All - &Alles speichern + &Alle speichern @@ -725,7 +725,7 @@ p, li { white-space: pre-wrap; } Save As... - Speichern unter... + Speichern unter ... @@ -745,7 +745,7 @@ p, li { white-space: pre-wrap; } &Print... - &Drucken... + &Drucken ... Print a list of all the phrases in the current Qt translation source file. @@ -853,7 +853,7 @@ p, li { white-space: pre-wrap; } Select &All - Alle &markieren + Alles &markieren @@ -868,12 +868,12 @@ p, li { white-space: pre-wrap; } &Find... - &Suchen... + &Suchen ... Search for some text in the translation source file. - Suche einen Text in der Übersetzungsdatei. + In der Übersetzungsdatei nach Text suchen. @@ -888,7 +888,7 @@ p, li { white-space: pre-wrap; } Continue the search where it was left. - Setze die Suche fort. + Die Suche fortsetzen. @@ -898,7 +898,7 @@ p, li { white-space: pre-wrap; } &Prev Unfinished - &Vorherige Unerledigte + &Vorheriger Unerledigter @@ -913,7 +913,7 @@ p, li { white-space: pre-wrap; } Ctrl+W - + Ctrl+W Moves to the previous unfinished item. @@ -927,7 +927,7 @@ p, li { white-space: pre-wrap; } &Next Unfinished - &Nächste Unerledigte + &Nächster Unerledigter Moves to the next unfinished item. @@ -940,7 +940,7 @@ p, li { white-space: pre-wrap; } P&rev - V&orherige + V&orheriger Moves to the previous item. @@ -954,7 +954,7 @@ p, li { white-space: pre-wrap; } Ne&xt - Nä&chste + Nä&chster Moves to the next item. @@ -967,7 +967,7 @@ p, li { white-space: pre-wrap; } &Done and Next - &Fertig und Nächste + &Fertig und Nächster Marks this item as done and moves to the next unfinished item. @@ -980,7 +980,7 @@ p, li { white-space: pre-wrap; } Copies the source text into the translation field. - Kopiere den Ursprungstext in das Übersetzungsfeld. + Kopiert den Ursprungstext in das Übersetzungsfeld. @@ -990,7 +990,7 @@ p, li { white-space: pre-wrap; } &Accelerators - &Kurztasten + &Kurzbefehle Toggle validity checks of accelerators. @@ -1013,7 +1013,7 @@ p, li { white-space: pre-wrap; } Toggle checking that phrase suggestions are used. - Aktiviere/Deaktiviere Überprüfung, ob Wörterbucheinträge benutzt wurden. + Überprüfung, ob Wörterbucheinträge benutzt werden, aktivieren/deaktivieren. @@ -1027,12 +1027,12 @@ p, li { white-space: pre-wrap; } &New Phrase Book... - &Neues Wörterbuch... + &Neues Wörterbuch ... Create a new phrase book. - Erzeuge ein neues Wörterbuch. + Ein neues Wörterbuch erzeugen. @@ -1042,12 +1042,12 @@ p, li { white-space: pre-wrap; } &Open Phrase Book... - &Wörterbuch Öffnen... + &Wörterbuch öffnen ... Open a phrase book to assist translation. - Öffne ein Wörterbuch als Unterstützung bei der Übersetzung. + Ein Wörterbuch zur Unterstützung bei der Übersetzung öffnen. @@ -1062,17 +1062,17 @@ p, li { white-space: pre-wrap; } Sort the items back in the same order as in the message file. - Sortiere die Einträge in der gleichen Reihenfolge wie in der ursprünglichen Übersetzungsdatei. + Die Einträge in der gleichen Reihenfolge wie in der ursprünglichen Übersetzungsdatei sortieren. &Display guesses - &Vorschläge + &Vorschläge anzeigen Set whether or not to display translation guesses. - Aktiviere/Deaktivere Darstellung von Übersetzungsvorschlägen. + Darstellung von Übersetzungsvorschlägen aktivieren/deaktivieren. @@ -1107,7 +1107,7 @@ p, li { white-space: pre-wrap; } Display information about the Qt toolkit by Trolltech. - Informationen über das Qt-Toolkit von Trolltech an. + Informationen über das Qt-Toolkit von Trolltech anzeigen. @@ -1132,18 +1132,18 @@ p, li { white-space: pre-wrap; } &Search And Translate... - Suchen und &Übersetzen... + Suchen und &übersetzen ... Replace the translation on all entries that matches the search source text. - Ersetze die Übersetzung von allen Einträgen, die dem Suchtext entsprechen. + Die Übersetzung aller Einträge ersetzen, die dem Suchtext entsprechen. &Batch Translation... - &Automatische Übersetzung... + &Automatische Übersetzung ... @@ -1160,7 +1160,7 @@ p, li { white-space: pre-wrap; } Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the .ts file. - Eine Qt-Nachrichtendatei aus der aktuellen Übersetzungsdatei erzeugen. Der Dateiname wird automatisch aus dem Namen der .ts-Datei abgeleitet. + Eine Qt-Nachrichtendatei aus der aktuellen Übersetzungsdatei erzeugen. Der Dateiname wird automatisch aus dem Namen der TS-Datei abgeleitet. @@ -1224,7 +1224,7 @@ p, li { white-space: pre-wrap; } Loading... - Lade... + Lade ... @@ -1298,7 +1298,7 @@ Alle Dateien (*) Printing... - Drucke... + Drucke ... @@ -1324,7 +1324,7 @@ Alle Dateien (*) Printing... (page %1) - Drucke... (Seite %1) + Drucke ... (Seite %1) @@ -1355,7 +1355,7 @@ Alle Dateien (*) Qt Linguist - + Qt Linguist @@ -1393,7 +1393,7 @@ Alle Dateien (*) No more occurrences of '%1'. Start over? - Keine weiteren Fundstellen von '%1'. Von vorne beginnen? + Keine weiteren Vorkommen von '%1'. Von vorne beginnen? @@ -1440,7 +1440,7 @@ Alle Dateien (*) No appropriate phrasebook found. - Es wurde kein geeignetes Wörterbuch gefunden. + Es kann kein geeignetes Wörterbuch gefunden werden. @@ -1484,12 +1484,12 @@ Alle Dateien (*) Qt Linguist[*] - + Qt Linguist[*] %1[*] - Qt Linguist - + %1[*] - Qt Linguist @@ -1510,27 +1510,27 @@ Alle Dateien (*) Ctrl+M - + Ctrl+M Display the manual for %1. - Zeige Handbuch für %1 an. + Handbuch zu %1 anzeigen. Display information about %1. - Zeige Informationen über %1 an. + Informationen über %1 anzeigen. &Save '%1' - '%1' &Speichern + '%1' &speichern Save '%1' &As... - Speichere '%1' &unter... + '%1' speichern &unter ... @@ -1540,12 +1540,12 @@ Alle Dateien (*) Release '%1' As... - Gebe '%1'frei unter ... + '%1' freigeben unter ... &Close '%1' - '%1' &Schließen + '%1' &schließen @@ -1572,22 +1572,22 @@ Alle Dateien (*) Translation File &Settings for '%1'... - Einstellungen der Übersetzungs&datei für '%1'... + Einstellungen der Übersetzungs&datei für '%1' ... &Batch Translation of '%1'... - &Automatische Übersetzung von '%1'... + &Automatische Übersetzung von '%1' ... Search And &Translate in '%1'... - Suchen und &Übersetzen in '%1'... + Suchen und &übersetzen in '%1' ... Search And &Translate... - Suchen und &Übersetzen... + Suchen und &übersetzen ... @@ -1622,27 +1622,27 @@ Alle Dateien (*) Cannot read from phrase book '%1'. - Kann Wörterbuch '%1' nicht lesen. + Wörterbuch '%1' kann nicht gelesen werden. Close this phrase book. - Schließe dieses Wörterbuch. + Dieses Wörterbuch schließen. Enables you to add, modify, or delete entries in this phrase book. - Erlaubt das Hinzufügen, Ändern und Entfernen von Einträgen aus dem Wörterbuch. + Erlaubt das Hinzufügen, Ändern und Entfernen von Wörterbuch-Einträgen. Print the entries in this phrase book. - Drucke die Einträge des Wörterbuchs. + Die Einträge des Wörterbuchs drucken. Cannot create phrase book '%1'. - Kann Wörterbuch '%1' nicht erzeugen. + Wörterbuch '%1' kann nicht erzeugt werden. @@ -1657,7 +1657,7 @@ Alle Dateien (*) Open/Refresh Form &Preview - Öffne/Aktualisiere die &Vorschau + Die &Vorschau öffnen/&aktualisieren @@ -1673,7 +1673,7 @@ Alle Dateien (*) Translation File &Settings... - E&instellungen... + E&instellungen ... Other &Languages... @@ -1686,7 +1686,7 @@ Alle Dateien (*) &Add to Phrase Book - &Füge zum Wörterbuch hinzu + Zum Wörterbuch &hinzufügen @@ -1696,12 +1696,12 @@ Alle Dateien (*) Ctrl+J - + Ctrl+J Ctrl+Shift+J - + Ctrl+Shift+J @@ -1893,7 +1893,7 @@ Zeile: %2 %1[*] - Qt Linguist - + %1[*] - Qt Linguist @@ -1903,12 +1903,12 @@ Zeile: %2 Cannot save phrase book '%1'. - Kann Wörterbuch '%1' nicht speichern. + Wörterbuch '%1' kann nicht gespeichert werden. Edit Phrase Book - Ändere Wörterbuch + Wörterbuch bearbeiten This window allows you to add, modify, or delete phrases in a phrase book. @@ -1917,7 +1917,7 @@ Zeile: %2 This window allows you to add, modify, or delete entries in a phrase book. - Dieses Fenster erlaubt das Hinzufügen, Ändern und Entfernen von Einträgen aus dem Wörterbuch. + Dieses Fenster erlaubt das Hinzufügen, Ändern und Entfernen von Wörterbuch-Einträgen. @@ -1927,7 +1927,7 @@ Zeile: %2 This is the phrase in the target language corresponding to the source phrase. - Dies ist der Text, die in der Zielsprache dem Ursprungstext entspricht. + Dies ist der Text, der in der Zielsprache dem Ursprungstext entspricht. @@ -1952,7 +1952,7 @@ Zeile: %2 Click here to add the phrase to the phrase book. - Füge eine neuen Eintrag ins Wörterbuch hinzu. + Einen neuen Eintrag ins Wörterbuch einfügen. @@ -1962,17 +1962,17 @@ Zeile: %2 Click here to remove the entry from the phrase book. - Entferne den Eintrag aus dem Wörterbuch. + Den Eintrag aus dem Wörterbuch entfernen. &Remove Entry - &Entferne Eintrag + &Eintrag entfernen Settin&gs... - &Einstellungen... + &Einstellungen ... &New Phrase @@ -1989,7 +1989,7 @@ Zeile: %2 Click here to save the changes made. - Speichere Änderungen. + Änderungen speichern. @@ -1999,7 +1999,7 @@ Zeile: %2 Click here to close this window. - Klicken Sie hier um das Fenster zu schließen. + Klicken Sie hier, um das Fenster zu schließen. @@ -2053,7 +2053,7 @@ Zeile: %2 Compiled Qt translations - + Kompilierte Qt-Übersetzungen @@ -2079,7 +2079,7 @@ Zeile: %2 C++ source files - C++-Quelltextdateien' + C++-Quelltextdateien @@ -2089,7 +2089,7 @@ Zeile: %2 GNU Gettext localization files - GNU-Gettext Übersetzungsdateien + GNU-Gettext-Übersetzungsdateien @@ -2109,7 +2109,7 @@ Zeile: %2 Qt translation sources (latest format) - Qt Übersetzungsdateien (aktuelles Format) + Qt-Übersetzungsdateien (aktuelles Format) @@ -2213,7 +2213,7 @@ Zeile: %2 Words: - Worte: + Wörter: @@ -2654,7 +2654,7 @@ Alle Dateien (*) Search options - Suchoptionen + Sucheinstellungen @@ -2669,12 +2669,12 @@ Alle Dateien (*) Mark new translation as &finished - Markiere neue Übersetzung als &erledigt + Neue Übersetzung als &erledigt markieren Click here to find the next occurrence of the text you typed in. - Hier klicken für das nächste Vorkommen des Suchtextes. + Klicken Sie hier, um zum nächsten Vorkommen des Suchtextes zu springen. @@ -2689,12 +2689,12 @@ Alle Dateien (*) Translate All - Alle Übersetzen + Alle übersetzen Click here to close this window. - Klicken Sie hier um das Fenster zu schließen. + Klicken Sie hier, um das Fenster zu schließen. -- cgit v0.12 From 33604fb02fa463f36fa78e515bb42a34a746f0f2 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Mon, 6 Jul 2009 13:47:01 +0200 Subject: general wording change for some file type names - .ts file -> TS file - .qm file -> QM file - .ui file -> UI file + a handfull of typos I stumbled over Merge-request: 802 Reviewed-by: Oswald Buddenhagen --- doc/src/designer-manual.qdoc | 40 +++++++-------- doc/src/dnd.qdoc | 2 +- doc/src/examples/arrowpad.qdoc | 8 +-- doc/src/examples/calculatorform.qdoc | 6 +-- doc/src/examples/helloscript.qdoc | 12 ++--- doc/src/examples/hellotr.qdoc | 26 +++++----- doc/src/examples/multipleinheritance.qdoc | 2 +- doc/src/examples/qtscripttetrix.qdoc | 2 +- doc/src/examples/svggenerator.qdoc | 4 +- doc/src/examples/textfinder.qdoc | 4 +- doc/src/examples/worldtimeclockbuilder.qdoc | 2 +- doc/src/i18n.qdoc | 18 +++---- doc/src/linguist-manual.qdoc | 59 +++++++++++----------- doc/src/porting4-canvas.qdoc | 2 +- doc/src/porting4-designer.qdoc | 40 +++++++-------- doc/src/porting4-overview.qdoc | 4 +- doc/src/porting4.qdoc | 12 ++--- doc/src/qmake-manual.qdoc | 18 +++---- doc/src/qmsdev.qdoc | 2 +- doc/src/qt3to4.qdoc | 2 +- doc/src/qt4-intro.qdoc | 2 +- doc/src/qtdesigner.qdoc | 8 +-- doc/src/qthelp.qdoc | 2 +- doc/src/qtscript.qdoc | 24 ++++----- doc/src/qtuiloader.qdoc | 2 +- doc/src/signalsandslots.qdoc | 2 +- doc/src/snippets/code/doc_src_linguist-manual.qdoc | 6 +-- doc/src/templates.qdoc | 2 +- examples/uitools/textfinder/forms/input.txt | 2 +- mkspecs/features/uic.prf | 2 +- src/corelib/kernel/qobject.cpp | 2 +- src/corelib/kernel/qtranslator.cpp | 2 +- src/tools/uic/uic.cpp | 4 +- src/tools/uic3/main.cpp | 6 +-- src/tools/uic3/uic.cpp | 4 +- src/xmlpatterns/data/qresourceloader_p.h | 2 +- .../testdata/good/mergeui/project.ts.before | 2 +- .../good/mergeui_obsolete/project.ts.result | 2 +- .../testdata/good/mergeui_obsolete/project.ui | 2 +- .../testdata/good/textsimilarity/project.ts.result | 2 +- .../testdata/good/textsimilarity/project.ui | 2 +- tools/designer/data/generate_shared.xsl | 4 +- .../components/formeditor/qdesigner_resource.cpp | 6 +-- tools/designer/src/designer/mainwindow.cpp | 2 +- .../designer/src/designer/qdesigner_workbench.cpp | 2 +- tools/designer/src/lib/sdk/abstractformwindow.cpp | 14 ++--- tools/designer/src/lib/sdk/script.cpp | 6 +-- .../designer/src/lib/uilib/abstractformbuilder.cpp | 14 ++--- tools/designer/src/lib/uilib/formbuilder.cpp | 4 +- tools/designer/src/uitools/quiloader.cpp | 8 +-- tools/linguist/lconvert/main.cpp | 8 +-- tools/linguist/linguist/mainwindow.ui | 2 +- tools/linguist/lrelease/lrelease.1 | 12 ++--- tools/linguist/lrelease/main.cpp | 10 ++-- tools/linguist/lupdate/lupdate.1 | 14 ++--- tools/linguist/lupdate/main.cpp | 6 +-- tools/linguist/shared/qm.cpp | 2 +- tools/linguist/shared/ts.dtd | 8 +-- tools/qtconfig/paletteeditoradvanced.cpp | 2 +- 59 files changed, 235 insertions(+), 236 deletions(-) diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index 67114b9..25e7455 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -86,7 +86,7 @@ \o \l{Creating Main Windows in Qt Designer} \o \l{Editing Resources with Qt Designer} \o \l{Using Stylesheets with Qt Designer} - \o \l{Using a Designer .ui File in Your Application} + \o \l{Using a Designer UI File in Your Application} \endlist For advanced usage of \QD, you can refer to these links: @@ -158,7 +158,7 @@ has been introduced to aid translators in the case of two source texts being the same but used for different purposes. For example, a dialog could have two \gui{Add} buttons for two different - reasons. \note To maintain compatibility, comments in \c{.ui} files + reasons. \note To maintain compatibility, comments in UI files created prior to Qt 4.5 will be listed in the \gui{Disambiguation} field. \endlist @@ -620,7 +620,7 @@ \key{Ctrl+O}. At any point, you can save your form by selecting the \gui{Save From As...} - option from the \gui File menu. The \c{.ui} files saved by \QD contain + option from the \gui File menu. The UI files saved by \QD contain information about the objects used, and any details of signal and slot connections between them. @@ -953,7 +953,7 @@ \image designer-form-layout.png - The \c{.ui} file above results in the previews shown below. + The UI file above results in the previews shown below. \table \header @@ -1226,7 +1226,7 @@ The whole connection can be selected by clicking on any of its path segments. Once selected, a connection can be deleted with the - \key Delete key, ensuring that it will not be set up in the \c{.ui} + \key Delete key, ensuring that it will not be set up in the UI file. \endtable */ @@ -1795,7 +1795,7 @@ pixmap property in the property editor. \page designer-stylesheet.html \contentspage {Qt Designer Manual}{Contents} \previouspage Editing Resources with Qt Designer - \nextpage Using a Designer .ui File in Your Application + \nextpage Using a Designer UI File in Your Application \title Using Stylesheets with Qt Designer @@ -1824,7 +1824,7 @@ pixmap property in the property editor. \contentspage {Qt Designer Manual}{Contents} \nextpage Using Custom Widgets with Qt Designer - \title Using a Designer .ui File in Your Application + \title Using a Designer UI File in Your Application With Qt's integrated build tools, \l{qmake Manual}{qmake} and \l uic, the code for user interface components created with \QD is automatically @@ -1855,11 +1855,11 @@ pixmap property in the property editor. \section2 The Direct Approach - To demonstrate how to use user interface (\c{.ui}) files straight from + To demonstrate how to use user interface (UI) files straight from \QD, we create a simple Calculator Form application. This is based on the original \l{Calculator Form Example}{Calculator Form} example. - The application consists of one source file, \c main.cpp and a \c{.ui} + The application consists of one source file, \c main.cpp and a UI file. The \c{calculatorform.ui} file designed with \QD is shown below: @@ -1882,7 +1882,7 @@ pixmap property in the property editor. \snippet doc/src/snippets/uitools/calculatorform/main.cpp 0 This include is an additional check to ensure that we do not generate code - for \c .ui files that are not used. + for UI files that are not used. The \c main function creates the calculator widget by constructing a standard QWidget that we use to host the user interface described by the @@ -2003,7 +2003,7 @@ pixmap property in the property editor. \section2 The UiTools Approach - A resource file containing a \c{.ui} file is required to process forms at + A resource file containing a UI file is required to process forms at run time. Also, the application needs to be configured to use the QtUiTools module. This is done by including the following declaration in a \c qmake project file, ensuring that the application is compiled and linked @@ -2034,7 +2034,7 @@ pixmap property in the property editor. \snippet examples/uitools/textfinder/textfinder.cpp 1 Processing forms at run-time gives the developer the freedom to change a - program's user interface, just by changing the \c{.ui} file. This is useful + program's user interface, just by changing the UI file. This is useful when customizing programs to suit various user needs, such as extra large icons or a different colour scheme for accessibility support. @@ -2130,12 +2130,12 @@ pixmap property in the property editor. \image designer-form-settings.png - When saving a form in \QD, it is stored as an \c .ui file. Several form + When saving a form in \QD, it is stored as a UI file. Several form settings, for example the grid settings or the margin and spacing for the default layout, are stored along with the form's components. These settings are used when the \l uic generates the form's C++ code. For more information on how to use forms in your application, see the - \l{Using a Designer .ui File in Your Application} section. + \l{Using a Designer UI File in Your Application} section. \section1 Modifying the Form Settings @@ -2168,7 +2168,7 @@ pixmap property in the property editor. You can also specify the form's \gui{Include Hints}; i.e., provide a list of the header files which will then be included in the form window's - associated \c .ui file. Header files may be local, i.e., relative to the + associated UI file. Header files may be local, i.e., relative to the project's directory, \c "mywidget.h", or global, i.e. part of Qt or the compilers standard libraries: \c . @@ -2331,7 +2331,7 @@ pixmap property in the property editor. \row \o \c includeFile() \o The header file that must be included in applications that use - this widget. This information is stored in .ui files and will + this widget. This information is stored in UI files and will be used by \c uic to create a suitable \c{#includes} statement in the code it generates for the form containing the custom widget. @@ -2379,12 +2379,12 @@ pixmap property in the property editor. \section2 Notes on the \c{domXml()} Function - The \c{domXml()} function returns a \c{.ui} file snippet that is used by + The \c{domXml()} function returns a UI file snippet that is used by \QD's widget factory to create a custom widget and its applicable properties. - Since Qt 4.4, \QD's widget box allows for a complete \c{.ui} file to - describe \bold one custom widget. The \c{.ui} file can be loaded using the + Since Qt 4.4, \QD's widget box allows for a complete UI file to + describe \bold one custom widget. The UI file can be loaded using the \c{} tag. Specifying the tag allows for adding the element that contains additional information for custom widgets. The \c{} tag is sufficient if no additional information is required @@ -2800,7 +2800,7 @@ pixmap property in the property editor. \title Qt Designer's UI File Format - The \c .ui file format used by \QD is described by the + The \c UI file format used by \QD is described by the \l{http://www.w3.org/XML/Schema}{XML schema} presented below, which we include for your convenience. Be aware that the format may change in future Qt releases. diff --git a/doc/src/dnd.qdoc b/doc/src/dnd.qdoc index 8d3d79d..b5039f6 100644 --- a/doc/src/dnd.qdoc +++ b/doc/src/dnd.qdoc @@ -435,7 +435,7 @@ \title Porting to Qt 4 - Drag and Drop \contentspage {Porting Guides}{Contents} \previouspage Porting to Qt 4 - Virtual Functions - \nextpage Porting .ui Files to Qt 4 + \nextpage Porting UI Files to Qt 4 \ingroup porting \brief An overview of the porting process for applications that use drag and drop. diff --git a/doc/src/examples/arrowpad.qdoc b/doc/src/examples/arrowpad.qdoc index 9e9268c..fa19fbb 100644 --- a/doc/src/examples/arrowpad.qdoc +++ b/doc/src/examples/arrowpad.qdoc @@ -140,10 +140,10 @@ QLocale::system() can be influenced by setting the \c LANG environment variable, for example. Notice that the use of a naming convention that incorporates the locale for \c .qm message files, - (and \c .ts files), makes it easy to implement choosing the + (and TS files), makes it easy to implement choosing the translation file according to locale. - If there is no \c .qm message file for the locale chosen the original + If there is no QM message file for the locale chosen the original source text will be used and no error raised. \section1 Translating to French and Dutch @@ -194,9 +194,9 @@ \endlist We have to convert the \c tt1_fr.ts and \c tt1_nl.ts translation source - files into \c .qm files. We could use \e {Qt Linguist} as we've done + files into QM files. We could use \e {Qt Linguist} as we've done before; however using the command line tool \c lrelease ensures that - \e all the \c .qm files for the application are created without us + \e all the QM files for the application are created without us having to remember to load and \gui File|Release each one individually from \e {Qt Linguist}. diff --git a/doc/src/examples/calculatorform.qdoc b/doc/src/examples/calculatorform.qdoc index 7cbf2ac..90eef3b 100644 --- a/doc/src/examples/calculatorform.qdoc +++ b/doc/src/examples/calculatorform.qdoc @@ -45,8 +45,8 @@ The Calculator Form Example shows how to use a form created with \QD in an application by using the user interface information from - a QWidget subclass. We use \l{Using a Designer .ui File in Your Application} - {uic's auto-connection} feature to automatically connect signals + a QWidget subclass. We use \l{Using a Designer UI File in Your Application} + {uic's auto-connection} feature to automatically connect signals from widgets on the form to slots in our code. \image calculatorform-example.png Screenshot of the Calculator Form example @@ -59,7 +59,7 @@ \section1 Preparation The user interface for this example is designed completely using \QD. The - result is a .ui file describing the form, the widgets used, any signal-slot + result is a UI file describing the form, the widgets used, any signal-slot connections between them, and other standard user interface properties. To ensure that the example can use this file, we need to include a \c FORMS diff --git a/doc/src/examples/helloscript.qdoc b/doc/src/examples/helloscript.qdoc index a18e4ad..1b0f43c 100644 --- a/doc/src/examples/helloscript.qdoc +++ b/doc/src/examples/helloscript.qdoc @@ -121,7 +121,7 @@ window). Don't forget the exclamation mark! Click the \gui Done checkbox and choose \gui File|Save from the - menu bar. The \c .ts file will no longer contain + menu bar. The TS file will no longer contain \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 3 @@ -129,11 +129,11 @@ \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 4 - To see the application running in Latin, we have to generate a \c .qm - file from the \c .ts file. Generating a \c .qm file can be achieved - either from within \e {Qt Linguist} (for a single \c .ts file), or - by using the command line program \c lrelease which will produce one \c - .qm file for each of the \c .ts files listed in the project file. + To see the application running in Latin, we have to generate a QM + file from the TS file. Generating a QM file can be achieved + either from within \e {Qt Linguist} (for a single TS file), or + by using the command line program \c lrelease which will produce one + QM file for each of the TS files listed in the project file. Generate \c hellotr_la.qm from \c hellotr_la.ts by choosing \gui File|Release from \e {Qt Linguist}'s menu bar and pressing \gui Save in the file save dialog that pops up. Now run the \c helloscript diff --git a/doc/src/examples/hellotr.qdoc b/doc/src/examples/hellotr.qdoc index bb38737..18e0715 100644 --- a/doc/src/examples/hellotr.qdoc +++ b/doc/src/examples/hellotr.qdoc @@ -108,12 +108,12 @@ Note that the file extension is \c .ts, not \c .qm. The \c .ts translation source format is designed for use during the application's development. Programmers or release managers run - the \c lupdate program to generate and update \c .ts files with + the \c lupdate program to generate and update TS files with the source text that is extracted from the source code. - Translators read and update the \c .ts files using \e {Qt + Translators read and update the TS files using \e {Qt Linguist} adding and editing their translations. - The \c .ts format is human-readable XML that can be emailed directly + The TS format is human-readable XML that can be emailed directly and is easy to put under version control. If you edit this file manually, be aware that the default encoding for XML is UTF-8, not Latin1 (ISO 8859-1). One way to type in a Latin1 character such as @@ -121,8 +121,8 @@ "\ø". This will work for any Unicode 4.0 character. Once the translations are complete the \c lrelease program is used to - convert the \c .ts files into the \c .qm Qt message file format. The - \c .qm format is a compact binary format designed to deliver very + convert the TS files into the QM Qt message file format. The + QM format is a compact binary format designed to deliver very fast lookup performance. Both \c lupdate and \c lrelease read all the project's source and header files (as specified in the HEADERS and SOURCES lines of the project file) and extract the strings that @@ -131,7 +131,7 @@ \c lupdate is used to create and update the message files (\c hellotr_la.ts in this case) to keep them in sync with the source code. It is safe to run \c lupdate at any time, as \c lupdate does not remove any - information. For example, you can put it in the makefile, so the \c .ts + information. For example, you can put it in the makefile, so the TS files are updated whenever the source changes. Try running \c lupdate right now, like this: @@ -151,7 +151,7 @@ We will use \e {Qt Linguist} to provide the translation, although you can use any XML or plain text editor to enter a translation into a - \c .ts file. + TS file. To start \e {Qt Linguist}, type @@ -163,7 +163,7 @@ window). Don't forget the exclamation mark! Click the \gui Done checkbox and choose \gui File|Save from the - menu bar. The \c .ts file will no longer contain + menu bar. The TS file will no longer contain \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 3 @@ -173,11 +173,11 @@ \section1 Running the Application in Latin - To see the application running in Latin, we have to generate a \c .qm - file from the \c .ts file. Generating a \c .qm file can be achieved - either from within \e {Qt Linguist} (for a single \c .ts file), or - by using the command line program \c lrelease which will produce one \c - .qm file for each of the \c .ts files listed in the project file. + To see the application running in Latin, we have to generate a QM + file from the TS file. Generating a QM file can be achieved + either from within \e {Qt Linguist} (for a single TS file), or + by using the command line program \c lrelease which will produce one + QM file for each of the TS files listed in the project file. Generate \c hellotr_la.qm from \c hellotr_la.ts by choosing \gui File|Release from \e {Qt Linguist}'s menu bar and pressing \gui Save in the file save dialog that pops up. Now run the \c hellotr diff --git a/doc/src/examples/multipleinheritance.qdoc b/doc/src/examples/multipleinheritance.qdoc index 5a77275..1622fb0 100644 --- a/doc/src/examples/multipleinheritance.qdoc +++ b/doc/src/examples/multipleinheritance.qdoc @@ -103,6 +103,6 @@ There are various approaches to include forms into applications. The Multiple Inheritance approach is just one of them. See - \l{Using a Designer .ui File in Your Application} for more information on + \l{Using a Designer UI File in Your Application} for more information on the other approaches available. */ diff --git a/doc/src/examples/qtscripttetrix.qdoc b/doc/src/examples/qtscripttetrix.qdoc index c94697a..fb2d537 100644 --- a/doc/src/examples/qtscripttetrix.qdoc +++ b/doc/src/examples/qtscripttetrix.qdoc @@ -57,7 +57,7 @@ \section1 Setting up the GUI - The graphical user interface is defined in a \c{.ui} file, creating + The graphical user interface is defined in a UI file, created using Qt Designer, and is set up in the example's C++ \c{main.cpp} file. \snippet examples/script/qstetrix/main.cpp 0 diff --git a/doc/src/examples/svggenerator.qdoc b/doc/src/examples/svggenerator.qdoc index 09fe6e1..dd7459a 100644 --- a/doc/src/examples/svggenerator.qdoc +++ b/doc/src/examples/svggenerator.qdoc @@ -55,8 +55,8 @@ The example consists of two classes: \c Window and \c DisplayWidget. The \c Window class contains the application logic and constructs the user - interface from a Qt Designer \c{.ui} file as described in the - \l{Using a Designer .ui File in Your Application#The Multiple Inheritance Approach}{Qt Designer manual}. + interface from a Qt Designer UI file as described in the + \l{Using a Designer UI File in Your Application#The Multiple Inheritance Approach}{Qt Designer manual}. It also contains the code to write an SVG file. The \c DisplayWidget class performs all the work of painting a picture on diff --git a/doc/src/examples/textfinder.qdoc b/doc/src/examples/textfinder.qdoc index adbbd0d..acfbd0f 100644 --- a/doc/src/examples/textfinder.qdoc +++ b/doc/src/examples/textfinder.qdoc @@ -45,7 +45,7 @@ The Text Finder example demonstrates how to dynamically process forms using the QtUiTools module. Dynamic form processing enables a form to - be processed at run-time only by changing the .ui file for the project. + be processed at run-time only by changing the UI file for the project. The program allows the user to look up a particular word within the contents of a text file. This text file is included in the project's resource and is loaded into the display at startup. @@ -95,7 +95,7 @@ \snippet examples/uitools/textfinder/textfinder.h 0 The slot \c{on_find_Button_clicked()} is a slot named according to the - \l{Using a Designer .ui File in Your Application#Automatic Connections} + \l{Using a Designer UI File in Your Application#Automatic Connections} {Automatic Connection} naming convention required by \c uic. diff --git a/doc/src/examples/worldtimeclockbuilder.qdoc b/doc/src/examples/worldtimeclockbuilder.qdoc index 55246e9..f38062a 100644 --- a/doc/src/examples/worldtimeclockbuilder.qdoc +++ b/doc/src/examples/worldtimeclockbuilder.qdoc @@ -66,7 +66,7 @@ generate a dependency on the \c libQtUiTools library containing the QtUiTools classes. - Note that we do not inform \c qmake about any .ui files, and so none will + Note that we do not inform \c qmake about any UI files, and so none will be processed and built into the application. The resource file contains an entry for the particular form that we wish to use: diff --git a/doc/src/i18n.qdoc b/doc/src/i18n.qdoc index 4109b62..5964926 100644 --- a/doc/src/i18n.qdoc +++ b/doc/src/i18n.qdoc @@ -266,19 +266,19 @@ \o Run \c lupdate to extract translatable text from the C++ source code of the Qt application, resulting in a message file - for translators (a \c .ts file). The utility recognizes the tr() + for translators (a TS file). The utility recognizes the tr() construct and the \c{QT_TR*_NOOP()} macros described above and - produces \c .ts files (usually one per language). + produces TS files (usually one per language). - \o Provide translations for the source texts in the \c .ts file, using - \e{Qt Linguist}. Since \c .ts files are in XML format, you can also + \o Provide translations for the source texts in the TS file, using + \e{Qt Linguist}. Since TS files are in XML format, you can also edit them by hand. - \o Run \c lrelease to obtain a light-weight message file (a \c .qm - file) from the \c .ts file, suitable only for end use. Think of the \c - .ts files as "source files", and \c .qm files as "object files". The - translator edits the \c .ts files, but the users of your application - only need the \c .qm files. Both kinds of files are platform and + \o Run \c lrelease to obtain a light-weight message file (a QM + file) from the TS file, suitable only for end use. Think of the TS + files as "source files", and QM files as "object files". The + translator edits the TS files, but the users of your application + only need the QM files. Both kinds of files are platform and locale independent. \endlist diff --git a/doc/src/linguist-manual.qdoc b/doc/src/linguist-manual.qdoc index ee59fdc..fd062bb 100644 --- a/doc/src/linguist-manual.qdoc +++ b/doc/src/linguist-manual.qdoc @@ -247,10 +247,10 @@ subsequent \l lupdate runs would probably take place during the final beta phase. - The \c .ts file format is a simple human-readable XML format that + The TS file format is a simple human-readable XML format that can be used with version control systems if required. \c lupdate can also process Localization Interchange File Format (XLIFF) - format files; file in this format typically have file names that + format files; files in this format typically have file names that end with the \c .xlf suffix. Pass the \c -help option to \c lupdate to obtain the list of @@ -266,19 +266,19 @@ Usage: \c {lrelease myproject.pro} - \l lrelease is a command line tool that produces \c .qm files out - of \c .ts files. The \c .qm file format is a compact binary format + \l lrelease is a command line tool that produces QM files out + of TS files. The QM file format is a compact binary format that is used by the localized application. It provides extremely - fast lookups for translations. The \c .ts files \l lrelease + fast lookups for translations. The TS files \l lrelease processes can be specified at the command line, or given indirectly by a Qt \c .pro project file. This tool is run whenever a release of the application is to be made, from initial test version through to final release - version. If the \c .qm files are not created, e.g. because an + version. If the QM files are not created, e.g. because an alpha release is required before any translation has been undertaken, the application will run perfectly well using the text - the programmers placed in the source files. Once the \c .qm files + the programmers placed in the source files. Once the QM files are available the application will detect them and use them automatically. @@ -293,7 +293,7 @@ \section1 Missing Translations - Both \l lupdate and \l lrelease may be used with \c .ts + Both \l lupdate and \l lrelease may be used with TS translation source files which are incomplete. Missing translations will be replaced with the native language phrases at runtime. @@ -317,8 +317,8 @@ from the taskbar menu, or by double clicking the desktop icon, or by entering the command \c {linguist} at the command line. Once \QL has started, choose \menu{File|Open} from the \l{menubar} - {menu bar} and select a translation source (\c{.ts} file) to - load. If you don't have a \c{.ts} file, see the \l {Qt Linguist + {menu bar} and select a translation source (TS file) to + load. If you do not have a TS file, see the \l {Qt Linguist Manual: Release Manager} {release manager manual} to learn how to generate one. @@ -928,12 +928,12 @@ \image linguist-previewtool.png - Forms created by \e{Qt Designer} are stored in special \c .ui files. - \QL can make use of these \c .ui files to show the translations - done so far on the form itself. This of course requires access to the \c .ui + Forms created by \e{Qt Designer} are stored in special UI files. + \QL can make use of these UI files to show the translations + done so far on the form itself. This of course requires access to the UI files during the translation process. Activate \menu{Tools|Open/Refresh Form Preview} to open the window shown above. - The list of \c .ui files \QL has detected are displayed in the Forms + The list of UI files \QL has detected are displayed in the Forms List on the left hand. If the path to the files has changed, you can load the files manually via \menu{File|Open Form...}. Double-click on an entry in the Forms List to display the Form File. Select \e{} from @@ -947,15 +947,15 @@ \QL makes use of four kinds of files: \list - \o \c .ts \e {translation source files} \BR are human-readable XML + \o TS \e {translation source files} \BR are human-readable XML files containing source phrases and their translations. These files are usually created and updated by \l lupdate and are specific to an application. \o \c .xlf \e {XLIFF files} \BR are human-readable XML files that adhere to the international XML Localization Interchange File Format. \QL can be used to edit XLIFF files generated by other programs. For standard - Qt projects, however, only the \c .ts file format is used. - \o \c .qm \e {Qt message files} \BR are binary files that contain + Qt projects, however, only the TS file format is used. + \o QM \e {Qt message files} \BR are binary files that contain translations used by an application at runtime. These files are generated by \l lrelease, but can also be generated by \QL. \o \c .qph \e {Qt phrase book files} \BR are human-readable XML @@ -974,18 +974,18 @@ \list \o \gui {Open... Ctrl+O} \BR pops up an open file dialog from which a translation source \c .ts or \c .xlf file can be chosen. - \o \gui {Recently opened files} \BR shows the \c .ts files that + \o \gui {Recently opened files} \BR shows the TS files that have been opened recently, click one to open it. \o \gui {Save Ctrl+S} \BR saves the current translation source file. \o \gui {Save As...} \BR pops up a save as file dialog so that the current translation source file may be saved with a different name, format and/or put in a different location. - \o \gui {Release} \BR create a Qt message \c .qm file with the same base + \o \gui {Release} \BR create a Qt message QM file with the same base name as the current translation source file. The release manager's command line tool \l lrelease performs the same function on \e all of an application's translation source files. \o \gui {Release As...} \BR pops up a save as file dialog. The - filename entered will be a Qt message \c .qm file of the translation + filename entered will be a Qt message QM file of the translation based on the current translation source file. The release manager's command line tool \l lrelease performs the same function on \e all of an application's translation source files. @@ -1136,16 +1136,15 @@ \list \o \inlineimage linguist-fileopen.png \BR - Pops up the open file dialog to open a new translation source \c .ts - file. + Pops up the open file dialog to open a new translation source TS file. \o \inlineimage linguist-filesave.png \BR - Saves the current translation source \c .ts file. + Saves the current translation source TS file. \o \inlineimage linguist-fileprint.png \BR - Prints the current translation source \c .ts file. + Prints the current translation source TS file. \o \inlineimage linguist-phrasebookopen.png \BR @@ -1263,10 +1262,10 @@ Translation files are created as follows: \list 1 - \o Run \l lupdate initially to generate the first set of \c .ts + \o Run \l lupdate initially to generate the first set of TS translation source files with all the user-visible text but no translations. - \o The \c .ts files are given to the translator who adds translations + \o The TS files are given to the translator who adds translations using \QL. \QL takes care of any changed or deleted source text. \o Run \l lupdate to incorporate any new text added to the @@ -1274,7 +1273,7 @@ application with the translations; it does not destroy any data. \o Steps 2 and 3 are repeated as often as necessary. \o When a release of the application is needed \l lrelease is run to - read the \c .ts files and produce the \c .qm files used by the + read the TS files and produce the QM files used by the application at runtime. \endlist @@ -1319,7 +1318,7 @@ In production applications a more flexible approach, for example, loading translations according to locale, might be more appropriate. If - the \c .ts files are all named according to a convention such as + the TS files are all named according to a convention such as \e appname_locale, e.g. \c tt2_fr, \c tt2_de etc, then the code above will load the current locale's translation at runtime. @@ -1413,7 +1412,7 @@ To handle plural forms in the native language, you need to load a translation file for this language, too. \l lupdate has the \c -pluralonly command line option, which allows the creation of - \c .ts files containing only entries with plural forms. + TS files containing only entries with plural forms. See the \l{http://doc.trolltech.com/qq/}{Qt Quarterly} Article \l{http://doc.trolltech.com/qq/qq19-plurals.html}{Plural Forms in Translations} @@ -1503,7 +1502,7 @@ \contentspage {Qt Linguist Manual}{Contents} \previouspage Qt Linguist Manual: Programmers - The \c .ts file format used by \QL is described by the + The TS file format used by \QL is described by the \l{http://www.w3.org/TR/1998/REC-xml-19980210}{DTD} presented below, which we include for your convenience. Be aware that the format may change in future Qt releases. diff --git a/doc/src/porting4-canvas.qdoc b/doc/src/porting4-canvas.qdoc index fa0bc6b..d1221cf 100644 --- a/doc/src/porting4-canvas.qdoc +++ b/doc/src/porting4-canvas.qdoc @@ -43,7 +43,7 @@ \page graphicsview-porting.html \title Porting to Graphics View \contentspage {Porting Guides}{Contents} - \previouspage Porting .ui Files to Qt 4 + \previouspage Porting UI Files to Qt 4 \nextpage qt3to4 - The Qt 3 to 4 Porting Tool \ingroup porting \ingroup multimedia diff --git a/doc/src/porting4-designer.qdoc b/doc/src/porting4-designer.qdoc index 916894b..7de1d43 100644 --- a/doc/src/porting4-designer.qdoc +++ b/doc/src/porting4-designer.qdoc @@ -41,12 +41,12 @@ /*! \page porting4-designer.html - \title Porting .ui Files to Qt 4 + \title Porting UI Files to Qt 4 \contentspage {Porting Guides}{Contents} \previouspage Porting to Qt 4 - Drag and Drop \nextpage Porting to Graphics View \ingroup porting - \brief Information about changes to the .ui file format in Qt 4. + \brief Information about changes to the UI file format in Qt 4. Qt Designer has changed significantly in the Qt 4 release. We have moved away from viewing Qt Designer as an IDE and @@ -57,20 +57,20 @@ IDEs. The most important changes in Qt Designer 4 which affect porting - for \c .ui files are summarized below: + for UI files are summarized below: \list \o \bold{Removed project manager.} - Qt Designer now only reads and edits \c .ui - files. It has no notion of a project (\c .pro file). + Qt Designer now only reads and edits UI + files. It has no notion of a project file (\c .pro). \o \bold{Removed code editor.} Qt Designer can no longer be used to edit source files. - \o \bold{Changed format of \c .ui files.} + \o \bold{Changed format of UI files.} Qt Designer 4 cannot read files created by Qt Designer 3 and vice versa. However, we provide the tool \c uic3 to generate Qt - 4 code out of Qt 3 \c .ui files, and to convert old \c .ui files + 4 code out of Qt 3 UI files, and to convert old UI files into a format readable by Qt Designer 4. \o \bold{Changed structure of the code generated by \c uic.} @@ -80,7 +80,7 @@ \c Ui::MyForm. \o \bold{New resource file system.} Icon data is no longer - stored in the \c .ui file. Instead, icons are put into resource + stored in the UI file. Instead, icons are put into resource files (\c .qrc). \endlist @@ -146,9 +146,9 @@ therefore has an interface identical to that of a class generated by \c uic in Qt 3. - Creating POD classes from \c .ui files is more flexible and + Creating POD classes from UI files is more flexible and generic than the old approach of creating widgets. Qt Designer - doesn't need to know anything about the main container apart from + does not need to know anything about the main container apart from the base widget class it inherits. Indeed, \c Ui::HelloWorld can be used to populate any container that inherits QWidget. Conversely, all non-GUI aspects of the main container may be @@ -163,10 +163,10 @@ \list 1 \o To generate headers and source code for a widget to implement any custom signals and slots added using Qt Designer 3. - \o To generate a new \c .ui file that can be used with Qt Designer 4. + \o To generate a new UI file that can be used with Qt Designer 4. \endlist - You can use both these methods in combination to obtain \c{.ui}, header + You can use both these methods in combination to obtain UI, header and source files that you can use as a starting point when porting your user interface to Qt 4. @@ -179,7 +179,7 @@ The resulting files \c myform.h and \c myform.cpp implement the form in Qt 4 using a QWidget that will include custom signals, - slots and connections specified in the \c .ui file. However, + slots and connections specified in the UI file. However, see below for the \l{#Limitations of uic3}{limitations} of this method. @@ -190,7 +190,7 @@ The resulting file \c myform4.ui can be edited in Qt Designer 4. The header file for the form is generated by Qt 4's \c uic. See the - \l{Using a Designer .ui File in Your Application} chapter of the + \l{Using a Designer UI File in Your Application} chapter of the \l{Qt Designer Manual} for information about the preferred ways to use forms created with Qt Designer 4. @@ -218,7 +218,7 @@ \section1 Limitations of uic3 - Converting Qt 3 \c .ui files to Qt 4 has some limitations. The + Converting Qt 3 UI files to Qt 4 has some limitations. The most noticeable limitation is the fact that since \c uic no longer generates a QObject, it's not possible to define custom signals or slots for the form. Instead, the programmer must @@ -231,9 +231,9 @@ A quick and dirty way to port forms containing custom signals and slots is to generate the code using \c uic3, rather than \c uic. Since \c uic3 does generate a QWidget, it will populate it with custom - signals, slots and connections specified in the \c .ui file. - However, \c uic3 can only generate code from Qt 3 \c .ui files, which - implies that the \c .ui files never get translated and need to be + signals, slots and connections specified in the UI file. + However, \c uic3 can only generate code from Qt 3 UI files, which + implies that the UI files never get translated and need to be edited using Qt Designer 3. Note also that it is possible to create implicit connections @@ -256,7 +256,7 @@ \section1 Icons In Qt 3, the binary data for the icons used by a form was stored - in the \c .ui file. In Qt 4 icons and any other external files + in the UI file. In Qt 4 icons and any other external files can be compiled into the application by listing them in a \l{The Qt Resource System}{resource file} (\c .qrc). This file is translated into a C++ source file using Qt's resource compiler @@ -306,7 +306,7 @@ the following steps: \list 1 - \o Use \c{uic3 -convert} to obtain a \c .ui file understood by + \o Use \c{uic3 -convert} to obtain a UI file understood by Qt Designer 4. \o Create a \c .qrc file with a list of all the icon files. diff --git a/doc/src/porting4-overview.qdoc b/doc/src/porting4-overview.qdoc index d91729d..3494c6d 100644 --- a/doc/src/porting4-overview.qdoc +++ b/doc/src/porting4-overview.qdoc @@ -115,13 +115,13 @@ support these project-level features. We recommend using one of the - \l{Using a Designer .ui File in Your Application}{form subclassing approaches} + \l{Using a Designer UI File in Your Application}{form subclassing approaches} with forms created using Qt Designer. This avoids the need to use \c{.ui.h} files and special purpose code editors. Existing Qt 3 forms created using Qt Designer can be gradually ported to Qt 4 by following the advice in the - \l{Porting .ui Files to Qt 4} guide. However, some extra effort + \l{Porting UI Files to Qt 4} guide. However, some extra effort will be required to move application logic from \c{.ui.h} files into the main body of a Qt 4 application. diff --git a/doc/src/porting4.qdoc b/doc/src/porting4.qdoc index 7ce2969..2414c4d 100644 --- a/doc/src/porting4.qdoc +++ b/doc/src/porting4.qdoc @@ -97,7 +97,7 @@ to developers porting from Qt 3 to Qt 4. \o \l{Porting to Qt 4 - Drag and Drop} \mdash covers differences in the way drag and drop is handled between Qt 3 and Qt 4. - \o \l{Porting .ui Files to Qt 4} \mdash describes the new format used to + \o \l{Porting UI Files to Qt 4} \mdash describes the new format used to describe forms created with \QD. \o \l{Porting to Graphics View} \mdash provides a class-by-class overview of the differences between Qt 3's canvas API and Qt 4's Graphics @@ -135,7 +135,7 @@ \o Run the \l qt3to4 porting tool. The tool will go through your source code and adapt it to Qt 4. - \o Follow the instructions in the \l{Porting .ui Files to Qt 4} + \o Follow the instructions in the \l{Porting UI Files to Qt 4} page to port Qt Designer files. \o Recompile with Qt 4. For each error, search below for related @@ -347,7 +347,7 @@ macro, removing the need for a \c Q_OVERRIDE() macro. The table below lists the Qt properties that have been renamed in - Qt 4. Occurrences of these in \e{Qt Designer} \c .ui files are + Qt 4. Occurrences of these in \e{Qt Designer} UI files are automatically converted to the new name by \c uic. \table @@ -406,11 +406,11 @@ Some properties have been removed from Qt 4, but the associated access functions are provided if \c QT3_SUPPORT is defined to help - porting to Qt 4. When converting Qt 3 \c .ui files to Qt 4, \c uic + porting to Qt 4. When converting Qt 3 UI files to Qt 4, \c uic generates calls to the Qt 3 compatibility functions. Note that this only applies to the properties of the Qt3Support library, i.e. \c QT3_SUPPORT properties of the other libraries must be - ported manually when converting Qt 3 .ui files to Qt 4. + ported manually when converting Qt 3 UI files to Qt 4. The table below lists these properties with the read and write functions that you can use instead. The documentation for the @@ -518,7 +518,7 @@ (Notice the \c & in the parameter declaration.) \omit - \section1 Qt Designer .ui Files + \section1 Qt Designer UI Files ### \endomit diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index 049f30c..0921ae7 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -235,7 +235,7 @@ \row \o CONFIG \o General project configuration options. \row \o DESTDIR \o The directory in which the executable or binary file will be placed. - \row \o FORMS \o A list of .ui files to be processed by \c uic. + \row \o FORMS \o A list of UI files to be processed by \c uic. \row \o HEADERS \o A list of filenames of header (.h) files used when building the project. \row \o QT \o Qt-specific configuration options. @@ -701,8 +701,8 @@ If a directory is specified, it will be included in the \c DEPENDPATH variable, and relevant code from there will be included in the generated project file. If a file is given, it will be appended to the correct - variable, depending on its extension; for example, .ui files are added - to \c FORMS, and .cpp files are added to \c SOURCES. + variable, depending on its extension; for example, UI files are added + to \c FORMS, and C++ files are added to \c SOURCES. You may also pass assignments on the command line in this mode. When doing so, these assignments will be placed last in the generated project file. @@ -1304,10 +1304,10 @@ \target FORMS \section1 FORMS - This variable specifies the .ui files (see \link + This variable specifies the UI files (see \link designer-manual.html Qt Designer \endlink) to be processed through \c uic before compiling. All dependencies, headers and source files required - to build these .ui files will automatically be added to the project. + to build these UI files will automatically be added to the project. For example: @@ -1320,10 +1320,10 @@ \target FORMS3 \section1 FORMS3 - This variable specifies the old style .ui files to be processed + This variable specifies the old style UI files to be processed through \c uic3 before compiling, when \c CONFIG contains uic3. All dependencies, headers and source files required to build these - .ui files will automatically be added to the project. + UI files will automatically be added to the project. For example: @@ -4151,7 +4151,7 @@ \list \o HEADERS - A list of all the header files for the application. \o SOURCES - A list of all the source files for the application. - \o FORMS - A list of all the .ui files (created using \c{Qt Designer}) + \o FORMS - A list of all the UI files (created using \c{Qt Designer}) for the application. \o LEXSOURCES - A list of all the lex source files for the application. \o YACCSOURCES - A list of all the yacc source files for the application. @@ -4169,7 +4169,7 @@ \endlist You only need to use the system variables that you have values for, - for instance, if you don't have any extra INCLUDEPATHs then you don't + for instance, if you do not have any extra INCLUDEPATHs then you do not need to specify any, \c qmake will add in the default ones needed. For instance, an example project file might look like this: diff --git a/doc/src/qmsdev.qdoc b/doc/src/qmsdev.qdoc index b8d8f85..127b514 100644 --- a/doc/src/qmsdev.qdoc +++ b/doc/src/qmsdev.qdoc @@ -87,7 +87,7 @@ the existing project. If you want to add an existing dialog to your project, then just select the - relevant \c .ui file. This will then add it to your existing project and add + relevant UI file. This will then add it to your existing project and add the relevant steps to create the generated code. \section2 Using the 'Qt Designer' button diff --git a/doc/src/qt3to4.qdoc b/doc/src/qt3to4.qdoc index 9ffd52e..47e85b4 100644 --- a/doc/src/qt3to4.qdoc +++ b/doc/src/qt3to4.qdoc @@ -50,7 +50,7 @@ to Qt 4. It is designed to automate the most tedious part of the porting effort. - See \l{Porting to Qt 4} and \l{Porting .ui Files to Qt 4} for + See \l{Porting to Qt 4} and \l{Porting UI Files to Qt 4} for more information about porting Qt 3 applications to Qt 4. \section1 Usage diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index 2fda7cf..6f59cae 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -235,7 +235,7 @@ for your project (using "DEFINES +=") on to moc, which has its own built-in C++ preprocessor. - To compile code that uses .ui files, you will also need this line in + To compile code that uses UI files, you will also need this line in the .pro file: \snippet doc/src/snippets/code/doc_src_qt4-intro.qdoc 2 diff --git a/doc/src/qtdesigner.qdoc b/doc/src/qtdesigner.qdoc index 2117b27..d913b32 100644 --- a/doc/src/qtdesigner.qdoc +++ b/doc/src/qtdesigner.qdoc @@ -52,7 +52,7 @@ that enable you to access Qt Designer's components. In addition, the QFormBuilder class provides the possibility of - constructing user interfaces from \c .ui files at run-time. + constructing user interfaces from UI files at run-time. To include the definitions of the module's classes, use the following directive: @@ -155,7 +155,7 @@ The \c QtDesigner module contains the QFormBuilder class that provides a mechanism for dynamically creating user interfaces at - run-time, based on \c .ui files created with \QD. This class is + run-time, based on UI files created with \QD. This class is typically used by custom components and applications that embed \QD. Standalone applications that need to dynamically generate user interfaces at run-time use the QUiLoader class, found in @@ -1427,7 +1427,7 @@ \fn bool QDesignerPropertySheetExtension::isAttribute(int index) const Returns true if the property at the given \a index is an attribute, - which will be \e excluded from the .ui file, otherwise false. + which will be \e excluded from the UI file, otherwise false. \sa indexOf(), setAttribute() */ @@ -1436,7 +1436,7 @@ \fn void QDesignerPropertySheetExtension::setAttribute(int index, bool attribute) If \a attribute is true, the property at the given \a index is - made an attribute which will be \e excluded from the .ui file; + made an attribute which will be \e excluded from the UI file; otherwise it will be included. \sa indexOf(), isAttribute() diff --git a/doc/src/qthelp.qdoc b/doc/src/qthelp.qdoc index 7260b6e..b5395c9 100644 --- a/doc/src/qthelp.qdoc +++ b/doc/src/qthelp.qdoc @@ -279,7 +279,7 @@ \section1 Qt Help Project File Format - The file format is XML based. For a better understanding of + The file format is XML-based. For a better understanding of the format we'll discuss the following example: \snippet doc/src/snippets/code/doc_src_qthelp.qdoc 7 diff --git a/doc/src/qtscript.qdoc b/doc/src/qtscript.qdoc index f2ac6c9..6b8f639 100644 --- a/doc/src/qtscript.qdoc +++ b/doc/src/qtscript.qdoc @@ -1782,20 +1782,20 @@ \list 1 \o Run \c lupdate to extract translatable text from the script source code - of the Qt application, resulting in a message file for translators (a \c - .ts file). The utility recognizes qsTr(), qsTranslate() and the - \c{QT_TR*_NOOP()} functions described above and produces \c .ts files + of the Qt application, resulting in a message file for translators (a TS + file). The utility recognizes qsTr(), qsTranslate() and the + \c{QT_TR*_NOOP()} functions described above and produces TS files (usually one per language). - \o Provide translations for the source texts in the \c .ts file, using - \e{Qt Linguist}. Since \c .ts files are in XML format, you can also + \o Provide translations for the source texts in the TS file, using + \e{Qt Linguist}. Since TS files are in XML format, you can also edit them by hand. - \o Run \c lrelease to obtain a light-weight message file (a \c .qm - file) from the \c .ts file, suitable only for end use. Think of the \c - .ts files as "source files", and \c .qm files as "object files". The - translator edits the \c .ts files, but the users of your application - only need the \c .qm files. Both kinds of files are platform and + \o Run \c lrelease to obtain a light-weight message file (a QM + file) from the TS file, suitable only for end use. Think of the TS + files as "source files", and QM files as "object files". The + translator edits the TS files, but the users of your application + only need the QM files. Both kinds of files are platform and locale independent. \endlist @@ -1805,7 +1805,7 @@ translations from previous releases. When running \c lupdate, you must specify the location of the script(s), - and the name of the \c{.ts} file to produce. Examples: + and the name of the TS file to produce. Examples: \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 87 @@ -1823,7 +1823,7 @@ \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 89 - When running \c lrelease, you must specify the name of the \c{.ts} input + When running \c lrelease, you must specify the name of the TS input file; or, if you are using a qmake project file to manage script translations, you specify the name of that file. \c lrelease will create \c myscript_la.qm, the binary representation of the translation. diff --git a/doc/src/qtuiloader.qdoc b/doc/src/qtuiloader.qdoc index 137cfeb..0a23366 100644 --- a/doc/src/qtuiloader.qdoc +++ b/doc/src/qtuiloader.qdoc @@ -53,7 +53,7 @@ These forms are processed at run-time to produce dynamically-generated user interfaces. In order to generate a form at run-time, a resource - file containing a \c{.ui} file is needed. Applications that use the + file containing a UI file is needed. Applications that use the form handling classes need to be configured to be built against the QtUiTools module. This is done by including the following declaration in a \c qmake project file to ensure that the application is compiled diff --git a/doc/src/signalsandslots.qdoc b/doc/src/signalsandslots.qdoc index 356db33..09eb0a6 100644 --- a/doc/src/signalsandslots.qdoc +++ b/doc/src/signalsandslots.qdoc @@ -190,7 +190,7 @@ know any information about each other. To enable this, the objects only need to be connected together, and this can be achieved with some simple QObject::connect() function calls, or with \c{uic}'s - \l{Using a Designer .ui File in Your Application#Automatic Connections} + \l{Using a Designer UI File in Your Application#Automatic Connections} {automatic connections} feature. \section1 Building the Example diff --git a/doc/src/snippets/code/doc_src_linguist-manual.qdoc b/doc/src/snippets/code/doc_src_linguist-manual.qdoc index ce3b997..5697300 100644 --- a/doc/src/snippets/code/doc_src_linguist-manual.qdoc +++ b/doc/src/snippets/code/doc_src_linguist-manual.qdoc @@ -42,7 +42,7 @@ Options: -pluralonly Only include plural form messages. -silent - Don't explain what is being done. + Do not explain what is being done. -version Display the version of lupdate and exit. //! [4] @@ -55,14 +55,14 @@ Usage: Options: -help Display this information and exit -compress - Compress the .qm files + Compress the QM files -nounfinished Do not include unfinished translations -removeidentical If the translated text is the same as the source text, do not include the message -silent - Don't explain what is being done + Do not explain what is being done -version Display the version of lrelease and exit //! [5] diff --git a/doc/src/templates.qdoc b/doc/src/templates.qdoc index 5a8acf7..8cfb851 100644 --- a/doc/src/templates.qdoc +++ b/doc/src/templates.qdoc @@ -162,7 +162,7 @@ without having to know the exact types of the objects we are connecting. This is impossible with a template based solution. This kind of runtime introspection opens up new possibilities, for example GUIs that are - generated and connected from Qt Designer's XML \c{ui} files. + generated and connected from Qt Designer's XML UI files. \section1 Calling Performance is Not Everything diff --git a/examples/uitools/textfinder/forms/input.txt b/examples/uitools/textfinder/forms/input.txt index fae542f..29dfe5d 100644 --- a/examples/uitools/textfinder/forms/input.txt +++ b/examples/uitools/textfinder/forms/input.txt @@ -1,5 +1,5 @@ These forms are processed at run-time to produce dynamically-generated user interfaces. -In order to generate a form at run-time, a resource file containing a .ui file is needed. +In order to generate a form at run-time, a resource file containing a UI file is needed. Applications that use the form handling classes need to be configured to be built against the QtUiTools module. This is done by including the following declaration in a qmake project file to ensure that the application is compiled and linked appropriately. A form loader object, diff --git a/mkspecs/features/uic.prf b/mkspecs/features/uic.prf index d2985f9..e768d0f 100644 --- a/mkspecs/features/uic.prf +++ b/mkspecs/features/uic.prf @@ -51,7 +51,7 @@ equals(UI_DIR, .) { uic3 { isEmpty(FORMS3) { UIC3_FORMS = FORMS - !build_pass:message("Project contains CONFIG+=uic3, but no files in FORMS3; .ui files in FORMS treated as UIC3 form files.") + !build_pass:message("Project contains CONFIG+=uic3, but no files in FORMS3; UI files in FORMS treated as UIC3 form files.") } else { UIC3_FORMS = FORMS3 } diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 9e87b3b..eb1bd0b 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -565,7 +565,7 @@ int QMetaCallEvent::placeMetaCall(QObject *object) \l uic generates code that invokes this function to enable auto-connection to be performed between widgets on forms created with \QD. More information about using auto-connection with \QD is - given in the \l{Using a Designer .ui File in Your Application} section of + given in the \l{Using a Designer UI File in Your Application} section of the \QD manual. \section2 Dynamic Properties diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 4aed2b2..dc1b530 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -503,7 +503,7 @@ bool QTranslator::load(const QString & filename, const QString & directory, \overload load() \fn bool QTranslator::load(const uchar *data, int len) - Loads the .qm file data \a data of length \a len into the + Loads the QM file data \a data of length \a len into the translator. The data is not copied. The caller must be able to guarantee that \a data diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index 1c6e3a5..bbb3af7 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -137,12 +137,12 @@ void Uic::writeCopyrightHeader(DomUI *ui) out << "/*\n" << comment << "\n*/\n\n"; out << "/********************************************************************************\n"; - out << "** Form generated from reading ui file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; + out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; out << "**\n"; out << "** Created: " << QDateTime::currentDateTime().toString() << "\n"; out << "** " << QString::fromLatin1("by: Qt User Interface Compiler version %1\n").arg(QLatin1String(QT_VERSION_STR)); out << "**\n"; - out << "** WARNING! All changes made in this file will be lost when recompiling ui file!\n"; + out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n"; out << "********************************************************************************/\n\n"; } diff --git a/src/tools/uic3/main.cpp b/src/tools/uic3/main.cpp index 38afc60..f4a9cba 100644 --- a/src/tools/uic3/main.cpp +++ b/src/tools/uic3/main.cpp @@ -114,7 +114,7 @@ int runUic3(int argc, char * argv[]) wrap = true; if (opt == "wrap" || opt[1] == '\0') { if (!(n < argc-1)) { - error = "Missing name of converted ui file"; + error = "Missing name of converted UI file"; break; } convertedUiFile = argv[++n]; @@ -230,7 +230,7 @@ int runUic3(int argc, char * argv[]) " %s [options] -decl \n" "\t name of the data file\n" " %s [options] -wrap \n" - "\t name of the converted ui file\n" + "\t name of the converted UI file\n" "Generate implementation:\n" " %s [options] -impl \n" "\t name of the declaration file\n" @@ -254,7 +254,7 @@ int runUic3(int argc, char * argv[]) "\t-pch file Add #include \"file\" as the first statement in implementation\n" "\t-nofwd Omit forward declarations of custom classes\n" "\t-no-implicit-includes Do not generate #include-directives for custom classes\n" - "\t-nounload Don't unload plugins after processing\n" + "\t-nounload Do not unload plugins after processing\n" "\t-tr func Use func() instead of tr() for i18n\n" "\t-L path Additional plugin search path\n" "\t-version Display version of uic\n" diff --git a/src/tools/uic3/uic.cpp b/src/tools/uic3/uic.cpp index e911844..16b2754 100644 --- a/src/tools/uic3/uic.cpp +++ b/src/tools/uic3/uic.cpp @@ -144,12 +144,12 @@ void Uic::writeCopyrightHeader(DomUI *ui) out << "/*\n" << comment << "\n*/\n\n"; out << "/********************************************************************************\n"; - out << "** Form generated from reading ui file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; + out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; out << "**\n"; out << "** Created: " << QDateTime::currentDateTime().toString() << "\n"; out << "** " << QString::fromLatin1("by: Qt User Interface Compiler version %1\n").arg(QLatin1String(QT_VERSION_STR)); out << "**\n"; - out << "** WARNING! All changes made in this file will be lost when recompiling ui file!\n"; + out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n"; out << "********************************************************************************/\n\n"; } diff --git a/src/xmlpatterns/data/qresourceloader_p.h b/src/xmlpatterns/data/qresourceloader_p.h index 8cb174d..0ebc885 100644 --- a/src/xmlpatterns/data/qresourceloader_p.h +++ b/src/xmlpatterns/data/qresourceloader_p.h @@ -114,7 +114,7 @@ namespace QPatternist * * Typically this hint is given when the URI is available at * compile-time, but it is used inside a conditional statement - * whose branching can't be determined at compile time. + * whose branching cannot be determined at compile time. */ MayUse, diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before index e297784..076520a 100644 --- a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before +++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before @@ -5,7 +5,7 @@ Qt Assistant - Find text - + Qt Assistant - Finn tekst diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result index d65110a..6bc565c 100644 --- a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result @@ -9,7 +9,7 @@ - This should not be considered to be more or less equal to the corresponding one in the ts file. + This should not be considered to be more or less equal to the corresponding one in the TS file. diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui index 0d0defd..a5f8e9f 100644 --- a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui +++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui @@ -17,7 +17,7 @@ - This should not be considered to be more or less equal to the corresponding one in the ts file. + This should not be considered to be more or less equal to the corresponding one in the TS file. Here, similarity should kick in! diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result index d65110a..6bc565c 100644 --- a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result @@ -9,7 +9,7 @@ - This should not be considered to be more or less equal to the corresponding one in the ts file. + This should not be considered to be more or less equal to the corresponding one in the TS file. diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui index 0d0defd..a5f8e9f 100644 --- a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui +++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui @@ -17,7 +17,7 @@ - This should not be considered to be more or less equal to the corresponding one in the ts file. + This should not be considered to be more or less equal to the corresponding one in the TS file. Here, similarity should kick in! diff --git a/tools/designer/data/generate_shared.xsl b/tools/designer/data/generate_shared.xsl index f7859cd..ec95fe2 100644 --- a/tools/designer/data/generate_shared.xsl +++ b/tools/designer/data/generate_shared.xsl @@ -6,8 +6,8 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema"> diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.cpp b/tools/designer/src/components/formeditor/qdesigner_resource.cpp index de4b57b..ac03909 100644 --- a/tools/designer/src/components/formeditor/qdesigner_resource.cpp +++ b/tools/designer/src/components/formeditor/qdesigner_resource.cpp @@ -631,13 +631,13 @@ static bool readUiAttributes(QIODevice *dev, QString *errorMessage, *language = attributes.value(languageAttribute).toString(); return true; } else { - *errorMessage = QCoreApplication::translate("Designer", "Invalid ui file: The root element is missing."); + *errorMessage = QCoreApplication::translate("Designer", "Invalid UI file: The root element is missing."); return false; } } } - *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the ui file at line %1, column %2: %3") + *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the UI file at line %1, column %2: %3") .arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()); return false; } @@ -756,7 +756,7 @@ void QDesignerResource::setSaveRelative(bool relative) QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget) { // Load extra info extension. This is used by Jambi for preventing - // C++ ui files from being loaded + // C++ UI files from being loaded if (QDesignerExtraInfoExtension *extra = qt_extension(core()->extensionManager(), core())) { if (!extra->loadUiExtraInfo(ui)) { const QString errorMessage = QApplication::translate("Designer", "This file cannot be read because the extra info extension failed to load."); diff --git a/tools/designer/src/designer/mainwindow.cpp b/tools/designer/src/designer/mainwindow.cpp index b72a790..a3ca234 100644 --- a/tools/designer/src/designer/mainwindow.cpp +++ b/tools/designer/src/designer/mainwindow.cpp @@ -155,7 +155,7 @@ DockedMdiArea::DockedMdiArea(const QString &extension, QWidget *parent) : QStringList DockedMdiArea::uiFiles(const QMimeData *d) const { - // Extract dropped ui files from Mime data. + // Extract dropped UI files from Mime data. QStringList rc; if (!d->hasFormat(QLatin1String(uriListMimeFormatC))) return rc; diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp index 923687a2..f21da8c 100644 --- a/tools/designer/src/designer/qdesigner_workbench.cpp +++ b/tools/designer/src/designer/qdesigner_workbench.cpp @@ -960,7 +960,7 @@ QDesignerFormWindow * QDesignerWorkbench::loadForm(const QString &fileName, removeFormWindow(formWindow); formWindowManager->removeFormWindow(editor); m_core->metaDataBase()->remove(editor); - *errorMessage = tr("The file %1 is not a valid Designer ui file.").arg(file.fileName()); + *errorMessage = tr("The file %1 is not a valid Designer UI file.").arg(file.fileName()); return 0; } *uic3Converted = editor->fileName().isEmpty(); diff --git a/tools/designer/src/lib/sdk/abstractformwindow.cpp b/tools/designer/src/lib/sdk/abstractformwindow.cpp index 89c1015..313b324 100644 --- a/tools/designer/src/lib/sdk/abstractformwindow.cpp +++ b/tools/designer/src/lib/sdk/abstractformwindow.cpp @@ -247,7 +247,7 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje /*! \fn virtual QString QDesignerFormWindowInterface::fileName() const - Returns the file name of the .ui file that describes the form + Returns the file name of the UI file that describes the form currently being shown. \sa setFileName() @@ -399,11 +399,11 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje \fn virtual QStringList QDesignerFormWindowInterface::includeHints() const Returns a list of the header files that will be included in the - form window's associated \c .ui file. + form window's associated UI file. Header files may be local, i.e. relative to the project's - directory,\c "mywidget.h", or global, i.e. part of Qt or the - compilers standard libraries:\c . + directory, \c "mywidget.h", or global, i.e. part of Qt or the + compilers standard libraries: \c . \sa setIncludeHints() */ @@ -412,11 +412,11 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje \fn virtual void QDesignerFormWindowInterface::setIncludeHints(const QStringList &includeHints) Sets the header files that will be included in the form window's - associated \c .ui file to the specified \a includeHints. + associated UI file to the specified \a includeHints. Header files may be local, i.e. relative to the project's - directory,\c "mywidget.h", or global, i.e. part of Qt or the - compilers standard libraries:\c . + directory, \c "mywidget.h", or global, i.e. part of Qt or the + compilers standard libraries: \c . \sa includeHints() */ diff --git a/tools/designer/src/lib/sdk/script.cpp b/tools/designer/src/lib/sdk/script.cpp index 90b4c73..2eda3d1 100644 --- a/tools/designer/src/lib/sdk/script.cpp +++ b/tools/designer/src/lib/sdk/script.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE \since 4.3 On saving the form, the extension is queried for a script snippet - to be associated with the widget while saving the \c .ui file. + to be associated with the widget while saving the UI file. This script is then run after creating the widget by \l uic or QUiLoader. @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE for which an editor is provided by the QDesignerTaskMenuExtension. While saving the form, the state is serialized as a QVariantMap of - \QD-supported properties, which is stored in the \c .ui file. This is + \QD-supported properties, which is stored in the UI file. This is handled by data() and setData(). For item view contents, there might be for example a key that determines @@ -97,7 +97,7 @@ QDesignerScriptExtension::~QDesignerScriptExtension() \fn virtual QVariantMap QDesignerScriptExtension::data() const Returns a map of variants describing the internal state to be - stored in the \c .ui file. + stored in the UI file. */ /*! diff --git a/tools/designer/src/lib/uilib/abstractformbuilder.cpp b/tools/designer/src/lib/uilib/abstractformbuilder.cpp index 65ea375..05e05c1 100644 --- a/tools/designer/src/lib/uilib/abstractformbuilder.cpp +++ b/tools/designer/src/lib/uilib/abstractformbuilder.cpp @@ -135,7 +135,7 @@ public: QAbstractFormBuilder provides a standard interface and a default implementation for constructing forms from user interface files. It is not intended to be instantiated directly. Use the - QFormBuilder class to create user interfaces from \c{.ui} files at + QFormBuilder class to create user interfaces from UI files at run-time. For example: \snippet doc/src/snippets/code/tools_designer_src_lib_uilib_abstractformbuilder.cpp 0 @@ -145,10 +145,10 @@ public: functions: \list - \o load() handles reading of \c{.ui} format files from arbitrary + \o load() handles reading of UI format files from arbitrary QIODevices, and construction of widgets from the XML data that they contain. - \o save() handles saving of widget details in \c{.ui} format to + \o save() handles saving of widget details in UI format to arbitrary QIODevices. \o workingDirectory() and setWorkingDirectory() control the directory in which forms are held. The form builder looks for @@ -208,13 +208,13 @@ QWidget *QAbstractFormBuilder::load(QIODevice *dev, QWidget *parentWidget) } } if (reader.hasError()) { - uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the ui file at line %1, column %2: %3") + uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the UI file at line %1, column %2: %3") .arg(reader.lineNumber()).arg(reader.columnNumber()) .arg(reader.errorString())); return 0; } if (!initialized) { - uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "Invalid ui file: The root element is missing.")); + uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file: The root element is missing.")); return 0; } @@ -657,7 +657,7 @@ void QAbstractFormBuilder::layoutInfo(DomLayout *ui_layout, QObject *parent, int spac = p->elementNumber(); #ifdef Q_OS_MAC - // here we recognize ui file < 4.3 (no we don't store margin property) + // here we recognize UI file < 4.3 (no we don't store margin property) if (mar != INT_MIN) { const int defaultMargin = parent->inherits("QLayoutWidget") ? 0 : 9; if (mar == defaultMargin) @@ -1202,7 +1202,7 @@ QActionGroup *QAbstractFormBuilder::createActionGroup(QObject *parent, const QSt \fn void QAbstractFormBuilder::save(QIODevice *device, QWidget *widget) Saves an XML representation of the given \a widget to the - specified \a device in the standard \c{.ui} file format. + specified \a device in the standard UI file format. \sa load()*/ void QAbstractFormBuilder::save(QIODevice *dev, QWidget *widget) diff --git a/tools/designer/src/lib/uilib/formbuilder.cpp b/tools/designer/src/lib/uilib/formbuilder.cpp index 043991e..f737311 100644 --- a/tools/designer/src/lib/uilib/formbuilder.cpp +++ b/tools/designer/src/lib/uilib/formbuilder.cpp @@ -57,12 +57,12 @@ namespace QFormInternal { \class QFormBuilder \brief The QFormBuilder class is used to dynamically construct - user interfaces from .ui files at run-time. + user interfaces from UI files at run-time. \inmodule QtDesigner The QFormBuilder class provides a mechanism for dynamically - creating user interfaces at run-time, based on \c{.ui} files + creating user interfaces at run-time, based on UI files created with \QD. For example: \snippet doc/src/snippets/code/tools_designer_src_lib_uilib_formbuilder.cpp 0 diff --git a/tools/designer/src/uitools/quiloader.cpp b/tools/designer/src/uitools/quiloader.cpp index 5387c2d..1c7d1cc 100644 --- a/tools/designer/src/uitools/quiloader.cpp +++ b/tools/designer/src/uitools/quiloader.cpp @@ -574,20 +574,20 @@ void QUiLoaderPrivate::setupWidgetMap() const \brief The QUiLoader class enables standalone applications to dynamically create user interfaces at run-time using the - information stored in .ui files or specified in plugin paths. + information stored in UI files or specified in plugin paths. In addition, you can customize or create your own user interface by deriving your own loader class. If you have a custom component or an application that embeds \QD, you can also use the QFormBuilder class provided by the QtDesigner module to create - user interfaces from \c{.ui} files. + user interfaces from UI files. The QUiLoader class provides a collection of functions allowing you to - create widgets based on the information stored in \c .ui files (created + create widgets based on the information stored in UI files (created with \QD) or available in the specified plugin paths. The specified plugin paths can be retrieved using the pluginPaths() function. Similarly, the - contents of a \c{.ui} file can be retrieved using the load() function. For + contents of a UI file can be retrieved using the load() function. For example: \snippet doc/src/snippets/quiloader/mywidget.cpp 0 diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp index 534bc11..4bed02f 100644 --- a/tools/linguist/lconvert/main.cpp +++ b/tools/linguist/lconvert/main.cpp @@ -81,10 +81,10 @@ static int usage(const QStringList &args) " --output-format \n" " Specify output format. See -if.\n\n" " --input-codec \n" - " Specify encoding for .qm input files. Default is 'Latin1'.\n" + " Specify encoding for QM input files. Default is 'Latin1'.\n" " UTF-8 is always tried as well, corresponding to the trUtf8() function.\n\n" " --drop-tags \n" - " Drop named extra tags when writing 'ts' or 'xlf' files.\n" + " Drop named extra tags when writing TS or XLIFF files.\n" " May be specified repeatedly.\n\n" " --drop-translations\n" " Drop existing translations and reset the status to 'unfinished'.\n" @@ -101,10 +101,10 @@ static int usage(const QStringList &args) " --no-finished\n" " Drop finished messages.\n\n" " --locations {absolute|relative|none}\n" - " Override how source code references are saved in ts files.\n" + " Override how source code references are saved in TS files.\n" " Default is absolute.\n\n" " --no-ui-lines\n" - " Drop line numbers from references to .ui files.\n\n" + " Drop line numbers from references to UI files.\n\n" " --verbose\n" " be a bit more verbose\n\n" "Long options can be specified with only one leading dash, too.\n\n" diff --git a/tools/linguist/linguist/mainwindow.ui b/tools/linguist/linguist/mainwindow.ui index 4f66f31..613241b 100644 --- a/tools/linguist/linguist/mainwindow.ui +++ b/tools/linguist/linguist/mainwindow.ui @@ -747,7 +747,7 @@ Release As... - Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the .ts file. + Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the TS file. diff --git a/tools/linguist/lrelease/lrelease.1 b/tools/linguist/lrelease/lrelease.1 index 9e77504..8dd14b2 100644 --- a/tools/linguist/lrelease/lrelease.1 +++ b/tools/linguist/lrelease/lrelease.1 @@ -51,10 +51,10 @@ This page documents the tool for the Qt GUI toolkit. .B Lrelease reads a qmake/tmake project file (.pro file) and converts the -translation files (.ts files) specified in it into Qt message files -(.qm files) used by the application to translate. +translation files (TS files) specified in it into Qt message files +(QM files) used by the application to translate. .PP -The .qm file format is a compact binary format that provides +The QM file format is a compact binary format that provides extremely fast lookups for translations and that is used by Qt. .SH OPTIONS .TP @@ -62,7 +62,7 @@ extremely fast lookups for translations and that is used by Qt. Display the usage and exit. .TP .I "-compress" -Compress the .qm files. +Compress the QM files. .TP .I "-nounfinished" Do not include unfinished translations. @@ -72,7 +72,7 @@ If the translated text is the same as the source text, do not include the message. .TP .I "-silent" -Don't explain what is being done. +Do not explain what is being done. .TP .I "-version" Display the version of @@ -105,7 +105,7 @@ generated from gnomovision_dk.ts, gnomovision_fi.ts, gnomovision_no.ts and gnomovision_se.ts, respectively. .PP .B Lrelease -can also be invoked with a list of .ts files to convert: +can also be invoked with a list of TS files to convert: .PP .in +4 .nf diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index 5fbecac..aeed1f2 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -66,21 +66,21 @@ static void printUsage() " lrelease [options] project-file\n" " lrelease [options] ts-files [-qm qm-file]\n\n" "lrelease is part of Qt's Linguist tool chain. It can be used as a\n" - "stand-alone tool to convert XML based translations files in the .ts\n" - "format into the 'compiled' .qm format used by QTranslator objects.\n\n" + "stand-alone tool to convert XML-based translations files in the TS\n" + "format into the 'compiled' QM format used by QTranslator objects.\n\n" "Options:\n" " -help Display this information and exit\n" " -idbased\n" " Use IDs instead of source strings for message keying\n" " -compress\n" - " Compress the .qm files\n" + " Compress the QM files\n" " -nounfinished\n" " Do not include unfinished translations\n" " -removeidentical\n" " If the translated text is the same as\n" " the source text, do not include the message\n" " -silent\n" - " Don't explain what is being done\n" + " Do not explain what is being done\n" " -version\n" " Display the version of lrelease and exit\n" )); @@ -244,7 +244,7 @@ int main(int argc, char **argv) } } else { qWarning("error: lrelease encountered project file functionality that is currently not supported.\n" - "You might want to consider using .ts files as input instead of a project file.\n" + "You might want to consider using TS files as input instead of a project file.\n" "Try the following syntax:\n" " lrelease [options] ts-files [-qm qm-file]\n"); } diff --git a/tools/linguist/lupdate/lupdate.1 b/tools/linguist/lupdate/lupdate.1 index 68958b9..b37e7b3 100644 --- a/tools/linguist/lupdate/lupdate.1 +++ b/tools/linguist/lupdate/lupdate.1 @@ -52,12 +52,12 @@ tool for the Qt GUI toolkit. .B Lupdate reads a qmake/tmake project file (.pro file), finds the translatable strings in the specified source, header and interface files, and -updates the translation files (.ts files) specified in it. The +updates the translation files (TS files) specified in it. The translation files are given to the translator who uses .B Qt Linguist to read the files and insert the translations. .PP -The .ts file format is a simple human-readable XML format that can be +The TS file format is a simple human-readable XML format that can be used with version control systems if required. .PP .SH OPTIONS @@ -74,7 +74,7 @@ Default: 'ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx'. Display the usage and exit. .TP .I "-locations {absolute|relative|none}" -Specify/override how source code references are saved in ts files. +Specify/override how source code references are saved in TS files. Default is absolute. .TP .I "-no-obsolete" @@ -84,7 +84,7 @@ Drop all obsolete strings. Do not recursively scan the following directories. .TP .I "-no-sort" -Do not sort contexts in .ts files. +Do not sort contexts in TS files. .TP .I "-pluralonly" Only include plural form messages. @@ -97,7 +97,7 @@ file syntax but different file suffix Recursively scan the following directories. .TP .I "-silent" -Don't explain what is being done. +Do not explain what is being done. .TP .I "-source-language [_]" Specify/override the language of the source strings. Defaults to @@ -139,8 +139,8 @@ translations will be reused as far as possible, and translated strings that have vanished from the source files are marked obsolete. .PP .B lupdate -can also be invoked with a list of C++ source files, .ui files -and .ts files: +can also be invoked with a list of C++ source files, UI files +and TS files: .PP .in +4 .nf diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index 18c8932..c9250c6 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -103,7 +103,7 @@ static void printUsage() " -silent\n" " Do not explain what is being done.\n" " -no-sort\n" - " Do not sort contexts in .ts files.\n" + " Do not sort contexts in TS files.\n" " -no-recursive\n" " Do not recursively scan the following directories.\n" " -recursive\n" @@ -112,10 +112,10 @@ static void printUsage() " Additional location to look for include files.\n" " May be specified multiple times.\n" " -locations {absolute|relative|none}\n" - " Specify/override how source code references are saved in ts files.\n" + " Specify/override how source code references are saved in TS files.\n" " Default is absolute.\n" " -no-ui-lines\n" - " Do not record line numbers in references to .ui files.\n" + " Do not record line numbers in references to UI files.\n" " -disable-heuristic {sametext|similartext|number}\n" " Disable the named merge heuristic. Can be specified multiple times.\n" " -pro \n" diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index 05d8e12..9523fde 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -245,7 +245,7 @@ void Releaser::writeMessage(const ByteTranslatorMessage &msg, QDataStream &strea if (mode == SaveEverything) prefix = HashContextSourceTextComment; - // lrelease produces "wrong" .qm files for QByteArrays that are .isNull(). + // lrelease produces "wrong" QM files for QByteArrays that are .isNull(). switch (prefix) { default: case HashContextSourceTextComment: diff --git a/tools/linguist/shared/ts.dtd b/tools/linguist/shared/ts.dtd index ab77f64..4d2cdeb 100644 --- a/tools/linguist/shared/ts.dtd +++ b/tools/linguist/shared/ts.dtd @@ -34,7 +34,7 @@ version CDATA #IMPLIED sourcelanguage CDATA #IMPLIED language CDATA #IMPLIED> - + diff --git a/tools/qtconfig/paletteeditoradvanced.cpp b/tools/qtconfig/paletteeditoradvanced.cpp index 45f6a45..36cbd89 100644 --- a/tools/qtconfig/paletteeditoradvanced.cpp +++ b/tools/qtconfig/paletteeditoradvanced.cpp @@ -55,7 +55,7 @@ PaletteEditorAdvanced::PaletteEditorAdvanced( QWidget * parent, const char * name, bool modal, Qt::WindowFlags f ) : PaletteEditorAdvancedBase( parent, name, modal, f ), selectedPalette(0) { - // work around buggy ui file + // work around buggy UI file comboEffect->setEnabled(false); buttonEffect->setEnabled(false); onToggleBuildEffects(true); -- cgit v0.12 From fd181167709283a2ceefa5285d6189fa7de23bb6 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 6 Jul 2009 14:08:41 +0200 Subject: Implement QApplication::setOverrideCursor to use pure Cocoa calls Seems this was a victim of our cursor fixing. Cocoa does a lot for us with setting cursors. This meant that we didn't need to do as much meddling and as a result qt_mac_set_cursor does nothing in Cocoa. Unfortunately, this broke setOverrideCursor. Luckily Cocoa has a stack that works exactly like Qt, so we can just use that. Task-number: 257507 Reviewed-by: Prasanth Ullattil --- src/gui/kernel/qapplication_mac.mm | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 5ded153..0d86c8e 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1294,8 +1294,13 @@ void QApplication::setOverrideCursor(const QCursor &cursor) { qApp->d_func()->cursor_list.prepend(cursor); +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; + [static_cast(qt_mac_nsCursorForQCursor(cursor)) push]; +#else if (qApp && qApp->activeWindow()) qt_mac_set_cursor(&qApp->d_func()->cursor_list.first(), QCursor::pos()); +#endif } void QApplication::restoreOverrideCursor() @@ -1304,12 +1309,17 @@ void QApplication::restoreOverrideCursor() return; qApp->d_func()->cursor_list.removeFirst(); +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; + [NSCursor pop]; +#else if (qApp && qApp->activeWindow()) { const QCursor def(Qt::ArrowCursor); qt_mac_set_cursor(qApp->d_func()->cursor_list.isEmpty() ? &def : &qApp->d_func()->cursor_list.first(), QCursor::pos()); } -} #endif +} +#endif // QT_NO_CURSOR QWidget *QApplication::topLevelAt(const QPoint &p) { -- cgit v0.12 From 039c800f728054a56ae1584d269ee1ddadd1312f Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 11:04:27 +0200 Subject: QHeaderView::sizeHint: small bug fix and refactor --- src/gui/itemviews/qheaderview.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index 57e44c7..2419c18 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -524,12 +524,12 @@ QSize QHeaderView::sizeHint() const Q_D(const QHeaderView); if (d->cachedSizeHint.isValid()) return d->cachedSizeHint; - d->cachedSizeHint = QSize(0, 0); - d->executePostedLayout(); + d->cachedSizeHint = QSize(0, 0); //reinitialize the cached size hint + const int sectionCount = count(); // get size hint for the first n sections int i = 0; - for (int checked = 0; checked < 100 && i < d->sectionCount; ++i) { + for (int checked = 0; checked < 100 && i < sectionCount; ++i) { if (isSectionHidden(i)) continue; checked++; @@ -537,8 +537,8 @@ QSize QHeaderView::sizeHint() const d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); } // get size hint for the last n sections - i = qMax(i, d->sectionCount - 100 ); - for (int j = d->sectionCount - 1, checked = 0; j > i && checked < 100; --j) { + i = qMax(i, sectionCount - 100 ); + for (int j = sectionCount - 1, checked = 0; j >= i && checked < 100; --j) { if (isSectionHidden(j)) continue; checked++; -- cgit v0.12 From 14ed83f4e65b26cea12b128043c1c67c5489832d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 12:21:00 +0200 Subject: Phonon: Some work done on binary size removing foreach seems to help on Windows --- src/3rdparty/phonon/ds9/iodevicereader.cpp | 10 +---- src/3rdparty/phonon/ds9/videorenderer_soft.cpp | 32 ++++++---------- src/3rdparty/phonon/ds9/volumeeffect.cpp | 12 +----- src/3rdparty/phonon/phonon/audiooutput.cpp | 14 ++++--- src/3rdparty/phonon/phonon/backendcapabilities.cpp | 14 +++---- src/3rdparty/phonon/phonon/effect.cpp | 6 ++- src/3rdparty/phonon/phonon/effectwidget.cpp | 10 +++-- src/3rdparty/phonon/phonon/factory.cpp | 43 +++++++++++----------- src/3rdparty/phonon/phonon/medianode.cpp | 4 +- src/3rdparty/phonon/phonon/mediaobject.cpp | 12 +++--- .../phonon/phonon/objectdescriptionmodel.cpp | 4 +- .../phonon/phonon/objectdescriptionmodel.h | 8 ++-- src/3rdparty/phonon/phonon/path.cpp | 24 +++++++----- 13 files changed, 88 insertions(+), 105 deletions(-) diff --git a/src/3rdparty/phonon/ds9/iodevicereader.cpp b/src/3rdparty/phonon/ds9/iodevicereader.cpp index ec10278..2dff1fe 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.cpp +++ b/src/3rdparty/phonon/ds9/iodevicereader.cpp @@ -36,15 +36,7 @@ namespace Phonon //these mediatypes define a stream, its type will be autodetected by DirectShow static QVector getMediaTypes() { - AM_MEDIA_TYPE mt; - mt.majortype = MEDIATYPE_Stream; - mt.bFixedSizeSamples = TRUE; - mt.bTemporalCompression = FALSE; - mt.lSampleSize = 1; - mt.formattype = GUID_NULL; - mt.pUnk = 0; - mt.cbFormat = 0; - mt.pbFormat = 0; + AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_NULL, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; QVector ret; //normal auto-detect stream diff --git a/src/3rdparty/phonon/ds9/videorenderer_soft.cpp b/src/3rdparty/phonon/ds9/videorenderer_soft.cpp index dd6e076..2112267 100644 --- a/src/3rdparty/phonon/ds9/videorenderer_soft.cpp +++ b/src/3rdparty/phonon/ds9/videorenderer_soft.cpp @@ -63,9 +63,9 @@ along with this library. If not, see . static const char yv12ToRgb[] = "!!ARBfp1.0" "PARAM c[5] = { program.local[0..1]," -" { 1.164, 0, 1.596, 0.5 }," -" { 0.0625, 1.164, -0.391, -0.81300002 }," -" { 1.164, 2.0179999, 0 } };" +"{ 1.164, 0, 1.596, 0.5 }," +"{ 0.0625, 1.164, -0.391, -0.81300002 }," +"{ 1.164, 2.0179999, 0 } };" "TEMP R0;" "TEX R0.x, fragment.texcoord[0], texture[1], 2D;" "ADD R0.y, R0.x, -c[2].w;" @@ -89,11 +89,11 @@ static const char yv12ToRgb[] = "END"; static const char yuy2ToRgb[] = - "!!ARBfp1.0" +"!!ARBfp1.0" "PARAM c[5] = { program.local[0..1]," -" { 0.5, 2, 1, 0.0625 }," -" { 1.164, 0, 1.596, 2.0179999 }," -" { 1.164, -0.391, -0.81300002 } };" +"{ 0.5, 2, 1, 0.0625 }," +"{ 1.164, 0, 1.596, 2.0179999 }," +"{ 1.164, -0.391, -0.81300002 } };" "TEMP R0;" "TEMP R1;" "TEMP R2;" @@ -149,24 +149,16 @@ namespace Phonon { static const QVector videoMediaTypes() { - AM_MEDIA_TYPE mt; - qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Video; - - //we accept any video format - mt.formattype = GUID_NULL; - mt.cbFormat = 0; - mt.pbFormat = 0; + AM_MEDIA_TYPE mt = { MEDIATYPE_Video, MEDIASUBTYPE_YV12, 0, 0, 0, GUID_NULL, 0, 0, 0 }; QVector ret; - //we support YUV (YV12 and YUY2) and RGB32 - mt.subtype = MEDIASUBTYPE_YV12; - ret << mt; + //we add all the subtypes we support + ret << mt; //YV12 mt.subtype = MEDIASUBTYPE_YUY2; - ret << mt; + ret << mt; //YUY2 mt.subtype = MEDIASUBTYPE_RGB32; - ret << mt; + ret << mt; //RGB32 return ret; } diff --git a/src/3rdparty/phonon/ds9/volumeeffect.cpp b/src/3rdparty/phonon/ds9/volumeeffect.cpp index 2fd1afc..b9a5fce 100644 --- a/src/3rdparty/phonon/ds9/volumeeffect.cpp +++ b/src/3rdparty/phonon/ds9/volumeeffect.cpp @@ -68,17 +68,7 @@ namespace Phonon static const QVector audioMediaType() { QVector ret; - - AM_MEDIA_TYPE mt; - mt.majortype = MEDIATYPE_Audio; - mt.subtype = MEDIASUBTYPE_PCM; - mt.bFixedSizeSamples = 1; - mt.bTemporalCompression = 0; - mt.pUnk = 0; - mt.lSampleSize = 1; - mt.cbFormat = 0; - mt.pbFormat = 0; - mt.formattype = GUID_NULL; + AM_MEDIA_TYPE mt = { MEDIATYPE_Audio, MEDIASUBTYPE_PCM, 1, 0, 1, GUID_NULL, 0, 0, 0}; ret << mt; return ret; } diff --git a/src/3rdparty/phonon/phonon/audiooutput.cpp b/src/3rdparty/phonon/phonon/audiooutput.cpp index 752580a..00b2ebd 100644 --- a/src/3rdparty/phonon/phonon/audiooutput.cpp +++ b/src/3rdparty/phonon/phonon/audiooutput.cpp @@ -264,8 +264,8 @@ void AudioOutputPrivate::setupBackendObject() if (deviceList.isEmpty()) { return; } - foreach (int devIndex, deviceList) { - const AudioOutputDevice &dev = AudioOutputDevice::fromIndex(devIndex); + for (int i = 0; i < deviceList.count(); ++i) { + const AudioOutputDevice &dev = AudioOutputDevice::fromIndex(deviceList.at(i)); if (callSetOutputDevice(this, dev)) { handleAutomaticDeviceChange(dev, AudioOutputPrivate::FallbackChange); return; // found one that works @@ -305,8 +305,9 @@ void AudioOutputPrivate::_k_audioDeviceFailed() pDebug() << Q_FUNC_INFO; // outputDeviceIndex identifies a failing device // fall back in the preference list of output devices - QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices); - foreach (int devIndex, deviceList) { + const QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices); + for (int i = 0; i < deviceList.count(); ++i) { + const int devIndex = deviceList.at(i); // if it's the same device as the one that failed, ignore it if (device.index() != devIndex) { const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex); @@ -326,9 +327,10 @@ void AudioOutputPrivate::_k_deviceListChanged() { pDebug() << Q_FUNC_INFO; // let's see if there's a usable device higher in the preference list - QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings); + const QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings); DeviceChangeType changeType = HigherPreferenceChange; - foreach (int devIndex, deviceList) { + for (int i = 0; i < deviceList.count(); ++i) { + const int devIndex = deviceList.at(i); const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex); if (!info.property("available").toBool()) { if (device.index() == devIndex) { diff --git a/src/3rdparty/phonon/phonon/backendcapabilities.cpp b/src/3rdparty/phonon/phonon/backendcapabilities.cpp index 5dee6a0..62c9cc9 100644 --- a/src/3rdparty/phonon/phonon/backendcapabilities.cpp +++ b/src/3rdparty/phonon/phonon/backendcapabilities.cpp @@ -76,8 +76,8 @@ QList BackendCapabilities::availableAudioOutputDevices() { QList ret; const QList deviceIndexes = GlobalConfig().audioOutputDeviceListFor(Phonon::NoCategory); - foreach (int i, deviceIndexes) { - ret.append(AudioOutputDevice::fromIndex(i)); + for (int i = 0; i < deviceIndexes.count(); ++i) { + ret.append(AudioOutputDevice::fromIndex(deviceIndexes.at(i))); } return ret; } @@ -88,8 +88,8 @@ QList BackendCapabilities::availableAudioCaptureDevices() { QList ret; const QList deviceIndexes = GlobalConfig().audioCaptureDeviceListFor(Phonon::NoCategory); - foreach (int i, deviceIndexes) { - ret.append(AudioCaptureDevice::fromIndex(i)); + for (int i = 0; i < deviceIndexes.count(); ++i) { + ret.append(AudioCaptureDevice::fromIndex(deviceIndexes.at(i))); } return ret; } @@ -101,9 +101,9 @@ QList BackendCapabilities::availableAudioEffects() BackendInterface *backendIface = qobject_cast(Factory::backend()); QList ret; if (backendIface) { - QList deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::EffectType); - foreach (int i, deviceIndexes) { - ret.append(EffectDescription::fromIndex(i)); + const QList deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::EffectType); + for (int i = 0; i < deviceIndexes.count(); ++i) { + ret.append(EffectDescription::fromIndex(deviceIndexes.at(i))); } } return ret; diff --git a/src/3rdparty/phonon/phonon/effect.cpp b/src/3rdparty/phonon/phonon/effect.cpp index c125232..98662a5 100644 --- a/src/3rdparty/phonon/phonon/effect.cpp +++ b/src/3rdparty/phonon/phonon/effect.cpp @@ -107,7 +107,8 @@ bool EffectPrivate::aboutToDeleteBackendObject() { if (m_backendObject) { const QList parameters = pINTERFACE_CALL(parameters()); - foreach (const EffectParameter &p, parameters) { + for (int i = 0; i < parameters.count(); ++i) { + const EffectParameter &p = parameters.at(i); parameterValues[p] = pINTERFACE_CALL(parameterValue(p)); } } @@ -120,7 +121,8 @@ void EffectPrivate::setupBackendObject() // set up attributes const QList parameters = pINTERFACE_CALL(parameters()); - foreach (const EffectParameter &p, parameters) { + for (int i = 0; i < parameters.count(); ++i) { + const EffectParameter &p = parameters.at(i); pINTERFACE_CALL(setParameterValue(p, parameterValues[p])); } } diff --git a/src/3rdparty/phonon/phonon/effectwidget.cpp b/src/3rdparty/phonon/phonon/effectwidget.cpp index d5c6c81..99478f7 100644 --- a/src/3rdparty/phonon/phonon/effectwidget.cpp +++ b/src/3rdparty/phonon/phonon/effectwidget.cpp @@ -97,7 +97,8 @@ void EffectWidgetPrivate::autogenerateUi() Q_Q(EffectWidget); QVBoxLayout *mainLayout = new QVBoxLayout(q); mainLayout->setMargin(0); - foreach (const EffectParameter ¶, effect->parameters()) { + for (int i = 0; i < effect->parameters().count(); ++i) { + const EffectParameter ¶ = effect->parameters().at(i); QVariant value = effect->parameterValue(para); QHBoxLayout *pLayout = new QHBoxLayout; mainLayout->addLayout(pLayout); @@ -117,13 +118,14 @@ void EffectWidgetPrivate::autogenerateUi() control = cb; if (value.type() == QVariant::Int) { //value just defines the item index - foreach (const QVariant &item, para.possibleValues()) { - cb->addItem(item.toString()); + for (int i = 0; i < para.possibleValues().count(); ++i) { + cb->addItem(para.possibleValues().at(i).toString()); } cb->setCurrentIndex(value.toInt()); QObject::connect(cb, SIGNAL(currentIndexChanged(int)), q, SLOT(_k_setIntParameter(int))); } else { - foreach (const QVariant &item, para.possibleValues()) { + for (int i = 0; i < para.possibleValues().count(); ++i) { + const QVariant &item = para.possibleValues().at(i); cb->addItem(item.toString()); if (item == value) { cb->setCurrentIndex(cb->count() - 1); diff --git a/src/3rdparty/phonon/phonon/factory.cpp b/src/3rdparty/phonon/phonon/factory.cpp index 43c45ee..fef88f0 100644 --- a/src/3rdparty/phonon/phonon/factory.cpp +++ b/src/3rdparty/phonon/phonon/factory.cpp @@ -124,15 +124,18 @@ bool FactoryPrivate::createBackend() // could not load a backend through the platform plugin. Falling back to the default // (finding the first loadable backend). const QLatin1String suffix("/phonon_backend/"); - foreach (QString libPath, QCoreApplication::libraryPaths()) { - libPath += suffix; + const QStringList paths = QCoreApplication::libraryPaths(); + for (int i = 0; i < paths.count(); ++i) { + const QString libPath = paths.at(i) + suffix; const QDir dir(libPath); if (!dir.exists()) { pDebug() << Q_FUNC_INFO << dir.absolutePath() << "does not exist"; continue; } - foreach (const QString &pluginName, dir.entryList(QDir::Files)) { - QPluginLoader pluginLoader(libPath + pluginName); + + const QStringList files = dir.entryList(QDir::Files); + for (int i = 0; i < files.count(); ++i) { + QPluginLoader pluginLoader(libPath + files.at(i)); if (!pluginLoader.load()) { pDebug() << Q_FUNC_INFO << " load failed:" << pluginLoader.errorString(); @@ -183,14 +186,8 @@ FactoryPrivate::FactoryPrivate() FactoryPrivate::~FactoryPrivate() { - foreach (QObject *o, objects) { - MediaObject *m = qobject_cast(o); - if (m) { - m->stop(); - } - } - foreach (MediaNodePrivate *bp, mediaNodePrivateList) { - bp->deleteBackendObject(); + for (int i = 0; i < mediaNodePrivateList.count(); ++i) { + mediaNodePrivateList.at(i)->deleteBackendObject(); } if (objects.size() > 0) { pError() << "The backend objects are not deleted as was requested."; @@ -258,8 +255,8 @@ void Factory::deregisterFrontendObject(MediaNodePrivate *bp) void FactoryPrivate::phononBackendChanged() { if (m_backendObject) { - foreach (MediaNodePrivate *bp, mediaNodePrivateList) { - bp->deleteBackendObject(); + for (int i = 0; i < mediaNodePrivateList.count(); ++i) { + mediaNodePrivateList.at(i)->deleteBackendObject(); } if (objects.size() > 0) { pDebug() << "WARNING: we were asked to change the backend but the application did\n" @@ -268,8 +265,8 @@ void FactoryPrivate::phononBackendChanged() "backendswitching possible."; // in case there were objects deleted give 'em a chance to recreate // them now - foreach (MediaNodePrivate *bp, mediaNodePrivateList) { - bp->createBackendObject(); + for (int i = 0; i < mediaNodePrivateList.count(); ++i) { + mediaNodePrivateList.at(i)->createBackendObject(); } return; } @@ -277,8 +274,8 @@ void FactoryPrivate::phononBackendChanged() m_backendObject = 0; } createBackend(); - foreach (MediaNodePrivate *bp, mediaNodePrivateList) { - bp->createBackendObject(); + for (int i = 0; i < mediaNodePrivateList.count(); ++i) { + mediaNodePrivateList.at(i)->createBackendObject(); } emit backendChanged(); } @@ -362,15 +359,17 @@ PlatformPlugin *FactoryPrivate::platformPlugin() QStringList()) ); dir.setFilter(QDir::Files); + const QStringList libPaths = QCoreApplication::libraryPaths(); forever { - foreach (QString libPath, QCoreApplication::libraryPaths()) { - libPath += suffix; + for (int i = 0; i < libPaths.count(); ++i) { + const QString libPath = libPaths.at(i) + suffix; dir.setPath(libPath); if (!dir.exists()) { continue; } - foreach (const QString &pluginName, dir.entryList()) { - QPluginLoader pluginLoader(libPath + pluginName); + const QStringList files = dir.entryList(QDir::Files); + for (int i = 0; i < files.count(); ++i) { + QPluginLoader pluginLoader(libPath + files.at(i)); if (!pluginLoader.load()) { pDebug() << Q_FUNC_INFO << " platform plugin load failed:" << pluginLoader.errorString(); diff --git a/src/3rdparty/phonon/phonon/medianode.cpp b/src/3rdparty/phonon/phonon/medianode.cpp index 4693cb8..63fa2e3 100644 --- a/src/3rdparty/phonon/phonon/medianode.cpp +++ b/src/3rdparty/phonon/phonon/medianode.cpp @@ -67,8 +67,8 @@ bool MediaNode::isValid() const MediaNodePrivate::~MediaNodePrivate() { - foreach (MediaNodeDestructionHandler *handler, handlers) { - handler->phononObjectDestroyed(this); + for (int i = 0 ; i < handlers.count(); ++i) { + handlers.at(i)->phononObjectDestroyed(this); } Factory::deregisterFrontendObject(this); delete m_backendObject; diff --git a/src/3rdparty/phonon/phonon/mediaobject.cpp b/src/3rdparty/phonon/phonon/mediaobject.cpp index de5fbc8..10fefbd 100644 --- a/src/3rdparty/phonon/phonon/mediaobject.cpp +++ b/src/3rdparty/phonon/phonon/mediaobject.cpp @@ -300,15 +300,15 @@ void MediaObject::enqueue(const MediaSource &source) void MediaObject::enqueue(const QList &sources) { - foreach (const MediaSource &m, sources) { - enqueue(m); + for (int i = 0; i < sources.count(); ++i) { + enqueue(sources.at(i)); } } void MediaObject::enqueue(const QList &urls) { - foreach (const QUrl &url, urls) { - enqueue(url); + for (int i = 0; i < urls.count(); ++i) { + enqueue(urls.at(i)); } } @@ -502,8 +502,8 @@ void MediaObjectPrivate::setupBackendObject() } #ifndef QT_NO_PHONON_MEDIACONTROLLER - foreach (FrontendInterfacePrivate *f, interfaceList) { - f->_backendObjectChanged(); + for (int i = 0 ; i < interfaceList.count(); ++i) { + interfaceList.at(i)->_backendObjectChanged(); } #endif //QT_NO_PHONON_MEDIACONTROLLER diff --git a/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp b/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp index e989d0c..b67344f 100644 --- a/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp +++ b/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp @@ -321,8 +321,8 @@ bool ObjectDescriptionModelData::dropMimeData(ObjectDescriptionType type, const } } d->model->beginInsertRows(QModelIndex(), row, row + toInsert.size() - 1); - foreach (const QExplicitlySharedDataPointer &obj, toInsert) { - d->data.insert(row, obj); + for (int i = 0 ; i < toInsert.count(); ++i) { + d->data.insert(row, toInsert.at(i)); } d->model->endInsertRows(); return true; diff --git a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h index 84dc0bb..ba3cb42 100644 --- a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h +++ b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h @@ -292,8 +292,8 @@ namespace Phonon */ inline void setModelData(const QList > &data) { //krazy:exclude=inline QList > list; - Q_FOREACH (const ObjectDescription &desc, data) { - list << desc.d; + for (int i = 0; i < data.count(); ++i) { + list += data.at(i).d; } d->setModelData(list); } @@ -307,8 +307,8 @@ namespace Phonon inline QList > modelData() const { //krazy:exclude=inline QList > ret; QList > list = d->modelData(); - Q_FOREACH (const QExplicitlySharedDataPointer &data, list) { - ret << ObjectDescription(data); + for (int i = 0; i < list.count(); ++i) { + ret << ObjectDescription(list.at(i)); } return ret; } diff --git a/src/3rdparty/phonon/phonon/path.cpp b/src/3rdparty/phonon/phonon/path.cpp index b46d30a..aec8d05 100644 --- a/src/3rdparty/phonon/phonon/path.cpp +++ b/src/3rdparty/phonon/phonon/path.cpp @@ -58,8 +58,8 @@ class ConnectionTransaction PathPrivate::~PathPrivate() { #ifndef QT_NO_PHONON_EFFECT - foreach (Effect *e, effects) { - e->k_ptr->removeDestructionHandler(this); + for (int i = 0; i < effects.count(); ++i) { + effects.at(i)->k_ptr->removeDestructionHandler(this); } delete effectsParent; #endif @@ -233,8 +233,8 @@ bool Path::disconnect() if (d->sourceNode) list << d->sourceNode->k_ptr->backendObject(); #ifndef QT_NO_PHONON_EFFECT - foreach(Effect *e, d->effects) { - list << e->k_ptr->backendObject(); + for (int i = 0; i < d->effects.count(); ++i) { + list << d->effects.at(i)->k_ptr->backendObject(); } #endif if (d->sinkNode) { @@ -260,8 +260,8 @@ bool Path::disconnect() d->sourceNode = 0; #ifndef QT_NO_PHONON_EFFECT - foreach(Effect *e, d->effects) { - e->k_ptr->removeDestructionHandler(d.data()); + for (int i = 0; i < d->effects.count(); ++i) { + d->effects.at(i)->k_ptr->removeDestructionHandler(d.data()); } d->effects.clear(); #endif @@ -292,11 +292,13 @@ MediaNode *Path::sink() const bool PathPrivate::executeTransaction( const QList &disconnections, const QList &connections) { QSet nodesForTransaction; - foreach(const QObjectPair &pair, disconnections) { + for (int i = 0; i < disconnections.count(); ++i) { + const QObjectPair &pair = disconnections.at(i); nodesForTransaction << pair.first; nodesForTransaction << pair.second; } - foreach(const QObjectPair &pair, connections) { + for (int i = 0; i < connections.count(); ++i) { + const QObjectPair &pair = connections.at(i); nodesForTransaction << pair.first; nodesForTransaction << pair.second; } @@ -338,7 +340,8 @@ bool PathPrivate::executeTransaction( const QList &disconnections, } //and now let's reconnect the nodes that were disconnected: rollback - foreach(const QObjectPair &pair, disconnections) { + for (int i = 0; i < disconnections.count(); ++i) { + const QObjectPair &pair = disconnections.at(i); bool success = backend->connectNodes(pair.first, pair.second); Q_ASSERT(success); //a failure here means it is impossible to reestablish the connection Q_UNUSED(success); @@ -417,7 +420,8 @@ void PathPrivate::phononObjectDestroyed(MediaNodePrivate *mediaNodePrivate) sinkNode = 0; } else { #ifndef QT_NO_PHONON_EFFECT - foreach (Effect *e, effects) { + for (int i = 0; i < effects.count(); ++i) { + Effect *e = effects.at(i); if (e->k_ptr == mediaNodePrivate) { removeEffect(e); } -- cgit v0.12 From bf51ca62d4d5c5df5aa8d3c09007eb1c44d7d710 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 14:17:04 +0200 Subject: Phonon: take advantage of more modern compiler to initialize struct This was not supported before by MSVC6 and MSVC2002 --- src/3rdparty/phonon/ds9/fakesource.cpp | 34 ++++----------------- src/3rdparty/phonon/ds9/iodevicereader.cpp | 1 - src/3rdparty/phonon/ds9/qaudiocdreader.cpp | 49 ++++++++++-------------------- src/3rdparty/phonon/ds9/qpin.cpp | 23 +++----------- 4 files changed, 27 insertions(+), 80 deletions(-) diff --git a/src/3rdparty/phonon/ds9/fakesource.cpp b/src/3rdparty/phonon/ds9/fakesource.cpp index 9a61a2e..a4d4640 100644 --- a/src/3rdparty/phonon/ds9/fakesource.cpp +++ b/src/3rdparty/phonon/ds9/fakesource.cpp @@ -29,8 +29,10 @@ namespace Phonon namespace DS9 { static WAVEFORMATEX g_defaultWaveFormat = {WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0}; - static BITMAPINFOHEADER g_defautBitmapHeader = { sizeof(BITMAPINFOHEADER), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}; - static VIDEOINFOHEADER2 g_defaultVideoInfo = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + static VIDEOINFOHEADER2 g_defaultVideoInfo = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, {sizeof(BITMAPINFOHEADER), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0} }; + + static const AM_MEDIA_TYPE g_fakeAudioType = {MEDIATYPE_Audio, MEDIASUBTYPE_PCM, 0, 0, 2, FORMAT_WaveFormatEx, 0, sizeof(WAVEFORMATEX), reinterpret_cast(&g_defaultWaveFormat)}; + static const AM_MEDIA_TYPE g_fakeVideoType = {MEDIATYPE_Video, MEDIASUBTYPE_RGB32, TRUE, FALSE, 0, FORMAT_VideoInfo2, 0, sizeof(VIDEOINFOHEADER2), reinterpret_cast(&g_defaultVideoInfo)}; class FakePin : public QPin { @@ -128,36 +130,12 @@ namespace Phonon void FakeSource::createFakeAudioPin() { - AM_MEDIA_TYPE mt; - qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Audio; - mt.subtype = MEDIASUBTYPE_PCM; - mt.formattype = FORMAT_WaveFormatEx; - mt.lSampleSize = 2; - - //fake the format (stereo 44.1 khz stereo 16 bits) - mt.cbFormat = sizeof(WAVEFORMATEX); - mt.pbFormat = reinterpret_cast(&g_defaultWaveFormat); - - new FakePin(this, mt); + new FakePin(this, g_fakeAudioType); } void FakeSource::createFakeVideoPin() { - AM_MEDIA_TYPE mt; - qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Video; - mt.subtype = MEDIASUBTYPE_RGB32; - mt.formattype = FORMAT_VideoInfo2; - mt.bFixedSizeSamples = 1; - - g_defaultVideoInfo.bmiHeader = g_defautBitmapHeader; - - //fake the format - mt.cbFormat = sizeof(VIDEOINFOHEADER2); - mt.pbFormat = reinterpret_cast(&g_defaultVideoInfo); - - new FakePin(this, mt); + new FakePin(this, g_fakeVideoType); } } diff --git a/src/3rdparty/phonon/ds9/iodevicereader.cpp b/src/3rdparty/phonon/ds9/iodevicereader.cpp index 2dff1fe..38c983b 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.cpp +++ b/src/3rdparty/phonon/ds9/iodevicereader.cpp @@ -40,7 +40,6 @@ namespace Phonon QVector ret; //normal auto-detect stream - mt.subtype = MEDIASUBTYPE_NULL; ret << mt; //AVI stream mt.subtype = MEDIASUBTYPE_Avi; diff --git a/src/3rdparty/phonon/ds9/qaudiocdreader.cpp b/src/3rdparty/phonon/ds9/qaudiocdreader.cpp index d5bdce2..6d0f335 100644 --- a/src/3rdparty/phonon/ds9/qaudiocdreader.cpp +++ b/src/3rdparty/phonon/ds9/qaudiocdreader.cpp @@ -103,8 +103,8 @@ namespace Phonon private: HANDLE m_cddrive; - CDROM_TOC *m_toc; - WaveStructure *m_waveHeader; + CDROM_TOC m_toc; + WaveStructure m_waveHeader; qint64 m_trackAddress; }; @@ -112,19 +112,8 @@ namespace Phonon #define SECTOR_SIZE 2352 #define NB_SECTORS_READ 20 - static AM_MEDIA_TYPE getAudioCDMediaType() - { - AM_MEDIA_TYPE mt; - qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Stream; - mt.subtype = MEDIASUBTYPE_WAVE; - mt.bFixedSizeSamples = TRUE; - mt.bTemporalCompression = FALSE; - mt.lSampleSize = 1; - mt.formattype = GUID_NULL; - return mt; - } - + static const AM_MEDIA_TYPE audioCDMediaType = { MEDIATYPE_Stream, MEDIASUBTYPE_WAVE, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; + int addressToSectors(UCHAR address[4]) { return ((address[0] * 60 + address[1]) * 60 + address[2]) * 75 + address[3] - 150; @@ -141,11 +130,8 @@ namespace Phonon } - QAudioCDReader::QAudioCDReader(QBaseFilter *parent, QChar drive) : QAsyncReader(parent, QVector() << getAudioCDMediaType()) + QAudioCDReader::QAudioCDReader(QBaseFilter *parent, QChar drive) : QAsyncReader(parent, QVector() << audioCDMediaType) { - m_toc = new CDROM_TOC; - m_waveHeader = new WaveStructure; - //now open the cd-drive QString path; if (drive.isNull()) { @@ -156,31 +142,28 @@ namespace Phonon m_cddrive = ::CreateFile((const wchar_t *)path.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - qMemSet(m_toc, 0, sizeof(CDROM_TOC)); + qMemSet(&m_toc, 0, sizeof(CDROM_TOC)); //read the TOC DWORD bytesRead = 0; - bool tocRead = ::DeviceIoControl(m_cddrive, IOCTL_CDROM_READ_TOC, 0, 0, m_toc, sizeof(CDROM_TOC), &bytesRead, 0); + bool tocRead = ::DeviceIoControl(m_cddrive, IOCTL_CDROM_READ_TOC, 0, 0, &m_toc, sizeof(CDROM_TOC), &bytesRead, 0); if (!tocRead) { qWarning("unable to load the TOC from the CD"); return; } - m_trackAddress = addressToSectors(m_toc->TrackData[0].Address); - const qint32 nbSectorsToRead = (addressToSectors(m_toc->TrackData[m_toc->LastTrack + 1 - m_toc->FirstTrack].Address) + m_trackAddress = addressToSectors(m_toc.TrackData[0].Address); + const qint32 nbSectorsToRead = (addressToSectors(m_toc.TrackData[m_toc.LastTrack + 1 - m_toc.FirstTrack].Address) - m_trackAddress); const qint32 dataLength = nbSectorsToRead * SECTOR_SIZE; - m_waveHeader->chunksize = 4 + (8 + m_waveHeader->chunksize2) + (8 + dataLength); - m_waveHeader->dataLength = dataLength; + m_waveHeader.chunksize = 4 + (8 + m_waveHeader.chunksize2) + (8 + dataLength); + m_waveHeader.dataLength = dataLength; } QAudioCDReader::~QAudioCDReader() { ::CloseHandle(m_cddrive); - delete m_toc; - delete m_waveHeader; - } STDMETHODIMP_(ULONG) QAudioCDReader::AddRef() @@ -196,7 +179,7 @@ namespace Phonon STDMETHODIMP QAudioCDReader::Length(LONGLONG *total,LONGLONG *available) { - const LONGLONG length = sizeof(WaveStructure) + m_waveHeader->dataLength; + const LONGLONG length = sizeof(WaveStructure) + m_waveHeader.dataLength; if (total) { *total = length; } @@ -235,11 +218,11 @@ namespace Phonon if (pos < sizeof(WaveStructure)) { //we first copy the content of the structure nbRead = qMin(LONG(sizeof(WaveStructure) - pos), length); - qMemCopy(buffer, reinterpret_cast(m_waveHeader) + pos, nbRead); + qMemCopy(buffer, reinterpret_cast(&m_waveHeader) + pos, nbRead); } const LONGLONG posInTrack = pos - sizeof(WaveStructure) + nbRead; - const int bytesLeft = qMin(m_waveHeader->dataLength - posInTrack, LONGLONG(length - nbRead)); + const int bytesLeft = qMin(m_waveHeader.dataLength - posInTrack, LONGLONG(length - nbRead)); if (bytesLeft > 0) { @@ -294,8 +277,8 @@ namespace Phonon { QList ret; ret << 0; - for(int i = m_toc->FirstTrack; i <= m_toc->LastTrack ; ++i) { - const uchar *address = m_toc->TrackData[i].Address; + for(int i = m_toc.FirstTrack; i <= m_toc.LastTrack ; ++i) { + const uchar *address = m_toc.TrackData[i].Address; ret << ((address[0] * 60 + address[1]) * 60 + address[2]) * 1000 + address[3]*1000/75 - 2000; } diff --git a/src/3rdparty/phonon/ds9/qpin.cpp b/src/3rdparty/phonon/ds9/qpin.cpp index 37fe48d..5f335ac 100644 --- a/src/3rdparty/phonon/ds9/qpin.cpp +++ b/src/3rdparty/phonon/ds9/qpin.cpp @@ -28,20 +28,7 @@ namespace Phonon namespace DS9 { - static const AM_MEDIA_TYPE defaultMediaType() - { - AM_MEDIA_TYPE ret; - ret.majortype = MEDIATYPE_NULL; - ret.subtype = MEDIASUBTYPE_NULL; - ret.bFixedSizeSamples = TRUE; - ret.bTemporalCompression = FALSE; - ret.lSampleSize = 1; - ret.formattype = GUID_NULL; - ret.pUnk = 0; - ret.cbFormat = 0; - ret.pbFormat = 0; - return ret; - } + static const AM_MEDIA_TYPE defaultMediaType = { MEDIATYPE_NULL, MEDIASUBTYPE_NULL, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; class QEnumMediaTypes : public IEnumMediaTypes { @@ -159,7 +146,7 @@ namespace Phonon QPin::QPin(QBaseFilter *parent, PIN_DIRECTION dir, const QVector &mt) : m_memAlloc(0), m_parent(parent), m_refCount(1), m_connected(0), - m_direction(dir), m_mediaTypes(mt), m_connectedType(defaultMediaType()), + m_direction(dir), m_mediaTypes(mt), m_connectedType(defaultMediaType), m_flushing(false) { Q_ASSERT(m_parent); @@ -273,7 +260,7 @@ namespace Phonon if (FAILED(hr)) { setConnected(0); - setConnectedType(defaultMediaType()); + setConnectedType(defaultMediaType); } else { ComPointer input(pin, IID_IMemInputPin); if (input) { @@ -315,7 +302,7 @@ namespace Phonon } setConnected(0); - setConnectedType(defaultMediaType()); + setConnectedType(defaultMediaType); if (m_direction == PINDIR_INPUT) { setMemoryAllocator(0); } @@ -470,7 +457,7 @@ namespace Phonon freeMediaType(type); return S_OK; } else { - setConnectedType(defaultMediaType()); + setConnectedType(defaultMediaType); freeMediaType(type); } } -- cgit v0.12 From 8a72074b0ab146942512b37439ffc8618e3f7d06 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 15:13:07 +0200 Subject: doc: Included note about the effect of WA_NoMousePropagation. Task-number: 162945 --- src/gui/kernel/qevent.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index bef7ee1..4fc3643 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -114,6 +114,10 @@ QInputEvent::~QInputEvent() propagated up the parent widget chain until a widget accepts it with accept(), or an event filter consumes it. + \note If a mouse event is propagated to a \l{QWidget}{widget} for + which Qt::WA_NoMousePropagation has been set, that mouse event + will not be propagated further up the parent widget chain. + The state of the keyboard modifier keys can be found by calling the \l{QInputEvent::modifiers()}{modifiers()} function, inhertied from QInputEvent. -- cgit v0.12 From ba25bdcb9122d45ccdd06f281a5f49999eaff089 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Mon, 6 Jul 2009 15:33:10 +0200 Subject: Doc - beautified some of the existing sentences in Part 6 Reviewed-By: TrustMe --- doc/src/tutorials/addressbook.qdoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/src/tutorials/addressbook.qdoc b/doc/src/tutorials/addressbook.qdoc index 33832da..95394eb 100644 --- a/doc/src/tutorials/addressbook.qdoc +++ b/doc/src/tutorials/addressbook.qdoc @@ -876,7 +876,7 @@ \image addressbook-tutorial-part6-save.png - If \c fileName is not empty, we create a QFile object, \c file with + If \c fileName is not empty, we create a QFile object, \c file, with \c fileName. QFile works with QDataStream as QFile is a QIODevice. Next, we attempt to open the file in \l{QIODevice::}{WriteOnly} mode. @@ -906,18 +906,18 @@ \image addressbook-tutorial-part6-load.png If \c fileName is not empty, again, we use a QFile object, \c file, and - attempt to open it in \l{QIODevice::}{ReadOnly} mode. In a similar way - to our implementation of \c saveToFile(), if this attempt is unsuccessful, - we display a QMessageBox to inform the user. + attempt to open it in \l{QIODevice::}{ReadOnly} mode. Similar to our + implementation of \c saveToFile(), if this attempt is unsuccessful, we + display a QMessageBox to inform the user. \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part2 Otherwise, we instantiate a QDataStream object, \c in, set its version as above and read the serialized data into the \c contacts data structure. - Note that we empty \c contacts before reading data into it to simplify the - file reading process. A more advanced method would be to read the contacts - into temporary QMap object, and copy only the contacts that do not already - exist in \c contacts. + The \c contacts object is emptied before data is read into it to simplify + the file reading process. A more advanced method would be to read the + contacts into a temporary QMap object, and copy over non-duplicate contacts + into \c contacts. \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part3 -- cgit v0.12 From e07e95da3d35a2ea1ab2b325df6c91620f948497 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 6 Jul 2009 15:43:03 +0200 Subject: Fix issue where a mainwindow would show two size grips in Cocoa. OK. this is a bit strange. It seems the topdata->resizer value is used to control whether or not we should show a resize handle based on a count (0 no, non-zero yes). Since we somehow decided that this value will never be larger than 15, we made it 4-bits wide. There's a "Qt/Mac" API, QWidgetPrivate::qt_mac_update_sizer(QWidget *, int = 0) which would adjust this value by the int passed in.. We use that in several places, not excluding the QStatusBar where we would pass 1 if we want to show, and -1 if we didn't. Now if you subtract -1 from zero when you are 4 bits wide, well, bad things happen. Therefore protect that (since if it's at zero we have succeeded, we don't want to show the resizer). This seems to work well. The private API is certainly an interesting way of solving the problem, but is easy to abuse (for example, this code will break if resizer = 1 and we are passed -2 in the function. Task-number: 257485 Reviewed-by: Prasanth Ullattil --- src/gui/kernel/qwidget_mac.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index ec9a049..f96d061 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -1526,12 +1526,16 @@ void QWidgetPrivate::toggleDrawers(bool visible) *****************************************************************************/ bool QWidgetPrivate::qt_mac_update_sizer(QWidget *w, int up) { + // I'm not sure what "up" is if(!w || !w->isWindow()) return false; QTLWExtra *topData = w->d_func()->topData(); QWExtra *extraData = w->d_func()->extraData(); - topData->resizer += up; + // topData->resizer is only 4 bits, so subtracting -1 from zero causes bad stuff + // to happen, prevent that here (you really want the thing hidden). + if (up >= 0 || topData->resizer != 0) + topData->resizer += up; OSWindowRef windowRef = qt_mac_window_for(OSViewRef(w->winId())); { #ifndef QT_MAC_USE_COCOA @@ -1544,7 +1548,6 @@ bool QWidgetPrivate::qt_mac_update_sizer(QWidget *w, int up) bool remove_grip = (topData->resizer || (w->windowFlags() & Qt::FramelessWindowHint) || (extraData->maxw && extraData->maxh && extraData->maxw == extraData->minw && extraData->maxh == extraData->minh)); - #ifndef QT_MAC_USE_COCOA WindowAttributes attr; GetWindowAttributes(windowRef, &attr); -- cgit v0.12 From d000c29f9039dab6cd46bb3a12df828d5f9354a7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 16:12:36 +0200 Subject: QMenu: scrolling in menus was broken --- src/gui/widgets/qmenu.cpp | 34 +++++++++++++++++++++------------- src/gui/widgets/qmenu_p.h | 6 +++--- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index d3f5bc5..ef892d7 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -257,7 +257,6 @@ void QMenuPrivate::updateActionRects() const //let the style modify the above size.. QStyleOptionMenuItem opt; q->initStyleOption(&opt, action); - opt.rect = q->rect(); const QFontMetrics &fm = opt.fontMetrics; QSize sz; @@ -757,9 +756,19 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc } //actually update flags - scroll->scrollOffset = newOffset; - if (scroll->scrollOffset > 0) - scroll->scrollOffset = 0; + const int delta = qMin(0, newOffset) - scroll->scrollOffset; //make sure the new offset is always negative + if (!itemsDirty && delta) { + //we've scrolled so we need to update the action rects + for (int i = 0; i < actionRects.count(); ++i) { + QRect ¤t = actionRects[i]; + current.moveTop(current.top() + delta); + + //we need to update the widgets geometry + if (QWidget *w = widgetItems.at(i)) + w->setGeometry(current); + } + } + scroll->scrollOffset += delta; scroll->scrollFlags = newScrollFlags; if (active) setCurrentAction(action); @@ -875,12 +884,10 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) } } if (isScroll) { - if (!scroll->scrollTimer) - scroll->scrollTimer = new QBasicTimer; - scroll->scrollTimer->start(50, q); + scroll->scrollTimer.start(50, q); return true; - } else if (scroll->scrollTimer && scroll->scrollTimer->isActive()) { - scroll->scrollTimer->stop(); + } else { + scroll->scrollTimer.stop(); } } @@ -2054,6 +2061,8 @@ void QMenu::hideEvent(QHideEvent *) d->hasHadMouse = false; d->causedPopup.widget = 0; d->causedPopup.action = 0; + if (d->scroll) + d->scroll->scrollTimer.stop(); //make sure the timer stops } /*! @@ -2499,8 +2508,7 @@ void QMenu::keyPressEvent(QKeyEvent *e) } if (nextAction) { if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) { - if (d->scroll->scrollTimer) - d->scroll->scrollTimer->stop(); + d->scroll->scrollTimer.stop(); d->scrollMenu(nextAction, scroll_loc); } d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard); @@ -2761,10 +2769,10 @@ void QMenu::timerEvent(QTimerEvent *e) { Q_D(QMenu); - if (d->scroll && d->scroll->scrollTimer && d->scroll->scrollTimer->timerId() == e->timerId()) { + if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) { d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection); if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone) - d->scroll->scrollTimer->stop(); + d->scroll->scrollTimer.stop(); } else if(QMenuPrivate::menuDelayTimer.timerId() == e->timerId()) { QMenuPrivate::menuDelayTimer.stop(); internalDelayedPopup(); diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 50a9f2f..461d435 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -189,10 +189,10 @@ public: enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 }; uint scrollFlags : 2, scrollDirection : 2; int scrollOffset; - QBasicTimer *scrollTimer; + QBasicTimer scrollTimer; - QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0), scrollTimer(0) { } - ~QMenuScroller() { delete scrollTimer; } + QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { } + ~QMenuScroller() { } } *scroll; void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false); void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false); -- cgit v0.12 From 134dad4c6a996045397098498eaf0afca889b6f9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 16:48:15 +0200 Subject: QMenu: the scroller now takes the qapp's global strut into account Task-number: 257118 --- src/gui/widgets/qmenu.cpp | 48 +++++++++++++++++++++++------------------------ src/gui/widgets/qmenu_p.h | 2 ++ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index ef892d7..af9ddf5 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -163,6 +163,12 @@ void QMenuPrivate::init() } } +int QMenuPrivate::scrollerHeight() const +{ + Q_Q(const QMenu); + return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q)); +} + //Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't QRect QMenuPrivate::popupGeometry(int screen) const { @@ -483,14 +489,13 @@ void QMenuPrivate::setFirstActionActive() { Q_Q(QMenu); updateActionRects(); - const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); for(int i = 0, saccum = 0; i < actions.count(); i++) { const QRect &rect = actionRects.at(i); if (rect.isNull()) continue; if (scroll && scroll->scrollFlags & QMenuScroller::ScrollUp) { saccum -= rect.height(); - if (saccum > scroll->scrollOffset-scrollerHeight) + if (saccum > scroll->scrollOffset - scrollerHeight()) continue; } QAction *act = actions.at(i); @@ -668,16 +673,14 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc return; updateActionRects(); int newOffset = 0; - const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); - const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; - const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0; + const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0; + const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0; const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q); const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); if (location == QMenuScroller::ScrollTop) { for(int i = 0, saccum = 0; i < actions.count(); i++) { - QAction *act = actions.at(i); - if (act == action) { + if (actions.at(i) == action) { newOffset = topScroll - saccum; break; } @@ -685,9 +688,8 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc } } else { for(int i = 0, saccum = 0; i < actions.count(); i++) { - QAction *act = actions.at(i); saccum += actionRects.at(i).height(); - if (act == action) { + if (actions.at(i) == action) { if (location == QMenuScroller::ScrollCenter) newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll); else @@ -820,9 +822,8 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag if (!scroll || !(scroll->scrollFlags & direction)) //not really possible... return; updateActionRects(); - const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); - const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; - const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0; + const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0; + const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0; const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q); const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); const int offset = topScroll ? topScroll-vmargin : 0; @@ -869,13 +870,12 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) if (scroll && !activeMenu) { //let the scroller "steal" the event bool isScroll = false; if (pos.x() >= 0 && pos.x() < q->width()) { - const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) { if (scroll->scrollFlags & dir) { if (dir == QMenuScroller::ScrollUp) - isScroll = (pos.y() <= scrollerHeight); + isScroll = (pos.y() <= scrollerHeight()); else if (dir == QMenuScroller::ScrollDown) - isScroll = (pos.y() >= q->height()-scrollerHeight); + isScroll = (pos.y() >= q->height() - scrollerHeight()); if (isScroll) { scroll->scrollDirection = dir; break; @@ -894,7 +894,7 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) if (tearoff) { //let the tear off thingie "steal" the event.. QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q)); if (scroll && scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) - tearRect.translate(0, q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q)); + tearRect.translate(0, scrollerHeight()); q->update(tearRect); if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) { setCurrentAction(0); @@ -2104,18 +2104,17 @@ void QMenu::paintEvent(QPaintEvent *e) const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this); //draw the scroller regions.. if (d->scroll) { - const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); menuOpt.menuItemType = QStyleOptionMenuItem::Scroller; menuOpt.state |= QStyle::State_Enabled; if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) { - menuOpt.rect.setRect(fw, fw, width() - (fw * 2), scrollerHeight); + menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight()); emptyArea -= QRegion(menuOpt.rect); p.setClipRect(menuOpt.rect); style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this); } if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) { - menuOpt.rect.setRect(fw, height() - scrollerHeight - fw, width() - (fw * 2), - scrollerHeight); + menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2), + d->scrollerHeight()); emptyArea -= QRegion(menuOpt.rect); menuOpt.state |= QStyle::State_DownArrow; p.setClipRect(menuOpt.rect); @@ -2128,7 +2127,7 @@ void QMenu::paintEvent(QPaintEvent *e) menuOpt.rect.setRect(fw, fw, width() - (fw * 2), style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this)); if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) - menuOpt.rect.translate(0, style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this)); + menuOpt.rect.translate(0, d->scrollerHeight()); emptyArea -= QRegion(menuOpt.rect); p.setClipRect(menuOpt.rect); menuOpt.state = QStyle::State_None; @@ -2458,7 +2457,7 @@ void QMenu::keyPressEvent(QKeyEvent *e) continue; nextAction = next; if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) { - int topVisible = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); + int topVisible = d->scrollerHeight(); if (d->tearoff) topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height()) @@ -2489,10 +2488,9 @@ void QMenu::keyPressEvent(QKeyEvent *e) continue; nextAction = next; if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) { - const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); - int bottomVisible = height()-scrollerHeight; + int bottomVisible = height() - d->scrollerHeight(); if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) - bottomVisible -= scrollerHeight; + bottomVisible -= d->scrollerHeight(); if (d->tearoff) bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible) diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 461d435..4e428fe 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -151,6 +151,8 @@ public: } void init(); + int scrollerHeight() const; + //item calculations mutable uint itemsDirty : 1; mutable uint maxIconWidth, tabWidth; -- cgit v0.12 From 1222ea208587ed039e436d58aa6d7ea6ea6c014e Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Mon, 6 Jul 2009 19:29:07 +0200 Subject: Update Russian Qt phrase book Merge-request: 803 Reviewed-by: Oswald Buddenhagen --- tools/linguist/phrasebooks/russian.qph | 52 +++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/tools/linguist/phrasebooks/russian.qph b/tools/linguist/phrasebooks/russian.qph index 629c60b..69af041 100644 --- a/tools/linguist/phrasebooks/russian.qph +++ b/tools/linguist/phrasebooks/russian.qph @@ -10,7 +10,7 @@ accessibility - удобство + специальные возможности action handle @@ -345,8 +345,8 @@ активная зона - icon - пиктограмма + Icon + Значок inactive @@ -402,7 +402,7 @@ list view - древовидный список + список manual link @@ -901,10 +901,6 @@ панель инструментов - tooltip - всплывающая подсказка - - tree view control древовидный список @@ -1054,10 +1050,46 @@ Case Sensitive - Регистрозависимо + Учитывать регистр Whole words - Слова полностью + Слова целиком + + + Find Next + Найти следующее + + + Find Previous + Найти предыдущее + + + Case Sensitive + Учитывать регистр символов + + + Whole words only + Только слова целиком + + + Subwindow + Дочернее окно + + + Next + Далее + + + tree view + древовидный список + + + ToolTip + Подсказка + + + Checkable + Переключаемое -- cgit v0.12 From e1d2dffc8cfe4195210ce435c394d8af9b9823e8 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Mon, 6 Jul 2009 19:29:08 +0200 Subject: Update Russian translation for Qt libraries. almost done; only few strings left untranslated. Merge-request: 803 Reviewed-by: Oswald Buddenhagen --- translations/qt_ru.ts | 212 +++++++++++++++++++++++++------------------------- 1 file changed, 104 insertions(+), 108 deletions(-) diff --git a/translations/qt_ru.ts b/translations/qt_ru.ts index 1e6a4eb..9529c33 100644 --- a/translations/qt_ru.ts +++ b/translations/qt_ru.ts @@ -57,7 +57,7 @@ Accessibility - Средства для людей с ограниченными возможностями + Специальные возможности @@ -87,7 +87,7 @@ Check your Gstreamer installation and make sure you have libgstreamer-plugins-base installed. Невозможно начать воспроизведение. -Проверьте установку Gstreamer и убедитесь, +Проверьте установку Gstreamer и убедитесь, что пакет libgstreamer-plugins-base установлен.
@@ -917,22 +917,22 @@ to QAxSelect - + Select ActiveX Control Выбор компоненты ActiveX - + OK Выбрать - + &Cancel &Отмена - + COM &Object: COM &Объект: @@ -1022,7 +1022,7 @@ to Открыть - + False Нет @@ -1491,32 +1491,32 @@ Please verify the correct file name was given. Показать скр&ытые файлы - - + + Back Назад - - + + Parent Directory Родительский каталог - - + + List View Список - - + + Detail View Подробный вид - - + + Files of type: Типы файлов: @@ -1595,8 +1595,8 @@ Do you want to delete it anyway? Показать - - + + Forward Вперёд @@ -1628,14 +1628,14 @@ Do you want to delete it anyway? &Имя файла: - - + + Look in: Перейти к: - - + + Create New Folder Создать папку @@ -1799,7 +1799,7 @@ Do you want to delete it anyway? Arabic - + Арабская @@ -1809,57 +1809,57 @@ Do you want to delete it anyway? Thaana - + Таана Devanagari - + Деванагири Bengali - + Бенгальская Gurmukhi - + Гурмукхи Gujarati - + Гуджарати Oriya - + Ория Tamil - + Тамильская Telugu - + Телугу Kannada - + Каннада Malayalam - + Малайялам Sinhala - + Сингальская @@ -1869,7 +1869,7 @@ Do you want to delete it anyway? Lao - + Лаосская @@ -1879,7 +1879,7 @@ Do you want to delete it anyway? Myanmar - + Мьянма @@ -1924,7 +1924,7 @@ Do you want to delete it anyway? Ogham - + Огамическая @@ -2210,7 +2210,7 @@ Do you want to delete it anyway? Ошибка записи ответа на устройство - + Connection refused Отказано в соединении @@ -2372,7 +2372,7 @@ Do you want to delete it anyway? QIBaseDriver - + Error opening database Ошибка открытия базы данных @@ -2395,7 +2395,7 @@ Do you want to delete it anyway? QIBaseResult - + Unable to create BLOB Невозможно создать BLOB @@ -2441,7 +2441,7 @@ Do you want to delete it anyway? Невозможно выполнить транзакцию - + Could not allocate statement Не удалось получить ресурсы для создания выражения @@ -2452,12 +2452,12 @@ Do you want to delete it anyway? - + Could not describe input statement Не удалось описать входящее выражение - + Could not describe statement Не удалось описать выражение @@ -3223,7 +3223,7 @@ Do you want to delete it anyway? Ошибка загрузки %1 - ответ сервера: %2 - + Protocol "%1" is unknown Неизвестный протокол "%1" @@ -3231,7 +3231,7 @@ Do you want to delete it anyway? QNetworkReplyImpl - + Operation canceled Операция отменена @@ -3240,7 +3240,7 @@ Do you want to delete it anyway? QOCIDriver - + Unable to logon Невозможно авторизоваться @@ -3269,7 +3269,7 @@ Do you want to delete it anyway? QOCIResult - + Unable to bind column for batch execute @@ -3281,7 +3281,7 @@ Do you want to delete it anyway? Невозможно выполнить пакетное выражение - + Unable to goto next Невозможно перейти к следующей строке @@ -3314,7 +3314,7 @@ Do you want to delete it anyway? QODBCDriver - + Unable to connect Невозможно соединиться @@ -3324,7 +3324,7 @@ Do you want to delete it anyway? Невозможно соединиться - Драйвер не поддерживает требуемый функционал - + Unable to disable autocommit Невозможно отключить автовыполнение транзакции @@ -3347,7 +3347,7 @@ Do you want to delete it anyway? QODBCResult - + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration QODBCResult::reset: Невозможно установить 'SQL_CURSOR_STATIC' атрибутом выражение. Проверьте настройки драйвера ODBC @@ -3376,12 +3376,12 @@ Do you want to delete it anyway? - + Unable to fetch last Невозможно получить последнюю строку - + Unable to fetch Невозможно получить данные @@ -3471,7 +3471,7 @@ Do you want to delete it anyway? Не удалось начать транзакцию - + Could not commit transaction Не удалось выполнить транзакцию @@ -3494,7 +3494,7 @@ Do you want to delete it anyway? QPSQLResult - + Unable to create query Невозможно создать запрос @@ -3527,86 +3527,82 @@ Do you want to delete it anyway? Точки (pt) - + Form Форма - + Paper Бумага - + Page size: Размер страницы: - + Width: Ширина: - + Height: Высота: - + Paper source: Источник бумаги: - + Orientation Ориентация - + Portrait Книжная - + Landscape Альбомная - + Reverse landscape Перевёрнутая альбомная - + Reverse portrait Перевёрнутая книжная - + Margins Поля - - + top margin верхнее поле - - + left margin левое поле - - + right margin правое поле - - + bottom margin нижнее поле @@ -4165,17 +4161,17 @@ Please choose a different file name. QPrintPropertiesWidget - + Form Форма - + Page Страница - + Advanced Дополнительно @@ -4183,97 +4179,97 @@ Please choose a different file name. QPrintSettingsOutput - + Form Форма - + Copies Копии - + Print range Диапазон печати - + Print all Все - + Pages from Страницы от - + to до - + Selection Выделенный фрагмент - + Output Settings Настройки вывода - + Copies: Количество копий: - + Collate Разобрать про копиям - + Reverse Обратный порядок - + Options Параметры - + Color Mode Режим цвета - + Color Цвет - + Grayscale Оттенки серого - + Duplex Printing Двусторонняя печать - + None Нет - + Long side По длинной стороне - + Short side По короткой стороне @@ -4281,47 +4277,47 @@ Please choose a different file name. QPrintWidget - + Form Форма - + Printer Принтер - + &Name: &Название: - + P&roperties С&войства - + Location: Расположение: - + Preview Просмотр - + Type: Тип: - + Output &file: Выходной &файл: - + ... ... @@ -6258,7 +6254,7 @@ Please choose a different file name. QWizard - + Go Back Назад -- cgit v0.12 From 16f03cce9fc898e751c04ef590e91e82e0c1f79d Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Mon, 6 Jul 2009 19:29:09 +0200 Subject: Update Russian translation for Qt Linguist. typo fixes; clarify several strings; use 'own languages' hack Merge-request: 803 Reviewed-by: Oswald Buddenhagen --- translations/linguist_ru.ts | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/translations/linguist_ru.ts b/translations/linguist_ru.ts index 058d86a..86c7434 100644 --- a/translations/linguist_ru.ts +++ b/translations/linguist_ru.ts @@ -42,7 +42,7 @@ Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked. - Имейте в виду, что изменённые записи будут отмечены как незавершённые, если не включен параметр "Помечать переведенные записи как завершённые". + Имейте в виду, что изменённые записи будут отмечены как незавершённые, если не включён параметр "Помечать переведенные записи как завершённые". @@ -289,7 +289,7 @@ Will assume a single universal form. LRelease - + Generated %n translation(s) (%1 finished and %2 unfinished) @@ -617,7 +617,7 @@ All files (*) <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist is a tool for adding translations to Qt applications.</p><p>%2</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> - <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist - инструмент для добавления переводов в приложения на основе Qt.</p><p>%2</p><p>Copyright (C) 2009 Корпорация Nokia и/или её дочерние подразделения.</p><p>Программа предоставляется "как есть" без гарантий любого рода, включая гарантии дизайна, коммерческой ценности и пригодности для определённой цели.</p> + @@ -1250,7 +1250,7 @@ All files (*) Toggle checking that phrase suggestions are used. - Переключение проверки использования предложений для фраз. Если выявлено несовпадение, будет показано сообщение в окне предупреждений. + Переключение проверки использования предложений для фраз. @@ -1466,6 +1466,11 @@ All files (*) + Russian + Русский + + + German Немецкий @@ -1517,7 +1522,7 @@ All files (*) Developer comments - Комментарии разработчика + Комментарий разработчика @@ -1547,7 +1552,7 @@ All files (*) %1 translator comments - Комментарий переводчика на %1 + %1 перевод: комментарий переводчика @@ -1583,10 +1588,11 @@ Line: %2 MsgEdit - + This is the right panel of the main window. - + Правая панель главного окна + @@ -1800,17 +1806,17 @@ Line: %2 C++ source files - Исходные коды C++ + Файлы исходных кодов C++ Java source files - Исходные коды Java + Файлы исходных кодов Java Qt Script source files - Исходные коды Qt Script + Файлы исходных кодов Qt Script -- cgit v0.12 From bcc679a7a06f64459b942b001ae7df2d27b43746 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Mon, 6 Jul 2009 19:29:09 +0200 Subject: Add Russian translation for qvfb Merge-request: 803 Reviewed-by: Oswald Buddenhagen --- tools/qvfb/translations/translations.pro | 1 + translations/qvfb_ru.ts | 328 +++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+) create mode 100644 translations/qvfb_ru.ts diff --git a/tools/qvfb/translations/translations.pro b/tools/qvfb/translations/translations.pro index 736a72c..f667bb8 100644 --- a/tools/qvfb/translations/translations.pro +++ b/tools/qvfb/translations/translations.pro @@ -27,6 +27,7 @@ SOURCES = ../qvfb.cpp \ ../../shared/deviceskin/deviceskin.cpp TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/qvfb_pl.ts \ + $$[QT_INSTALL_TRANSLATIONS]/qvfb_ru.ts \ $$[QT_INSTALL_TRANSLATIONS]/qvfb_untranslated.ts \ $$[QT_INSTALL_TRANSLATIONS]/qvfb_zh_CN.ts \ $$[QT_INSTALL_TRANSLATIONS]/qvfb_zh_TW.ts diff --git a/translations/qvfb_ru.ts b/translations/qvfb_ru.ts new file mode 100644 index 0000000..b084380 --- /dev/null +++ b/translations/qvfb_ru.ts @@ -0,0 +1,328 @@ + + + + + AnimationSaveWidget + + + + Record + Записать + + + + Reset + Сбросить + + + + Save + Сохранить + + + + Save in MPEG format (requires netpbm package installed) + Сохранить в формат MPEG (требуется установленный пакет netpbm) + + + + + Click record to begin recording. + Нажмите "Записать" для начала записи. + + + + + Finished saving. + Сохранение завершено. + + + + Paused. Click record to resume, or save if done. + Приостановлено. Нажмите "Записать" для продолжения или "Сохранить", если готово. + + + + Pause + Пауза + + + + Recording... + Идёт запись... + + + + Saving... + Сохранение... + + + + + Save animation... + Сохранение анимации... + + + + Save canceled. + Сохранение отменено. + + + + Save failed! + Сохранение не удалось! + + + + Config + + + Configure + Настройка + + + + Size + Размер + + + + 176x220 "SmartPhone" + + + + + 240x320 "PDA" + + + + + 320x240 "TV" / "QVGA" + + + + + 640x480 "VGA" + + + + + 800x600 + + + + + 1024x768 + + + + + Custom + Особый + + + + Depth + Глубина + + + + 1 bit monochrome + 1 бит (монохромный) + + + + 4 bit grayscale + 4 бита (градации серого) + + + + 8 bit + 8 бит + + + + 12 (16) bit + 12 (16) бит + + + + 15 bit + 15 бит + + + + 16 bit + 16 бит + + + + 18 bit + 18 бит + + + + 24 bit + 24 бита + + + + 32 bit + 32 бита + + + + 32 bit ARGB + 32 бита (ARGB) + + + + Skin + Обложка + + + + None + Нет + + + + Emulate touch screen (no mouse move) + Эмулировать тачскрин (без перемещения мыши) + + + + Emulate LCD screen (Only with fixed zoom of 3.0 times magnification) + Эмулировать ж/к экран (только с 3-х кратным увеличением) + + + + <p>Note that any applications using the virtual framebuffer will be terminated if you change the Size or Depth <i>above</i>. You may freely modify the Gamma <i>below</i>. + <p>Имейте в виду, что любая программа будет завершена, если изменится размер или глубина экрана. Параметр Гамма можно менять свободно. + + + + Gamma + Гамма + + + + Blue + Синий + + + + + + + 1.0 + + + + + Green + Зеленый + + + + All + Все + + + + Red + Красный + + + + Set all to 1.0 + Выставить все в 1.0 + + + + &OK + &Готово + + + + &Cancel + &Отмена + + + + DeviceSkin + + + The image file '%1' could not be loaded. + Не удалось загрузить изображение '%1'. + + + + The skin directory '%1' does not contain a configuration file. + Каталог обложки '%1' не содержит файла настроек. + + + + The skin configuration file '%1' could not be opened. + Не удалось открыть файл настроек обложки '%1'. + + + + The skin configuration file '%1' could not be read: %2 + Не удалось прочитать файл настроек обложки '%1': %2 + + + + Syntax error: %1 + Синтаксическая ошибка: %1 + + + + The skin "up" image file '%1' does not exist. + Файл изображения "up" '%1' не существует. + + + + The skin "down" image file '%1' does not exist. + Файл изображения "down" '%1' не существует. + + + + The skin "closed" image file '%1' does not exist. + Файл изображения "closed" '%1' не существует. + + + + The skin cursor image file '%1' does not exist. + Файл изображения курсора '%1' не существует. + + + + Syntax error in area definition: %1 + Синтаксическая ошибка в определении области: %1 + + + + Mismatch in number of areas, expected %1, got %2. + Несовпадение количества зон: ожидается %1, указано %2. + + + + QVFb + + + Browse... + Обзор... + + + + Load Custom Skin... + Загрузить обложку пользователя... + + + + All QVFB Skins (*.skin) + Все обложки QVFB (*.skin) + + + -- cgit v0.12 From 962bdf2eb305c5dd01fc03dbe0c17afb4a42c8aa Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Mon, 6 Jul 2009 19:29:10 +0200 Subject: Add basic Russian translation for qtconfig Merge-request: 803 Reviewed-by: Oswald Buddenhagen --- tools/qtconfig/translations/translations.pro | 1 + translations/qtconfig_ru.ts | 906 +++++++++++++++++++++++++++ 2 files changed, 907 insertions(+) create mode 100644 translations/qtconfig_ru.ts diff --git a/tools/qtconfig/translations/translations.pro b/tools/qtconfig/translations/translations.pro index fbbdb2bba2..1f9f572 100644 --- a/tools/qtconfig/translations/translations.pro +++ b/tools/qtconfig/translations/translations.pro @@ -8,6 +8,7 @@ HEADERS += ../colorbutton.h ../previewframe.h ../previewwidget.h ../mainw FORMS = ../mainwindowbase.ui ../paletteeditoradvancedbase.ui ../previewwidgetbase.ui TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/qtconfig_pl.ts \ + $$[QT_INSTALL_TRANSLATIONS]/qtconfig_ru.ts \ $$[QT_INSTALL_TRANSLATIONS]/qtconfig_untranslated.ts \ $$[QT_INSTALL_TRANSLATIONS]/qtconfig_zh_CN.ts \ $$[QT_INSTALL_TRANSLATIONS]/qtconfig_zh_TW.ts diff --git a/translations/qtconfig_ru.ts b/translations/qtconfig_ru.ts new file mode 100644 index 0000000..b1965f2 --- /dev/null +++ b/translations/qtconfig_ru.ts @@ -0,0 +1,906 @@ + + + + + MainWindow + + + Desktop Settings (Default) + Настройки рабочего стола (по умолчанию) + + + + Choose style and palette based on your desktop settings. + Выбор стиля и палитры на основе настроек рабочего стола. + + + + On The Spot + + + + + + + + Auto (default) + Автоматически (по умолчанию) + + + + Choose audio output automatically. + Автоматический выбор звукового выхода. + + + + + aRts + aRts + + + + Experimental aRts support for GStreamer. + Экспериментальная поддержка aRts в GStreamer. + + + + Phonon GStreamer backend not available. + Модуль Phonon поддержки GStreamer не доступен. + + + + Choose render method automatically + Автоматический выбор метода отрисовки + + + + + X11 + + + + + Use X11 Overlays + Использовать оверлеи X11 + + + + + OpenGL + + + + + Use OpenGL if avaiable + Использовать OpenGL, если доступен + + + + + Software + Программный + + + + Use simple software rendering + Использовать простую программную отрисовку + + + + No changes to be saved. + Нет изменений для сохранения. + + + + Saving changes... + Сохранение изменений... + + + + Over The Spot + + + + + Off The Spot + + + + + Root + + + + + Select a Directory + Выбор каталога + + + + <h3>%1</h3><br/>Version %2<br/><br/>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).<br/><br/>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.<br/> + + + + + + + Qt Configuration + Конфигурация Qt + + + + Save Changes + Сохранение изменений + + + + Save changes to settings? + Сохранить изменения настроек? + + + + &Yes + &Да + + + + &No + &Нет + + + + &Cancel + &Отмена + + + + MainWindowBase + + + Qt Configuration + Конфигурация Qt + + + + Appearance + Внешний вид + + + + GUI Style + Стиль пользовательского графического интерфейса + + + + Select GUI &Style: + &Стиль интерфейса: + + + + Build Palette + Палитра + + + + &3-D Effects: + Эффекты &3-D: + + + + Window Back&ground: + &Фон окна: + + + + &Tune Palette... + &Настроить палитру... + + + + Please use the KDE Control Center to set the palette. + Используйте Центр управления KDE для настройки цветов. + + + + Preview + Предпросмотр + + + + Select &Palette: + Выбор &палитры: + + + + Active Palette + Палитра активных элементов + + + + Inactive Palette + Палитра неактивных элементов + + + + Disabled Palette + Палитра выключенных элементов + + + + Fonts + Шрифты + + + + Default Font + Шрифт по умолчанию + + + + &Style: + &Стиль: + + + + &Point Size: + &Размер в точках: + + + + F&amily: + Семе&йство: + + + + Sample Text + Текст для примера (Sample Text) + + + + Font Substitution + Подстановка шрифтов + + + + S&elect or Enter a Family: + &Выберите или введите семейство: + + + + Current Substitutions: + Текущие замены: + + + + + Up + Выше + + + + + Down + Ниже + + + + + Remove + Удалить + + + + Select s&ubstitute Family: + Выберите п&одставляемое семейство: + + + + + Add + Добавить + + + + Interface + Интерфейс + + + + Feel Settings + Настройка указателя + + + + + ms + мс + + + + &Double Click Interval: + &Интервал двойного щелчка: + + + + No blinking + Без мигания + + + + &Cursor Flash Time: + &Период мигания курсора: + + + + lines + строк + + + + Wheel &Scroll Lines: + &Прокручивать строк при повороте колёсика: + + + + Resolve symlinks in URLs + Разрешать символьные ссылки в URL-ах + + + + GUI Effects + Эффекты пользовательского интерфейса + + + + &Enable + &Включить + + + + Alt+E + Alt+D + + + + &Menu Effect: + Эффект &меню: + + + + C&omboBox Effect: + Эффект C&omboBox: + + + + &ToolTip Effect: + Эффект &ToolTip: + + + + Tool&Box Effect: + Эффект Tool&Box: + + + + + + + Disable + Выключен + + + + + + + Animate + Анимация + + + + + Fade + Затухание + + + + Global Strut + Специальные возможности + + + + Minimum &Width: + Минимальная &ширина: + + + + Minimum Hei&ght: + Минимальная в&ысота: + + + + + pixels + пикселей + + + + Enhanced support for languages written right-to-left + Расширенная поддержка письма справа налево + + + + XIM Input Style: + Стиль ввода XIM: + + + + On The Spot + + + + + Over The Spot + + + + + Off The Spot + + + + + Root + + + + + Default Input Method: + Метод ввода по умолчанию: + + + + Printer + Принтер + + + + Enable Font embedding + Разрешить встраивание шрифтов + + + + Font Paths + Пути к шрифтам + + + + Browse... + Обзор... + + + + Press the <b>Browse</b> button or enter a directory and press Enter to add them to the list. + Нажмите кнопку <b>Обзор...</b> или укажите каталог и нажмите Ввод для добавления его в список. + + + + Phonon + Phonon + + + + About Phonon + О Phonon + + + + + Current Version: + Текущая версия: + + + + + Not available + Недоступно + + + + + Website: + Вэб-сайт: + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://phonon.kde.org"><span style=" text-decoration: underline; color:#0000ff;">http://phonon.kde.org</span></a></p></body></html> + + + + + About GStreamer + О GStreamer + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://gstreamer.freedesktop.org/"><span style=" text-decoration: underline; color:#0000ff;">http://gstreamer.freedesktop.org/</span></a></p></body></html> + + + + + GStreamer backend settings + Настройки модуля GStreamer + + + + Preferred audio sink: + Предпочитаемое звуковое устройство: + + + + Preferred render method: + Предпочитаемый метод отрисовки: + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Note: changes to these settings may prevent applications from starting up correctly.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Внимание: Изменение данных настроек может повлечь невозможность корректного запуска приложений.</span></p></body></html> + + + + &File + &Файл + + + + &Help + &Справка + + + + &Save + &Сохранить + + + + Save + Сохранить + + + + Ctrl+S + + + + + E&xit + В&ыход + + + + Exit + Выход + + + + &About + &О программе + + + + About + О программе + + + + About &Qt + О &Qt + + + + About Qt + О Qt + + + + PaletteEditorAdvancedBase + + + Tune Palette + Настройка палитры + + + + <b>Edit Palette</b><p>Change the palette of the current widget or form.</p><p>Use a generated palette or select colors for each color group and each color role.</p><p>The palette can be tested with different widget layouts in the preview section.</p> + <b>Изменение палитры</b><p>Изменение палитры текущего виджета или формы.</p><p>Используйте сформированную палитру или выберите цвета для каждой группы цветов и каждой их роли.</p><p>Палитру можно проверить на виджетах в разных режимах отображения в разделе предпросмотра.</p> + + + + Select &Palette: + Выбор &палитры: + + + + Active Palette + Палитра активных элементов + + + + Inactive Palette + Палитра неактивных элементов + + + + Disabled Palette + Палитра выключенных элементов + + + + Auto + Автоматически + + + + Build inactive palette from active + Создать неактивную палитру из активной + + + + Build disabled palette from active + Создать выключенную палитру из активной + + + + Central color &roles + Роли &цветов + + + + Choose central color role + Выберите роль цвета + + + + <b>Select a color role.</b><p>Available central roles are: <ul> <li>Window - general background color.</li> <li>WindowText - general foreground color. </li> <li>Base - used as background color for e.g. text entry widgets, usually white or another light color. </li> <li>Text - the foreground color used with Base. Usually this is the same as WindowText, in what case it must provide good contrast both with Window and Base. </li> <li>Button - general button background color, where buttons need a background different from Window, as in the Macintosh style. </li> <li>ButtonText - a foreground color used with the Button color. </li> <li>Highlight - a color to indicate a selected or highlighted item. </li> <li>HighlightedText - a text color that contrasts to Highlight. </li> <li>BrightText - a text color that is very different from WindowText and contrasts well with e.g. black. </li> </ul> </p> + <b>Выбор роли цвета.</b><p>Доступны следующие роли: <ul><li>Window - основной цвет фона.</li> <li>WindowText - основной цвет текста.</li> <li>Base - используется в качестве фона для, например, виджетов с текстовыми полями, обычно, белый или другой светлый цвет.</li> <li>Text - цвет текста используемый совместно с Base. Обычно, он совпадает с WindowText, так как в этом случае получается максимальный контраст и с Window, и с Base.</li> <li>Button - основной цвет фона кнопки, которой требуется цвет отличный от Window, например, в стиле Macintosh.</li> <li>ButtonText - цвет текста используемый совместно с Button.</li> <li>Highlight - цвет для обозначения выбранного или выделенного элемента.</li> <li>HighlightedText - цвет текста контрастирующий с Highlight.</li> <li>BrightText - цвет текста, который отличается от WindowText и хорошо контрастирует с черным.</li></ul></p> + + + + Window + + + + + WindowText + + + + + Button + + + + + Base + + + + + Text + + + + + BrightText + + + + + ButtonText + + + + + Highlight + + + + + HighlightedText + + + + + &Select Color: + &Выбор цвета: + + + + + Choose a color + Выберите цвет + + + + Choose a color for the selected central color role. + Выберите цвет для указанной роли. + + + + 3-D shadow &effects + Эффекты т&рехмерной тени + + + + Build &from button color + Получ&ить из цвета кнопки + + + + Generate shadings + Создание полутонов + + + + Check to let 3D-effect colors be calculated from button-color. + Включите, чтобы цвета эффекта трёхмерности были получены из цвета кнопки. + + + + Choose 3D-effect color role + Выбор роли цвета дял эффекта трёхмерности + + + + <b>Select a color role.</b><p>Available effect roles are: <ul> <li>Light - lighter than Button color. </li> <li>Midlight - between Button and Light. </li> <li>Mid - between Button and Dark. </li> <li>Dark - darker than Button. </li> <li>Shadow - a very dark color. </li> </ul> + <b>Выбор роли цвета.</b><p>Доступны следующие роли: <ul> <li>Light - светлее цвета Button. </li> <li>Midlight - среднее между Light и Button. </li> <li>Mid - среднее между Button и Dark. </li> <li>Dark - темнее цвета Button. </li> <li>Shadow - очень темный цвет. </li> </ul> + + + + Light + + + + + Midlight + + + + + Mid + + + + + Dark + + + + + Shadow + + + + + Select Co&lor: + Выбор &цвета: + + + + Choose a color for the selected effect color role. + Выбор цвета для указанной роли. + + + + OK + Принять + + + + Close dialog and apply all changes. + Закрыть окно с применением изменений. + + + + Cancel + Отмена + + + + Close dialog and discard all changes. + Закрыть окно с отменой изменений. + + + + PreviewFrame + + + Desktop settings will only take effect after an application restart. + Настройки рабочего стола применятся после перезапуска приложения. + + + + PreviewWidgetBase + + + Preview Window + Окно предпросмотра + + + + ButtonGroup + + + + + RadioButton1 + + + + + RadioButton2 + + + + + RadioButton3 + + + + + ButtonGroup2 + + + + + CheckBox1 + + + + + CheckBox2 + + + + + LineEdit + + + + + ComboBox + + + + + PushButton + + + + + <p> +<a href="http://qtsoftware.com">http://qtsoftware.com</a> +</p> +<p> +<a href="http://www.kde.org">http://www.kde.org</a> +</p> + + + + -- cgit v0.12 From 4a5340fbe4d6ca3df4573fe4147103fb8379cb55 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Mon, 6 Jul 2009 19:29:11 +0200 Subject: Update Russian translation for Qt Help Merge-request: 803 Reviewed-by: Oswald Buddenhagen --- translations/qt_help_ru.ts | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/translations/qt_help_ru.ts b/translations/qt_help_ru.ts index 16748fb..c2dc041 100644 --- a/translations/qt_help_ru.ts +++ b/translations/qt_help_ru.ts @@ -6,17 +6,17 @@ Search Results - Результаты поиска + Результат поиска Note: - Замечание: + Примечание: The search results may not be complete since the documentation is still being indexed! - Могли быть показаны не все результаты, так как документация ещё индексируется! + Результат поиска может быть неполным, так как документация ещё индексируется! @@ -45,7 +45,7 @@ Cannot open collection file: %1 - Не удалось открыть файл набора: %1 + Не удалось открыть файл набора: %1 @@ -168,12 +168,12 @@ Insert custom filters... - Вставка индивидуальных фильтров... + Добавление индивидуальных фильтров... Insert help data for filter section (%1 of %2)... - Вставка данных справки для секции фильтра (%1 из %2)... + Добавление данных справки для раздела фильтра (%1 из %2)... @@ -198,7 +198,7 @@ Insert files... - Вставка файлов... + Добавление файлов... @@ -228,22 +228,22 @@ Insert indices... - Вставка указателей... + Добавление указателей... Insert contents... - Вставка оглавления... + Добавление содержания... Cannot insert contents! - Не удаётся вставить оглавление! + Не удалось добавить содержание! Cannot register contents! - Не удаётся зарегистрировать оглавление! + Не удалось зарегистрировать содержание! @@ -271,12 +271,12 @@ <B>without</B> the words: - <B>не содержит</B> слова: + <B>не содержит</B> слов: with <B>exact phrase</B>: - содержит <B>фразу полностью</B>: + содержит <B>точную фразу</B>: @@ -286,7 +286,7 @@ with <B>at least one</B> of the words: - содержит <B> минимум одно</B> из слов: + содержит <B>хотя бы одно</B> из слов: @@ -294,7 +294,7 @@ 0 - 0 of 0 Hits - 0 - 0 из 0 соответствий + 0 - 0 из 0 совпадений @@ -302,7 +302,7 @@ %1 - %2 of %3 Hits - %1 - %2 из %3 соответствий + %1 - %2 из %3 совпадений @@ -315,12 +315,12 @@ Unknown token. - Неизвестный токен. + Неизвестный идентификатор. Unknown token. Expected "QtHelpProject"! - Неизвестный токен. Ожидается "QtHelpProject"! + Неизвестный идентификатор. Ожидается "QtHelpProject"! -- cgit v0.12 From 034e15917bb81b65de7828466dbc15b2e2a84b47 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Mon, 6 Jul 2009 19:29:12 +0200 Subject: Update Russian translation for Qt Assistant Merge-request: 803 Reviewed-by: Oswald Buddenhagen --- translations/assistant_ru.ts | 80 ++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/translations/assistant_ru.ts b/translations/assistant_ru.ts index 32aa739..ecec0f8 100644 --- a/translations/assistant_ru.ts +++ b/translations/assistant_ru.ts @@ -57,16 +57,16 @@ Новая папка - + - - - + + + Bookmarks Закладки - + Delete Folder Удалить папку @@ -79,12 +79,12 @@ BookmarkManager - + Bookmarks Закладки - + Remove Удалить @@ -94,7 +94,7 @@ Удаление папки приведёт к удалению её содержимого.<br>Желаете продолжить? - + New Folder Новая папка @@ -103,7 +103,7 @@ BookmarkWidget - + Delete Folder Удалить папку @@ -138,7 +138,7 @@ Фильтр: - + Add Добавить @@ -161,7 +161,7 @@ Закрыть текущую страницу - + Print Document Печать документа @@ -226,24 +226,24 @@ FindWidget - + Previous - Предыдущее совпадение + Предыдущее Next - Следующее совпадение + Следующее Case Sensitive - Регистрозависимо + Учитывать регистр Whole words - Слова полностью + Слова целиком @@ -441,31 +441,31 @@ MainWindow - + Index - Индекс + Указатель - - + + Contents Содержание - - + + Bookmarks Закладки - - - + + + Qt Assistant Qt Assistant - + Unfiltered Без фильтрации @@ -473,10 +473,10 @@ Looking for Qt Documentation... - Поиск по документации Qt... + Поиск документации по Qt... - + &File &Файл @@ -656,7 +656,7 @@ Добавить закладку... - + CTRL+D @@ -723,12 +723,12 @@ Could not find the associated content item. - Не удалось найти элемент, связанный с содержанием. + Не удалось найти элемент, связанный с содержанием. About %1 - О %1 + О %1 @@ -767,7 +767,7 @@ Some documents currently opened in Assistant reference the documentation you are attempting to remove. Removing the documentation will close those documents. - Некоторые открытые в Qt Assistant документы ссылаются на документацию, которую вы пытаетесь удалить. Удаление данной документации приведёт к закрытию таких документов. + Некоторые открытые в Qt Assistant документы ссылаются на документацию, которую вы пытаетесь удалить. Её удаление приведёт к закрытию этих документов. @@ -830,7 +830,7 @@ 1 - + 1 @@ -876,18 +876,12 @@ Restore to default - Восстановить по умолчанию + Страница по умолчанию QObject - - - Bookmark - Закладка - - The specified collection file does not exist! Указанный файл набора отсутствует! @@ -1037,17 +1031,17 @@ Reason: Choose a topic for <b>%1</b>: - Выберите статью для <b>%1</b>: + Выберите раздел для <b>%1</b>: Choose Topic - Выбор статьи + Выбор раздела &Topics - &Статьи + &Разделы -- cgit v0.12 From 283b1ba1cf6cd34d07d9f2b2bb0d40223e172339 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Mon, 6 Jul 2009 19:29:12 +0200 Subject: Update Russian translation for Qt Assistant adp Merge-request: 803 Reviewed-by: Oswald Buddenhagen --- translations/assistant_adp_ru.ts | 289 ++++++++++++++++++++++++++++++++------- 1 file changed, 243 insertions(+), 46 deletions(-) diff --git a/translations/assistant_adp_ru.ts b/translations/assistant_adp_ru.ts index a587a91..c47798b 100644 --- a/translations/assistant_adp_ru.ts +++ b/translations/assistant_adp_ru.ts @@ -4,10 +4,12 @@ AssistantServer + Failed to bind to port %1 Не удалось открыть порт %1 + Qt Assistant Qt Assistant @@ -15,22 +17,27 @@ FontPanel + &Family Се&мейство + &Style &Стиль + Font Шрифт + &Writing system Система &письма + &Point size &Размер в пикселях @@ -38,22 +45,27 @@ FontSettingsDialog + Application Приложение + Browser Обозреватель + Font settings for: Настройки шрифта для: + Use custom settings Использование индивидуальных настроек + Font Settings Настройки шрифта @@ -61,202 +73,261 @@ HelpDialog + &Index &Указатель + &Look For: &Искать: + &New - &Создать + &Новая + + &Search &Поиск + <b>Enter a keyword.</b><p>The list will select an item that matches the entered string best.</p> - <b>Ввод слова.</b><p>В список попадет то, что лучше соответствует введенной строке.</p> + <b>Указание ключевого слова.</b><p>Список заполняется элементами, лучше соответствующими указанному ключевому слову.</p> + <b>Enter search word(s).</b><p>Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.</p> - <b>Ввод одного или более слов для поиска.</b><p>Сюда следует ввести одно или несколько слов, которые требуется найти. Слова могут содержкать символы-заменители (*). Если требуется найти словосочетание, то его нужно заключить в кавычки.</p> + <b>Указание слов для поиска.</b><p>Введите одно или несколько слов, по которым требуется осуществить поиск. Слова могут содержкать символы-заменители (*). Если требуется найти сочетание слов, заключите искомую фразу в кавычки.</p> + <b>Found documents</b><p>This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.</p> - <b>Найденные документы</b><p>В этом списке представлены все найденные при последнем поиске документы. Документы упорядочены по релевантности, т.е. чем выше, тем чаще в нём встречаются указанные слова.</p> + <b>Найденные документы</b><p>В данном списке представлены все найденные при последнем поиске документы. Документы упорядочены по релевантности, т.е. чем выше в списке, тем чаще в нём встречаются искомые слова.</p> + <b>Help topics organized by category.</b><p>Double-click an item to see the topics in that category. To view a topic, just double-click it.</p> - <b>Статьи справки распределённые по разделам.</b><p>Дважды кликните по одному из пунктов, чтобы увидеть какие статьи содержатся в данном разделе. Для открытия статьи просто дважды щелкните на ней.</p> + <b>Разделы справки, распределённые по категориям.</b><p>Дважды щёлкните по одному из пунктов для отображения разделов в данной категории. Для открытия раздела дважды щёлкните по нему.</p> + <b>Help</b><p>Choose the topic you want help on from the contents list, or search the index for keywords.</p> - <b>Справка</b><p>Выберите необходимую статью справки из списка разделов или воспользуйтесь поиском по предметному указателю.</p> + <b>Справка</b><p>Выберите раздел справки из содержания или воспользуйтесь поиском по предметному указателю.</p> + <b>List of available help topics.</b><p>Double-click on an item to open its help page. If more than one is found, you must specify which page you want.</p> - <b>Список доступных статей справки.</b><p>Дважды щёлкните на пункте для открытия страницы помощи. Если найдено более одной, то потребуется выбрать желаемую страницу.</p> + <b>Список доступных разделов справки.</b><p>Дважды щёлкните по одному из пунктов для открытия страницы справки. Если найдено более одной страницы, выберите желаемую.</p> + Add new bookmark - Добавить новую закладку + Добавить закладку + Add the currently displayed page as a new bookmark. - Добавление текущей открытой страницы в закладки. + Добавить отображаемую страницу в закладки. + Cannot open the index file %1 Не удаётся открыть файл индекса %1 + Con&tents Содер&жание + Delete bookmark Удалить закладку + Delete the selected bookmark. - Удаление выбранной закладки. + Удалить выбранную закладку. + Display the help page for the full text search. - Открытие справки по полнотекстовому поиску. + Показать справку по полнотекстовому поиску. + Display the help page. - Открыть страницу справки. + Показать страницу справки. + Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search. - Здесь отображается список тем, распределенных по разделам, указатель или закладки. Последняя вкладка содержит полнотекстовый поиск. + Отображает список разделов, распредёленных по категориям, указатель или закладки. Последняя вкладка содержит панель полнотекстового поиска. + Displays the list of bookmarks. Отображает список закладок. + + Documentation file %1 does not exist! Skipping file. Файл документации %1 не существует! Пропущен. + Documentation file %1 is not compatible! Skipping file. - Файл документации %1 не совместим! + Несовместимый файл документации %1! Пропущен. + + Done Готово + Enter keyword Введите ключевое слово + Enter searchword(s). - Введите одно или более слов для поиска. + Введите одно или несколько слов для поиска. + Failed to load keyword index file Assistant will not work! Не удалось загрузить файл индекса ключевых слов -Assistant не будет работать! +Qt Assistant не будет работать! + Failed to save fulltext search index Assistant will not work! Не удалось сохранить индекс полнотекстового поиска -Assistant не будет работать! +Qt Assistant не будет работать! + Found &Documents: Найденные &документы: + + Full Text Search Полнотекстовый поиск + He&lp &Справка + Help Справка + Indexing files... Индексирование файлов... + Open Link in New Tab Открыть ссылку в новой вкладке + Open Link in New Window Открыть ссылку в новом окне + + Parse Error Ошибка обработки + + Prepare... Подготовка... + Preparing... Подготовка... + Pressing this button starts the search. Нажатие на эту кнопку запустит процесс поиска. + + + Qt Assistant Qt Assistant + Reading dictionary... Чтение каталога... + Searching f&or: &Искать: + Start searching. Начать поиск. + The closing quotation mark is missing. Пропущена закрывающая кавычка. + Using a wildcard within phrases is not allowed. - Использование символов-заменителей внутри фраз не допустимо. + Использование символов-заменителей внутри фраз недопустимо. + + + Warning Предупреждение + + column 1 столбец 1 + Open Link in Current Tab Открыть ссылку в текущей вкладке + %n document(s) found. Найден %n документ. @@ -265,10 +336,12 @@ Assistant не будет работать! + &Bookmarks &Закладки + &Delete &Удалить @@ -276,38 +349,47 @@ Assistant не будет работать! HelpWindow + <div align="center"><h1>The page could not be found</h1><br><h3>'%1'</h3></div> <div align="center"><h1>Страница не найдена</h1><br><h3>'%1'</h3></div> + Copy &Link Location Копировать &адрес ссылки + Error... Ошибка... + Failed to open link: '%1' Не удалось открыть ссылку: '%1' + Help Справка + OK Закрыть + Open Link in New Tab Открыть ссылку в новой вкладке + Open Link in New Window Shift+LMB Открыть ссылку в новом окне Shift+LMB + Unable to launch web browser. Невозможно запустить вэб-браузер. @@ -317,6 +399,7 @@ Assistant не будет работать! Index + Untitled Неозаглавлено @@ -324,354 +407,445 @@ Assistant не будет работать! MainWindow + + "What's This?" context sensitive help. - "Что это?" - контекстная справка. + Контекстная справка "Что это?". + &Add Bookmark - &Добавление закладки + &Добавить закладку + &Close &Закрыть + &Copy &Копировать + &Edit &Правка + &File &Файл + &Find in Text... П&оиск по тексту... + &Go &Перейти + &Help &Справка + &Home &Домой + &Next - &Вперёд + Сл&едующий + &Previous - &Назад + &Предыдущий + &Print... &Печать... + &View &Вид + &Window &Окно + ... ... + About Qt О Qt + About Qt Assistant О Qt Assistant + Add Tab Добавить вкладку + Add the currently displayed page as a new bookmark. - Добавление текущей открытой страницы в закладки. + Добавить отображаемую страницу в закладки. + Boo&kmarks &Закладки + Cannot open file for writing! - Не удается открыть файл для записи! + Не удалось открыть файл для записи! + Close Tab Закрыть вкладку + Close the current window. Закрыть текущее окно. + Display further information about Qt Assistant. Показать дополнительную информацию о Qt Assistant. + Displays the main page of a specific documentation set. - Открывает главную страницу выбранного набора документации. + Открывает стартовую страницу выбранного набора документации. + E&xit - Вы&ход + В&ыход + Failed to open about application contents in file: '%1' Не удалось получить информацию о приложении из файла: '%1' + Find &Next - Продолжить п&оиск + Найти &следующее + Find &Previous Найти &предыдущее + Font Settings... Настройки шрифта... + Go Перейти + Go to the home page. Qt Assistant's home page is the Qt Reference Documentation. Перейти на домашнюю страницу. Домашная страница Qt Assistant - Справочная документация по Qt. + Go to the next page. Переход на следующую страницу. + Initializing Qt Assistant... Инициализация Qt Assistant... + Minimize Свернуть + New Window Новое окно + Next Tab Следующая вкладка + Open a new window. Открыть новое окно. + Open the Find dialog. Qt Assistant will search the currently displayed page for the text you enter. - Открыть окно поиска. Qt Assistant произведёт поиск введённого текста на текущей открытой странице. + Открыть окно поиска. Qt Assistant произведёт поиск введённого текста на отображаемой странице. + Previous Tab Предыдущая вкладка + Print the currently displayed page. - Печать текущей открытой страницы. + Печатать отображаемую страницу. + + Qt Assistant Qt Assistant + Qt Assistant Manual Руководство по Qt Assistant + Qt Assistant by Nokia Qt Assistant от Nokia + Quit Qt Assistant. Выйти из Qt Assistant. + + Save Page Сохранить страницу + Save Page As... Сохранить страницу как... + Select the page in contents tab. - Выбор страницы в оглавлении. + Выбрать страницу во вкладке содержания. + Sidebar Боковая панель + Sync with Table of Contents - Синхронизировать с оглавлением + Синхронизировать с содержанием + Toolbar Панель инструментов + Views Виды + What's This? Что это? + Zoom &in У&величить + Zoom &out У&меньшить + Zoom in on the document, i.e. increase the font size. - Увеличение масштаба документа, т.е. увеличение размера шрифта. + Увеличить размер шрифта. + Zoom out on the document, i.e. decrease the font size. - Уменьшение масштаба документа, т.е. уменьшение размера шрифта. + Уменьшить размер шрифта. + Ctrl+M + SHIFT+CTRL+= + Ctrl+T + Ctrl+I + Ctrl+B + Ctrl+S + Ctrl+] + Ctrl+[ + Ctrl+P + Ctrl+Q + Copy the selected text to the clipboard. Скопировать выделенный текст в буфер обмена. + Ctrl+C + Ctrl+F + F3 + Shift+F3 + Ctrl+Home + Go to the previous page. Переход на предыдущую страницу. + Alt+Left + Alt+Right + Ctrl++ + Ctrl+- + Ctrl+N + Ctrl+W + Shift+F1 + Ctrl+Alt+N + Ctrl+Alt+Right + Ctrl+Alt+Left + Ctrl+Alt+Q + F1 + Ctrl+Alt+S @@ -679,6 +853,7 @@ Assistant не будет работать! QObject + Qt Assistant by Nokia Qt Assistant от Nokia @@ -686,54 +861,67 @@ Assistant не будет работать! TabbedBrowser + ... ... + <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Поиск с начала + Add page - Добавить страницу + Добавить вкладку + Case Sensitive - Регистрозависимо + Учитывать регистр + Close Other Tabs Закрыть остальные вкладки + Close Tab Закрыть вкладку + Close page - Закрыть страницу + Закрыть вкладку + New Tab Новая вкладка + Next - Следующий + Следующее + Previous - Предыдущий + Предыдущее + Untitled Безымянный + Whole words - Слова полностью + Слова целиком + TabbedBrowser @@ -741,40 +929,49 @@ Assistant не будет работать! TopicChooser + &Close &Закрыть + &Display &Показать + &Topics - &Статьи + &Разделы + Choose Topic - Выбор статьи + Выбор раздела + Choose a topic for <b>%1</b> - Выберите статью для <b>%1</b> + Выберите раздел для <b>%1</b> + Close the Dialog. - Закрытие окна. + Закрыть диалог. + Displays a list of available help topics for the keyword. - Показывает список доступных статей справки, соответствующих ключевому слову. + Показывает список доступных разделов справки, найденных по ключевому слову. + Open the topic selected in the list. - Открытие выбранной в списке темы. + Открыть выбранный раздел. + Select a topic from the list and click the <b>Display</b>-button to open the online help. - Выберите статью из списка и нажмите на кнопку <b>Показать</b> для открытия онлайн справки. + Выберите раздел из списка и нажмите на кнопку <b>Показать</b> для открытия онлайн справки. -- cgit v0.12 From 3814b2adf50b5724e3375ea2048d13960c8aed82 Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Tue, 7 Jul 2009 14:44:52 +1000 Subject: Handle all PostgreSQL notifications sitting in the queue Task-number: 257247 Reviewed-by: trustme --- src/sql/drivers/psql/qsql_psql.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 770df4c..69697da 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -1248,15 +1248,15 @@ QStringList QPSQLDriver::subscribedToNotificationsImplementation() const void QPSQLDriver::_q_handleNotification(int) { PQconsumeInput(d->connection); - PGnotify *notify = PQnotifies(d->connection); - if (notify) { - QString name(QLatin1String(notify->relname)); + PGnotify *notify = 0; + while((notify = PQnotifies(d->connection)) != 0) { + QString name(QLatin1String(notify->relname)); if (d->seid.contains(name)) emit notification(name); else qWarning("QPSQLDriver: received notification for '%s' which isn't subscribed to.", - qPrintable(name)); + qPrintable(name)); qPQfreemem(notify); } -- cgit v0.12 From 4e31ccad1cfb9df0d624d5c39d7906a75b4fc2d0 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 10:01:21 +0200 Subject: QFontComboBox: used to emit currentFontChanged twice when setting it. Setting the current font would change the current font and then it would try to select the right model index and get the font only from the text of the combobox. This was resetting the point size of the font, resulting in emitting the signal a second time. In the case of the user, it was also causing signals to be called in a loop. Task-number: 229731 --- src/gui/widgets/qfontcombobox.cpp | 2 +- tests/auto/qfontcombobox/tst_qfontcombobox.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/gui/widgets/qfontcombobox.cpp index 9660399..f87ccd3 100644 --- a/src/gui/widgets/qfontcombobox.cpp +++ b/src/gui/widgets/qfontcombobox.cpp @@ -263,7 +263,7 @@ void QFontComboBoxPrivate::_q_currentChanged(const QString &text) { Q_Q(QFontComboBox); QFont newFont(text); - if (currentFont != newFont) { + if (currentFont.family() != newFont.family()) { currentFont = newFont; emit q->currentFontChanged(currentFont); } diff --git a/tests/auto/qfontcombobox/tst_qfontcombobox.cpp b/tests/auto/qfontcombobox/tst_qfontcombobox.cpp index 62bfdf7..e2515ae 100644 --- a/tests/auto/qfontcombobox/tst_qfontcombobox.cpp +++ b/tests/auto/qfontcombobox/tst_qfontcombobox.cpp @@ -122,7 +122,10 @@ void tst_QFontComboBox::currentFont_data() { QTest::addColumn("currentFont"); // Normalize the names - QTest::newRow("default") << QFont(QFontInfo(QFont()).family()); + QFont defaultFont; + QTest::newRow("default") << defaultFont; + defaultFont.setPointSize(defaultFont.pointSize() + 10); + QTest::newRow("default") << defaultFont; QFontDatabase db; QStringList list = db.families(); for (int i = 0; i < list.count(); ++i) { @@ -141,6 +144,7 @@ void tst_QFontComboBox::currentFont() QFont oldCurrentFont = box.currentFont(); box.setCurrentFont(currentFont); + QCOMPARE(box.currentFont(), currentFont); QString boxFontFamily = QFontInfo(box.currentFont()).family(); QRegExp foundry(" \\[.*\\]"); if (!currentFont.family().contains(foundry)) -- cgit v0.12 From 343e8b7e75c98a4fd1b692a230de8d1132988705 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Jul 2009 10:05:02 +0200 Subject: Fix typo in color calculation. Argh! It's divide by 256 not 265. The worst part was that I used the same values in Cocoa as well, so they were both "damaged." It should be good now. Task-number: 257499 Reviewed-by: Prasanth Ullattil --- src/gui/kernel/qt_mac.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qt_mac.cpp b/src/gui/kernel/qt_mac.cpp index 27df5d1..0c3b707 100644 --- a/src/gui/kernel/qt_mac.cpp +++ b/src/gui/kernel/qt_mac.cpp @@ -134,7 +134,7 @@ QColor qcolorForThemeTextColor(ThemeTextColor themeColor) #ifdef Q_OS_MAC32 RGBColor c; GetThemeTextColor(themeColor, 32, true, &c); - QColor color = QColor(c.red / 265, c.green / 256, c.blue / 256); + QColor color = QColor(c.red / 256, c.green / 256, c.blue / 256); return color; #else // There is no equivalent to GetThemeTextColor in 64-bit and it was rather bad that @@ -156,13 +156,13 @@ QColor qcolorForThemeTextColor(ThemeTextColor themeColor) case kThemeTextColorAlertInactive: case kThemeTextColorDialogInactive: case kThemeTextColorPlacardInactive: - return QColor(67, 69, 69, 255); + return QColor(69, 69, 69, 255); case kThemeTextColorPopupButtonInactive: case kThemeTextColorPopupLabelInactive: case kThemeTextColorPushButtonInactive: case kThemeTextColorTabFrontInactive: case kThemeTextColorBevelButtonInactive: - return QColor(123, 127, 127, 255); + return QColor(127, 127, 127, 255); default: { QNativeImage nativeImage(16,16, QNativeImage::systemFormat()); CGRect cgrect = CGRectMake(0, 0, 16, 16); -- cgit v0.12 From 07ba75cb8031b844484901bef903fb055cc0b182 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 11:12:39 +0200 Subject: QToolBar: better management of positions when hiding/unhiding The toolbar that one would unhide could be packed at the right of the screen. This was because the last toolbar always has a size that fills the space. So if you unhide a toolbar situated after this one, it got "compressed". --- src/gui/widgets/qtoolbararealayout.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp index 0c11700..b4a0ef0 100644 --- a/src/gui/widgets/qtoolbararealayout.cpp +++ b/src/gui/widgets/qtoolbararealayout.cpp @@ -156,21 +156,15 @@ void QToolBarAreaLayoutLine::fitLayout() if (item.skip()) continue; - QToolBarLayout *tblayout = qobject_cast(item.widgetItem->widget()->layout()); - if (tblayout) + if (QToolBarLayout *tblayout = qobject_cast(item.widgetItem->widget()->layout())) tblayout->checkUsePopupMenu(); - int itemMin = pick(o, item.minimumSize()); - int itemHint = pick(o, item.sizeHint()); - //we ensure the extraspace is not too low - item.size = qMax(item.size, itemHint); - if (item.preferredSize > 0) { - //preferredSize would be the default size - item.size = item.preferredSize; - } + const int itemMin = pick(o, item.minimumSize()); + //preferredSize is the default if it is set, otherwise, we take the sizehint + item.size = item.preferredSize > 0 ? item.preferredSize : pick(o, item.sizeHint()); //the extraspace is the space above the item minimum sizehint - int extraSpace = qMin(item.size - itemMin, extra); + const int extraSpace = qMin(item.size - itemMin, extra); item.size = itemMin + extraSpace; //that is the real size extra -= extraSpace; -- cgit v0.12 From a28dc778305cf67830f15119b29c5a77754a8c18 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 11:14:26 +0200 Subject: QMenu: with tearoff handle, it would reserve the space for it twice sizeHint is now fixed --- src/gui/widgets/qmenu.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index af9ddf5..35b68b4 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1355,8 +1355,7 @@ QMenu::~QMenu() if (d->eventLoop) d->eventLoop->exit(); - if (d->tornPopup) - d->tornPopup->close(); + hideTearOffMenu(); } /*! @@ -1567,8 +1566,8 @@ void QMenu::setTearOffEnabled(bool b) Q_D(QMenu); if (d->tearoff == b) return; - if (!b && d->tornPopup) - d->tornPopup->close(); + if (!b) + hideTearOffMenu(); d->tearoff = b; d->itemsDirty = true; @@ -1603,8 +1602,8 @@ bool QMenu::isTearOffMenuVisible() const */ void QMenu::hideTearOffMenu() { - if (d_func()->tornPopup) - d_func()->tornPopup->close(); + if (QWidget *w = d_func()->tornPopup) + w->close(); } @@ -1719,8 +1718,6 @@ QSize QMenu::sizeHint() const if (rect.right() >= s.width()) s.setWidth(rect.x() + rect.width()); } - if (d->tearoff) - s.rheight() += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, this); // Note that the action rects calculated above already include // the top and left margins, so we only need to add margins for // the bottom and right. -- cgit v0.12 From ac6fad8a677eb113839ff4ca79c8185e0aa8237b Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 7 Jul 2009 11:23:45 +0200 Subject: Added wildcard support for file lists in help projects. The qhelpgenerator auto test was also updated to test the new feature. Reviewed-by: kh --- tests/auto/qhelpgenerator/data/test.qhp | 7 +++---- tools/assistant/lib/qhelpprojectdata.cpp | 22 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/tests/auto/qhelpgenerator/data/test.qhp b/tests/auto/qhelpgenerator/data/test.qhp index e9ac7f2..a97c00d 100644 --- a/tests/auto/qhelpgenerator/data/test.qhp +++ b/tests/auto/qhelpgenerator/data/test.qhp @@ -38,9 +38,8 @@ classic.css - test.html - people.html - ./sub/about.html + [pt]*.html + ./sub/abou?.html @@ -69,4 +68,4 @@ cars.html - \ No newline at end of file + diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp index 8947a36..55b4ea7 100644 --- a/tools/assistant/lib/qhelpprojectdata.cpp +++ b/tools/assistant/lib/qhelpprojectdata.cpp @@ -41,6 +41,7 @@ #include "qhelpprojectdata_p.h" +#include #include #include #include @@ -73,6 +74,7 @@ private: void readKeywords(); void readFiles(); void raiseUnknownTokenError(); + void addMatchingFiles(const QString &pattern); }; void QHelpProjectDataPrivate::raiseUnknownTokenError() @@ -161,7 +163,7 @@ void QHelpProjectDataPrivate::readFilterSection() readNext(); if (isStartElement()) { if (name() == QLatin1String("filterAttribute")) - filterSectionList.last().addFilterAttribute(readElementText()); + filterSectionList.last().addFilterAttribute(readElementText()); else if (name() == QLatin1String("toc")) readTOC(); else if (name() == QLatin1String("keywords")) @@ -244,7 +246,7 @@ void QHelpProjectDataPrivate::readFiles() readNext(); if (isStartElement()) { if (name() == QLatin1String("file")) - filterSectionList.last().addFile(readElementText()); + addMatchingFiles(readElementText()); else raiseUnknownTokenError(); } else if (isEndElement()) { @@ -258,7 +260,21 @@ void QHelpProjectDataPrivate::readFiles() } } - +// Expand file pattern and add matches into list. If the pattern does not match +// any files, insert the pattern itself so the QHelpGenerator will emit a +// meaningful warning later. +void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern) +{ + QFileInfo fileInfo(rootPath + '/' + pattern); + const QStringList &matches = + fileInfo.dir().entryList(QStringList(fileInfo.fileName())); + for (QStringList::ConstIterator it = matches.constBegin(); + it != matches.constEnd(); + ++it) + filterSectionList.last().addFile(QFileInfo(pattern).dir().path() + '/' + *it); + if (matches.empty()) + filterSectionList.last().addFile(pattern); +} /*! \internal -- cgit v0.12 From 53b116be1bbadd416449d9a0104f514139f495c8 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 11:49:59 +0200 Subject: ItemViews: it would go into DraggingState even without clicking an item We now just make sure that we start the drag if there was a pressed index. Task-number: 252643 --- src/gui/itemviews/qabstractitemview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index b64bc71..cefe8a5 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -1602,7 +1602,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) d->checkMouseMove(index); #ifndef QT_NO_DRAGANDDROP - if (index.isValid() + if (d->pressedIndex.isValid() && d->dragEnabled && (state() != DragSelectingState) && (event->buttons() != Qt::NoButton) -- cgit v0.12 From f70f321c8b5769476796e2bae540a57b3b62c684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 7 Jul 2009 11:39:43 +0200 Subject: Make sure we send a ValueChanged event if the spinbox value has changed Unfortunately the codepath for keyPressEvent does not call updateState, so we have to add the same line in two places. Note that updateState() is only called from mousePressEvent() and mouseMoveEvent(). Task-number: 254053 --- src/gui/widgets/qabstractspinbox.cpp | 9 +++++++++ tests/auto/qaccessibility/tst_qaccessibility.cpp | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index 25acd6e..da18d13 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -57,6 +57,9 @@ #include #include #include +#ifndef QT_NO_ACCESSIBILITY +# include +#endif #if defined(Q_WS_X11) #include @@ -951,6 +954,9 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) d->buttonState = (Keyboard | (up ? Up : Down)); } stepBy(steps); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged); +#endif return; } #ifdef QT_KEYPAD_NAVIGATION @@ -1548,6 +1554,9 @@ void QAbstractSpinBoxPrivate::updateState(bool up) spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval); buttonState = (up ? (Mouse | Up) : (Mouse | Down)); q->stepBy(up ? 1 : -1); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged); +#endif } } diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 8a88b59..b8aec50 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -2623,6 +2623,13 @@ void tst_QAccessibility::spinBoxTest() QVERIFY(childRect.isNull() == false); } + spinBox->setFocus(); + QTestAccessibility::clearEvents(); + QTest::keyPress(spinBox, Qt::Key_Up); + QTest::qWait(200); + EventList events = QTestAccessibility::events(); + QTestAccessibilityEvent expectedEvent(spinBox, 0, (int)QAccessible::ValueChanged); + QVERIFY(events.contains(expectedEvent)); delete spinBox; QTestAccessibility::clearEvents(); #else -- cgit v0.12 From 1e9d76013ef0121bcfc6efbe4328ded58c1eebd3 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 13:25:42 +0200 Subject: QMainWindow: layout private API cleanup using const references to pass parameter --- src/gui/widgets/qmainwindowlayout.cpp | 56 +++++++++++++++++------------------ src/gui/widgets/qmainwindowlayout_p.h | 14 ++++----- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 0318f53..1057f5f 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -426,42 +426,42 @@ QList QMainWindowLayoutState::gapIndex(QWidget *widget, return result; } -bool QMainWindowLayoutState::insertGap(QList path, QLayoutItem *item) +bool QMainWindowLayoutState::insertGap(const QList &path, QLayoutItem *item) { if (path.isEmpty()) return false; - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) { Q_ASSERT(qobject_cast(item->widget()) != 0); - return toolBarAreaLayout.insertGap(path, item); + return toolBarAreaLayout.insertGap(path.mid(1), item); } #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) { Q_ASSERT(qobject_cast(item->widget()) != 0); - return dockAreaLayout.insertGap(path, item); + return dockAreaLayout.insertGap(path.mid(1), item); } #endif //QT_NO_DOCKWIDGET return false; } -void QMainWindowLayoutState::remove(QList path) +void QMainWindowLayoutState::remove(const QList &path) { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - toolBarAreaLayout.remove(path); + toolBarAreaLayout.remove(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - dockAreaLayout.remove(path); + dockAreaLayout.remove(path.mid(1)); #endif //QT_NO_DOCKWIDGET } @@ -501,88 +501,88 @@ bool QMainWindowLayoutState::isValid() const return rect.isValid(); } -QLayoutItem *QMainWindowLayoutState::item(QList path) +QLayoutItem *QMainWindowLayoutState::item(const QList &path) { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.item(path).widgetItem; + return toolBarAreaLayout.item(path.mid(1)).widgetItem; #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.item(path).widgetItem; + return dockAreaLayout.item(path.mid(1)).widgetItem; #endif //QT_NO_DOCKWIDGET return 0; } -QRect QMainWindowLayoutState::itemRect(QList path) const +QRect QMainWindowLayoutState::itemRect(const QList &path) const { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.itemRect(path); + return toolBarAreaLayout.itemRect(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.itemRect(path); + return dockAreaLayout.itemRect(path.mid(1)); #endif //QT_NO_DOCKWIDGET return QRect(); } -QRect QMainWindowLayoutState::gapRect(QList path) const +QRect QMainWindowLayoutState::gapRect(const QList &path) const { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.itemRect(path); + return toolBarAreaLayout.itemRect(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.gapRect(path); + return dockAreaLayout.gapRect(path.mid(1)); #endif //QT_NO_DOCKWIDGET return QRect(); } -QLayoutItem *QMainWindowLayoutState::plug(QList path) +QLayoutItem *QMainWindowLayoutState::plug(const QList &path) { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.plug(path); + return toolBarAreaLayout.plug(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.plug(path); + return dockAreaLayout.plug(path.mid(1)); #endif //QT_NO_DOCKWIDGET return 0; } -QLayoutItem *QMainWindowLayoutState::unplug(QList path, QMainWindowLayoutState *other) +QLayoutItem *QMainWindowLayoutState::unplug(const QList &path, QMainWindowLayoutState *other) { - int i = path.takeFirst(); + int i = path.first(); #ifdef QT_NO_TOOLBAR Q_UNUSED(other); #else if (i == 0) - return toolBarAreaLayout.unplug(path, other ? &other->toolBarAreaLayout : 0); + return toolBarAreaLayout.unplug(path.mid(1), other ? &other->toolBarAreaLayout : 0); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.unplug(path); + return dockAreaLayout.unplug(path.mid(1)); #endif //QT_NO_DOCKWIDGET return 0; diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 5c5965a..759461b 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -129,9 +129,9 @@ public: QLayoutItem *itemAt(int index, int *x) const; QLayoutItem *takeAt(int index, int *x); QList indexOf(QWidget *widget) const; - QLayoutItem *item(QList path); - QRect itemRect(QList path) const; - QRect gapRect(QList path) const; // ### get rid of this, use itemRect() instead + QLayoutItem *item(const QList &path); + QRect itemRect(const QList &path) const; + QRect gapRect(const QList &path) const; // ### get rid of this, use itemRect() instead bool contains(QWidget *widget) const; @@ -139,14 +139,14 @@ public: QWidget *centralWidget() const; QList gapIndex(QWidget *widget, const QPoint &pos) const; - bool insertGap(QList path, QLayoutItem *item); - void remove(QList path); + bool insertGap(const QList &path, QLayoutItem *item); + void remove(const QList &path); void remove(QLayoutItem *item); void clear(); bool isValid() const; - QLayoutItem *plug(QList path); - QLayoutItem *unplug(QList path, QMainWindowLayoutState *savedState = 0); + QLayoutItem *plug(const QList &path); + QLayoutItem *unplug(const QList &path, QMainWindowLayoutState *savedState = 0); void saveState(QDataStream &stream) const; bool checkFormat(QDataStream &stream, bool pre43); -- cgit v0.12 From 5c756b368f5a76eeeff9e8e762a89368ba0b8149 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 7 Jul 2009 13:41:09 +0200 Subject: doc: Explained that you can't add new Q3DockAreas to a Widget. They won't be shown. Task-number: 166508 --- src/qt3support/widgets/q3dockarea.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/qt3support/widgets/q3dockarea.cpp b/src/qt3support/widgets/q3dockarea.cpp index a00bc81..a823caa 100644 --- a/src/qt3support/widgets/q3dockarea.cpp +++ b/src/qt3support/widgets/q3dockarea.cpp @@ -473,24 +473,25 @@ int Q3DockAreaLayout::widthForHeight(int h) const contain Q3ToolBars since Q3ToolBar is a Q3DockWindow subclass. QMainWindow contains four Q3DockAreas which you can use for your - Q3ToolBars and Q3DockWindows, so in most situations you do not need - to use the Q3DockArea class directly. Although QMainWindow contains - support for its own dock areas it isn't convenient for adding new - Q3DockAreas. If you need to create your own dock areas we suggest - that you create a subclass of QWidget and add your Q3DockAreas to - your subclass. + Q3ToolBars and Q3DockWindows, so in most situations you do not + need to use the Q3DockArea class directly. Although QMainWindow + contains support for its own dock areas, you can't add new ones. + You also can't add a Q3DockArea to your own subclass of QWidget. + It won't be shown. \img qmainwindow-qdockareas.png QMainWindow's Q3DockAreas \target lines - \e Lines. Q3DockArea uses the concept of lines. A line is a - horizontal region which may contain dock windows side-by-side. A - dock area may have room for more than one line. When dock windows - are docked into a dock area they are usually added at the right - hand side of the top-most line that has room (unless manually - placed by the user). When users move dock windows they may leave - empty lines or gaps in non-empty lines. Qt::Dock windows can be lined - up to minimize wasted space using the lineUp() function. + \section2 Lines. + + Q3DockArea uses the concept of lines. A line is a horizontal + region which may contain dock windows side-by-side. A dock area + may have room for more than one line. When dock windows are docked + into a dock area they are usually added at the right hand side of + the top-most line that has room (unless manually placed by the + user). When users move dock windows they may leave empty lines or + gaps in non-empty lines. Qt::Dock windows can be lined up to + minimize wasted space using the lineUp() function. The Q3DockArea class maintains a position list of all its child dock windows. Qt::Dock windows are added to a dock area from position -- cgit v0.12 From 20b2c6bd8e6f6a7ef384f4b478623768c11e01ae Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Jul 2009 13:45:15 +0200 Subject: Document limitation in Cocoa cursor handling. It seems there is a bug in AppKit which will automatically reset a cursor even when it is grabbed, but won't reset it when it's brought back into the window. The upshot of this is that doing a setCursor() inside of mouse handling behaves slightly different than on the other platforms (including Carbon). However, we are at the mercy of Cocoa here and I would rather have all the other things AppKit does right and live with this bug which they may fix some day. --- src/gui/kernel/qwidget.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e6a5ae0..9d40b00 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -4590,6 +4590,11 @@ void QWidget::unsetLayoutDirection() By default, this property contains a cursor with the Qt::ArrowCursor shape. + Some underlying window implementations will reset the cursor if it + leaves a widget even if the mouse is grabbed. If you want to have + a cursor set for all widgets, even when outside the window, consider + QApplication::setOverrideCursor(). + \sa QApplication::setOverrideCursor() */ -- cgit v0.12 From da1dee6894f96b416bb123578cc6e61c6444ddd8 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 7 Jul 2009 13:49:20 +0200 Subject: improve the QScriptEngine::importExtension() autotest Error messages and __postInit__. --- tests/auto/qscriptengine/script/com/__init__.js | 4 ++++ tests/auto/qscriptengine/script/com/trolltech/__init__.js | 4 ++++ tests/auto/qscriptengine/tst_qscriptengine.cpp | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/tests/auto/qscriptengine/script/com/__init__.js b/tests/auto/qscriptengine/script/com/__init__.js index 381816a..7db3ee4 100644 --- a/tests/auto/qscriptengine/script/com/__init__.js +++ b/tests/auto/qscriptengine/script/com/__init__.js @@ -3,3 +3,7 @@ __setupPackage__("com"); com.wasDefinedAlready = wasDefinedAlready; com.name = __extension__; com.level = 1; + +com.postInitCallCount = 0; +com.originalPostInit = __postInit__; +__postInit__ = function() { ++com.postInitCallCount; }; diff --git a/tests/auto/qscriptengine/script/com/trolltech/__init__.js b/tests/auto/qscriptengine/script/com/trolltech/__init__.js index f12b17d..a55b132 100644 --- a/tests/auto/qscriptengine/script/com/trolltech/__init__.js +++ b/tests/auto/qscriptengine/script/com/trolltech/__init__.js @@ -3,3 +3,7 @@ __setupPackage__("com.trolltech"); com.trolltech.wasDefinedAlready = wasDefinedAlready; com.trolltech.name = __extension__; com.trolltech.level = com.level + 1; + +com.trolltech.postInitCallCount = 0; +com.trolltech.originalPostInit = __postInit__; +__postInit__ = function() { ++com.trolltech.postInitCallCount; }; diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index c17454d..57c5167 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -1583,6 +1583,7 @@ void tst_QScriptEngine::importExtension() QScriptValue ret = eng.importExtension("this.extension.does.not.exist"); QCOMPARE(eng.hasUncaughtException(), true); QCOMPARE(ret.isError(), true); + QCOMPARE(ret.toString(), QString::fromLatin1("Error: Unable to import this.extension.does.not.exist: no such extension")); } { @@ -1601,6 +1602,8 @@ void tst_QScriptEngine::importExtension() .strictlyEquals(QScriptValue(&eng, "com")), true); QCOMPARE(com.property("level") .strictlyEquals(QScriptValue(&eng, 1)), true); + QVERIFY(com.property("originalPostInit").isUndefined()); + QVERIFY(com.property("postInitCallCount").strictlyEquals(1)); QScriptValue trolltech = com.property("trolltech"); QCOMPARE(trolltech.isObject(), true); @@ -1610,6 +1613,8 @@ void tst_QScriptEngine::importExtension() .strictlyEquals(QScriptValue(&eng, "com.trolltech")), true); QCOMPARE(trolltech.property("level") .strictlyEquals(QScriptValue(&eng, 2)), true); + QVERIFY(trolltech.property("originalPostInit").isUndefined()); + QVERIFY(trolltech.property("postInitCallCount").strictlyEquals(1)); } QStringList imp = eng.importedExtensions(); QCOMPARE(imp.size(), 2); @@ -1625,6 +1630,8 @@ void tst_QScriptEngine::importExtension() eng.globalObject().setProperty("__import__", eng.newFunction(__import__)); QScriptValue ret = eng.importExtension("com.trolltech.recursive"); QCOMPARE(eng.hasUncaughtException(), true); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("Error: recursive import of com.trolltech.recursive")); QStringList imp = eng.importedExtensions(); QCOMPARE(imp.size(), 2); QCOMPARE(imp.at(0), QString::fromLatin1("com")); -- cgit v0.12 From 9e2573bac15e39dc4f3545351ad87e221b4785e7 Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 7 Jul 2009 13:54:39 +0200 Subject: Updated docs to mention pattern matching in help project file lists. Reviewed-by: kh --- doc/src/examples/simpletextviewer.qdoc | 7 +------ doc/src/qthelp.qdoc | 14 ++++++++------ doc/src/snippets/code/doc_src_qthelp.qdoc | 6 ++---- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/doc/src/examples/simpletextviewer.qdoc b/doc/src/examples/simpletextviewer.qdoc index 87eae57..2531a86 100644 --- a/doc/src/examples/simpletextviewer.qdoc +++ b/doc/src/examples/simpletextviewer.qdoc @@ -198,12 +198,7 @@ openfile.html wildcardmatching.html images/browse.png - images/fadedfilemenu.png - images/filedialog.png - images/handbook.png - images/mainwindow.png - images/open.png - images/wildcard.png + images/*.png diff --git a/doc/src/qthelp.qdoc b/doc/src/qthelp.qdoc index b5395c9..92c9609 100644 --- a/doc/src/qthelp.qdoc +++ b/doc/src/qthelp.qdoc @@ -398,11 +398,13 @@ Finally, the actual documentation files have to be listed. Make sure that all files neccessary to display the help are mentioned, i.e. - stylesheets or similar files need to be there as well. The file, like all + stylesheets or similar files need to be there as well. The files, like all file references in a Qt help project, are relative to the help project file - itself. All listed files will be compressed and written to the Qt compressed - help file. So, in the end, one single Qt help file contains all - documentation files along with the contents and indices. \note The - referenced files must be inside the same directory (or within a subdirectory) - as the help project file. An absolute file path is not supported either. + itself. As the example shows, files (but not directories) can also be + specified as patterns using wildcards. All listed files will be compressed + and written to the Qt compressed help file. So, in the end, one single Qt + help file contains all documentation files along with the contents and + indices. \note The referenced files must be inside the same directory + (or within a subdirectory) as the help project file. An absolute file path + is not supported either. */ diff --git a/doc/src/snippets/code/doc_src_qthelp.qdoc b/doc/src/snippets/code/doc_src_qthelp.qdoc index 11d231f..949e2a5 100644 --- a/doc/src/snippets/code/doc_src_qthelp.qdoc +++ b/doc/src/snippets/code/doc_src_qthelp.qdoc @@ -92,8 +92,7 @@ if (links.count()) { classic.css - index.html - doc.html + *.html @@ -154,8 +153,7 @@ if (links.count()) { ... classic.css - index.html - doc.html + *.html ... //! [13] -- cgit v0.12 From 0044b3c968f5023f502e3574c96d4e4df0de865d Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 7 Jul 2009 14:18:12 +0200 Subject: Doc: Mentioned the use of the meta-type declaration macro and the function for registering types. Additional clean-up. Task-number: 221375 Reviewed-by: Trust Me --- src/network/socket/qlocalsocket.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp index acacdf2..7809226 100644 --- a/src/network/socket/qlocalsocket.cpp +++ b/src/network/socket/qlocalsocket.cpp @@ -63,7 +63,8 @@ QT_BEGIN_NAMESPACE waitForReadyRead(), waitForBytesWritten(), and waitForDisconnected() which blocks until the operation is complete or the timeout expires. - Note that this feature is not supported on Window 9x. + Note that this feature is not supported on versions of Windows earlier than + Windows XP. \sa QLocalServer */ @@ -102,7 +103,7 @@ QT_BEGIN_NAMESPACE opened in the mode specified by \a openMode, and enters the socket state specified by \a socketState. - Note: It is not possible to initialize two local sockets with the same + \note It is not possible to initialize two local sockets with the same native socket descriptor. \sa socketDescriptor(), state(), openMode() @@ -207,10 +208,10 @@ QT_BEGIN_NAMESPACE Returns true if the socket is valid and ready for use; otherwise returns false. - Note: The socket's state must be ConnectedState before reading + \note The socket's state must be ConnectedState before reading and writing can occur. - \sa state() + \sa state(), connectToServer() */ /*! @@ -243,9 +244,9 @@ QT_BEGIN_NAMESPACE */ /*! - \fn bool QLocalSocket::waitForConnected(int msec) + \fn bool QLocalSocket::waitForConnected(int msecs) - Waits until the socket is connected, up to \a msec milliseconds. If the + Waits until the socket is connected, up to \a msecs milliseconds. If the connection has been established, this function returns true; otherwise it returns false. In the case where it returns false, you can call error() to determine the cause of the error. @@ -255,7 +256,7 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp 0 - If msecs is -1, this function will not time out. + If \a msecs is -1, this function will not time out. \sa connectToServer(), connected() */ @@ -274,7 +275,7 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp 1 - If msecs is -1, this function will not time out. + If \a msecs is -1, this function will not time out. \sa disconnectFromServer(), close() */ @@ -309,9 +310,10 @@ QT_BEGIN_NAMESPACE parameter describes the type of error that occurred. QLocalSocket::LocalSocketError is not a registered metatype, so for queued - connections, you will have to register it with Q_DECLARE_METATYPE. + connections, you will have to register it with Q_DECLARE_METATYPE() and + qRegisterMetaType(). - \sa error(), errorString() + \sa error(), errorString(), {Creating Custom Qt Types} */ /*! @@ -321,9 +323,10 @@ QT_BEGIN_NAMESPACE The \a socketState parameter is the new state. QLocalSocket::SocketState is not a registered metatype, so for queued - connections, you will have to register it with Q_DECLARE_METATYPE. + connections, you will have to register it with Q_DECLARE_METATYPE() and + qRegisterMetaType(). - \sa state() + \sa state(), {Creating Custom Qt Types} */ /*! @@ -365,7 +368,7 @@ QString QLocalSocket::serverName() const /*! Returns the server path that the socket is connected to. - Note: This is platform specific + \note The return value of this function is platform specific. \sa connectToServer(), serverName() */ -- cgit v0.12 From 2a834d39a69430058df3916392afab064ca941ee Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 7 Jul 2009 13:48:03 +0200 Subject: try to fix the accept4 not being found in some older kernels --- src/corelib/kernel/qcore_unix.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index 2549f77..b04abae 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -138,22 +138,32 @@ static inline int syscall(...) { errno = ENOSYS; return -1;} # define __NR_dup3 330 # define __NR_pipe2 331 # elif defined(__x86_64__) -# define __NR_accept4 288 # define __NR_dup3 292 # define __NR_pipe2 293 # elif defined(__ia64__) -# define __NR_accept4 -1 # define __NR_dup3 1316 # define __NR_pipe2 1317 # else // set the syscalls to absurd numbers so that they'll cause ENOSYS errors -# warning "Please port the pipe2/dup3/accept4 code to this platform" -# define __NR_accept4 -1 +# warning "Please port the pipe2/dup3 code to this platform" # define __NR_dup3 -1 # define __NR_pipe2 -1 # endif # endif +# if !defined(__NR_socketcall) && !defined(__NR_accept4) +# if defined(__x86_64__) +# define __NR_accept4 288 +# elif defined(__ia64__) +// not assigned yet to IA-64 +# define __NR_accept4 -1 +# else +// set the syscalls to absurd numbers so that they'll cause ENOSYS errors +# warning "Please port the accept4 code to this platform" +# define __NR_accept4 -1 +# endif +# endif + QT_BEGIN_NAMESPACE namespace QtLibcSupplement { int pipe2(int pipes[], int flags) -- cgit v0.12 From e5e2f9fd5c1554337a576374ec6744f953d2404d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 15:13:44 +0200 Subject: QColumnView: didn't react to addition of rows/cols in the current view Task-number: 246999 --- src/gui/itemviews/qabstractitemview_p.h | 13 +++++---- src/gui/itemviews/qcolumnview.cpp | 45 +++++++++++++++++++++++++++++- src/gui/itemviews/qcolumnview.h | 8 ++---- src/gui/itemviews/qcolumnview_p.h | 3 ++ src/gui/itemviews/qheaderview.h | 1 - src/gui/itemviews/qtreeview.h | 7 ++--- src/gui/widgets/qabstractscrollarea.cpp | 3 -- src/gui/widgets/qabstractscrollarea_p.h | 2 +- tests/auto/qcolumnview/tst_qcolumnview.cpp | 42 +++++++++++++++++++++++----- 9 files changed, 96 insertions(+), 28 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index c2c1f32..026912a 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -109,12 +109,13 @@ public: void init(); - void _q_rowsRemoved(const QModelIndex &parent, int start, int end); - void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); - void _q_columnsRemoved(const QModelIndex &parent, int start, int end); - void _q_columnsInserted(const QModelIndex &parent, int start, int end); - void _q_modelDestroyed(); - void _q_layoutChanged(); + virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end); + virtual void _q_modelDestroyed(); + virtual void _q_layoutChanged(); + void _q_fetchMore(); bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const; diff --git a/src/gui/itemviews/qcolumnview.cpp b/src/gui/itemviews/qcolumnview.cpp index 1662fa8..ff20163 100644 --- a/src/gui/itemviews/qcolumnview.cpp +++ b/src/gui/itemviews/qcolumnview.cpp @@ -52,7 +52,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE @@ -896,6 +895,15 @@ QList QColumnView::columnWidths() const /*! \reimp */ +void QColumnView::rowsInserted(const QModelIndex &parent, int start, int end) +{ + QAbstractItemView::rowsInserted(parent, start, end); + d_func()->checkColumnCreation(parent); +} + +/*! + \reimp +*/ void QColumnView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { Q_D(QColumnView); @@ -1048,6 +1056,41 @@ QColumnViewPrivate::~QColumnViewPrivate() /*! \internal + + */ +void QColumnViewPrivate::_q_columnsInserted(const QModelIndex &parent, int start, int end) +{ + QAbstractItemViewPrivate::_q_columnsInserted(parent, start, end); + checkColumnCreation(parent); +} + +/*! + \internal + + Makes sure we create a corresponding column as a result of changing the model. + + */ +void QColumnViewPrivate::checkColumnCreation(const QModelIndex &parent) +{ + if (parent == q_func()->currentIndex() && model->hasChildren(parent)) { + //the parent has children and is the current + //let's try to find out if there is already a mapping that is good + for (int i = 0; i < columns.count(); ++i) { + QAbstractItemView *view = columns.at(i); + if (view->rootIndex() == parent) { + if (view == previewColumn) { + //let's recreate the parent + closeColumns(parent, false); + createColumn(parent, true /*show*/); + } + break; + } + } + } +} + +/*! + \internal Place all of the columns where they belong inside of the viewport, resize as necessary. */ void QColumnViewPrivate::doLayout() diff --git a/src/gui/itemviews/qcolumnview.h b/src/gui/itemviews/qcolumnview.h index 880870a..f8697e9 100644 --- a/src/gui/itemviews/qcolumnview.h +++ b/src/gui/itemviews/qcolumnview.h @@ -97,16 +97,14 @@ protected: QRegion visualRegionForSelection(const QItemSelection &selection) const; int horizontalOffset() const; int verticalOffset() const; - void scrollContentsBy(int dx, int dy); + void rowsInserted(const QModelIndex &parent, int start, int end); + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); // QColumnView functions + void scrollContentsBy(int dx, int dy); virtual QAbstractItemView* createColumn(const QModelIndex &rootIndex); void initializeColumn(QAbstractItemView *column) const; -protected Q_SLOTS: - // QAbstractItemView overloads - void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); - private: Q_DECLARE_PRIVATE(QColumnView) Q_DISABLE_COPY(QColumnView) diff --git a/src/gui/itemviews/qcolumnview_p.h b/src/gui/itemviews/qcolumnview_p.h index 92a4d2a..233dc3c 100644 --- a/src/gui/itemviews/qcolumnview_p.h +++ b/src/gui/itemviews/qcolumnview_p.h @@ -148,10 +148,13 @@ public: void closeColumns(const QModelIndex &parent = QModelIndex(), bool build = false); void doLayout(); void setPreviewWidget(QWidget *widget); + void checkColumnCreation(const QModelIndex &parent); + void _q_gripMoved(int offset); void _q_changeCurrentColumn(); void _q_clicked(const QModelIndex &index); + void _q_columnsInserted(const QModelIndex &parent, int start, int end); QList columns; QVector columnSizes; // used during init and corner moving diff --git a/src/gui/itemviews/qheaderview.h b/src/gui/itemviews/qheaderview.h index bf92667..3a66c9a 100644 --- a/src/gui/itemviews/qheaderview.h +++ b/src/gui/itemviews/qheaderview.h @@ -228,7 +228,6 @@ protected: private: Q_PRIVATE_SLOT(d_func(), void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast)) Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged()) - Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) Q_DECLARE_PRIVATE(QHeaderView) Q_DISABLE_COPY(QHeaderView) }; diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index 35a205c..0347645 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -144,19 +144,20 @@ public: void sortByColumn(int column, Qt::SortOrder order); + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void selectAll(); + Q_SIGNALS: void expanded(const QModelIndex &index); void collapsed(const QModelIndex &index); public Q_SLOTS: - void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); void hideColumn(int column); void showColumn(int column); void expand(const QModelIndex &index); void collapse(const QModelIndex &index); void resizeColumnToContents(int column); void sortByColumn(int column); - void selectAll(); void expandAll(); void collapseAll(); void expandToDepth(int depth); @@ -225,8 +226,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation()) Q_PRIVATE_SLOT(d_func(), void _q_animate()) Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &)) - Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int)) - Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex &, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 66572b8..d952ab0 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -490,9 +490,6 @@ void QAbstractScrollAreaPrivate::layoutChildren() viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last } -// ### Fix for 4.4, talk to Bjoern E or Girish. -void QAbstractScrollAreaPrivate::scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} - /*! \internal diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 5d3494b..7e0f444 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -88,7 +88,7 @@ public: void init(); void layoutChildren(); // ### Fix for 4.4, talk to Bjoern E or Girish. - virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy); + virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} void _q_hslide(int); void _q_vslide(int); diff --git a/tests/auto/qcolumnview/tst_qcolumnview.cpp b/tests/auto/qcolumnview/tst_qcolumnview.cpp index 0216e0f..0b3ba7a 100644 --- a/tests/auto/qcolumnview/tst_qcolumnview.cpp +++ b/tests/auto/qcolumnview/tst_qcolumnview.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #include "../../../src/gui/itemviews/qcolumnviewgrip_p.h" #include "../../../src/gui/dialogs/qfilesystemmodel_p.h" @@ -87,6 +88,8 @@ private slots: void setSelectionModel(); void visualRegionForSelection(); + void dynamicModelChanges(); + // grip void moveGrip_basic(); void moveGrip_data(); @@ -133,16 +136,10 @@ public: inline QModelIndex thirdLevel() { return index(0, 0, secondLevel()); } }; -class ColumnViewPrivate : public QColumnViewPrivate -{ -public: - ColumnViewPrivate() : QColumnViewPrivate() {} -}; - class ColumnView : public QColumnView { public: - ColumnView(QWidget *parent = 0) : QColumnView(*new ColumnViewPrivate, parent){} + ColumnView(QWidget *parent = 0) : QColumnView(parent){} QList > createdColumns; void ScrollContentsBy(int x, int y) {scrollContentsBy(x,y); } @@ -1002,6 +999,37 @@ void tst_QColumnView::pullRug() // don't crash } +void tst_QColumnView::dynamicModelChanges() +{ + struct MyItemDelegate : public QItemDelegate + { + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const + { + paintedIndexes += index; + QItemDelegate::paint(painter, option, index); + } + + mutable QSet paintedIndexes; + + } delegate;; + QStandardItemModel model; + ColumnView view; + view.setModel(&model); + view.setItemDelegate(&delegate); + view.show(); + + QStandardItem *item = new QStandardItem(QLatin1String("item")); + model.appendRow(item); + + QTest::qWait(200); //let the time for painting to occur + QCOMPARE(delegate.paintedIndexes.count(), 1); + QCOMPARE(*delegate.paintedIndexes.begin(), model.index(0,0)); + + +} + QTEST_MAIN(tst_QColumnView) #include "tst_qcolumnview.moc" -- cgit v0.12 From 1a112561126c7f2148d91e40a6c3f52ccf506fd5 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 15:29:05 +0200 Subject: Getting rid of compiler warnings on windows --- src/gui/kernel/qapplication.cpp | 6 ++---- src/gui/kernel/qapplication_win.cpp | 4 +--- src/gui/util/qsystemtrayicon_win.cpp | 4 ++-- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 0e8978f..839e465 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5233,8 +5233,6 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, const QList &touchPoints) { QApplicationPrivate *d = self; - QApplication *q = self->q_func(); - typedef QPair > StatesAndTouchPoints; QHash widgetsNeedingEvents; @@ -5256,7 +5254,7 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, if (!widget) { // determine which widget this event will go to if (!window) - window = q->topLevelAt(touchPoint.screenPos().toPoint()); + window = QApplication::topLevelAt(touchPoint.screenPos().toPoint()); if (!window) continue; widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint())); @@ -5356,7 +5354,7 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, QTouchEvent touchEvent(eventType, deviceType, - q->keyboardModifiers(), + QApplication::keyboardModifiers(), it.value().first, it.value().second); updateTouchPointsForWidget(widget, &touchEvent); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 13f19a3..e0eda82 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3940,13 +3940,11 @@ void QApplicationPrivate::cleanupMultitouch_sys() bool QApplicationPrivate::translateTouchEvent(const MSG &msg) { - Q_Q(QApplication); - QWidget *widgetForHwnd = QWidget::find(msg.hwnd); if (!widgetForHwnd) return false; - QRect screenGeometry = q->desktop()->screenGeometry(widgetForHwnd); + QRect screenGeometry = QApplication::desktop()->screenGeometry(widgetForHwnd); QList touchPoints; diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp index c1b7e7f..dea9264 100644 --- a/src/gui/util/qsystemtrayicon_win.cpp +++ b/src/gui/util/qsystemtrayicon_win.cpp @@ -163,7 +163,7 @@ void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd) } } -int iconFlag( QSystemTrayIcon::MessageIcon icon ) +static int iconFlag( QSystemTrayIcon::MessageIcon icon ) { #if NOTIFYICON_VERSION >= 3 switch (icon) { @@ -176,7 +176,7 @@ int iconFlag( QSystemTrayIcon::MessageIcon icon ) case QSystemTrayIcon::NoIcon: return NIIF_NONE; default: - Q_ASSERT("Invalid QSystemTrayIcon::MessageIcon value", false); + Q_ASSERT_X(false, "QSystemTrayIconSys::showMessage", "Invalid QSystemTrayIcon::MessageIcon value"); return NIIF_NONE; } #else -- cgit v0.12 From e348e7b633ff3a0279d4d1759e35f0920afcc3e0 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 15:56:07 +0200 Subject: QColumnView: new uses QPropertyAnimation over QTimeLine --- src/gui/itemviews/qcolumnview.cpp | 27 +++++++-------------------- src/gui/itemviews/qcolumnview_p.h | 4 ++-- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/gui/itemviews/qcolumnview.cpp b/src/gui/itemviews/qcolumnview.cpp index ff20163..fc89967 100644 --- a/src/gui/itemviews/qcolumnview.cpp +++ b/src/gui/itemviews/qcolumnview.cpp @@ -107,9 +107,10 @@ void QColumnViewPrivate::initialize() { Q_Q(QColumnView); q->setTextElideMode(Qt::ElideMiddle); - QObject::connect(¤tAnimation, SIGNAL(frameChanged(int)), - hbar, SLOT(setValue(int))); QObject::connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); + currentAnimation.setDuration(ANIMATION_DURATION_MSEC); + currentAnimation.setTargetObject(hbar); + currentAnimation.setEasingCurve(QEasingCurve::InOutQuad); delete itemDelegate; q->setItemDelegate(new QColumnViewDelegate(q)); } @@ -259,7 +260,7 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) if (!index.isValid() || d->columns.isEmpty()) return; - if (d->currentAnimation.state() == QTimeLine::Running) + if (d->currentAnimation.state() == QPropertyAnimation::Running) return; d->currentAnimation.stop(); @@ -325,21 +326,7 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) } } - //horizontalScrollBar()->setValue(newScrollbarValue); - //d->_q_changeCurrentColumn(); - //return; - // or do the following currentAnimation - - int oldValue = horizontalScrollBar()->value(); - - if (oldValue < newScrollbarValue) { - d->currentAnimation.setFrameRange(oldValue, newScrollbarValue); - d->currentAnimation.setDirection(QTimeLine::Forward); - d->currentAnimation.setCurrentTime(0); - } else { - d->currentAnimation.setFrameRange(newScrollbarValue, oldValue); - d->currentAnimation.setDirection(QTimeLine::Backward); - } + d->currentAnimation.setEndValue(newScrollbarValue); d->currentAnimation.start(); } @@ -409,7 +396,7 @@ void QColumnView::resizeEvent(QResizeEvent *event) void QColumnViewPrivate::updateScrollbars() { Q_Q(QColumnView); - if (currentAnimation.state() == QTimeLine::Running) + if (currentAnimation.state() == QPropertyAnimation::Running) return; // find the total horizontal length of the laid out columns @@ -1044,7 +1031,7 @@ QColumnViewPrivate::QColumnViewPrivate() : QAbstractItemViewPrivate() ,showResizeGrips(true) ,offset(0) -,currentAnimation(ANIMATION_DURATION_MSEC) +,currentAnimation(0, "value") // will set the target later ,previewWidget(0) ,previewColumn(0) { diff --git a/src/gui/itemviews/qcolumnview_p.h b/src/gui/itemviews/qcolumnview_p.h index 233dc3c..1a8be70 100644 --- a/src/gui/itemviews/qcolumnview_p.h +++ b/src/gui/itemviews/qcolumnview_p.h @@ -60,7 +60,7 @@ #include #include -#include +#include #include #include #include @@ -160,7 +160,7 @@ public: QVector columnSizes; // used during init and corner moving bool showResizeGrips; int offset; - QTimeLine currentAnimation; + QPropertyAnimation currentAnimation; QWidget *previewWidget; QAbstractItemView *previewColumn; }; -- cgit v0.12 From 5f48e2a16b0b64536a205320fbf7a22f7461d80d Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 7 Jul 2009 15:43:53 +0200 Subject: Fixes a crash when scrolling a scrollarea with a mouse wheel. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a crashed introduced in 60e965fd35037f4a27816d2aeccafdff0d6ae9d6 - those lines were removed by accident. Reviewed-by: João Abecasis Author: João Abecasis --- src/gui/kernel/qwidget.cpp | 1 + src/gui/widgets/qabstractscrollarea.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 611cb44..d1ab45a 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -7484,6 +7484,7 @@ bool QWidget::event(QEvent *event) #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: #endif + return false; default: break; } diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index d952ab0..e78f5a7 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -937,6 +937,7 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::DragMove: case QEvent::DragLeave: #endif + return false; case QEvent::StyleChange: case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: -- cgit v0.12 From 424e2e68f9a3f556ad2d06e2fbceac0d48c060be Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 16:42:20 +0200 Subject: ItemViews: _q_fetchMore now uses a timer instead of invokeMethod --- src/gui/itemviews/qabstractitemview.cpp | 11 +++++++---- src/gui/itemviews/qabstractitemview.h | 1 - src/gui/itemviews/qabstractitemview_p.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index cefe8a5..dd84304 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -2200,6 +2200,8 @@ void QAbstractItemView::resizeEvent(QResizeEvent *event) void QAbstractItemView::timerEvent(QTimerEvent *event) { Q_D(QAbstractItemView); + if (event->timerId() == d->fetchMoreTimer.timerId()) + d->fetchMore(); if (event->timerId() == d->autoScrollTimer.timerId()) doAutoScroll(); else if (event->timerId() == d->updateTimer.timerId()) @@ -2415,7 +2417,7 @@ void QAbstractItemView::updateEditorGeometries() void QAbstractItemView::updateGeometries() { updateEditorGeometries(); - QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection); + d_func()->fetchMoreTimer.start(0, this); //fetch more later } /*! @@ -2960,7 +2962,7 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde void QAbstractItemView::rowsInserted(const QModelIndex &, int, int) { if (!isVisible()) - QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection); + d_func()->fetchMoreTimer.start(0, this); //fetch more later else updateEditorGeometries(); } @@ -3183,7 +3185,7 @@ void QAbstractItemView::currentChanged(const QModelIndex ¤t, const QModelI update(current); edit(current, CurrentChanged, 0); if (current.row() == (d->model->rowCount(d->root) - 1)) - d->_q_fetchMore(); + d->fetchMore(); } else { d->shouldScrollToCurrentOnShow = d->autoScroll; } @@ -3604,8 +3606,9 @@ QAbstractItemViewPrivate::contiguousSelectionCommand(const QModelIndex &index, } } -void QAbstractItemViewPrivate::_q_fetchMore() +void QAbstractItemViewPrivate::fetchMore() { + fetchMoreTimer.stop(); if (!model->canFetchMore(root)) return; int last = model->rowCount(root) - 1; diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index f98dd16..da6f0ea 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -353,7 +353,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) - Q_PRIVATE_SLOT(d_func(), void _q_fetchMore()) friend class QTreeViewPrivate; // needed to compile with MSVC friend class QAccessibleItemRow; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 026912a..2950bcd 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -116,7 +116,7 @@ public: virtual void _q_modelDestroyed(); virtual void _q_layoutChanged(); - void _q_fetchMore(); + void fetchMore(); bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const; bool shouldForwardEvent(QAbstractItemView::EditTrigger trigger, const QEvent *event) const; @@ -388,6 +388,7 @@ public: private: mutable QBasicTimer delayedLayout; + mutable QBasicTimer fetchMoreTimer; }; QT_BEGIN_INCLUDE_NAMESPACE -- cgit v0.12 From f37bd111f7622a34b3a7bd63f5a82f6042dc0f0d Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Jul 2009 16:46:30 +0200 Subject: Stop showing then hiding windows on starting designer in top-level mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've had this since 4.5 and it's very annoying to see the window show and quickly hide itself. I was hoping it wasn't a bug in Qt, and it turns it isn't and it was happening on all platforms. Reviewed-by: Friedemann Kleint Shout outs: João for testing. --- tools/designer/src/designer/qdesigner_workbench.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp index 923687a2..ce8dde6 100644 --- a/tools/designer/src/designer/qdesigner_workbench.cpp +++ b/tools/designer/src/designer/qdesigner_workbench.cpp @@ -462,8 +462,7 @@ void QDesignerWorkbench::switchToTopLevelMode() // make sure that the widgetbox is visible if it is different from neutral. QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow(); Q_ASSERT(widgetBoxWrapper); - if (!widgetBoxWrapper->action()->isChecked()) - widgetBoxWrapper->action()->trigger(); + const bool needWidgetBoxWrapperVisible = widgetBoxWrapper->action()->isChecked(); switchToNeutralMode(); const QPoint desktopOffset = desktopGeometry().topLeft(); @@ -502,7 +501,7 @@ void QDesignerWorkbench::switchToTopLevelMode() found_visible_window |= tw->isVisible(); } - if (!widgetBoxWrapper->action()->isChecked()) + if (needWidgetBoxWrapperVisible) widgetBoxWrapper->action()->trigger(); if (!m_toolWindows.isEmpty() && !found_visible_window) -- cgit v0.12 From fbc384f1bc1dd57e4af8e008b9db000b6ff82a37 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Tue, 7 Jul 2009 16:24:49 +0200 Subject: On Mac OS X, translate the wrect to the coordinates on screen In the following configuration, wrect was off-screen and the widget was not painted: -scroll area "A" -contains another scrollarea "B" with 2*WRECT_MAX < size < XCOORD_MAX -the widget contained in B has size > XCOORD_MAX -A is scrolled to the the bottom To fix the issue, wrect is moved to the area where the top level window is in the widget coordinate. Task-number: 144779 Reviewed-by: nrc --- src/gui/kernel/qwidget_mac.mm | 23 ++++++++++++++++------- tests/auto/qwidget/tst_qwidget.cpp | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index b0531ec..48e174b 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3823,7 +3823,6 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) Qt coordinate system for parent X coordinate system for parent (relative to parent's wrect). */ - QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX); QRect wrect; //xrect is the X geometry of my X widget. (starts out in parent's Qt coord sys, and ends up in parent's X coord sys) QRect xrect = data.crect; @@ -3845,6 +3844,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) parentWRect = QRect(tmpRect.origin.x, tmpRect.origin.y, tmpRect.size.width, tmpRect.size.height); } else { + const QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX); parentWRect = wrectRange; } } else { @@ -3900,15 +3900,24 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) } } - if (xrect.height() > XCOORD_MAX || xrect.width() > XCOORD_MAX) { + const QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX); + if (!validRange.contains(xrect)) { // we are too big, and must clip - xrect &=wrectRange; + QPoint screenOffset(0, 0); // offset of the part being on screen + const QWidget *parentWidget = q->parentWidget(); + while (parentWidget) { + screenOffset -= parentWidget->data->crect.topLeft(); + parentWidget = parentWidget->parentWidget(); + } + QRect cropRect(screenOffset.x() - WRECT_MAX, + screenOffset.y() - WRECT_MAX, + 2*WRECT_MAX, + 2*WRECT_MAX); + + xrect &=cropRect; wrect = xrect; - wrect.translate(-data.crect.topLeft()); - //parent's X coord system is equal to parent's Qt coord - //sys, so we don't need to map xrect. + wrect.translate(-data.crect.topLeft()); // translate wrect in my Qt coordinates } - } // unmap if we are outside the valid window system coord system diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 04ec77d..fa36496 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -353,6 +353,7 @@ private slots: void toplevelLineEditFocus(); void focusWidget_task254563(); + void rectOutsideCoordinatesLimit_task144779(); private: bool ensureScreenSize(int width, int height); @@ -9117,5 +9118,39 @@ void tst_QWidget::focusWidget_task254563() QVERIFY(top.focusWidget() != widget); //dangling pointer } +void tst_QWidget::rectOutsideCoordinatesLimit_task144779() +{ + QWidget main; + QPalette palette; + palette.setColor(QPalette::Window, Qt::red); + main.setPalette(palette); + main.resize(400, 400); + + QWidget *offsetWidget = new QWidget(&main); + offsetWidget->setGeometry(0, -14600, 400, 15000); + + // big widget is too big for the coordinates, it must be limited by wrect + // if wrect is not at the right position because of offsetWidget, bigwidget + // is not painted correctly + QWidget *bigWidget = new QWidget(offsetWidget); + bigWidget->setGeometry(0, 0, 400, 50000); + palette.setColor(QPalette::Window, Qt::green); + bigWidget->setPalette(palette); + bigWidget->setAutoFillBackground(true); + + main.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&main); +#endif + QTest::qWait(100); + QPixmap pixmap = QPixmap::grabWindow(main.winId()); + + QPixmap correct(main.size()); + correct.fill(Qt::green); + + QRect center(100, 100, 200, 200); // to avoid the decorations + QCOMPARE(pixmap.toImage().copy(center), correct.toImage().copy(center)); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" -- cgit v0.12 From e5049ecc4590896a75dedcb098da9e991e1764ee Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 09:20:31 +1000 Subject: Handle special number cases (nan,{+-}infinity) in PostgreSQL When contructing the EXECUTE statement, there is a special case that we need to handle whereby we explicitly put quotes around the special float values before submutting the statement for execution Task-number:233829 Reviewed-by: Bill King --- src/sql/drivers/psql/qsql_psql.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 69697da..64b2a23 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -54,6 +54,8 @@ #include #include +#include + #include #include @@ -1144,6 +1146,21 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const qPQfreemem(data); break; } + case QVariant::Double: { + double val = field.value().toDouble(); + if (isnan(val)) + r = QLatin1String("'NaN'"); + else { + int res = isinf(val); + if (res == 1) + r = QLatin1String("'Infinity'"); + else if (res == -1) + r = QLatin1String("'-Infinity'"); + else + r = QSqlDriver::formatValue(field, trimStrings); + } + break; + } default: r = QSqlDriver::formatValue(field, trimStrings); break; -- cgit v0.12 From c2198e1c7884b835807e45ff53c3c54e86900211 Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 09:29:33 +1000 Subject: Auto test for task 233829 - postgreSQL specific autotest. Task-number:233829 --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index ed19e91..4b41eaf 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -188,6 +188,9 @@ private slots: void task_205701_data() { generic_data("QMYSQL"); } void task_205701(); + void task_233829_data() { generic_data(); } + void task_233829(); + private: // returns all database connections @@ -301,7 +304,7 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) tablenames << qTableName( "qtest_lockedtable" ); tablenames << qTableName( "Planet" ); - + tablenames << qTableName( "task_250026" ); tst_Databases::safeDropTables( db, tablenames ); @@ -2814,5 +2817,30 @@ void tst_QSqlQuery::task_234422() #endif +void tst_QSqlQuery::task_233829() +{ + QFETCH( QString, dbName ); + QSqlDatabase db = QSqlDatabase::database( dbName ); + CHECK_DATABASE( db ); + + if (!db.driverName().startsWith( "QPSQL" )) { + QSKIP( "This is a PostgreSQL specific test", SkipSingle ); + } + + QSqlQuery q( db ); + QString tableName = qTableName("task_233829"); + q.exec("DROP TABLE " + tableName); + QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + " (dbl1 double precision,dbl2 double precision) without oids;")); + + QString queryString("INSERT INTO " + tableName +"(dbl1, dbl2) VALUES(?,?)"); + + double k = 0.0; + QVERIFY_SQL(q,prepare(queryString)); + q.bindValue(0,0.0 / k); // nan + q.bindValue(1,0.0 / k); // nan + QVERIFY_SQL(q,exec()); + q.exec("DROP TABLE " + tableName); +} + QTEST_MAIN( tst_QSqlQuery ) #include "tst_qsqlquery.moc" -- cgit v0.12 From 529df6f1dbcf8992417d03ef2c9c3ec3f2d7bc4b Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 09:39:53 +1000 Subject: remove debug --- src/sql/drivers/psql/qsql_psql.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 64b2a23..8de79a3 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -54,7 +54,6 @@ #include #include -#include #include #include -- cgit v0.12 From 355d058a0c7eba3ae3b2a54dda566d94a4134941 Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 10:50:09 +1000 Subject: safely drop tables. --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 4b41eaf..30b85e8 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -295,6 +295,9 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName( "blobstest" ) << qTableName( "oraRowId" ); + if ( db.driverName().startsWith("QPSQL") ) + tablenames <<"task_233829"; + if ( db.driverName().startsWith("QSQLITE") ) tablenames << qTableName( "record_sqlite" ); @@ -2839,7 +2842,6 @@ void tst_QSqlQuery::task_233829() q.bindValue(0,0.0 / k); // nan q.bindValue(1,0.0 / k); // nan QVERIFY_SQL(q,exec()); - q.exec("DROP TABLE " + tableName); } QTEST_MAIN( tst_QSqlQuery ) -- cgit v0.12 From 5ff22b1ed4da11dc16a236825c939b5ae38d27cc Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Jul 2009 11:09:42 +1000 Subject: Fixes Dericks inf/nan patch for msvc --- src/sql/drivers/psql/qsql_psql.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 8de79a3..33f2e2b 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -59,7 +59,20 @@ #include #include +#if defined(_MSC_VER) +#include +#define isnan(x) _isnan(x) +int isinf(double x) +{ + if(_fpclass(x) == _FPCLASS_NINF) + return -1; + else if(_fpclass(x) == _FPCLASS_PINF) + return 1; + else return 0; +} +#else #include +#endif // workaround for postgres defining their OIDs in a private header file #define QBOOLOID 16 -- cgit v0.12 From b2e62931f1b2968a69aa013b27a50d2e6beb4e27 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Jul 2009 11:17:40 +1000 Subject: Cleanup more SQL autotest failures. --- tests/auto/qsqldatabase/tst_databases.h | 13 +++++++++++++ tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 7 ++++++- tests/auto/qsqlquery/tst_qsqlquery.cpp | 20 +++++++++----------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index bd51b97..8ee74df 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -249,12 +249,15 @@ public: // addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" ); // addDb( "QODBC", "DRIVER={MySQL ODBC 3.51 Driver};SERVER=mysql5-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); +// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=mysql4-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); // addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" ); // addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" ); // addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" ); // addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" ); // addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2003" ); // addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2008" ); +// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" ); +// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" ); } void open() @@ -438,6 +441,16 @@ public: return db.databaseName().contains( "Access Driver", Qt::CaseInsensitive ); } + static bool isPostgreSQL( QSqlDatabase db ) + { + return db.driverName().startsWith("QPSQL") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("PostgreSQL") ); + } + + static bool isMySQL( QSqlDatabase db ) + { + return db.driverName().startsWith("QMYSQL") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("MySQL") ); + } + // -1 on fail, else Oracle version static int getOraVersion( QSqlDatabase db ) { diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 21064c3..025e895 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -256,6 +256,8 @@ static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db) QString autoName = tst_Databases::autoFieldName(db); if (tst_Databases::isMSAccess(db)) qs.append(" (id int not null"); + else if (tst_Databases::isPostgreSQL(db)) + qs.append(" (id serial not null"); else qs.append(QString("(id integer not null %1 primary key").arg(autoName)); @@ -1350,6 +1352,8 @@ void tst_QSqlDatabase::transaction() } QVERIFY_SQL(q, exec("select * from " + qTableName("qtest") + " where id = 41")); + if(db.driverName().startsWith("QODBC") && dbName.contains("MySQL")) + QEXPECT_FAIL("", "Some odbc drivers don't actually roll back despite telling us they do, especially the mysql driver", Continue); QVERIFY(!q.next()); populateTestTables(db); @@ -1427,7 +1431,8 @@ void tst_QSqlDatabase::caseSensivity() bool cs = false; if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") - || db.driverName().startsWith("QTDS")) + || db.driverName().startsWith("QTDS") + || db.driverName().startsWith("QODBC")) cs = true; QSqlRecord rec = db.record(qTableName("qtest")); diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 30b85e8..5e782ca 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -188,7 +188,7 @@ private slots: void task_205701_data() { generic_data("QMYSQL"); } void task_205701(); - void task_233829_data() { generic_data(); } + void task_233829_data() { generic_data("QPSQL"); } void task_233829(); @@ -322,7 +322,10 @@ void tst_QSqlQuery::createTestTables( QSqlDatabase db ) // in the MySQL server startup script q.exec( "set table_type=innodb" ); - QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest" ) + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) ); + if(tst_Databases::isPostgreSQL(db)) + QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest" ) + " (id serial NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id)) WITH OIDS" ) ); + else + QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest" ) + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) ); if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QTDS" ) ) QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_null" ) + " (id int null, t_varchar varchar(20) null)" ) ); @@ -1874,7 +1877,7 @@ void tst_QSqlQuery::invalidQuery() QVERIFY( !q.next() ); QVERIFY( !q.isActive() ); - if ( !db.driverName().startsWith( "QOCI" ) && !db.driverName().startsWith( "QDB2" ) ) { + if ( !db.driverName().startsWith( "QOCI" ) && !db.driverName().startsWith( "QDB2" ) && !db.driverName().startsWith( "QODBC" ) ) { // oracle and db2 just prepares everything without complaining if ( db.driver()->hasFeature( QSqlDriver::PreparedQueries ) ) QVERIFY( !q.prepare( "blahfasel" ) ); @@ -2034,7 +2037,7 @@ void tst_QSqlQuery::oraArrayBind() q.bindValue( 0, list, QSql::In ); - QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsRows ) ); + QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsColumns ) ); QVERIFY_SQL( q, prepare( "BEGIN " "ora_array_test.get_table(?); " @@ -2046,7 +2049,7 @@ void tst_QSqlQuery::oraArrayBind() q.bindValue( 0, list, QSql::Out ); - QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsRows ) ); + QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsColumns ) ); QVariantList out_list = q.boundValue( 0 ).toList(); @@ -2593,7 +2596,7 @@ void tst_QSqlQuery::blobsPreparedQuery() if ( db.driverName().startsWith( "QPSQL" ) ) typeName = "BYTEA"; - else if ( db.driverName().startsWith( "QODBC" ) ) + else if ( db.driverName().startsWith( "QODBC" ) && tst_Databases::isSqlServer( db )) typeName = "IMAGE"; QVERIFY_SQL( q, exec( QString( "CREATE TABLE %1(id INTEGER, data %2)" ).arg( tableName ).arg( typeName ) ) ); @@ -2826,13 +2829,8 @@ void tst_QSqlQuery::task_233829() QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - if (!db.driverName().startsWith( "QPSQL" )) { - QSKIP( "This is a PostgreSQL specific test", SkipSingle ); - } - QSqlQuery q( db ); QString tableName = qTableName("task_233829"); - q.exec("DROP TABLE " + tableName); QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + " (dbl1 double precision,dbl2 double precision) without oids;")); QString queryString("INSERT INTO " + tableName +"(dbl1, dbl2) VALUES(?,?)"); -- cgit v0.12 From 291279cc24aa543454953b93b1db026caf0d7eb6 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Jul 2009 11:52:38 +1000 Subject: Make the table actually delete before the autotest --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 5e782ca..c94b693 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -296,7 +296,7 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName( "oraRowId" ); if ( db.driverName().startsWith("QPSQL") ) - tablenames <<"task_233829"; + tablenames << qTableName("task_233829"); if ( db.driverName().startsWith("QSQLITE") ) tablenames << qTableName( "record_sqlite" ); -- cgit v0.12 From 9e2b47da3b88c63acb1b3a8cb7566f2a1e0e18ff Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 14:47:21 +1000 Subject: make test behave like others --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index c94b693..0e30873 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -2831,7 +2831,7 @@ void tst_QSqlQuery::task_233829() QSqlQuery q( db ); QString tableName = qTableName("task_233829"); - QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + " (dbl1 double precision,dbl2 double precision) without oids;")); + QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + "(dbl1 double precision,dbl2 double precision) without oids;")); QString queryString("INSERT INTO " + tableName +"(dbl1, dbl2) VALUES(?,?)"); -- cgit v0.12 From e33704cdd6f935410dbbdbfedca6ddd648e70f4e Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Jul 2009 15:24:36 +1000 Subject: Tables aren't deleting properly. Send the correct name . --- .../qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index e2dace8..d934b35 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -167,10 +167,10 @@ void tst_QSqlRelationalTableModel::dropTestTables( QSqlDatabase db ) << qTableName( "reltest3" ) << qTableName( "reltest4" ) << qTableName( "reltest5" ) - << qTableName( "rel test6", db.driver() ) - << qTableName( "rel test7", db.driver() ) - << qTableName("CASETEST1", db.driver() ) - << qTableName("casetest1", db.driver() ); + << qTableName( "rel test6" ) + << qTableName( "rel test7" ) + << qTableName("CASETEST1" ) + << qTableName("casetest1" ); tst_Databases::safeDropTables( db, tableNames ); } -- cgit v0.12 From 4d2f47da2e4869b0419cf13856ddca8a3e34e88a Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Wed, 8 Jul 2009 10:11:03 +0200 Subject: The offset of cropRect should not depend on the position of the window The rect cropRect should be positioned with the offset to the top-level window, not the screen position. --- src/gui/kernel/qwidget_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 48e174b..ad16485 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3905,7 +3905,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) // we are too big, and must clip QPoint screenOffset(0, 0); // offset of the part being on screen const QWidget *parentWidget = q->parentWidget(); - while (parentWidget) { + while (parentWidget && !parentWidget->isWindow()) { screenOffset -= parentWidget->data->crect.topLeft(); parentWidget = parentWidget->parentWidget(); } -- cgit v0.12 From 7486389a0d742a7c9e70c6110692186f70dbf1e5 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 10:25:04 +0200 Subject: QMainWindow: made use of QPropertyAnimation for animations This required some refactoring as well. Now code is leaner and cleaner --- src/gui/widgets/qmainwindowlayout.cpp | 75 ++++++++++-------------- src/gui/widgets/qmainwindowlayout_p.h | 3 +- src/gui/widgets/qwidgetanimator.cpp | 107 +++++++--------------------------- src/gui/widgets/qwidgetanimator_p.h | 23 ++------ 4 files changed, 59 insertions(+), 149 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 1057f5f..a02dca3 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1550,37 +1550,10 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) return true; } -void QMainWindowLayout::allAnimationsFinished() -{ -#ifndef QT_NO_DOCKWIDGET - parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); - -#ifndef QT_NO_TABBAR - foreach (QTabBar *tab_bar, usedTabBars) - tab_bar->show(); -#endif // QT_NO_TABBAR -#endif // QT_NO_DOCKWIDGET - - updateGapIndicator(); -} - void QMainWindowLayout::animationFinished(QWidget *widget) { - - /* This signal is delivered from QWidgetAnimator over a qeued connection. The problem is that - the widget can be deleted. This is handled as follows: - - The animator only ever animates widgets that have been added to this layout. If a widget - is deleted during animation, the widget's destructor removes the widget form this layout. - This in turn aborts the animation (see takeAt()) and this signal will never be delivered. - - If the widget is deleted after the animation is finished but before this qeued signal - is delivered, the widget is no longer in the layout and we catch it here. The key is that - QMainWindowLayoutState::contains() never dereferences the pointer. */ - - if (!layoutState.contains(widget)) - return; - + //this function is called from within the Widget Animator whenever an animation is finished + //on a certain widget #ifndef QT_NO_TOOLBAR if (QToolBar *tb = qobject_cast(widget)) { QToolBarLayout *tbl = qobject_cast(tb->layout()); @@ -1593,32 +1566,44 @@ void QMainWindowLayout::animationFinished(QWidget *widget) } #endif - if (widget != pluggingWidget) - return; + if (widget == pluggingWidget) { #ifndef QT_NO_DOCKWIDGET - if (QDockWidget *dw = qobject_cast(widget)) - dw->d_func()->plug(currentGapRect); + if (QDockWidget *dw = qobject_cast(widget)) + dw->d_func()->plug(currentGapRect); #endif #ifndef QT_NO_TOOLBAR - if (QToolBar *tb = qobject_cast(widget)) - tb->d_func()->plug(currentGapRect); + if (QToolBar *tb = qobject_cast(widget)) + tb->d_func()->plug(currentGapRect); #endif - applyState(layoutState, false); + applyState(layoutState, false); #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR - if (qobject_cast(widget) != 0) { - // info() might return null if the widget is destroyed while - // animating but before the animationFinished signal is received. - if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget)) - info->setCurrentTab(widget); - } + if (qobject_cast(widget) != 0) { + // info() might return null if the widget is destroyed while + // animating but before the animationFinished signal is received. + if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget)) + info->setCurrentTab(widget); + } #endif #endif - savedState.clear(); - currentGapPos.clear(); - pluggingWidget = 0; + savedState.clear(); + currentGapPos.clear(); + pluggingWidget = 0; + } + + if (!widgetAnimator.animating()) { + //all animations are finished +#ifndef QT_NO_DOCKWIDGET + parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); +#ifndef QT_NO_TABBAR + foreach (QTabBar *tab_bar, usedTabBars) + tab_bar->show(); +#endif // QT_NO_TABBAR +#endif // QT_NO_DOCKWIDGET + } + updateGapIndicator(); } diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 759461b..a7f70b4 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -297,9 +297,8 @@ public: void restore(bool keepSavedState = false); void updateHIToolBarStatus(); void animationFinished(QWidget *widget); - void allAnimationsFinished(); -private slots: +private Q_SLOTS: #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR void tabChanged(); diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index 56b3f43..d820b59 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include #include #include @@ -46,47 +47,25 @@ QT_BEGIN_NAMESPACE -static const int g_animation_steps = 12; -static const int g_animation_interval = 16; - -// 1000 * (x/(1 + x*x) + 0.5) on interval [-1, 1] -static const int g_animate_function[] = -{ - 0, 1, 5, 12, 23, 38, 58, 84, 116, 155, 199, 251, 307, 368, - 433, 500, 566, 631, 692, 748, 799, 844, 883, 915, 941, 961, - 976, 987, 994, 998, 1000 -}; -static const int g_animate_function_points = sizeof(g_animate_function)/sizeof(int); - -static inline int animateHelper(int start, int stop, int step, int steps) -{ - if (start == stop) - return start; - if (step == 0) - return start; - if (step == steps) - return stop; - - int x = g_animate_function_points*step/(steps + 1); - return start + g_animate_function[x]*(stop - start)/1000; -} - QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout(layout) { } -QWidgetAnimator::~QWidgetAnimator() +void QWidgetAnimator::abort(QWidget *w) { + AnimationMap::iterator it = m_animation_map.find(w); + if (it == m_animation_map.end()) + return; + QPropertyAnimation *anim = *it; + m_animation_map.erase(it); + anim->stop(); + m_mainWindowLayout->animationFinished(w); } -void QWidgetAnimator::abort(QWidget *w) +void QWidgetAnimator::animationFinished() { - if (m_animation_map.remove(w) == 0) - return; - if (m_animation_map.isEmpty()) { - m_timer.stop(); - m_mainWindowLayout->allAnimationsFinished(); - } + QPropertyAnimation *anim = qobject_cast(sender()); + abort(static_cast(anim->targetObject())); } void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate) @@ -101,16 +80,17 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo animate = false; AnimationMap::const_iterator it = m_animation_map.constFind(widget); - if (it != m_animation_map.constEnd() && (*it).r2 == final_geometry) + if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry) return; if (animate) { - AnimationItem item(widget, r, final_geometry); - m_animation_map[widget] = item; - if (!m_timer.isActive()) { - m_timer.start(g_animation_interval, this); - m_time.start(); - } + QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry"); + anim->setDuration(200); + anim->setEasingCurve(QEasingCurve::InOutQuad); + anim->setEndValue(final_geometry); + m_animation_map[widget] = anim; + connect(anim, SIGNAL(finished()), SLOT(animationFinished())); + anim->start(QPropertyAnimation::DeleteWhenStopped); } else { if (!final_geometry.isValid() && !widget->isWindow()) { // Make the wigdet go away by sending it to negative space @@ -118,58 +98,15 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo final_geometry = QRect(-500 - s.width(), -500 - s.height(), s.width(), s.height()); } widget->setGeometry(final_geometry); - - if (m_animation_map.remove(widget)) { - m_mainWindowLayout->animationFinished(widget); - if (m_animation_map.isEmpty()) { - m_timer.stop(); - m_mainWindowLayout->allAnimationsFinished(); - } - } - } -} - -void QWidgetAnimator::timerEvent(QTimerEvent *) -{ - int steps = (1 + m_time.restart())/g_animation_interval; - AnimationMap::iterator it = m_animation_map.begin(); - while (it != m_animation_map.end()) { - AnimationItem &item = *it; - - item.step = qMin(item.step + steps, g_animation_steps); - - int x = animateHelper(item.r1.left(), item.r2.left(), - item.step, g_animation_steps); - int y = animateHelper(item.r1.top(), item.r2.top(), - item.step, g_animation_steps); - int w = animateHelper(item.r1.width(), item.r2.width(), - item.step, g_animation_steps); - int h = animateHelper(item.r1.height(), item.r2.height(), - item.step, g_animation_steps); - - item.widget->setGeometry(x, y, w, h); - - if (item.step == g_animation_steps) { - QWidget *widget = item.widget; - it = m_animation_map.erase(it); - m_mainWindowLayout->animationFinished(widget); - } else { - ++it; - } - } - - if (m_animation_map.isEmpty()) { - m_timer.stop(); - m_mainWindowLayout->allAnimationsFinished(); } } bool QWidgetAnimator::animating() const { - return m_timer.isActive(); + return !m_animation_map.isEmpty(); } -bool QWidgetAnimator::animating(QWidget *widget) +bool QWidgetAnimator::animating(QWidget *widget) const { return m_animation_map.contains(widget); } diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index 0c68e00..edd8e7c 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -56,41 +56,30 @@ #include #include #include -#include -#include QT_BEGIN_NAMESPACE class QWidget; class QMainWindowLayout; +class QPropertyAnimation; class QWidgetAnimator : public QObject { + Q_OBJECT public: QWidgetAnimator(QMainWindowLayout *layout); - ~QWidgetAnimator(); void animate(QWidget *widget, const QRect &final_geometry, bool animate); bool animating() const; - bool animating(QWidget *widget); + bool animating(QWidget *widget) const; void abort(QWidget *widget); -protected: - void timerEvent(QTimerEvent *e); +private Q_SLOTS: + void animationFinished(); private: - struct AnimationItem { - AnimationItem(QWidget *_widget = 0, const QRect &_r1 = QRect(), - const QRect &_r2 = QRect()) - : widget(_widget), r1(_r1), r2(_r2), step(0) {} - QWidget *widget; - QRect r1, r2; - int step; - }; - typedef QMap AnimationMap; + typedef QMap AnimationMap; AnimationMap m_animation_map; - QBasicTimer m_timer; - QTime m_time; QMainWindowLayout *m_mainWindowLayout; }; -- cgit v0.12 From ed4c85c33683ce541590639f19adcef8dcd001a8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 8 Jul 2009 12:09:08 +0200 Subject: don't drop all location tags after the first file without any Task-number: 256647 --- tools/linguist/lupdate/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index c28bf8b..52a57fb 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -178,9 +178,10 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil if (options & Verbose) printOut(QObject::tr("Updating '%1'...\n").arg(fn)); + UpdateOptions theseOptions = options; if (tor.locationsType() == Translator::NoLocations) // Could be set from file - options |= NoLocations; - Translator out = merge(tor, fetchedTor, options, err); + theseOptions |= NoLocations; + Translator out = merge(tor, fetchedTor, theseOptions, err); if (!codecForTr.isEmpty()) out.setCodecName(codecForTr); -- cgit v0.12 From 191c621cbaa318e60111ae88c7b1e57286b1368b Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 13:18:24 +0200 Subject: QMainWindow: fixed a crash in some cases when deleting the widget This happened because the rubberband used as a gapindicator was not allocated on the heap and might have been deleted by the QMainWindow destructor. Task-number: 257626 --- src/gui/widgets/qmainwindowlayout.cpp | 16 +++++----------- src/gui/widgets/qmainwindowlayout_p.h | 3 +-- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index a02dca3..ad608d3 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1639,7 +1639,7 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) , widgetAnimator(this) , pluggingWidget(0) #ifndef QT_NO_RUBBERBAND - , gapIndicator(QRubberBand::Rectangle, mainwindow) + , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) #endif //QT_NO_RUBBERBAND { #ifndef QT_NO_DOCKWIDGET @@ -1655,8 +1655,8 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) #ifndef QT_NO_RUBBERBAND // For accessibility to identify this special widget. - gapIndicator.setObjectName(QLatin1String("qt_rubberband")); - gapIndicator.hide(); + gapIndicator->setObjectName(QLatin1String("qt_rubberband")); + gapIndicator->hide(); #endif pluggingWidget = 0; @@ -1762,14 +1762,8 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) void QMainWindowLayout::updateGapIndicator() { #ifndef QT_NO_RUBBERBAND - if (widgetAnimator.animating() || currentGapPos.isEmpty()) { - gapIndicator.hide(); - } else { - if (gapIndicator.geometry() != currentGapRect) - gapIndicator.setGeometry(currentGapRect); - if (!gapIndicator.isVisible()) - gapIndicator.show(); - } + gapIndicator->setVisible(!widgetAnimator.animating() && !currentGapPos.isEmpty()); + gapIndicator->setGeometry(currentGapRect); #endif } diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index a7f70b4..45f62cd 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -59,7 +59,6 @@ #include "QtGui/qlayout.h" #include "QtGui/qtabbar.h" -#include "QtGui/qrubberband.h" #include "QtCore/qvector.h" #include "QtCore/qset.h" #include "QtCore/qbasictimer.h" @@ -284,7 +283,7 @@ public: QRect currentGapRect; QWidget *pluggingWidget; #ifndef QT_NO_RUBBERBAND - QRubberBand gapIndicator; + QRubberBand *gapIndicator; #endif QList hover(QLayoutItem *widgetItem, const QPoint &mousePos); -- cgit v0.12 From 12dc33d0e7191dbabb03db989b0f56372de731e3 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 14:19:00 +0200 Subject: QMainWindow: compile fix when defining QT_NO_DOCKWIDGET --- src/gui/widgets/qmainwindowlayout.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index ad608d3..8fb7c4f 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -237,7 +237,7 @@ void QMainWindowLayoutState::apply(bool animated) if (centralWidgetItem != 0) { QMainWindowLayout *layout = qobject_cast(mainWindow->layout()); Q_ASSERT(layout != 0); - layout->widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect, animated); + layout->widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animated); } #endif } @@ -946,7 +946,6 @@ void QMainWindowLayout::toggleToolBarsVisible() r = layoutState.toolBarAreaLayout.rectHint(r); r.moveTo(topLeft); parentWidget()->setGeometry(r); -// widgetAnimator->animate(parentWidget(), r, true); } else{ update(); } -- cgit v0.12 From 19a824cfe36458732f12e6374848df37cd92eed8 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 15:12:08 +0200 Subject: Animations: fix compilation with QT_NO_ANIMATION --- src/corelib/animation/qabstractanimation_p.h | 7 ++++++- src/corelib/animation/qanimationgroup_p.h | 4 ++++ src/corelib/animation/qparallelanimationgroup_p.h | 4 ++++ src/corelib/animation/qpropertyanimation_p.h | 6 +++++- .../animation/qsequentialanimationgroup_p.h | 3 +++ src/corelib/animation/qvariantanimation_p.h | 4 ++++ src/gui/itemviews/qcolumnview.cpp | 12 +++++++++++- src/gui/itemviews/qcolumnview_p.h | 2 ++ src/gui/widgets/qwidgetanimator.cpp | 22 +++++++++++++++++++++- src/gui/widgets/qwidgetanimator_p.h | 3 +++ 10 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 00def55..0d8402e 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -58,6 +58,8 @@ #include #include +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QAnimationGroup; @@ -147,4 +149,7 @@ private: }; QT_END_NAMESPACE -#endif + +#endif //QT_NO_ANIMATION + +#endif //QABSTRACTANIMATION_P_H diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h index 8e668f0..01252c5 100644 --- a/src/corelib/animation/qanimationgroup_p.h +++ b/src/corelib/animation/qanimationgroup_p.h @@ -59,6 +59,8 @@ #include "private/qabstractanimation_p.h" +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QAnimationGroupPrivate : public QAbstractAnimationPrivate @@ -76,4 +78,6 @@ public: QT_END_NAMESPACE +#endif //QT_NO_ANIMATION + #endif //QANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qparallelanimationgroup_p.h b/src/corelib/animation/qparallelanimationgroup_p.h index 201eb16..949a9b2 100644 --- a/src/corelib/animation/qparallelanimationgroup_p.h +++ b/src/corelib/animation/qparallelanimationgroup_p.h @@ -57,6 +57,8 @@ #include "private/qanimationgroup_p.h" #include +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QParallelAnimationGroupPrivate : public QAnimationGroupPrivate @@ -82,4 +84,6 @@ public: QT_END_NAMESPACE +#endif //QT_NO_ANIMATION + #endif //QPARALLELANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h index 68b2519..a2ae5ec 100644 --- a/src/corelib/animation/qpropertyanimation_p.h +++ b/src/corelib/animation/qpropertyanimation_p.h @@ -58,6 +58,8 @@ #include "private/qvariantanimation_p.h" +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QPropertyAnimationPrivate : public QVariantAnimationPrivate @@ -86,4 +88,6 @@ public: QT_END_NAMESPACE -#endif +#endif //QT_NO_ANIMATION + +#endif //QPROPERTYANIMATION_P_H diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h index 555b696..8db79a0 100644 --- a/src/corelib/animation/qsequentialanimationgroup_p.h +++ b/src/corelib/animation/qsequentialanimationgroup_p.h @@ -56,6 +56,7 @@ #include "qsequentialanimationgroup.h" #include "private/qanimationgroup_p.h" +#ifndef QT_NO_ANIMATION QT_BEGIN_NAMESPACE @@ -108,4 +109,6 @@ public: QT_END_NAMESPACE +#endif //QT_NO_ANIMATION + #endif //QSEQUENTIALANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h index b848e12..69e23dc 100644 --- a/src/corelib/animation/qvariantanimation_p.h +++ b/src/corelib/animation/qvariantanimation_p.h @@ -60,6 +60,8 @@ #include "private/qabstractanimation_p.h" +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QVariantAnimationPrivate : public QAbstractAnimationPrivate @@ -120,4 +122,6 @@ template inline QVariant _q_interpolateVariant(const T &from, const QT_END_NAMESPACE +#endif //QT_NO_ANIMATION + #endif //QANIMATION_P_H diff --git a/src/gui/itemviews/qcolumnview.cpp b/src/gui/itemviews/qcolumnview.cpp index fc89967..c544394 100644 --- a/src/gui/itemviews/qcolumnview.cpp +++ b/src/gui/itemviews/qcolumnview.cpp @@ -107,10 +107,13 @@ void QColumnViewPrivate::initialize() { Q_Q(QColumnView); q->setTextElideMode(Qt::ElideMiddle); +#ifndef QT_NO_ANIMATION QObject::connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); currentAnimation.setDuration(ANIMATION_DURATION_MSEC); currentAnimation.setTargetObject(hbar); + currentAnimation.setPropertyName("value"); currentAnimation.setEasingCurve(QEasingCurve::InOutQuad); +#endif //QT_NO_ANIMATION delete itemDelegate; q->setItemDelegate(new QColumnViewDelegate(q)); } @@ -260,10 +263,12 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) if (!index.isValid() || d->columns.isEmpty()) return; +#ifndef QT_NO_ANIMATION if (d->currentAnimation.state() == QPropertyAnimation::Running) return; d->currentAnimation.stop(); +#endif //QT_NO_ANIMATION // Fill up what is needed to get to index d->closeColumns(index, true); @@ -326,8 +331,12 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) } } +#ifndef QT_NO_ANIMATION d->currentAnimation.setEndValue(newScrollbarValue); d->currentAnimation.start(); +#else + horizontalScrollBar()->setValue(newScrollbarValue); +#endif //QT_NO_ANIMATION } /*! @@ -396,8 +405,10 @@ void QColumnView::resizeEvent(QResizeEvent *event) void QColumnViewPrivate::updateScrollbars() { Q_Q(QColumnView); +#ifndef QT_NO_ANIMATION if (currentAnimation.state() == QPropertyAnimation::Running) return; +#endif //QT_NO_ANIMATION // find the total horizontal length of the laid out columns int horizontalLength = 0; @@ -1031,7 +1042,6 @@ QColumnViewPrivate::QColumnViewPrivate() : QAbstractItemViewPrivate() ,showResizeGrips(true) ,offset(0) -,currentAnimation(0, "value") // will set the target later ,previewWidget(0) ,previewColumn(0) { diff --git a/src/gui/itemviews/qcolumnview_p.h b/src/gui/itemviews/qcolumnview_p.h index 1a8be70..3f99220 100644 --- a/src/gui/itemviews/qcolumnview_p.h +++ b/src/gui/itemviews/qcolumnview_p.h @@ -160,7 +160,9 @@ public: QVector columnSizes; // used during init and corner moving bool showResizeGrips; int offset; +#ifndef QT_NO_ANIMATION QPropertyAnimation currentAnimation; +#endif QWidget *previewWidget; QAbstractItemView *previewColumn; }; diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index d820b59..7a3a464 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -53,6 +53,7 @@ QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout void QWidgetAnimator::abort(QWidget *w) { +#ifndef QT_NO_ANIMATION AnimationMap::iterator it = m_animation_map.find(w); if (it == m_animation_map.end()) return; @@ -60,13 +61,18 @@ void QWidgetAnimator::abort(QWidget *w) m_animation_map.erase(it); anim->stop(); m_mainWindowLayout->animationFinished(w); +#else + Q_UNUSED(w); //there is no animation to abort +#endif //QT_NO_ANIMATION } +#ifndef QT_NO_ANIMATION void QWidgetAnimator::animationFinished() { QPropertyAnimation *anim = qobject_cast(sender()); abort(static_cast(anim->targetObject())); } +#endif //QT_NO_ANIMATION void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate) { @@ -76,6 +82,9 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo if (r.right() < 0 || r.bottom() < 0) r = QRect(); +#ifdef QT_NO_ANIMATION + Q_UNUSED(animate); +#else if (r.isNull() || final_geometry.isNull() || r == final_geometry) animate = false; @@ -91,7 +100,9 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo m_animation_map[widget] = anim; connect(anim, SIGNAL(finished()), SLOT(animationFinished())); anim->start(QPropertyAnimation::DeleteWhenStopped); - } else { + } else +#endif //QT_NO_ANIMATION + { if (!final_geometry.isValid() && !widget->isWindow()) { // Make the wigdet go away by sending it to negative space QSize s = widget->size(); @@ -103,12 +114,21 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo bool QWidgetAnimator::animating() const { +#ifdef QT_NO_ANIMATION + return false; +#else return !m_animation_map.isEmpty(); +#endif //QT_NO_ANIMATION } bool QWidgetAnimator::animating(QWidget *widget) const { +#ifdef QT_NO_ANIMATION + Q_UNUSED(widget); + return false; +#else return m_animation_map.contains(widget); +#endif //QT_NO_ANIMATION } QT_END_NAMESPACE diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index edd8e7c..4047395 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -74,12 +74,15 @@ public: void abort(QWidget *widget); +#ifndef QT_NO_ANIMATION private Q_SLOTS: void animationFinished(); private: typedef QMap AnimationMap; AnimationMap m_animation_map; +#endif +private: QMainWindowLayout *m_mainWindowLayout; }; -- cgit v0.12 From a92a6ede9c6a13833d1a6c83b863a5e492b2ba9e Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 8 Jul 2009 13:40:29 +0200 Subject: Cocoa: Plain text from clipboard use '\r' as newline instead of '\n' The 'public.utf16-plain-text' clipboard type maps newlines to '\r' instead of '\n'. The NSStringPboardType from NSPasteboard does this correctly, so first try to get data through this type. Task-number: 257661 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qclipboard_mac.cpp | 14 ++++++++++++-- src/gui/kernel/qt_cocoa_helpers_mac.mm | 12 ++++++++++++ src/gui/kernel/qt_cocoa_helpers_mac_p.h | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/gui/kernel/qclipboard_mac.cpp index b7b57b8..45050b2 100644 --- a/src/gui/kernel/qclipboard_mac.cpp +++ b/src/gui/kernel/qclipboard_mac.cpp @@ -50,6 +50,7 @@ #include "qurl.h" #include #include +#include "qt_cocoa_helpers_mac_p.h" QT_BEGIN_NAMESPACE @@ -525,8 +526,17 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const QString c_flavor = c->flavorFor(format); if(!c_flavor.isEmpty()) { // Handle text/plain a little differently. Try handling Unicode first. - if((c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") || c_flavor == QLatin1String("public.utf8-plain-text")) && - hasFlavor(QLatin1String("public.utf16-plain-text"))) + bool checkForUtf16 = (c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") + || c_flavor == QLatin1String("public.utf8-plain-text")); + if (checkForUtf16 || c_flavor == QLatin1String("public.utf16-plain-text")) { + // Try to get the NSStringPboardType from NSPasteboard, newlines are mapped + // correctly (as '\n') in this data. The 'public.utf16-plain-text' type + // usually maps newlines to '\r' instead. + QString str = qt_mac_get_pasteboardString(); + if (!str.isEmpty()) + return str; + } + if (checkForUtf16 && hasFlavor(QLatin1String("public.utf16-plain-text"))) c_flavor = QLatin1String("public.utf16-plain-text"); QVariant ret; diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 073a00e..13b0e50 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -1131,4 +1131,16 @@ CGFloat qt_mac_get_scalefactor() #endif } +QString qt_mac_get_pasteboardString() +{ + QMacCocoaAutoReleasePool pool; + NSPasteboard *pb = [NSPasteboard generalPasteboard]; + NSString *text = [pb stringForType:NSStringPboardType]; + if (text) { + return qt_mac_NSStringToQString(text); + } else { + return QString(); + } +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 7b975f5..3881ccd 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -162,6 +162,7 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list); void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow); CGFloat qt_mac_get_scalefactor(); +QString qt_mac_get_pasteboardString(); #ifdef __OBJC__ inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist) -- cgit v0.12 From 94c44ba8d6d1220d00a844d95f9dfb15165ea983 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 14:26:57 +0200 Subject: Phonon: Fixed a possible race condition Task-number: 257495 --- src/3rdparty/phonon/ds9/mediaobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index 1d0b69d..26ba8eb 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -207,10 +207,10 @@ namespace Phonon HRESULT hr = S_OK; + QMutexLocker locker(&m_mutex); m_currentRender = w.graph; m_currentRenderId = w.id; if (w.task == ReplaceGraph) { - QMutexLocker locker(&m_mutex); HANDLE h; int index = -1; -- cgit v0.12 From e21e83b9b81801257337902102ea1b267227de4a Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 2 Jul 2009 14:53:13 +0200 Subject: added auto test tst_QLocalSocket::readBufferOverflow This test handles the case when one limits the size of the socket's read buffer and more data than the buffer size is available. Reviewed-by: ossi --- tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index 4f1eb1d..0f636a4 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -80,6 +80,8 @@ private slots: void sendData_data(); void sendData(); + void readBufferOverflow(); + void fullPath(); void hitMaximumConnections_data(); @@ -531,6 +533,37 @@ void tst_QLocalSocket::sendData() QCOMPARE(spy.count(), (canListen ? 1 : 0)); } +void tst_QLocalSocket::readBufferOverflow() +{ + const int readBufferSize = 128; + const int dataBufferSize = readBufferSize * 2; + const QString serverName = QLatin1String("myPreciousTestServer"); + LocalServer server; + server.listen(serverName); + QVERIFY(server.isListening()); + + LocalSocket client; + client.setReadBufferSize(readBufferSize); + client.connectToServer(serverName); + + bool timedOut = true; + QVERIFY(server.waitForNewConnection(3000, &timedOut)); + QVERIFY(!timedOut); + + QCOMPARE(client.state(), QLocalSocket::ConnectedState); + QVERIFY(server.hasPendingConnections()); + + QLocalSocket* serverSocket = server.nextPendingConnection(); + char* buffer = (char*)qMalloc(dataBufferSize); + memset(buffer, 0, dataBufferSize); + serverSocket->write(buffer, dataBufferSize); + serverSocket->flush(); + qFree(buffer); + + QVERIFY(client.waitForReadyRead()); + QCOMPARE(client.readAll().size(), dataBufferSize); +} + // QLocalSocket/Server can take a name or path, check that it works as expected void tst_QLocalSocket::fullPath() { -- cgit v0.12 From 16d23fdced8577e9ad015fd9283373761b8464ef Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 1 Jul 2009 11:06:13 +0200 Subject: fast Windows version of QLocalSocket This commit removes the 100 ms polling timer from QLocalSocket and replaces it with proper overlapped IO handling. Reviewed-by: ossi --- src/network/socket/qlocalsocket.h | 1 + src/network/socket/qlocalsocket_p.h | 16 ++- src/network/socket/qlocalsocket_win.cpp | 241 +++++++++++++++++--------------- 3 files changed, 138 insertions(+), 120 deletions(-) diff --git a/src/network/socket/qlocalsocket.h b/src/network/socket/qlocalsocket.h index 417671a..4bff62e 100644 --- a/src/network/socket/qlocalsocket.h +++ b/src/network/socket/qlocalsocket.h @@ -134,6 +134,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_notified()) Q_PRIVATE_SLOT(d_func(), void _q_canWrite()) Q_PRIVATE_SLOT(d_func(), void _q_pipeClosed()) + Q_PRIVATE_SLOT(d_func(), void _q_emitReadyRead()) #else Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QAbstractSocket::SocketState)) Q_PRIVATE_SLOT(d_func(), void _q_error(QAbstractSocket::SocketError)) diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index bdbba42..2dae7d9 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -65,6 +65,7 @@ #elif defined(Q_OS_WIN) # include "private/qwindowspipewriter_p.h" # include "private/qringbuffer_p.h" +# include #else # include "private/qnativesocketengine_p.h" # include @@ -135,18 +136,23 @@ public: void _q_notified(); void _q_canWrite(); void _q_pipeClosed(); - qint64 readData(char *data, qint64 maxSize); - qint64 bytesAvailable(); - bool readFromSocket(); + void _q_emitReadyRead(); + DWORD bytesAvailable(); + void startAsyncRead(); + void completeAsyncRead(); + void checkReadyRead(); HANDLE handle; OVERLAPPED overlapped; QWindowsPipeWriter *pipeWriter; qint64 readBufferMaxSize; QRingBuffer readBuffer; - QTimer dataNotifier; + int actualReadBufferSize; + QWinEventNotifier *dataReadNotifier; QLocalSocket::LocalSocketError error; - bool readyReadEmitted; + bool readSequenceStarted; + bool pendingReadyRead; bool pipeClosed; + static const qint64 initialReadBufferSize = 4096; #else QLocalUnixSocket unixSocket; QString generateErrorString(QLocalSocket::LocalSocketError, const QString &function) const; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index b1b69fc..1a971f0 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -48,13 +48,13 @@ QT_BEGIN_NAMESPACE -#define NOTIFYTIMEOUT 100 - void QLocalSocketPrivate::init() { Q_Q(QLocalSocket); - QObject::connect(&dataNotifier, SIGNAL(timeout()), q, SLOT(_q_notified())); + memset(&overlapped, 0, sizeof(overlapped)); overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + dataReadNotifier = new QWinEventNotifier(overlapped.hEvent, q); + q->connect(dataReadNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_notified())); } void QLocalSocketPrivate::setErrorString(const QString &function) @@ -101,8 +101,10 @@ QLocalSocketPrivate::QLocalSocketPrivate() : QIODevicePrivate(), handle(INVALID_HANDLE_VALUE), pipeWriter(0), readBufferMaxSize(0), + actualReadBufferSize(0), error(QLocalSocket::UnknownSocketError), - readyReadEmitted(false), + readSequenceStarted(false), + pendingReadyRead(false), pipeClosed(false), state(QLocalSocket::UnconnectedState) { @@ -176,82 +178,103 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) qint64 QLocalSocket::readData(char *data, qint64 maxSize) { Q_D(QLocalSocket); - if (d->readBuffer.isEmpty()) { - if (!d->readFromSocket()) { - if (d->pipeClosed) - return -1; - return 0; - } - } - - if (!d->dataNotifier.isActive() && d->threadData->eventDispatcher) - d->dataNotifier.start(NOTIFYTIMEOUT); - - if (d->readBuffer.isEmpty()) - return qint64(0); - // If readFromSocket() read data, copy it to its destination. - if (maxSize == 1) { + qint64 readSoFar; + // If startAsyncRead() read data, copy it to its destination. + if (maxSize == 1 && d->actualReadBufferSize > 0) { *data = d->readBuffer.getChar(); - return 1; + d->actualReadBufferSize--; + readSoFar = 1; + } else { + qint64 bytesToRead = qMin(qint64(d->actualReadBufferSize), maxSize); + readSoFar = 0; + while (readSoFar < bytesToRead) { + const char *ptr = d->readBuffer.readPointer(); + int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, + qint64(d->readBuffer.nextDataBlockSize())); + memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); + readSoFar += bytesToReadFromThisBlock; + d->readBuffer.free(bytesToReadFromThisBlock); + d->actualReadBufferSize -= bytesToReadFromThisBlock; + } } - qint64 bytesToRead = qMin(qint64(d->readBuffer.size()), maxSize); - qint64 readSoFar = 0; - while (readSoFar < bytesToRead) { - const char *ptr = d->readBuffer.readPointer(); - int bytesToReadFromThisBlock = qMin(int(bytesToRead - readSoFar), - d->readBuffer.nextDataBlockSize()); - memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); - readSoFar += bytesToReadFromThisBlock; - d->readBuffer.free(bytesToReadFromThisBlock); - } + if (!d->readSequenceStarted) + d->startAsyncRead(); + d->checkReadyRead(); + return readSoFar; } /*! \internal - read from the socket + Schedules or cancels a readyRead() emission depending on actual data availability */ -qint64 QLocalSocketPrivate::readData(char *data, qint64 maxSize) +void QLocalSocketPrivate::checkReadyRead() { - DWORD bytesRead = 0; - overlapped.Offset = 0; - overlapped.OffsetHigh = 0; - bool success = ReadFile(handle, data, maxSize, &bytesRead, &overlapped); - if (!success && GetLastError() == ERROR_IO_PENDING) - if (GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) - success = true; - if (!success) { - setErrorString(QLatin1String("QLocalSocket::readData")); - return 0; + if (actualReadBufferSize > 0) { + if (!pendingReadyRead) { + Q_Q(QLocalSocket); + QTimer::singleShot(0, q, SLOT(_q_emitReadyRead())); + pendingReadyRead = true; + } + } else { + pendingReadyRead = false; } - return bytesRead; } /*! \internal Reads data from the socket into the readbuffer */ -bool QLocalSocketPrivate::readFromSocket() +void QLocalSocketPrivate::startAsyncRead() { - qint64 bytesToRead = bytesAvailable(); - if (bytesToRead == 0) - return false; + do { + DWORD bytesToRead = bytesAvailable(); + if (bytesToRead == 0) { + // There are no bytes in the pipe but we need to + // start the overlapped read with some buffer size. + bytesToRead = initialReadBufferSize; + } - if (readBufferMaxSize && bytesToRead - > (readBufferMaxSize - readBuffer.size())) - bytesToRead = readBufferMaxSize - readBuffer.size(); + if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) { + bytesToRead = readBufferMaxSize - readBuffer.size(); + if (bytesToRead == 0) { + // Buffer is full. User must read data from the buffer + // before we can read more from the pipe. + return; + } + } - char *ptr = readBuffer.reserve(bytesToRead); - qint64 readBytes = readData(ptr, bytesToRead); - if (readBytes == 0) { - readBuffer.chop(bytesToRead); - return false; + char *ptr = readBuffer.reserve(bytesToRead); + + readSequenceStarted = true; + if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) { + completeAsyncRead(); + } else if (GetLastError() != ERROR_IO_PENDING) { + setErrorString(QLatin1String("QLocalSocketPrivate::startAsyncRead")); + return; + } + } while (!readSequenceStarted); +} + +/*! + \internal + Sets the correct size of the read buffer after a read operation. + */ +void QLocalSocketPrivate::completeAsyncRead() +{ + ResetEvent(overlapped.hEvent); + readSequenceStarted = false; + + DWORD bytesRead; + if (!GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) { + setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); + return; } - readyReadEmitted = false; - readBuffer.chop(int(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes))); - return true; + + actualReadBufferSize += bytesRead; + readBuffer.truncate(actualReadBufferSize); } qint64 QLocalSocket::writeData(const char *data, qint64 maxSize) @@ -273,7 +296,7 @@ void QLocalSocket::abort() /*! The number of bytes available from the pipe */ -qint64 QLocalSocketPrivate::bytesAvailable() +DWORD QLocalSocketPrivate::bytesAvailable() { Q_Q(QLocalSocket); if (q->state() != QLocalSocket::ConnectedState) @@ -300,7 +323,7 @@ qint64 QLocalSocket::bytesAvailable() const { Q_D(const QLocalSocket); qint64 available = QIODevice::bytesAvailable(); - available += (qint64) d->readBuffer.size(); + available += (qint64) d->actualReadBufferSize; return available; } @@ -327,7 +350,6 @@ void QLocalSocket::close() QIODevice::close(); d->state = ClosingState; emit stateChanged(d->state); - d->readyReadEmitted = false; emit readChannelFinished(); d->serverName = QString(); d->fullServerName = QString(); @@ -336,10 +358,13 @@ void QLocalSocket::close() disconnectFromServer(); return; } + d->readSequenceStarted = false; + d->pendingReadyRead = false; d->pipeClosed = false; DisconnectNamedPipe(d->handle); CloseHandle(d->handle); d->handle = INVALID_HANDLE_VALUE; + ResetEvent(d->overlapped.hEvent); d->state = UnconnectedState; emit stateChanged(d->state); emit disconnected(); @@ -347,7 +372,6 @@ void QLocalSocket::close() delete d->pipeWriter; d->pipeWriter = 0; } - d->dataNotifier.stop(); } bool QLocalSocket::flush() @@ -381,12 +405,15 @@ bool QLocalSocket::setSocketDescriptor(quintptr socketDescriptor, { Q_D(QLocalSocket); d->readBuffer.clear(); + d->actualReadBufferSize = 0; QIODevice::open(openMode); d->handle = (int*)socketDescriptor; d->state = socketState; emit stateChanged(d->state); - if (d->threadData->eventDispatcher) - d->dataNotifier.start(NOTIFYTIMEOUT); + if (d->state == ConnectedState) { + d->startAsyncRead(); + d->checkReadyRead(); + } return true; } @@ -400,20 +427,18 @@ void QLocalSocketPrivate::_q_canWrite() void QLocalSocketPrivate::_q_notified() { Q_Q(QLocalSocket); - if (0 != bytesAvailable()) { - if (readBufferMaxSize == 0 || readBuffer.size() < readBufferMaxSize) { - if (!readFromSocket()) { - return; - } - // wait until buffer is cleared before starting again - if (readBufferMaxSize && readBuffer.size() == readBufferMaxSize) { - dataNotifier.stop(); - } - } - if (!readyReadEmitted) { - readyReadEmitted = true; - q->emit readyRead(); - } + completeAsyncRead(); + startAsyncRead(); + pendingReadyRead = false; + emit q->readyRead(); +} + +void QLocalSocketPrivate::_q_emitReadyRead() +{ + if (pendingReadyRead) { + Q_Q(QLocalSocket); + pendingReadyRead = false; + emit q->readyRead(); } } @@ -448,9 +473,9 @@ bool QLocalSocket::waitForDisconnected(int msecs) return false; QIncrementalSleepTimer timer(msecs); forever { - d->_q_notified(); - if (d->pipeClosed) - close(); + d->bytesAvailable(); // to check if PeekNamedPipe fails + if (d->pipeClosed) + close(); if (state() == UnconnectedState) return true; Sleep(timer.nextSleepTime()); @@ -470,22 +495,24 @@ bool QLocalSocket::isValid() const bool QLocalSocket::waitForReadyRead(int msecs) { Q_D(QLocalSocket); - QIncrementalSleepTimer timer(msecs); - forever { - d->_q_notified(); - if (bytesAvailable() > 0) { - if (!d->readyReadEmitted) { - d->readyReadEmitted = true; - emit readyRead(); - } - return true; - } - Sleep(timer.nextSleepTime()); - if (timer.hasTimedOut()) - break; + if (bytesAvailable() > 0) + return true; + + if (d->state != QLocalSocket::ConnectedState) + return false; + + Q_ASSERT(d->readSequenceStarted); + DWORD result = WaitForSingleObject(d->overlapped.hEvent, msecs == -1 ? INFINITE : msecs); + switch (result) { + case WAIT_OBJECT_0: + d->_q_notified(); + return true; + case WAIT_TIMEOUT: + return false; } + qWarning("QLocalSocket::waitForReadyRead WaitForSingleObject failed with error code %d.", GetLastError()); return false; } @@ -495,27 +522,11 @@ bool QLocalSocket::waitForBytesWritten(int msecs) if (!d->pipeWriter) return false; - QIncrementalSleepTimer timer(msecs); - forever { - if (d->pipeWriter->hadWritten()) - return true; - - if (d->pipeWriter->bytesToWrite() == 0) - return false; - - // Wait for the pipe writer to acknowledge that it has - // written. This will succeed if either the pipe writer has - // already written the data, or if it manages to write data - // within the given timeout. - if (d->pipeWriter->waitForWrite(0)) - return true; - - Sleep(timer.nextSleepTime()); - if (timer.hasTimedOut()) - break; - } - - return false; + // Wait for the pipe writer to acknowledge that it has + // written. This will succeed if either the pipe writer has + // already written the data, or if it manages to write data + // within the given timeout. + return d->pipeWriter->waitForWrite(msecs); } QT_END_NAMESPACE -- cgit v0.12 From 1dd1cb8c70a8986c1acc911a663d99d7043d15c7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 14:26:57 +0200 Subject: Phonon: Fixed a possible race condition Task-number: 257495 --- src/3rdparty/phonon/ds9/mediaobject.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index 26ba8eb..f77bdc1 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -207,12 +207,14 @@ namespace Phonon HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - m_currentRender = w.graph; - m_currentRenderId = w.id; - if (w.task == ReplaceGraph) { - HANDLE h; + { + QMutexLocker locker(&m_mutex); + m_currentRender = w.graph; + m_currentRenderId = w.id; + } + if (w.task == ReplaceGraph) { + QMutexLocker locker(&m_mutex); int index = -1; for(int i = 0; i < FILTER_COUNT; ++i) { if (m_graphHandle[i].graph == w.oldGraph) { @@ -228,6 +230,7 @@ namespace Phonon Q_ASSERT(index != -1); //add the new graph + HANDLE h; if (SUCCEEDED(ComPointer(w.graph, IID_IMediaEvent) ->GetEventHandle(reinterpret_cast(&h)))) { m_graphHandle[index].graph = w.graph; @@ -324,8 +327,11 @@ namespace Phonon } } - m_currentRender = Graph(); - m_currentRenderId = 0; + { + QMutexLocker locker(&m_mutex); + m_currentRender = Graph(); + m_currentRenderId = 0; + } } -- cgit v0.12 From 0ed214105547980803336337096fd9429ce9f1a1 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 8 Jul 2009 14:46:59 +0200 Subject: Use current license header. --- src/corelib/kernel/qcore_unix_p.h | 4 ++-- src/network/socket/qnet_unix_p.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 61d8401..1bf2425 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index ffd5b39..392c1e2 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtNetwork module of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ -- cgit v0.12 From 0f34ed602bcb00b19b0e550d790ae6521de37aa6 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 14:48:52 +0200 Subject: QMenuBar: the extension could be visible when it shouldn't If you had invisible actions in the menubar, it would always show the extension button --- src/gui/widgets/qmenubar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index caacc58..be6ed67 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -218,7 +218,7 @@ void QMenuBarPrivate::updateGeometries() bool hasHiddenActions = false; for (int i = 0; i < actions.count(); ++i) { const QRect &rect = actionRects.at(i); - if (!menuRect.contains(rect)) { + if (rect.isValid() && !menuRect.contains(rect)) { hasHiddenActions = true; break; } @@ -229,7 +229,7 @@ void QMenuBarPrivate::updateGeometries() menuRect = this->menuRect(true); for (int i = 0; i < actions.count(); ++i) { const QRect &rect = actionRects.at(i); - if (!menuRect.contains(rect)) { + if (rect.isValid() && !menuRect.contains(rect)) { hiddenActions.append(actions.at(i)); } } -- cgit v0.12 From d85d31c50620a215647ab2c3d27636006c04a01d Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 8 Jul 2009 14:54:59 +0200 Subject: doc: Output a clearer "All functions in this class are..." statement. Task-number: 189232 --- tools/qdoc3/generator.cpp | 168 +++++++++++++++++++++++++++++++++++----------- tools/qdoc3/generator.h | 4 ++ tools/qdoc3/separator.cpp | 36 ++++++---- tools/qdoc3/separator.h | 1 + 4 files changed, 156 insertions(+), 53 deletions(-) diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 00831d1..e97b7f2 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -68,10 +68,12 @@ QStringList Generator::imageDirs; QString Generator::outDir; QString Generator::project; -static Text stockLink(const QString &target) +static void singularPlural(Text& text, const NodeList& nodes) { - return Text() << Atom(Atom::Link, target) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << target << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + if (nodes.count() == 1) + text << " is"; + else + text << " are"; } Generator::Generator() @@ -775,64 +777,138 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker) { Text text; Text theStockLink; - Node::ThreadSafeness parent = node->parent()->inheritedThreadSafeness(); + Node::ThreadSafeness threadSafeness = node->threadSafeness(); + + Text rlink; + rlink << Atom(Atom::Link,"reentrant") + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << "reentrant" + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - switch (node->threadSafeness()) { + Text tlink; + tlink << Atom(Atom::Link,"thread-safe") + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << "thread-safe" + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + + switch (threadSafeness) { case Node::UnspecifiedSafeness: break; case Node::NonReentrant: - text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "Warning:" - << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " This " - << typeString(node) << " is not " << stockLink("reentrant") << "." << Atom::ParaRight; + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) + << "Warning:" + << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD) + << " This " + << typeString(node) + << " is not " + << rlink + << "." + << Atom::ParaRight; break; case Node::Reentrant: case Node::ThreadSafe: - text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD); - if (parent == Node::ThreadSafe) { - text << "Warning:"; - } else { - text << "Note:"; - } - text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " "; - - if (node->threadSafeness() == Node::ThreadSafe) - theStockLink = stockLink("thread-safe"); - else - theStockLink = stockLink("reentrant"); + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) + << "Note:" + << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD) + << " "; if (node->isInnerNode()) { - const InnerNode *innerNode = static_cast(node); - text << "All the functions in this " << typeString(node) << " are " - << theStockLink; - - NodeList except; + const InnerNode* innerNode = static_cast(node); + text << "All functions in this " + << typeString(node) + << " are "; + if (threadSafeness == Node::ThreadSafe) + text << tlink; + else + text << rlink; + + bool exceptions = false; + NodeList reentrant; + NodeList threadsafe; + NodeList nonreentrant; NodeList::ConstIterator c = innerNode->childNodes().begin(); while (c != innerNode->childNodes().end()) { - if ((*c)->threadSafeness() != Node::UnspecifiedSafeness) - except.append(*c); + switch ((*c)->threadSafeness()) { + case Node::Reentrant: + reentrant.append(*c); + if (threadSafeness == Node::ThreadSafe) + exceptions = true; + break; + case Node::ThreadSafe: + threadsafe.append(*c); + if (threadSafeness == Node::Reentrant) + exceptions = true; + break; + case Node::NonReentrant: + nonreentrant.append(*c); + exceptions = true; + break; + default: + break; + } ++c; } - if (except.isEmpty()) { + if (!exceptions) text << "."; + else if (threadSafeness == Node::Reentrant) { + if (nonreentrant.isEmpty()) { + if (!threadsafe.isEmpty()) { + text << ", but "; + appendFullNames(text,threadsafe,innerNode,marker); + singularPlural(text,threadsafe); + text << " also " << tlink << "."; + } + else + text << "."; + } + else { + text << ", except for "; + appendFullNames(text,nonreentrant,innerNode,marker); + text << ", which"; + singularPlural(text,nonreentrant); + text << " nonreentrant."; + if (!threadsafe.isEmpty()) { + text << " "; + appendFullNames(text,threadsafe,innerNode,marker); + singularPlural(text,threadsafe); + text << " " << tlink << "."; + } + } } - else { - text << ", except "; - - NodeList::ConstIterator e = except.begin(); - int index = 0; - while (e != except.end()) { - appendFullName(text, *e, innerNode, marker); - text << separator(index++, except.count()); - ++e; + else { // thread-safe + if (!nonreentrant.isEmpty() || !reentrant.isEmpty()) { + text << ", except for "; + if (!reentrant.isEmpty()) { + appendFullNames(text,reentrant,innerNode,marker); + text << ", which"; + singularPlural(text,reentrant); + text << " only " << rlink; + if (!nonreentrant.isEmpty()) + text << ", and "; + } + if (!nonreentrant.isEmpty()) { + appendFullNames(text,nonreentrant,innerNode,marker); + text << ", which"; + singularPlural(text,nonreentrant); + text << " nonreentrant."; + } + text << "."; } } } else { - text << "This " << typeString(node) << " is " << theStockLink << "."; + text << "This " << typeString(node) << " is "; + if (threadSafeness == Node::ThreadSafe) + text << tlink; + else + text << rlink; + text << "."; } text << Atom::ParaRight; } - generateText(text, node, marker); + generateText(text,node,marker); } void Generator::generateSince(const Node *node, CodeMarker *marker) @@ -966,6 +1042,20 @@ void Generator::appendFullName(Text& text, << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); } +void Generator::appendFullNames(Text& text, + const NodeList& nodes, + const Node* relative, + CodeMarker* marker) +{ + NodeList::ConstIterator n = nodes.begin(); + int index = 0; + while (n != nodes.end()) { + appendFullName(text,*n,relative,marker); + text << comma(index++,nodes.count()); + ++n; + } +} + void Generator::appendSortedNames(Text& text, const ClassNode *classe, const QList &classes, diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index 08b857b..cdc4c29 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -154,6 +154,10 @@ class Generator const Node *apparentNode, const QString& fullName, const Node *actualNode); + void appendFullNames(Text& text, + const NodeList& nodes, + const Node* relative, + CodeMarker* marker); void appendSortedNames(Text& text, const ClassNode *classe, const QList &classes, diff --git a/tools/qdoc3/separator.cpp b/tools/qdoc3/separator.cpp index 8f27f90..60674be 100644 --- a/tools/qdoc3/separator.cpp +++ b/tools/qdoc3/separator.cpp @@ -48,22 +48,30 @@ QT_BEGIN_NAMESPACE -QString separator( int index, int count ) +QString separator(int index, int count) { - if ( index == count - 1 ) - return tr( ".", "terminator" ); + if (index == count - 1) + return tr(".", "terminator"); + if (count == 2) + return tr(" and ", "separator when N = 2"); + if (index == 0) + return tr(", ", "first separator when N > 2"); + if (index < count - 2) + return tr(", ", "general separator when N > 2"); + return tr(", and ", "last separator when N > 2"); +} - if ( count == 2 ) { - return tr( " and ", "separator when N = 2" ); - } else { - if ( index == 0 ) { - return tr( ", ", "first separator when N > 2" ); - } else if ( index < count - 2 ) { - return tr( ", ", "general separator when N > 2" ); - } else { - return tr( ", and ", "last separator when N > 2" ); - } - } +QString comma(int index, int count) +{ + if (index == count - 1) + return QString(""); + if (count == 2) + return tr(" and ", "separator when N = 2"); + if (index == 0) + return tr(", ", "first separator when N > 2"); + if (index < count - 2) + return tr(", ", "general separator when N > 2"); + return tr(", and ", "last separator when N > 2"); } QT_END_NAMESPACE diff --git a/tools/qdoc3/separator.h b/tools/qdoc3/separator.h index 70ba624..2336d94 100644 --- a/tools/qdoc3/separator.h +++ b/tools/qdoc3/separator.h @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE QString separator( int index, int count ); +QString comma( int index, int count ); QT_END_NAMESPACE -- cgit v0.12 From 48f049d6fbddd60d99fb6ebc15fd5b52a3b515ec Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Wed, 8 Jul 2009 16:23:21 +0200 Subject: Update QGroupBox on focus We cannot assume the position of the decorations when a QGroupBox get the focus. Task-number: 257660 Reviewed-by: Thierry --- src/gui/widgets/qgroupbox.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/gui/widgets/qgroupbox.cpp b/src/gui/widgets/qgroupbox.cpp index fe882a6..022c377 100644 --- a/src/gui/widgets/qgroupbox.cpp +++ b/src/gui/widgets/qgroupbox.cpp @@ -479,11 +479,7 @@ void QGroupBox::focusInEvent(QFocusEvent *fe) if (focusPolicy() == Qt::NoFocus) { d->_q_fixFocus(fe->reason()); } else { - QStyleOptionGroupBox box; - initStyleOption(&box); - QRect rect = style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this) - | style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxLabel, this); - update(rect); + QWidget::focusInEvent(fe); } } -- cgit v0.12 From e95f4fb1c11795625be8b3b4adc62ed3c520a467 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 16:36:30 +0200 Subject: autotest compile fix for MacOSX --- tests/auto/qfontdialog/tst_qfontdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qfontdialog/tst_qfontdialog.cpp b/tests/auto/qfontdialog/tst_qfontdialog.cpp index 1444ee0..5f1797b 100644 --- a/tests/auto/qfontdialog/tst_qfontdialog.cpp +++ b/tests/auto/qfontdialog/tst_qfontdialog.cpp @@ -156,7 +156,7 @@ void tst_QFontDialog::setFont() class FriendlyFontDialog : public QFontDialog { - friend tst_QFontDialog; + friend class tst_QFontDialog; Q_DECLARE_PRIVATE(QFontDialog); }; -- cgit v0.12 From c02a9925f10fbf1a4883983f35c735666862a3f6 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 8 Jul 2009 15:48:57 +0200 Subject: Compile fix for the qapplication autotest. Reviewed-by: TrustMe --- tests/auto/qapplication/tst_qapplication.cpp | 68 ++++++++++++++++++---------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index 85494af..8532723 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -1820,27 +1820,38 @@ void tst_QApplication::touchEventPropagation() { int argc = 1; QApplication app(argc, &argv0, QApplication::GuiServer); - QTouchEvent::TouchPoint touchPoint(0); - QTouchEvent touchEvent(QEvent::TouchBegin, Qt::NoModifier, QList() << (&touchPoint)); + + QList pressedTouchPoints; + QTouchEvent::TouchPoint press(0); + press.setState(Qt::TouchPointPressed); + pressedTouchPoints << press; + + QList releasedTouchPoints; + QTouchEvent::TouchPoint release(0); + release.setState(Qt::TouchPointReleased); + releasedTouchPoints << release; { // touch event behavior on a window TouchEventPropagationTestWidget window; window.setObjectName("1. window"); - QApplicationPrivate::sendTouchEvent(&window, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); - window.setAttribute(Qt::WA_AcceptsTouchEvents); - QApplicationPrivate::sendTouchEvent(&window, &touchEvent); + window.setAttribute(Qt::WA_AcceptTouchEvents); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); window.acceptTouchEvent = true; - QApplicationPrivate::sendTouchEvent(&window, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(window.seenTouchEvent); QVERIFY(!window.seenMouseEvent); } @@ -1852,34 +1863,38 @@ void tst_QApplication::touchEventPropagation() TouchEventPropagationTestWidget widget(&window); widget.setObjectName("2. widget"); - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!widget.seenTouchEvent); - QVERIFY(widget.seenMouseEvent); + QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); widget.reset(); - widget.setAttribute(Qt::WA_AcceptsTouchEvents); - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + widget.setAttribute(Qt::WA_AcceptTouchEvents); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(widget.seenTouchEvent); - QVERIFY(widget.seenMouseEvent); + QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); widget.reset(); widget.acceptMouseEvent = true; - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(widget.seenTouchEvent); - QVERIFY(widget.seenMouseEvent); + QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); QVERIFY(!window.seenMouseEvent); window.reset(); widget.reset(); widget.acceptTouchEvent = true; - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); @@ -1887,18 +1902,20 @@ void tst_QApplication::touchEventPropagation() window.reset(); widget.reset(); - widget.setAttribute(Qt::WA_AcceptsTouchEvents, false); - window.setAttribute(Qt::WA_AcceptsTouchEvents); - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + widget.setAttribute(Qt::WA_AcceptTouchEvents, false); + window.setAttribute(Qt::WA_AcceptTouchEvents); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!widget.seenTouchEvent); - QVERIFY(widget.seenMouseEvent); + QVERIFY(!widget.seenMouseEvent); QVERIFY(window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); widget.reset(); window.acceptTouchEvent = true; - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(window.seenTouchEvent); @@ -1908,7 +1925,8 @@ void tst_QApplication::touchEventPropagation() widget.reset(); widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first window.acceptTouchEvent = true; - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(window.seenTouchEvent); -- cgit v0.12 From c2f2b6509fcd91617ae3eb860d6d3f947c5ea443 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 16:34:55 +0200 Subject: QMainWindow: fix the use of animation and improve code quality --- src/gui/widgets/qmainwindowlayout.cpp | 33 +++++++++++----------- src/gui/widgets/qwidgetanimator.cpp | 53 +++++++++++++---------------------- src/gui/widgets/qwidgetanimator_p.h | 4 +-- 3 files changed, 38 insertions(+), 52 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 8fb7c4f..aba9120 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1527,24 +1527,20 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) layoutState.remove(previousPath); pluggingWidget = widget; - if (dockOptions & QMainWindow::AnimatedDocks) { - QRect globalRect = currentGapRect; - globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft())); + QRect globalRect = currentGapRect; + globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft())); #ifndef QT_NO_DOCKWIDGET - if (qobject_cast(widget) != 0) { - QDockWidgetLayout *layout = qobject_cast(widget->layout()); - if (layout->nativeWindowDeco()) { - globalRect.adjust(0, layout->titleHeight(), 0, 0); - } else { - int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget); - globalRect.adjust(-fw, -fw, fw, fw); - } + if (qobject_cast(widget) != 0) { + QDockWidgetLayout *layout = qobject_cast(widget->layout()); + if (layout->nativeWindowDeco()) { + globalRect.adjust(0, layout->titleHeight(), 0, 0); + } else { + int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget); + globalRect.adjust(-fw, -fw, fw, fw); } -#endif - widgetAnimator.animate(widget, globalRect, true); - } else { - animationFinished(widget); } +#endif + widgetAnimator.animate(widget, globalRect, dockOptions & QMainWindow::AnimatedDocks); return true; } @@ -1576,9 +1572,11 @@ void QMainWindowLayout::animationFinished(QWidget *widget) tb->d_func()->plug(currentGapRect); #endif - applyState(layoutState, false); #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR + //it is important to set the current tab before applying the layout + //so that applyState will not try to counter the result of the animation + //by putting the item in negative space if (qobject_cast(widget) != 0) { // info() might return null if the widget is destroyed while // animating but before the animationFinished signal is received. @@ -1587,6 +1585,9 @@ void QMainWindowLayout::animationFinished(QWidget *widget) } #endif #endif + + applyState(layoutState, false); + savedState.clear(); currentGapPos.clear(); pluggingWidget = 0; diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index 7a3a464..26cf905 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -76,59 +76,46 @@ void QWidgetAnimator::animationFinished() void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate) { - QRect final_geometry = _final_geometry; - QRect r = widget->geometry(); if (r.right() < 0 || r.bottom() < 0) r = QRect(); -#ifdef QT_NO_ANIMATION - Q_UNUSED(animate); -#else - if (r.isNull() || final_geometry.isNull() || r == final_geometry) - animate = false; + animate = animate && !r.isNull() && !_final_geometry.isNull(); + + // might make the wigdet go away by sending it to negative space + const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry : + QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size()); + if (r == final_geometry) + return; //the widget is already where it should be +#ifndef QT_NO_ANIMATION AnimationMap::const_iterator it = m_animation_map.constFind(widget); if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry) return; - if (animate) { - QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry"); - anim->setDuration(200); - anim->setEasingCurve(QEasingCurve::InOutQuad); - anim->setEndValue(final_geometry); - m_animation_map[widget] = anim; - connect(anim, SIGNAL(finished()), SLOT(animationFinished())); - anim->start(QPropertyAnimation::DeleteWhenStopped); - } else + QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry"); + anim->setDuration(animate ? 200 : 0); + anim->setEasingCurve(QEasingCurve::InOutQuad); + anim->setEndValue(final_geometry); + m_animation_map[widget] = anim; + connect(anim, SIGNAL(finished()), SLOT(animationFinished())); + anim->start(QPropertyAnimation::DeleteWhenStopped); + Q_ASSERT(animate || widget->geometry() == final_geometry); +#else + //we do it in one shot + widget->setGeometry(final_geometry); + m_mainWindowLayout->animationFinished(widget); #endif //QT_NO_ANIMATION - { - if (!final_geometry.isValid() && !widget->isWindow()) { - // Make the wigdet go away by sending it to negative space - QSize s = widget->size(); - final_geometry = QRect(-500 - s.width(), -500 - s.height(), s.width(), s.height()); - } - widget->setGeometry(final_geometry); - } } bool QWidgetAnimator::animating() const { -#ifdef QT_NO_ANIMATION - return false; -#else return !m_animation_map.isEmpty(); -#endif //QT_NO_ANIMATION } bool QWidgetAnimator::animating(QWidget *widget) const { -#ifdef QT_NO_ANIMATION - Q_UNUSED(widget); - return false; -#else return m_animation_map.contains(widget); -#endif //QT_NO_ANIMATION } QT_END_NAMESPACE diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index 4047395..64697a9 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -54,7 +54,6 @@ // #include -#include #include QT_BEGIN_NAMESPACE @@ -77,12 +76,11 @@ public: #ifndef QT_NO_ANIMATION private Q_SLOTS: void animationFinished(); +#endif private: typedef QMap AnimationMap; AnimationMap m_animation_map; -#endif -private: QMainWindowLayout *m_mainWindowLayout; }; -- cgit v0.12 From cf7ca87e057ef3810c5db36ff975a98f532a8dc0 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 8 Jul 2009 17:00:43 +0200 Subject: Make test pass when executed from debug/release directory. --- tests/auto/qchar/tst_qchar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/qchar/tst_qchar.cpp b/tests/auto/qchar/tst_qchar.cpp index 01ba534..512c180 100644 --- a/tests/auto/qchar/tst_qchar.cpp +++ b/tests/auto/qchar/tst_qchar.cpp @@ -500,6 +500,9 @@ void tst_QChar::normalization() } QFile f("NormalizationTest.txt"); + // Windows - current directory is the debug/release subdirectory where the executable is located + if (!f.exists()) + f.setFileName("../NormalizationTest.txt");; if (!f.exists()) { QFAIL("Couldn't find NormalizationTest.txt"); return; -- cgit v0.12 From b358143b7eb5dc3d76a09e501914fa00d0c3876c Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 8 Jul 2009 17:02:23 +0200 Subject: Define M_PI in qmath.h if not defined by math.h (as is the case on Windows), and remove duplicate defines elsewhere. --- src/corelib/kernel/qmath.h | 4 ++++ src/gui/math3d/qmatrix4x4.cpp | 4 ---- src/gui/math3d/qquaternion.cpp | 4 ---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h index 348957f..7a77d56 100644 --- a/src/corelib/kernel/qmath.h +++ b/src/corelib/kernel/qmath.h @@ -132,6 +132,10 @@ inline qreal qPow(qreal x, qreal y) return pow(x, y); } +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index 9fe487b..b998353 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1004,10 +1004,6 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, const QVector3D& vector) #endif -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - /*! \overload diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 17c4373..9988e2b 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -339,10 +339,6 @@ QVector3D QQuaternion::rotateVector(const QVector3D& vector) const \sa operator*=() */ -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - #ifndef QT_NO_VECTOR3D /*! -- cgit v0.12 From 34357998f38614a7c724ba4561c0e68b19fffc4a Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 18:19:21 +0200 Subject: Fix possible crash in QDockAreas --- src/gui/widgets/qdockarealayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index b905ccd..ee29b55 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1707,7 +1707,7 @@ QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList &path) Q_ASSERT(!path.isEmpty()); const int index = path.first(); if (path.count() > 1) { - const QDockAreaLayoutItem &item = item_list.at(index); + const QDockAreaLayoutItem &item = item_list[index]; Q_ASSERT(item.subinfo != 0); return item.subinfo->item(path.mid(1)); } -- cgit v0.12 From cfacb284593008094136905a2497843a4bbac639 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 18:22:09 +0200 Subject: QPropertyAnimation: save a Q_GLOBAL_STATIC This is possible because we anyway use a Mutex to access the static hash --- src/corelib/animation/qpropertyanimation.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index 7526a81..5f224aa 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -100,10 +100,6 @@ QT_BEGIN_NAMESPACE -typedef QPair QPropertyAnimationPair; -typedef QHash QPropertyAnimationHash; -Q_GLOBAL_STATIC(QPropertyAnimationHash, _q_runningAnimations) - void QPropertyAnimationPrivate::updateMetaProperty() { if (!target || propertyName.isEmpty()) @@ -286,19 +282,21 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State oldState, QPropertyAnimation *animToStop = 0; { - QPropertyAnimationHash * hash = _q_runningAnimations(); - QMutexLocker locker(QMutexPool::globalInstanceGet(hash)); + QMutexLocker locker(QMutexPool::globalInstanceGet(&staticMetaObject)); + typedef QPair QPropertyAnimationPair; + typedef QHash QPropertyAnimationHash; + static QPropertyAnimationHash hash; QPropertyAnimationPair key(d->target, d->propertyName); if (newState == Running) { d->updateMetaProperty(); - animToStop = hash->value(key, 0); - hash->insert(key, this); + animToStop = hash.value(key, 0); + hash.insert(key, this); // update the default start value if (oldState == Stopped) { d->setDefaultStartValue(d->target->property(d->propertyName.constData())); } - } else if (hash->value(key) == this) { - hash->remove(key); + } else if (hash.value(key) == this) { + hash.remove(key); } } -- cgit v0.12 From 6e35b15d75aeb140bf56690ce7369f54342c2739 Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 9 Jul 2009 08:41:56 +1000 Subject: Make compile --- src/gui/widgets/qwidgetanimator_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index 64697a9..5a3e39d 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QWidget; class QMainWindowLayout; class QPropertyAnimation; +class QRect; class QWidgetAnimator : public QObject { -- cgit v0.12 From 6cb86a552f4f320b47232ef745ae897ad5ead591 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 9 Jul 2009 10:56:15 +1000 Subject: Remove some left-over mentions of fixed-point in math3d Reviewed-by: trustme --- src/gui/math3d/qmatrix4x4.cpp | 7 +---- src/gui/math3d/qquaternion.cpp | 4 --- src/gui/math3d/qvector2d.cpp | 4 +-- src/gui/math3d/qvector3d.cpp | 4 +-- src/gui/math3d/qvector4d.cpp | 4 --- tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp | 35 +++++++++++------------ tests/auto/math3d/qquaternion/tst_qquaternion.cpp | 4 +-- tests/auto/math3d/qvectornd/tst_qvectornd.cpp | 4 +-- 8 files changed, 23 insertions(+), 43 deletions(-) diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index b998353..88f58c8 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -53,10 +53,6 @@ QT_BEGIN_NAMESPACE \brief The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space. \since 4.6 - The matrix elements are stored internally using the most efficient - numeric representation for the underlying hardware: floating-point - or fixed-point. - \sa QVector3D, QGenericMatrix */ @@ -308,8 +304,7 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform) // The 4x4 matrix inverse algorithm is based on that described at: // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q24 // Some optimization has been done to avoid making copies of 3x3 -// sub-matrices, to do calculations in fixed-point where required, -// and to unroll the loops. +// sub-matrices and to unroll the loops. // Calculate the determinant of a 3x3 sub-matrix. // | A B C | diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 9988e2b..d9d4160 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -55,10 +55,6 @@ QT_BEGIN_NAMESPACE Quaternions are used to represent rotations in 3D space, and consist of a 3D rotation axis specified by the x, y, and z coordinates, and a scalar representing the rotation angle. - - The components of a quaternion are stored internally using the most - efficient representation for the GL rendering engine, which will be - either floating-point or fixed-point. */ /*! diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp index 9b5d123..b492aa8 100644 --- a/src/gui/math3d/qvector2d.cpp +++ b/src/gui/math3d/qvector2d.cpp @@ -57,9 +57,7 @@ QT_BEGIN_NAMESPACE The QVector2D class can also be used to represent vertices in 2D space. We therefore do not need to provide a separate vertex class. - The coordinates are stored internally using the most efficient - representation for the GL rendering engine, which will be either - floating-point or fixed-point. + \sa QVector3D, QVector4D, QQuaternion */ /*! diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp index 977152a..95550cd 100644 --- a/src/gui/math3d/qvector3d.cpp +++ b/src/gui/math3d/qvector3d.cpp @@ -61,9 +61,7 @@ QT_BEGIN_NAMESPACE The QVector3D class can also be used to represent vertices in 3D space. We therefore do not need to provide a separate vertex class. - The coordinates are stored internally using the most efficient - representation for the GL rendering engine, which will be either - floating-point or fixed-point. + \sa QVector2D, QVector4D, QQuaternion */ /*! diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp index a28d2a1..1f7d921 100644 --- a/src/gui/math3d/qvector4d.cpp +++ b/src/gui/math3d/qvector4d.cpp @@ -57,10 +57,6 @@ QT_BEGIN_NAMESPACE The QVector4D class can also be used to represent vertices in 4D space. We therefore do not need to provide a separate vertex class. - The coordinates are stored internally using the most efficient - representation for the GL rendering engine, which will be either - floating-point or fixed-point. - \sa QQuaternion, QVector2D, QVector3D */ diff --git a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp index 7facf4a..d799c1b 100644 --- a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp +++ b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp @@ -172,22 +172,22 @@ private slots: private: static void setMatrix(QMatrix2x2& m, const qreal *values); - static void setMatrixFixed(QMatrix2x2& m, const qreal *values); + static void setMatrixDirect(QMatrix2x2& m, const qreal *values); static bool isSame(const QMatrix2x2& m, const qreal *values); static bool isIdentity(const QMatrix2x2& m); static void setMatrix(QMatrix3x3& m, const qreal *values); - static void setMatrixFixed(QMatrix3x3& m, const qreal *values); + static void setMatrixDirect(QMatrix3x3& m, const qreal *values); static bool isSame(const QMatrix3x3& m, const qreal *values); static bool isIdentity(const QMatrix3x3& m); static void setMatrix(QMatrix4x4& m, const qreal *values); - static void setMatrixFixed(QMatrix4x4& m, const qreal *values); + static void setMatrixDirect(QMatrix4x4& m, const qreal *values); static bool isSame(const QMatrix4x4& m, const qreal *values); static bool isIdentity(const QMatrix4x4& m); static void setMatrix(QMatrix4x3& m, const qreal *values); - static void setMatrixFixed(QMatrix4x3& m, const qreal *values); + static void setMatrixDirect(QMatrix4x3& m, const qreal *values); static bool isSame(const QMatrix4x3& m, const qreal *values); static bool isIdentity(const QMatrix4x3& m); }; @@ -321,8 +321,9 @@ void tst_QMatrix::setMatrix(QMatrix4x3& m, const qreal *values) } // Set a matrix to a specified array of values, which are assumed -// to be in row-major order. This sets the values using fixed-point. -void tst_QMatrix::setMatrixFixed(QMatrix2x2& m, const qreal *values) +// to be in row-major order. This sets the values directly into +// the internal data() array. +void tst_QMatrix::setMatrixDirect(QMatrix2x2& m, const qreal *values) { float *data = m.data(); for (int row = 0; row < 2; ++row) { @@ -331,7 +332,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix2x2& m, const qreal *values) } } } -void tst_QMatrix::setMatrixFixed(QMatrix3x3& m, const qreal *values) +void tst_QMatrix::setMatrixDirect(QMatrix3x3& m, const qreal *values) { float *data = m.data(); for (int row = 0; row < 3; ++row) { @@ -340,7 +341,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix3x3& m, const qreal *values) } } } -void tst_QMatrix::setMatrixFixed(QMatrix4x4& m, const qreal *values) +void tst_QMatrix::setMatrixDirect(QMatrix4x4& m, const qreal *values) { float *data = m.data(); for (int row = 0; row < 4; ++row) { @@ -349,7 +350,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix4x4& m, const qreal *values) } } } -void tst_QMatrix::setMatrixFixed(QMatrix4x3& m, const qreal *values) +void tst_QMatrix::setMatrixDirect(QMatrix4x3& m, const qreal *values) { float *data = m.data(); for (int row = 0; row < 3; ++row) { @@ -359,8 +360,8 @@ void tst_QMatrix::setMatrixFixed(QMatrix4x3& m, const qreal *values) } } -// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion -// to fixed-point and back again. So create "fuzzier" compares. +// qFuzzyCompare isn't always "fuzzy" enough to handle conversion +// between float, double, and qreal. So create "fuzzier" compares. static bool fuzzyCompare(float x, float y, qreal epsilon = 0.001) { float diff = x - y; @@ -511,7 +512,7 @@ void tst_QMatrix::create2x2() QVERIFY(!m2.isIdentity()); QMatrix2x2 m3; - setMatrixFixed(m3, uniqueValues2); + setMatrixDirect(m3, uniqueValues2); QVERIFY(isSame(m3, uniqueValues2)); QMatrix2x2 m4(m3); @@ -546,7 +547,7 @@ void tst_QMatrix::create3x3() QVERIFY(!m2.isIdentity()); QMatrix3x3 m3; - setMatrixFixed(m3, uniqueValues3); + setMatrixDirect(m3, uniqueValues3); QVERIFY(isSame(m3, uniqueValues3)); QMatrix3x3 m4(m3); @@ -581,7 +582,7 @@ void tst_QMatrix::create4x4() QVERIFY(!m2.isIdentity()); QMatrix4x4 m3; - setMatrixFixed(m3, uniqueValues4); + setMatrixDirect(m3, uniqueValues4); QVERIFY(isSame(m3, uniqueValues4)); QMatrix4x4 m4(m3); @@ -623,7 +624,7 @@ void tst_QMatrix::create4x3() QVERIFY(!m2.isIdentity()); QMatrix4x3 m3; - setMatrixFixed(m3, uniqueValues4x3); + setMatrixDirect(m3, uniqueValues4x3); QVERIFY(isSame(m3, uniqueValues4x3)); QMatrix4x3 m4(m3); @@ -2961,10 +2962,6 @@ void tst_QMatrix::extractTranslation() QVERIFY(fuzzyCompare(vec.y(), y, epsilon)); QVERIFY(fuzzyCompare(vec.z(), z, epsilon)); - // Have to be careful with numbers here, it is really easy to blow away - // the precision of a fixed pointer number, especially when doing distance - // formula for vector normalization - QMatrix4x4 lookAt; QVector3D eye(1.5f, -2.5f, 2.5f); lookAt.lookAt(eye, diff --git a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp index 395032f..16b87a1 100644 --- a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp @@ -95,8 +95,8 @@ private slots: void nlerp(); }; -// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion -// to fixed-point and back again. So create "fuzzier" compares. +// qFuzzyCompare isn't always "fuzzy" enough to handle conversion +// between float, double, and qreal. So create "fuzzier" compares. static bool fuzzyCompare(float x, float y) { float diff = x - y; diff --git a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp index 0eb5b07..9c1ea83 100644 --- a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp +++ b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp @@ -139,8 +139,8 @@ private slots: void dotProduct4(); }; -// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion -// to fixed-point and back again. So create "fuzzier" compares. +// qFuzzyCompare isn't always "fuzzy" enough to handle conversion +// between float, double, and qreal. So create "fuzzier" compares. static bool fuzzyCompare(float x, float y) { float diff = x - y; -- cgit v0.12 From 3e50d680a37401c05d753982eb5d43c0f1225f63 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 9 Jul 2009 11:11:35 +1000 Subject: Directly copy QGenericMatrix members instead of using qMemCopy() Using qMemCopy limits QGenericMatrix to plain old types like float and double. Copying the values normally will allow copy constructors to work on non plain types. Reviewed-by: trustme --- src/gui/math3d/qgenericmatrix.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h index 1131f9b..7bdf70a 100644 --- a/src/gui/math3d/qgenericmatrix.h +++ b/src/gui/math3d/qgenericmatrix.h @@ -119,7 +119,9 @@ Q_INLINE_TEMPLATE QGenericMatrix::QGenericMatrix() template Q_INLINE_TEMPLATE QGenericMatrix::QGenericMatrix(const QGenericMatrix& other) { - qMemCopy(m, other.m, sizeof(m)); + for (int col = 0; col < N; ++col) + for (int row = 0; row < M; ++row) + m[col][row] = other.m[col][row]; } template -- cgit v0.12 From bae8bc5d23946036b2c1079fc6f1b3bceeaa19ca Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 8 Jul 2009 10:18:56 +1000 Subject: Disable private unit tests when Qt is configured without -developer-build, part 1. Adds QT_CONFIG+=private_tests to qconfig.pri when Qt is configured with -developer-build. Reviewed-by: Michael Goddard --- configure | 4 +++- tools/configure/configureapp.cpp | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/configure b/configure index f9b3030..bd8b0ca 100755 --- a/configure +++ b/configure @@ -6256,7 +6256,6 @@ esac # debug release # dll staticlib # -# internal # nocrosscompiler # GNUmake # largefile @@ -6736,6 +6735,9 @@ fi if [ "$PLATFORM_MAC" = "yes" ]; then QT_CONFIG="$QT_CONFIG $CFG_MAC_ARCHS" fi +if [ "$CFG_DEV" = "yes" ]; then + QT_CONFIG="$QT_CONFIG private_tests" +fi # Make the application arch follow the Qt arch for single arch builds. # (for multiple-arch builds, set CONFIG manually in the application .pro file) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index ce9fe6b..80cfc64 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1135,6 +1135,10 @@ void Configure::parseCmdLine() useUnixSeparators = (dictionary["QMAKESPEC"] == "win32-g++"); + // Allow tests for private classes to be compiled against internal builds + if (dictionary["BUILDDEV"] == "yes") + qtConfig += "private_tests"; + #if !defined(EVAL) for( QStringList::Iterator dis = disabledModules.begin(); dis != disabledModules.end(); ++dis ) { @@ -1997,7 +2001,6 @@ bool Configure::verifyConfiguration() no-gif gif dll staticlib - internal nocrosscompiler GNUmake largefile -- cgit v0.12 From 87df094ed204c237393eac1dd0b2fb907e642dcb Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 6 Jul 2009 16:40:59 +1000 Subject: Disable private unit tests when Qt is configured without -developer-build, part 2. Some autotests use private (unexported) code, either because they're testing private classes or because that's the easiest way to test the public classes. Configuring Qt with `-developer-build' is needed for these tests. This commit fixes the tests so configuring without `-developer-build' only builds the tests which strictly use public API. --- tests/auto/qcombobox/tst_qcombobox.cpp | 6 ++++ tests/auto/qcssparser/qcssparser.pro | 1 + tests/auto/qfiledialog/tst_qfiledialog.cpp | 18 ++++++++++-- .../auto/qfilesystemmodel/tst_qfilesystemmodel.cpp | 2 ++ tests/auto/qgl/qgl.pro | 3 +- tests/auto/qgl/tst_qgl.cpp | 23 ++-------------- .../qhttpnetworkconnection.pro | 2 ++ tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro | 2 ++ .../qitemeditorfactory/tst_qitemeditorfactory.cpp | 10 +++---- tests/auto/qkeysequence/tst_qkeysequence.cpp | 2 +- tests/auto/qmainwindow/tst_qmainwindow.cpp | 6 ++++ .../qnativesocketengine/qnativesocketengine.pro | 2 ++ tests/auto/qnetworkreply/qnetworkreply.pro | 2 ++ tests/auto/qpathclipper/qpathclipper.pro | 2 ++ tests/auto/qplaintextedit/tst_qplaintextedit.cpp | 2 ++ tests/auto/qregion/tst_qregion.cpp | 6 ++-- tests/auto/qsettings/tst_qsettings.cpp | 22 +++++++++++++-- tests/auto/qsharedpointer/qsharedpointer.pro | 1 + tests/auto/qsocketnotifier/qsocketnotifier.pro | 2 ++ .../qsocks5socketengine/qsocks5socketengine.pro | 1 + .../qstandarditemmodel/tst_qstandarditemmodel.cpp | 4 +++ tests/auto/qstatemachine/tst_qstatemachine.cpp | 2 ++ tests/auto/qstylesheetstyle/qstylesheetstyle.pro | 1 + tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 4 +++ tests/auto/qtextedit/tst_qtextedit.cpp | 4 +++ tests/auto/qtextpiecetable/qtextpiecetable.pro | 5 ++-- tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp | 32 +--------------------- tests/auto/qurl/tst_qurl.cpp | 4 +++ .../xmlpatternsdiagnosticsts.pro | 1 + tests/auto/xmlpatternsview/xmlpatternsview.pro | 1 + tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro | 3 ++ tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro | 1 + 32 files changed, 108 insertions(+), 69 deletions(-) diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index c94ace0..67c9ac9 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -1973,6 +1973,7 @@ void tst_QComboBox::task190351_layout() listCombo.showPopup(); QTest::qWait(100); +#ifdef QT_BUILD_INTERNAL QFrame *container = qFindChild(&listCombo); QVERIFY(container); QCOMPARE(static_cast(list), qFindChild(container)); @@ -1980,6 +1981,7 @@ void tst_QComboBox::task190351_layout() QVERIFY(top); QVERIFY(top->isVisible()); QCOMPARE(top->mapToGlobal(QPoint(0, top->height())).y(), list->mapToGlobal(QPoint()).y()); +#endif QApplication::setStyle(oldStyle); #else @@ -2045,6 +2047,7 @@ void tst_QComboBox::task191329_size() tableCombo.showPopup(); QTest::qWait(100); +#ifdef QT_BUILD_INTERNAL QFrame *container = qFindChild(&tableCombo); QVERIFY(container); QCOMPARE(static_cast(table), qFindChild(container)); @@ -2052,6 +2055,7 @@ void tst_QComboBox::task191329_size() //the popup should be large enough to contains everithing so the top and left button are hidden QVERIFY(!button->isVisible()); } +#endif QApplication::setStyle(oldStyle); #else @@ -2107,9 +2111,11 @@ void tst_QComboBox::task248169_popupWithMinimalSize() comboBox.showPopup(); QTest::qWait(100); +#ifdef QT_BUILD_INTERNAL QFrame *container = qFindChild(&comboBox); QVERIFY(container); QVERIFY(desktop.screenGeometry(container).contains(container->geometry())); +#endif } void tst_QComboBox::task247863_keyBoardSelection() diff --git a/tests/auto/qcssparser/qcssparser.pro b/tests/auto/qcssparser/qcssparser.pro index 57d6804..723e4d3 100644 --- a/tests/auto/qcssparser/qcssparser.pro +++ b/tests/auto/qcssparser/qcssparser.pro @@ -3,6 +3,7 @@ SOURCES += tst_cssparser.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" QT += xml +requires(contains(QT_CONFIG,private_tests)) wince*: { addFiles.sources = testdata diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index e4fec1d..8bb81e7 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -231,6 +231,7 @@ void tst_QFiledialog::currentChangedSignal() // only emited from the views, sidebar, or lookin combo void tst_QFiledialog::directoryEnteredSignal() { +#if defined QT_BUILD_INTERNAL QNonNativeFileDialog fd(0, "", QDir::root().path()); fd.setOptions(QFileDialog::DontUseNativeDialog); fd.show(); @@ -274,6 +275,7 @@ void tst_QFiledialog::directoryEnteredSignal() QTest::mouseDClick(listView->viewport(), Qt::LeftButton, 0, listView->visualRect(folder).center()); QTRY_COMPARE(spyDirectoryEntered.count(), 1); */ +#endif } Q_DECLARE_METATYPE(QFileDialog::FileMode) @@ -1314,16 +1316,14 @@ void tst_QFiledialog::hooks() void tst_QFiledialog::listRoot() { +#if defined QT_BUILD_INTERNAL QFileInfoGatherer::fetchedRoot = false; QString dir(QDir::currentPath()); QNonNativeFileDialog fd(0, QString(), dir); fd.show(); -#if defined Q_AUTOTEST_EXPORT QCOMPARE(QFileInfoGatherer::fetchedRoot,false); -#endif fd.setDirectory(""); QTest::qWait(500); -#if defined Q_AUTOTEST_EXPORT QCOMPARE(QFileInfoGatherer::fetchedRoot,true); #endif } @@ -1347,6 +1347,7 @@ struct FriendlyQFileDialog : public QFileDialog void tst_QFiledialog::deleteDirAndFiles() { +#if defined QT_BUILD_INTERNAL QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir4FullDelete"; QDir dir; QVERIFY(dir.mkpath(tempPath + "/foo")); @@ -1373,6 +1374,7 @@ void tst_QFiledialog::deleteDirAndFiles() QFileInfo info(tempPath); QTest::qWait(2000); QVERIFY(!info.exists()); +#endif } void tst_QFiledialog::filter() @@ -1583,6 +1585,7 @@ QString &dir, const QString &filter) void tst_QFiledialog::task227304_proxyOnFileDialog() { +#if defined QT_BUILD_INTERNAL QNonNativeFileDialog fd(0, "", QDir::currentPath(), 0); fd.setProxyModel(new FilterDirModel(QDir::currentPath())); fd.show(); @@ -1616,6 +1619,7 @@ void tst_QFiledialog::task227304_proxyOnFileDialog() QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(1, 0)).center()); QTest::qWait(250); //We shouldn't crash +#endif } void tst_QFiledialog::task227930_correctNavigationKeyboardBehavior() @@ -1727,6 +1731,7 @@ void tst_QFiledialog::task235069_hideOnEscape() void tst_QFiledialog::task236402_dontWatchDeletedDir() { +#if defined QT_BUILD_INTERNAL //THIS TEST SHOULD NOT DISPLAY WARNINGS QDir current = QDir::currentPath(); //make sure it is the first on the list @@ -1746,6 +1751,7 @@ void tst_QFiledialog::task236402_dontWatchDeletedDir() QTest::qWait(200); fd.d_func()->removeDirectory(current.absolutePath() + "/aaaaaaaaaa/"); QTest::qWait(1000); +#endif } void tst_QFiledialog::task203703_returnProperSeparator() @@ -1870,6 +1876,7 @@ void tst_QFiledialog::task218353_relativePaths() void tst_QFiledialog::task251321_sideBarHiddenEntries() { +#if defined QT_BUILD_INTERNAL QNonNativeFileDialog fd; QDir current = QDir::currentPath(); @@ -1899,8 +1906,10 @@ void tst_QFiledialog::task251321_sideBarHiddenEntries() hiddenSubDir.rmdir("happy"); hiddenDir.rmdir("subdir"); current.rmdir(".hidden"); +#endif } +#if defined QT_BUILD_INTERNAL class MyQSideBar : public QSidebar { public : @@ -1918,9 +1927,11 @@ public : model()->removeRow(indexes.at(i).row()); } }; +#endif void tst_QFiledialog::task251341_sideBarRemoveEntries() { +#if defined QT_BUILD_INTERNAL QNonNativeFileDialog fd; QDir current = QDir::currentPath(); @@ -1980,6 +1991,7 @@ void tst_QFiledialog::task251341_sideBarRemoveEntries() QCOMPARE(mySideBar.urls(), expected); current.rmdir("testDir"); +#endif } void tst_QFiledialog::task254490_selectFileMultipleTimes() diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp index e415b02..d49083f 100644 --- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -254,6 +254,7 @@ void tst_QFileSystemModel::naturalCompare_data() void tst_QFileSystemModel::naturalCompare() { +#ifdef QT_BUILD_INTERNAL QFETCH(QString, s1); QFETCH(QString, s2); QFETCH(int, caseSensitive); @@ -271,6 +272,7 @@ void tst_QFileSystemModel::naturalCompare() // created. The scheduler takes its time to recognize ended threads. QTest::qWait(300); #endif +#endif } void tst_QFileSystemModel::readOnly() diff --git a/tests/auto/qgl/qgl.pro b/tests/auto/qgl/qgl.pro index 55e329d..420c4bb 100644 --- a/tests/auto/qgl/qgl.pro +++ b/tests/auto/qgl/qgl.pro @@ -3,7 +3,8 @@ ############################################################ load(qttest_p4) -contains(QT_CONFIG, opengl):QT += opengl +requires(contains(QT_CONFIG,opengl)) +QT += opengl SOURCES += tst_qgl.cpp diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index 078c559..96f5ddd 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -44,9 +44,7 @@ #include #include -#ifndef QT_NO_OPENGL #include -#endif #include #include @@ -78,7 +76,6 @@ tst_QGL::~tst_QGL() { } -#ifndef QT_NO_OPENGL class MyGLContext : public QGLContext { public: @@ -96,13 +93,10 @@ public: bool autoBufferSwap() const { return QGLWidget::autoBufferSwap(); } void setAutoBufferSwap(bool on) { QGLWidget::setAutoBufferSwap(on); } }; -#endif + // Testing get/set functions void tst_QGL::getSetCheck() { -#ifdef QT_NO_OPENGL - QSKIP("QGL not yet supported", SkipAll); -#else if (!QGLFormat::hasOpenGL()) QSKIP("QGL not supported on this platform", SkipAll); @@ -246,10 +240,9 @@ void tst_QGL::getSetCheck() QCOMPARE(false, obj3.autoBufferSwap()); obj3.setAutoBufferSwap(true); QCOMPARE(true, obj3.autoBufferSwap()); -#endif } -#ifndef QT_NO_OPENGL +#ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE extern QGLFormat::OpenGLVersionFlags qOpenGLVersionFlagsFromString(const QString &versionString); QT_END_NAMESPACE @@ -257,9 +250,7 @@ QT_END_NAMESPACE void tst_QGL::openGLVersionCheck() { -#ifdef QT_NO_OPENGL - QSKIP("QGL not yet supported", SkipAll); -#else +#ifdef QT_BUILD_INTERNAL if (!QGLFormat::hasOpenGL()) QSKIP("QGL not supported on this platform", SkipAll); @@ -366,9 +357,6 @@ public: void tst_QGL::graphicsViewClipping() { -#ifdef QT_NO_OPENGL - QSKIP("QGL not supported", SkipAll); -#else const int size = 64; UnclippedWidget *widget = new UnclippedWidget; widget->setFixedSize(size, size); @@ -403,7 +391,6 @@ void tst_QGL::graphicsViewClipping() p.end(); QCOMPARE(image, expected); -#endif } void tst_QGL::partialGLWidgetUpdates_data() @@ -420,9 +407,6 @@ void tst_QGL::partialGLWidgetUpdates_data() void tst_QGL::partialGLWidgetUpdates() { -#ifdef QT_NO_OPENGL - QSKIP("QGL not yet supported", SkipAll); -#else if (!QGLFormat::hasOpenGL()) QSKIP("QGL not supported on this platform", SkipAll); @@ -466,7 +450,6 @@ void tst_QGL::partialGLWidgetUpdates() QCOMPARE(widget.paintEventRegion, QRegion(50, 50, 50, 50)); else QCOMPARE(widget.paintEventRegion, QRegion(widget.rect())); -#endif } QTEST_MAIN(tst_QGL) diff --git a/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro b/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro index 3283873..e19d962 100644 --- a/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro +++ b/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro @@ -2,4 +2,6 @@ load(qttest_p4) SOURCES += tst_qhttpnetworkconnection.cpp INCLUDEPATH += $$(QTDIR)/src/3rdparty/zlib +requires(contains(QT_CONFIG,private_tests)) + QT = core network diff --git a/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro b/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro index 2e41fcd..f86250a 100644 --- a/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro +++ b/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro @@ -2,4 +2,6 @@ load(qttest_p4) SOURCES += tst_qhttpnetworkreply.cpp INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/zlib +requires(contains(QT_CONFIG,private_tests)) + QT = core network diff --git a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp index d9a7d56..e235ff5 100644 --- a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp +++ b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp @@ -59,13 +59,13 @@ void tst_QItemEditorFactory::createEditor() QCOMPARE(w->metaObject()->className(), "QExpandingLineEdit"); } -void tst_QItemEditorFactory::createCustomEditor() +//we make it inherit from QObject so that we can use QPointer +class MyEditor : public QObject, public QStandardItemEditorCreator { - //we make it inherit from QObject so that we can use QPointer - class MyEditor : public QObject, public QStandardItemEditorCreator - { - }; +}; +void tst_QItemEditorFactory::createCustomEditor() +{ QPointer creator = new MyEditor; QPointer creator2 = new MyEditor; diff --git a/tests/auto/qkeysequence/tst_qkeysequence.cpp b/tests/auto/qkeysequence/tst_qkeysequence.cpp index aeb57ef..2e4b850 100644 --- a/tests/auto/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/qkeysequence/tst_qkeysequence.cpp @@ -270,7 +270,7 @@ void tst_QKeySequence::checkMultipleNames() void tst_QKeySequence::ensureSorted() { //### accessing static members from private classes does not work on msvc at the moment -#ifndef Q_WS_WIN +#if defined(QT_BUILD_INTERNAL) && !defined(Q_WS_WIN) uint N = QKeySequencePrivate::numberOfKeyBindings; uint val = QKeySequencePrivate::keyBindings[0].shortcut; for ( uint i = 1 ; i < N ; ++i) { diff --git a/tests/auto/qmainwindow/tst_qmainwindow.cpp b/tests/auto/qmainwindow/tst_qmainwindow.cpp index e46c2e1..6ae7a3e 100644 --- a/tests/auto/qmainwindow/tst_qmainwindow.cpp +++ b/tests/auto/qmainwindow/tst_qmainwindow.cpp @@ -1400,6 +1400,7 @@ void AddDockWidget::apply(QMainWindow *mw) const } } +#ifdef QT_BUILD_INTERNAL struct MoveSeparator { MoveSeparator() {} @@ -1436,6 +1437,7 @@ void MoveSeparator::apply(QMainWindow *mw) const l->layoutState.dockAreaLayout.separatorMove(path, QPoint(0, 0), QPoint(delta, delta)); } +#endif QMap dockWidgetGeometries(QMainWindow *mw) { @@ -1463,6 +1465,7 @@ QMap dockWidgetGeometries(QMainWindow *mw) void tst_QMainWindow::saveRestore_data() { +#ifdef QT_BUILD_INTERNAL QTest::addColumn("addList"); QTest::addColumn("moveList"); @@ -1497,10 +1500,12 @@ void tst_QMainWindow::saveRestore_data() << MoveSeparator(-30, "right1") << MoveSeparator(30, "right2a") ); +#endif } void tst_QMainWindow::saveRestore() { +#ifdef QT_BUILD_INTERNAL QFETCH(AddList, addList); QFETCH(MoveList, moveList); @@ -1570,6 +1575,7 @@ void tst_QMainWindow::saveRestore() mainWindow.show(); COMPARE_DOCK_WIDGET_GEOS(dockWidgetGeos, dockWidgetGeometries(&mainWindow)); } +#endif } void tst_QMainWindow::iconSizeChanged() diff --git a/tests/auto/qnativesocketengine/qnativesocketengine.pro b/tests/auto/qnativesocketengine/qnativesocketengine.pro index 320f24c..ad40d53 100644 --- a/tests/auto/qnativesocketengine/qnativesocketengine.pro +++ b/tests/auto/qnativesocketengine/qnativesocketengine.pro @@ -3,6 +3,8 @@ SOURCES += tst_qnativesocketengine.cpp include(../qnativesocketengine/qsocketengine.pri) +requires(contains(QT_CONFIG,private_tests)) + MOC_DIR=tmp QT = core network diff --git a/tests/auto/qnetworkreply/qnetworkreply.pro b/tests/auto/qnetworkreply/qnetworkreply.pro index 0bcf067..fd8454c 100644 --- a/tests/auto/qnetworkreply/qnetworkreply.pro +++ b/tests/auto/qnetworkreply/qnetworkreply.pro @@ -1,4 +1,6 @@ TEMPLATE = subdirs SUBDIRS = test +requires(contains(QT_CONFIG,private_tests)) + !wince*:SUBDIRS += echo diff --git a/tests/auto/qpathclipper/qpathclipper.pro b/tests/auto/qpathclipper/qpathclipper.pro index 675e463..dc9d60f 100644 --- a/tests/auto/qpathclipper/qpathclipper.pro +++ b/tests/auto/qpathclipper/qpathclipper.pro @@ -3,6 +3,8 @@ INCLUDEPATH += . HEADERS += paths.h SOURCES += tst_qpathclipper.cpp paths.cpp +requires(contains(QT_CONFIG,private_tests)) + unix:!mac:LIBS+=-lm diff --git a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp index fceefd2..40ad539 100644 --- a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp @@ -1106,6 +1106,7 @@ void tst_QPlainTextEdit::mimeDataReimplementations() QCOMPARE(ed.canInsertCallCount, 0); QCOMPARE(ed.insertCallCount, 0); +#ifdef QT_BUILD_INTERNAL QTextControl *control = qFindChild(&ed); QVERIFY(control); @@ -1120,6 +1121,7 @@ void tst_QPlainTextEdit::mimeDataReimplementations() QCOMPARE(ed.createMimeDataCallCount, 1); QCOMPARE(ed.canInsertCallCount, 1); QCOMPARE(ed.insertCallCount, 1); +#endif } void tst_QPlainTextEdit::shiftEnterShouldInsertLineSeparator() diff --git a/tests/auto/qregion/tst_qregion.cpp b/tests/auto/qregion/tst_qregion.cpp index 3ffa87e..2ad202d 100644 --- a/tests/auto/qregion/tst_qregion.cpp +++ b/tests/auto/qregion/tst_qregion.cpp @@ -96,7 +96,7 @@ private slots: #ifdef Q_OS_WIN void handle(); #endif -#ifdef Q_WS_X11 +#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL) void clipRectangles(); #endif @@ -865,7 +865,7 @@ void tst_QRegion::handle() } #endif -#ifdef Q_WS_X11 +#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL) void tst_QRegion::clipRectangles() { QRegion region(30, 30, 30, 30); @@ -967,6 +967,7 @@ void tst_QRegion::regionToPath_data() void tst_QRegion::regionToPath() { +#ifdef QT_BUILD_INTERNAL extern QPainterPath qt_regionToPath(const QRegion ®ion); QFETCH(QPainterPath, path); @@ -1002,6 +1003,7 @@ void tst_QRegion::regionToPath() QCOMPARE(ia, ib); QCOMPARE(a.boundingRect(), b.boundingRect()); } +#endif } QTEST_MAIN(tst_QRegion) diff --git a/tests/auto/qsettings/tst_qsettings.cpp b/tests/auto/qsettings/tst_qsettings.cpp index f0f446d..77fef1f 100644 --- a/tests/auto/qsettings/tst_qsettings.cpp +++ b/tests/auto/qsettings/tst_qsettings.cpp @@ -713,6 +713,7 @@ void tst_QSettings::testErrorHandling_data() void tst_QSettings::testErrorHandling() { +#ifdef QT_BUILD_INTERNAL #ifdef Q_OS_WIN QSKIP("Windows doesn't support most file modes, including read-only directories, so this test is moot.", SkipAll); #else @@ -776,6 +777,7 @@ void tst_QSettings::testErrorHandling() QCOMPARE((int)settings.status(), statusAfterSetAndSync); } #endif // !Q_OS_WIN +#endif } Q_DECLARE_METATYPE(QVariant) @@ -821,6 +823,7 @@ void tst_QSettings::testIniParsing_data() void tst_QSettings::testIniParsing() { +#ifdef QT_BUILD_INTERNAL qRegisterMetaType("QVariant"); qRegisterMetaType("QSettings::Status"); @@ -854,6 +857,7 @@ void tst_QSettings::testIniParsing() } QCOMPARE(settings.status(), status); +#endif } /* @@ -1058,6 +1062,7 @@ void tst_QSettings::testVariantTypes_data() void tst_QSettings::testVariantTypes() { +#ifdef QT_BUILD_INTERNAL #define testVal(key, val, tp, rtype) \ { \ QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP"); \ @@ -1141,6 +1146,7 @@ void tst_QSettings::testVariantTypes() } #undef testVal +#endif } void tst_QSettings::remove() @@ -1801,9 +1807,7 @@ void tst_QSettings::testNormalizedKey_data() void tst_QSettings::testNormalizedKey() { -#ifdef QTEST_REDUCED_EXPORTS - QSKIP("We can't test QSettingsPrivate on Windows", SkipAll); -#else +#ifdef QT_BUILD_INTERNAL QFETCH(QString, inKey); QFETCH(QString, outKey); @@ -1981,6 +1985,7 @@ void tst_QSettings::fromFile() void tst_QSettings::setIniCodec() { +#ifdef QT_BUILD_INTERNAL QByteArray expeContents4, expeContents5; QByteArray actualContents4, actualContents5; @@ -2040,6 +2045,7 @@ void tst_QSettings::setIniCodec() QCOMPARE(settings4.allKeys().first(), settings5.allKeys().first()); QCOMPARE(settings4.value(settings4.allKeys().first()).toString(), settings5.value(settings5.allKeys().first()).toString()); +#endif } static bool containsSubList(QStringList mom, QStringList son) @@ -2316,6 +2322,7 @@ void tst_QSettings::testArrays() settings1.endArray(); } +#ifdef QT_BUILD_INTERNAL static QByteArray iniEscapedKey(const QString &str) { QByteArray result; @@ -2360,6 +2367,7 @@ static QStringList iniUnescapedStringList(const QByteArray &ba) #endif return result; } +#endif QString escapeWeirdChars(const QString &s) { @@ -2383,6 +2391,7 @@ QString escapeWeirdChars(const QString &s) void tst_QSettings::testEscapes() { +#ifdef QT_BUILD_INTERNAL QSettings settings(QSettings::UserScope, "software.org", "KillerAPP"); #define testEscapedKey(plainKey, escKey) \ @@ -2505,6 +2514,7 @@ void tst_QSettings::testEscapes() testBadEscape("@Rect)", "@Rect)"); testBadEscape("@Rect(1 2 3)", "@Rect(1 2 3)"); testBadEscape("@@Rect(1 2 3)", "@Rect(1 2 3)"); +#endif } void tst_QSettings::testCompatFunctions() @@ -3355,6 +3365,7 @@ void tst_QSettings::childGroups_data() void tst_QSettings::childGroups() { +#ifdef QT_BUILD_INTERNAL QFETCH(QSettings::Format, format); { @@ -3408,6 +3419,7 @@ void tst_QSettings::childGroups() QCOMPARE(settings.childGroups(), QStringList() << "alpha" << "gamma" << "omicron" << "zeta"); } +#endif } void tst_QSettings::childKeys_data() @@ -3417,6 +3429,7 @@ void tst_QSettings::childKeys_data() void tst_QSettings::childKeys() { +#ifdef QT_BUILD_INTERNAL QFETCH(QSettings::Format, format); { @@ -3470,6 +3483,7 @@ void tst_QSettings::childKeys() QCOMPARE(settings.childKeys(), QStringList() << "alpha" << "beta" << "gamma"); } +#endif } void tst_QSettings::allKeys_data() @@ -3479,6 +3493,7 @@ void tst_QSettings::allKeys_data() void tst_QSettings::allKeys() { +#ifdef QT_BUILD_INTERNAL QFETCH(QSettings::Format, format); QStringList allKeys; @@ -3527,6 +3542,7 @@ void tst_QSettings::allKeys() QCOMPARE(settings.allKeys(), allKeys); } +#endif } void tst_QSettings::registerFormat() diff --git a/tests/auto/qsharedpointer/qsharedpointer.pro b/tests/auto/qsharedpointer/qsharedpointer.pro index 30c81cb..90fde06 100644 --- a/tests/auto/qsharedpointer/qsharedpointer.pro +++ b/tests/auto/qsharedpointer/qsharedpointer.pro @@ -4,5 +4,6 @@ SOURCES += tst_qsharedpointer.cpp \ forwarddeclared.cpp QT = core DEFINES += SRCDIR=\\\"$$PWD/\\\" +requires(contains(QT_CONFIG,private_tests)) include(externaltests.pri) HEADERS += forwarddeclared.h diff --git a/tests/auto/qsocketnotifier/qsocketnotifier.pro b/tests/auto/qsocketnotifier/qsocketnotifier.pro index 10ed3a5..ec924c1 100644 --- a/tests/auto/qsocketnotifier/qsocketnotifier.pro +++ b/tests/auto/qsocketnotifier/qsocketnotifier.pro @@ -2,6 +2,8 @@ load(qttest_p4) SOURCES += tst_qsocketnotifier.cpp QT = core network +requires(contains(QT_CONFIG,private_tests)) + include(../qnativesocketengine/qsocketengine.pri) diff --git a/tests/auto/qsocks5socketengine/qsocks5socketengine.pro b/tests/auto/qsocks5socketengine/qsocks5socketengine.pro index 2949ee2..d19b732 100644 --- a/tests/auto/qsocks5socketengine/qsocks5socketengine.pro +++ b/tests/auto/qsocks5socketengine/qsocks5socketengine.pro @@ -11,3 +11,4 @@ QT = core network +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp index fa44034..fba7b1b 100644 --- a/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp +++ b/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp @@ -1454,6 +1454,7 @@ static QStandardItem *itemFromText(QStandardItem *parent, const QString &text) return item; } +#ifdef QT_BUILD_INTERNAL static QModelIndex indexFromText(QStandardItemModel *model, const QString &text) { QStandardItem *item = itemFromText(model->invisibleRootItem(), text); @@ -1467,9 +1468,11 @@ struct FriendlyTreeView : public QTreeView friend class tst_QStandardItemModel; Q_DECLARE_PRIVATE(QTreeView) }; +#endif void tst_QStandardItemModel::treeDragAndDrop() { +#ifdef QT_BUILD_INTERNAL const int nRow = 5; const int nCol = 3; @@ -1605,6 +1608,7 @@ void tst_QStandardItemModel::treeDragAndDrop() QVERIFY(compareModels(&model, &checkModel)); } +#endif } void tst_QStandardItemModel::removeRowsAndColumns() diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index a859866..efcb983 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -1015,6 +1015,7 @@ void tst_QStateMachine::rootState() void tst_QStateMachine::addAndRemoveState() { +#ifdef QT_BUILD_INTERNAL QStateMachine machine; QStatePrivate *root_d = QStatePrivate::get(machine.rootState()); QCOMPARE(root_d->childStates().size(), 0); @@ -1075,6 +1076,7 @@ void tst_QStateMachine::addAndRemoveState() delete s2; // ### how to deal with this? // machine.removeState(machine.errorState()); +#endif } void tst_QStateMachine::stateEntryAndExit() diff --git a/tests/auto/qstylesheetstyle/qstylesheetstyle.pro b/tests/auto/qstylesheetstyle/qstylesheetstyle.pro index 6acb0b4..f6101f4 100644 --- a/tests/auto/qstylesheetstyle/qstylesheetstyle.pro +++ b/tests/auto/qstylesheetstyle/qstylesheetstyle.pro @@ -13,3 +13,4 @@ contains(QT_CONFIG, qt3support): QT += qt3support # Input SOURCES += tst_qstylesheetstyle.cpp RESOURCES += resources.qrc +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index 7b62eae..3f658ec 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -625,9 +625,11 @@ void tst_QSvgRenderer::testGzLoading() QVERIFY(autoDetectGzData.isValid()); } +#ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE QByteArray qt_inflateGZipDataFrom(QIODevice *device); QT_END_NAMESPACE +#endif void tst_QSvgRenderer::testGzHelper_data() { @@ -660,6 +662,7 @@ void tst_QSvgRenderer::testGzHelper_data() void tst_QSvgRenderer::testGzHelper() { +#ifdef QT_BUILD_INTERNAL QFETCH(QByteArray, in); QFETCH(QByteArray, out); @@ -668,6 +671,7 @@ void tst_QSvgRenderer::testGzHelper() QVERIFY(buffer.isReadable()); QByteArray result = qt_inflateGZipDataFrom(&buffer); QCOMPARE(result, out); +#endif } #endif diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 3bc1517..d54645c 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -1460,6 +1460,7 @@ void tst_QTextEdit::mimeDataReimplementations() QCOMPARE(ed.canInsertCallCount, 0); QCOMPARE(ed.insertCallCount, 0); +#ifdef QT_BUILD_INTERNAL QTextControl *control = qFindChild(&ed); QVERIFY(control); @@ -1474,6 +1475,7 @@ void tst_QTextEdit::mimeDataReimplementations() QCOMPARE(ed.createMimeDataCallCount, 1); QCOMPARE(ed.canInsertCallCount, 1); QCOMPARE(ed.insertCallCount, 1); +#endif } void tst_QTextEdit::ctrlEnterShouldInsertLineSeparator_NOT() @@ -2066,6 +2068,7 @@ void tst_QTextEdit::cursorRect() void tst_QTextEdit::setDocumentPreservesPalette() { +#ifdef QT_BUILD_INTERNAL QTextControl *control = qFindChild(ed); QVERIFY(control); @@ -2085,6 +2088,7 @@ void tst_QTextEdit::setDocumentPreservesPalette() QVERIFY(control->document() == newDoc); QVERIFY(whitePal.color(QPalette::Active, QPalette::Text) == control->palette().color(QPalette::Active, QPalette::Text)); +#endif } class PublicTextEdit : public QTextEdit diff --git a/tests/auto/qtextpiecetable/qtextpiecetable.pro b/tests/auto/qtextpiecetable/qtextpiecetable.pro index 318a8c7..0926b83 100644 --- a/tests/auto/qtextpiecetable/qtextpiecetable.pro +++ b/tests/auto/qtextpiecetable/qtextpiecetable.pro @@ -2,7 +2,6 @@ load(qttest_p4) SOURCES += tst_qtextpiecetable.cpp HEADERS += ../qtextdocument/common.h -!win32:DEFINES += QTEST_REDUCED_EXPORTS - - +requires(!win32) +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp b/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp index accbabb..0e60c16 100644 --- a/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp +++ b/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp @@ -42,9 +42,7 @@ #include -#ifdef QTEST_REDUCED_EXPORTS #define private public -#endif #include #include @@ -65,7 +63,6 @@ public: tst_QTextPieceTable(); -#ifdef QTEST_REDUCED_EXPORTS public slots: void init(); void cleanup(); @@ -112,13 +109,7 @@ private slots: void removeFrameDirect(); void removeWithChildFrame(); void clearWithFrames(); -#else -public slots: - void init(); - void cleanup(); -private slots: - void skip(); -#endif + private: QTextDocument *doc; QTextDocumentPrivate *table; @@ -130,8 +121,6 @@ tst_QTextPieceTable::tst_QTextPieceTable() { doc = 0; table = 0; } -#ifdef QTEST_REDUCED_EXPORTS - void tst_QTextPieceTable::init() { doc = new QTextDocument(0); @@ -1148,25 +1137,6 @@ void tst_QTextPieceTable::clearWithFrames() QVERIFY(true); } -#else // QTEST_REDUCED_EXPORTS - -void tst_QTextPieceTable::init() -{ -} - -void tst_QTextPieceTable::cleanup() -{ -} - -void tst_QTextPieceTable::skip() -{ - QSKIP( "Not tested on win32", SkipAll ); -} - - -#endif // QTEST_REDUCED_EXPORTS - - QTEST_MAIN(tst_QTextPieceTable) diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index ea551da..723f882 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -3057,12 +3057,15 @@ void tst_QUrl::nameprep_testsuite_data() << QString() << 0 << 0; } +#ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE extern QString qt_nameprep(const QString &source); QT_END_NAMESPACE +#endif void tst_QUrl::nameprep_testsuite() { +#ifdef QT_BUILD_INTERNAL QFETCH(QString, in); QFETCH(QString, out); QFETCH(QString, profile); @@ -3082,6 +3085,7 @@ void tst_QUrl::nameprep_testsuite() QEXPECT_FAIL("Larger test (expanding)", "Investigate further", Continue); QCOMPARE(qt_nameprep(in), out); +#endif } void tst_QUrl::ace_testsuite_data() diff --git a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro index e90b335..3d82eaf 100644 --- a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro +++ b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro @@ -2,3 +2,4 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS = ../xmlpatternsxqts test +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsview/xmlpatternsview.pro b/tests/auto/xmlpatternsview/xmlpatternsview.pro index 3544264..04ee4d0 100644 --- a/tests/auto/xmlpatternsview/xmlpatternsview.pro +++ b/tests/auto/xmlpatternsview/xmlpatternsview.pro @@ -6,3 +6,4 @@ SUBDIRS = ../xmlpatternsxqts test contains(QT_CONFIG,xmlpatterns) { SUBDIRS += view } +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro index 368a028..a3b13da 100644 --- a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro +++ b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro @@ -9,3 +9,6 @@ contains(QT_CONFIG,xmlpatterns) { # Needed on the win32-g++ setup and on the test machine arsia. INCLUDEPATH += $$QT_BUILD_TREE/include/QtXmlPatterns/private \ ../../../include/QtXmlPatterns/private + +requires(contains(QT_CONFIG,private_tests)) + diff --git a/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro b/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro index 4a688c4..9b63a52 100644 --- a/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro +++ b/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro @@ -23,3 +23,4 @@ wince*: { DEPLOYMENT += testdata } +requires(contains(QT_CONFIG,private_tests)) -- cgit v0.12 From 21b32a69fc4607e60677b978fbcdc6424cc4f63b Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 9 Jul 2009 14:36:26 +1000 Subject: New configure.exe. Includes: 9b532a999944c70c2e8f57d9156c1887867ad9f1 - qtlibinfix bb8e25a5074a378d5003577fefbeabb1de846a81 - cetest fix 5ea86cfac34f65b2321ceeeb651e4e7099bf59a0 - QT_WA removal 349997b5c4167b07d0bdc55beff175b39f3abe75 - spelling fix bae8bc5d23946036b2c1079fc6f1b3bceeaa19ca - QT_CONFIG+=private_tests --- configure.exe | Bin 835584 -> 1101312 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index a139116..10b926e 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From 458c547aefcb529fe807a220109e2a7ce6bd9105 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 9 Jul 2009 16:51:41 +1000 Subject: Improved cetest error reporting. Now, if you try to run an unsigned test on a locked device, you'll get: "Error invoking qRemoteLaunch on \Windows\QtRemote.dll: Invalid Signature. (0x80090006)" Instead of what you would previously get: "Error: Could not execute target file" --- tools/qtestlib/wince/cetest/activesyncconnection.cpp | 12 ++++++++---- tools/qtestlib/wince/cetest/remoteconnection.cpp | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 0f98619..1080477 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -385,10 +385,14 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo DWORD error = 0; HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); if (S_OK != res) { - if (S_OK != CeGetLastError()) - debugOutput(QString::fromLatin1("Error: Could not invoke method on QtRemote"),1); - else - debugOutput(QString::fromLatin1("Error: QtRemote return unexpectedly with error Code %1").arg(res), 1); + DWORD ce_error = CeGetLastError(); + if (S_OK != ce_error) { + qWarning("Error invoking %s on %s: %s", qPrintable(functionName), + qPrintable(dllLocation), strwinerror(ce_error).constData()); + } else { + qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), + qPrintable(dllLocation), res); + } } else { DWORD written; int strSize = program.length(); diff --git a/tools/qtestlib/wince/cetest/remoteconnection.cpp b/tools/qtestlib/wince/cetest/remoteconnection.cpp index 75788e2..3d0c3f3 100644 --- a/tools/qtestlib/wince/cetest/remoteconnection.cpp +++ b/tools/qtestlib/wince/cetest/remoteconnection.cpp @@ -66,8 +66,8 @@ QByteArray strwinerror(DWORD errorcode) out.chop(2); /* Append error number to error message for good measure */ - out.append(" ("); - out.append(QByteArray::number((int)errorcode)); + out.append(" (0x"); + out.append(QByteArray::number(uint(errorcode), 16).rightJustified(8, '0')); out.append(")"); } return out; -- cgit v0.12 From c365e7e91feab7d07653e0086ba297bb1f8a6234 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 9 Jul 2009 17:03:58 +1000 Subject: Let cetest return nonzero when it fails to run a test. --- tools/qtestlib/wince/cetest/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp index ba3ef8d..782f6d9 100644 --- a/tools/qtestlib/wince/cetest/main.cpp +++ b/tools/qtestlib/wince/cetest/main.cpp @@ -320,6 +320,7 @@ int main(int argc, char **argv) cout << endl << "Remote Launch:" << qPrintable(TestConfiguration::remoteExecutable) << " " << qPrintable(launchArguments.join(" ")) << endl; if (!connection.execute(TestConfiguration::remoteExecutable, launchArguments.join(" "), timeout)) { cout << "Error: Could not execute target file" << endl; + return -1; } -- cgit v0.12 From dc2b39a866190e302eed171381c2c0384e152800 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 9 Jul 2009 09:25:30 +0200 Subject: qdoc: Removed unnecessary error report/rule qdoc reported an error if you used \section2 on its owin, i.e. with no outer \section1. While strictly speaking correct, it imposed an unnecessary restriction, e.g. sometimes you just want to use \section2 to get a smaller title for a section. --- tools/qdoc3/doc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index 222b9a1..d5aca0e 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -1677,10 +1677,13 @@ void DocParser::startSection(Doc::SectioningUnit unit, int cmd) leavePara(); if (currentSectioningUnit == Doc::Book) { +#if 0 + // mws didn't think this was necessary. if (unit > Doc::Section1) location().warning(tr("Unexpected '\\%1' without '\\%2'") .arg(cmdName(cmd)) .arg(cmdName(CMD_SECTION1))); +#endif currentSectioningUnit = (Doc::SectioningUnit) (unit - 1); priv->constructExtra(); priv->extra->sectioningUnit = currentSectioningUnit; -- cgit v0.12 From d0a36a9e33937066866ef1ecfde3eaecd578d0b7 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 9 Jul 2009 10:37:26 +0200 Subject: Add QT_END_HEADER to fix compile on PowerPC Mac and make autotest pass. --- src/corelib/tools/qstring.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 6bb0d8e..235c603 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1235,6 +1235,8 @@ inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef QT_END_NAMESPACE +QT_END_HEADER + #ifdef QT_USE_FAST_CONCATENATION #include #endif -- cgit v0.12 From 015946b60c991593d28cd1d9383f0eb7e8c30334 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 9 Jul 2009 10:40:13 +0200 Subject: Remove unneeded assert. Triggered on Designer startup on Linux. Acked-by: Thierry Bastian --- src/gui/widgets/qwidgetanimator.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index 26cf905..1a93b51 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -100,7 +100,6 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo m_animation_map[widget] = anim; connect(anim, SIGNAL(finished()), SLOT(animationFinished())); anim->start(QPropertyAnimation::DeleteWhenStopped); - Q_ASSERT(animate || widget->geometry() == final_geometry); #else //we do it in one shot widget->setGeometry(final_geometry); -- cgit v0.12 From def00d15449551cd2e98b1f3f5b4199ad8be92c2 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 12:14:38 +0200 Subject: autotest fix On the font from the font dialog, we can only test family, size and style --- tests/auto/qfontdialog/tst_qfontdialog.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/auto/qfontdialog/tst_qfontdialog.cpp b/tests/auto/qfontdialog/tst_qfontdialog.cpp index 5f1797b..cbdd440 100644 --- a/tests/auto/qfontdialog/tst_qfontdialog.cpp +++ b/tests/auto/qfontdialog/tst_qfontdialog.cpp @@ -170,8 +170,12 @@ void tst_QFontDialog::task256466_wrongStyle() for (int i = 0; i < familyList->model()->rowCount(); ++i) { QModelIndex currentFamily = familyList->model()->index(i, 0); familyList->setCurrentIndex(currentFamily); - QCOMPARE(dialog.currentFont(), fdb.font(currentFamily.data().toString(), - styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt())); + const QFont current = dialog.currentFont(), + expected = fdb.font(currentFamily.data().toString(), + styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt()); + QCOMPARE(current.family(), expected.family()); + QCOMPARE(current.style(), expected.style()); + QCOMPARE(current.pointSizeF(), expected.pointSizeF()); } } -- cgit v0.12 From ce770ef755e2dae405ea3c91bd0dedda2f267716 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 9 Jul 2009 10:52:50 +0200 Subject: QRingBuffer micro optimization --- src/corelib/tools/qringbuffer_p.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index f3daca7..008c068 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -303,6 +303,9 @@ public: // read an unspecified amount (will read the first buffer) inline QByteArray read() { + if (bufferSize == 0) + return QByteArray(); + // multiple buffers, just take the first one if (head == 0 && tailBuffer != 0) { QByteArray qba = buffers.takeFirst(); @@ -325,7 +328,7 @@ public: // We can avoid by initializing the QRingBuffer with basicBlockSize of 0 // and only using this read() function. QByteArray qba(readPointer(), nextDataBlockSize()); - buffers.takeFirst(); + buffers.removeFirst(); head = 0; if (tailBuffer == 0) { buffers << QByteArray(); -- cgit v0.12 From 259575734a52c27018f26e1f7c857ae25a27d39a Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 9 Jul 2009 11:35:56 +0200 Subject: doc: Clarified the meanings in Qt for reentrant and thread-safe. Task-number: 189232 --- doc/src/threads.qdoc | 82 ++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/doc/src/threads.qdoc b/doc/src/threads.qdoc index 9f7f857..e3da0d4 100644 --- a/doc/src/threads.qdoc +++ b/doc/src/threads.qdoc @@ -262,48 +262,41 @@ \keyword thread-safe \section1 Reentrancy and Thread-Safety - Throughout the Qt documentation, the terms \e reentrant and \e - thread-safe are used to specify how a function can be used in - multithreaded applications: + Throughout the documentation, the terms \e{reentrant} and + \e{thread-safe} are used to mark classes and functions to indicate + how they can be used in multithread applications: \list - \o A \e reentrant function can be called simultaneously by - multiple threads provided that each invocation of the function - references unique data. - \o A \e thread-safe function can be called simultaneously by - multiple threads when each invocation references shared data. - All access to the shared data is serialized. + \o A \e thread-safe function can be called simultaneously from + multiple threads, even when the invocations use shared data, + because all references to the shared data are serialized. + \o A \e reentrant function can also be called simultaneously from + multiple threads, but only if each invocation uses its own data. \endlist - By extension, a class is said to be reentrant if each and every - one of its functions can be called simultaneously by multiple - threads on different instances of the class. Similarly, the class - is said to be thread-safe if the functions can be called by - different threads on the same instance. + Hence, a \e{thread-safe} function is always \e{reentrant}, but a + \e{reentrant} function is not always \e{thread-safe}. - Classes in the documentation will be documented as thread-safe only - if they are intended to be used by multiple threads. + By extension, a class is said to be \e{reentrant} if its member + functions can be called safely from multiple threads as long as + each thread uses a \e{different} instance of the class. The class + is \e{thread-safe} if its member functions can be called safely + from multiple threads, even if all the threads use the \e{same} + instance of the class. - Note that the terminology in this domain isn't entirely - standardized. POSIX uses a somewhat different definition of - reentrancy and thread-safety for its C APIs. When dealing with an - object-oriented C++ class library such as Qt, the definitions - must be adapted. - - Most C++ classes are inherently reentrant, since they typically - only reference member data. Any thread can call such a member - function on an instance of the class, as long as no other thread - is calling a member function on the same instance. For example, - the \c Counter class below is reentrant: + C++ classes are often reentrant, simply because they only access + their own member data. Any thread can call a member function on an + instance of a reentrant class, as long as no other thread can call + a member function on the \e{same} instance of the class at the + same time. For example, the \c Counter class below is reentrant: \snippet doc/src/snippets/threads/threads.cpp 3 \snippet doc/src/snippets/threads/threads.cpp 4 The class isn't thread-safe, because if multiple threads try to modify the data member \c n, the result is undefined. This is - because C++'s \c ++ and \c -- operators aren't necessarily - atomic. Indeed, they usually expand to three machine - instructions: + because the \c ++ and \c -- operators aren't always atomic. + Indeed, they usually expand to three machine instructions: \list 1 \o Load the variable's value in a register. @@ -332,14 +325,27 @@ declared with the \c mutable qualifier because we need to lock and unlock the mutex in \c value(), which is a const function. - Most Qt classes are reentrant and not thread-safe, to avoid the - overhead of repeatedly locking and unlocking a QMutex. For - example, QString is reentrant, meaning that you can use it in - different threads, but you can't access the same QString object - from different threads simultaneously (unless you protect it with - a mutex yourself). A few classes and functions are thread-safe; - these are mainly thread-related classes such as QMutex, or - fundamental functions such as QCoreApplication::postEvent(). + Most Qt classes are \e{reentrant}, but they are not made + \e{thread-safe}, because making them thread-safe would incur the + extra overhead of repeatedly locking and unlocking a QMutex. For + example, QString is reentrant but not thread-safe. You can safely + access \e{different} instances of QString from multiple threads + simultaneously, but you can't access the \e{same} instance of + QString from multiple threads simultaneously (unless you protect + the accesses yourself with a QMutex). + + Some Qt classes and functions are thread-safe. These are mainly + the thread-related classes (e.g. QMutex) and fundamental functions + (e.g. QCoreApplication::postEvent()). + + \note Qt Classes are only documented as \e{thread-safe} if they + are intended to be used by multiple threads. + + \note Terminology in the multithreading domain isn't entirely + standardized. POSIX uses definitions of reentrant and thread-safe + that are somewhat different for its C APIs. When using other + object-oriented C++ class libraries with Qt, be sure the + definitions in use are understood. \section1 Threads and QObjects -- cgit v0.12 From 14ef40f9b96c5afea9d08701a2a1856388349f9e Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 3 Jul 2009 16:32:26 +0200 Subject: Use 'struct QConcatenable' instead of 'class QConcatenable' to make compiler distinguishing both happy. --- src/corelib/tools/qstringbuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 852c072..4d6b64b 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -69,7 +69,7 @@ private: }; -template class QConcatenable {}; +template struct QConcatenable {}; template class QStringBuilder -- cgit v0.12 From 6574240d8ea657d02c3d5bf5567da7d28f42d69b Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 9 Jul 2009 12:40:22 +0200 Subject: QHttpNetworkReply: Cache isChunked Cache return value of expensive function. Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkreply.cpp | 6 +++++- src/network/access/qhttpnetworkreply_p.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 483589b..7a616aa 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -201,6 +201,7 @@ bool QHttpNetworkReply::isFinished() const QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100), majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0), + chunkedTransferEncoding(0), currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false), autoDecompress(false), responseData(0), requestIsPrepared(false) { @@ -506,6 +507,9 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) state = ReadingDataState; fragment.clear(); // next fragment bodyLength = contentLength(); // cache the length + + // cache isChunked() since it is called often + chunkedTransferEncoding = headerField("transfer-encoding").toLower().contains("chunked"); } return bytes; } @@ -546,7 +550,7 @@ void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header) bool QHttpNetworkReplyPrivate::isChunked() { - return headerField("transfer-encoding").toLower().contains("chunked"); + return chunkedTransferEncoding; } bool QHttpNetworkReplyPrivate::connectionCloseEnabled() diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index b86cfaa..5eb70ce 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -198,6 +198,7 @@ public: qint64 contentRead; qint64 totalProgress; QByteArray fragment; // used for header, status, chunk header etc, not for reply data + bool chunkedTransferEncoding; qint64 currentChunkSize; qint64 currentChunkRead; QPointer connection; -- cgit v0.12 From 1c6edd28d528dbb946fcf2a9e0d4349075ca6f9b Mon Sep 17 00:00:00 2001 From: Suneel BS Date: Tue, 7 Jul 2009 14:57:02 +0530 Subject: Fixed inheritence of SVG fill attributes. Fixed inheritence of fill-opacity, fill-rule and fill. Autotest included. Reviewed-by: Kim --- src/svg/qsvghandler.cpp | 57 ++++++++++++++--------- src/svg/qsvgstyle.cpp | 14 +++++- src/svg/qsvgstyle_p.h | 28 +++++++----- tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 68 ++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 35 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 5950fac..f64fb3e 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -631,15 +631,32 @@ static void parseBrush(QSvgNode *node, QString opacity = attributes.value(QLatin1String("fill-opacity")).toString(); QString myId = someId(attributes); - value = value.trimmed(); - fillRule = fillRule.trimmed(); - if (!value.isEmpty() || !fillRule.isEmpty()) { - Qt::FillRule f = Qt::WindingFill; + QSvgFillStyle *inherited = + static_cast(node->parent()->styleProperty( + QSvgStyleProperty::FILL)); + QSvgFillStyle *prop = new QSvgFillStyle(QColor(Qt::black)); + + //fill-rule attribute handling + Qt::FillRule f = Qt::WindingFill; + if (!fillRule.isEmpty() && fillRule != QLatin1String("inherit")) { if (fillRule == QLatin1String("evenodd")) f = Qt::OddEvenFill; + } else if (inherited) { + f = inherited->fillRule(); + } + + //fill-opacity atttribute handling + qreal fillOpacity = 1.0; + if (!opacity.isEmpty() && opacity != QLatin1String("inherit")) { + fillOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); + } else if (inherited) { + fillOpacity = inherited->fillOpacity(); + } + + //fill attribute handling + if ((!value.isEmpty()) && (value != QLatin1String("inherit")) ) { if (value.startsWith(QLatin1String("url"))) { value = value.remove(0, 3); - QSvgFillStyle *prop = new QSvgFillStyle(0); QSvgStyleProperty *style = styleFromUrl(node, value); if (style) { prop->setFillStyle(style); @@ -648,30 +665,26 @@ static void parseBrush(QSvgNode *node, prop->setGradientId(id); prop->setGradientResolved(false); } - if (!opacity.isEmpty()) { - qreal clampedOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); - prop->setFillOpacity(clampedOpacity); - } - if (!fillRule.isEmpty()) - prop->setFillRule(f); - node->appendStyleProperty(prop,myId); } else if (value != QLatin1String("none")) { QColor color; - if (constructColor(value, opacity, color, handler)) { - QSvgFillStyle *prop = new QSvgFillStyle(QBrush(color)); - if (!fillRule.isEmpty()) - prop->setFillRule(f); - node->appendStyleProperty(prop, myId); - } + if (resolveColor(value, color, handler)) + prop->setBrush(QBrush(color)); } else { - QSvgFillStyle *prop = new QSvgFillStyle(QBrush(Qt::NoBrush)); - if (!fillRule.isEmpty()) - prop->setFillRule(f); - node->appendStyleProperty(prop, myId); + prop->setBrush(QBrush(Qt::NoBrush)); + } + } else if (inherited) { + if (inherited->style()) { + prop->setFillStyle(inherited->style()); + } else { + prop->setBrush(inherited->qbrush()); } } + prop->setFillOpacity(fillOpacity); + prop->setFillRule(f); + node->appendStyleProperty(prop,myId); } + static void parseQPen(QPen &pen, QSvgNode *node, const QSvgAttributes &attributes, QSvgHandler *handler) diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index 556201b..4c8247b 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -81,12 +81,12 @@ void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &) } QSvgFillStyle::QSvgFillStyle(const QBrush &brush) - : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true) + : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false), m_fillRule(Qt::WindingFill), m_fillOpacity(1.0), m_gradientResolved (true) { } QSvgFillStyle::QSvgFillStyle(QSvgStyleProperty *style) - : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true) + : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false), m_fillRule(Qt::WindingFill), m_fillOpacity(1.0), m_gradientResolved (true) { } @@ -102,6 +102,16 @@ void QSvgFillStyle::setFillOpacity(qreal opacity) m_fillOpacity = opacity; } +void QSvgFillStyle::setFillStyle(QSvgStyleProperty* style) +{ + m_style = style; +} + +void QSvgFillStyle::setBrush(QBrush brush) +{ + m_fill = brush; +} + static void recursivelySetFill(QSvgNode *node, Qt::FillRule f) { if (node->type() == QSvgNode::PATH) { diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h index f1d0811..ac5e109 100644 --- a/src/svg/qsvgstyle_p.h +++ b/src/svg/qsvgstyle_p.h @@ -224,12 +224,29 @@ public: void setFillRule(Qt::FillRule f); void setFillOpacity(qreal opacity); + void setFillStyle(QSvgStyleProperty* style); + void setBrush(QBrush brush); const QBrush & qbrush() const { return m_fill; } + qreal fillOpacity() const + { + return m_fillOpacity; + } + + Qt::FillRule fillRule() const + { + return m_fillRule; + } + + QSvgStyleProperty* style() const + { + return m_style; + } + void setGradientId(const QString &Id) { m_gradientId = Id; @@ -240,7 +257,6 @@ public: return m_gradientId; } - void setGradientResolved(bool resolved) { m_gradientResolved = resolved; @@ -251,16 +267,6 @@ public: return m_gradientResolved; } - void setFillStyle(QSvgStyleProperty* style) - { - m_style = style; - } - - void setBrush(QBrush brush) - { - m_fill = brush; - } - private: // fill v v 'inherit' | // fill-opacity v v 'inherit' | diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index 3f658ec..68539ef 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -81,6 +81,7 @@ private slots: void paths(); void displayMode(); void strokeInherit(); + void testFillInheritance(); #ifndef QT_NO_COMPRESS void testGzLoading(); @@ -1053,5 +1054,72 @@ void tst_QSvgRenderer::strokeInherit() } } +void tst_QSvgRenderer::testFillInheritance() +{ + static const char *svgs[] = { + //reference + "" + " " + "", + "" + " " + " " + "", + "" + " " + " " + " " + " " + "", + "" + " " + " " + " " + " " + " " + " " + "", + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "", + "" + " " + " " + " " + " " + " " + " " + "" + }; + + const int COUNT = sizeof(svgs) / sizeof(svgs[0]); + QImage images[COUNT]; + QPainter p; + + for (int i = 0; i < COUNT; ++i) { + QByteArray data(svgs[i]); + QSvgRenderer renderer(data); + QVERIFY(renderer.isValid()); + images[i] = QImage(200, 200, QImage::Format_ARGB32_Premultiplied); + images[i].fill(-1); + p.begin(&images[i]); + renderer.render(&p); + p.end(); + if (i != 0) { + QCOMPARE(images[0], images[i]); + } + } +} QTEST_MAIN(tst_QSvgRenderer) #include "tst_qsvgrenderer.moc" -- cgit v0.12 From ed564a3fef39b649bd38a181126711431f0b40ab Mon Sep 17 00:00:00 2001 From: Suneel BS Date: Thu, 14 May 2009 14:25:16 +0530 Subject: Fixed handling of some SVG attributes when value is invalid. When the parsing of an SVG attribute fails, it should be given the default value. Fixed handling of invalid viewBox, stop-opacity and stop-offset. Autotest included. Reviewed-by: Kim --- src/svg/qsvghandler.cpp | 48 +++++++++++----- tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 84 ++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 14 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index f64fb3e..5f9d1dd 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -68,6 +68,7 @@ QT_BEGIN_NAMESPACE + double qstrtod(const char *s00, char const **se, bool *ok); static bool parsePathDataFast(const QStringRef &data, QPainterPath &path); @@ -320,6 +321,7 @@ static qreal toDouble(const QChar *&str) ++str; } } + temp[pos] = '\0'; qreal val; @@ -365,16 +367,24 @@ static qreal toDouble(const QChar *&str) return val; } -static qreal toDouble(const QString &str) +static qreal toDouble(const QString &str, bool *ok = NULL) { const QChar *c = str.constData(); - return toDouble(c); + qreal res = toDouble(c); + if (ok) { + *ok = ((*c) == QLatin1Char('\0')); + } + return res; } -static qreal toDouble(const QStringRef &str) +static qreal toDouble(const QStringRef &str, bool *ok = NULL) { const QChar *c = str.constData(); - return toDouble(c); + qreal res = toDouble(c); + if (ok) { + *ok = (c == (str.constData() + str.length())); + } + return res; } static QVector parseNumbersList(const QChar *&str) @@ -497,14 +507,17 @@ static bool constructColor(const QString &colorStr, const QString &opacity, if (!resolveColor(colorStr, color, handler)) return false; if (!opacity.isEmpty()) { - qreal op = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); + bool ok = true; + qreal op = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity, &ok))); + if (!ok) + op = 1.0; color.setAlphaF(op); } return true; } static qreal parseLength(const QString &str, QSvgHandler::LengthType &type, - QSvgHandler *handler) + QSvgHandler *handler, bool *ok = NULL) { QString numStr = str.trimmed(); @@ -533,15 +546,15 @@ static qreal parseLength(const QString &str, QSvgHandler::LengthType &type, type = handler->defaultCoordinateSystem(); //type = QSvgHandler::LT_OTHER; } - qreal len = toDouble(numStr); + qreal len = toDouble(numStr, ok); //qDebug()<<"len is "<setViewBox(QRectF(x, y, w, h)); - } else if (width && height){ + + } else if (width && height) { if (type == QSvgHandler::LT_PT) { width = convertToPixels(width, false, type); height = convertToPixels(height, false, type); } - node->setViewBox(QRectF(0, 0, width, height)); } - handler->setDefaultCoordinateSystem(QSvgHandler::LT_PX); return node; diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index 68539ef..2bbe897 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -82,6 +82,7 @@ private slots: void displayMode(); void strokeInherit(); void testFillInheritance(); + void testStopOffsetOpacity(); #ifndef QT_NO_COMPRESS void testGzLoading(); @@ -1121,5 +1122,88 @@ void tst_QSvgRenderer::testFillInheritance() } } } +void tst_QSvgRenderer::testStopOffsetOpacity() +{ + static const char *svgs[] = { + //reference + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "", + //Stop Offset + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "", + //Stop Opacity + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "", + //Stop offset and Stop opacity + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + }; + + QImage images[4]; + QPainter p; + + for (int i = 0; i < 4; ++i) { + QByteArray data(svgs[i]); + QSvgRenderer renderer(data); + QVERIFY(renderer.isValid()); + images[i] = QImage(64, 64, QImage::Format_ARGB32_Premultiplied); + images[i].fill(-1); + p.begin(&images[i]); + renderer.render(&p); + p.end(); + } + QCOMPARE(images[0], images[1]); + QCOMPARE(images[0], images[2]); + QCOMPARE(images[0], images[3]); +} + QTEST_MAIN(tst_QSvgRenderer) #include "tst_qsvgrenderer.moc" -- cgit v0.12 From cae93bf07958ea065f4fefd729099bac59a1bf14 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 9 Jul 2009 13:18:28 +0200 Subject: Fixes a memory corruption when converting data with QIconvCodec This partially reverts 9a5b40a011bd1b15a67d83564af55011761f8ad9 for the QIconvCodec. Reviewed-by: hjk --- src/corelib/codecs/qiconvcodec.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp index 1bf76ea..188ac8c 100644 --- a/src/corelib/codecs/qiconvcodec.cpp +++ b/src/corelib/codecs/qiconvcodec.cpp @@ -225,10 +225,11 @@ QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState char *inBytes = const_cast(chars); #endif + QByteArray in; if (remainingCount) { // we have to prepend the remaining bytes from the previous conversion inBytesLeft += remainingCount; - QByteArray in(inBytesLeft, Qt::Uninitialized); + in.resize(inBytesLeft); inBytes = in.data(); memcpy(in.data(), remainingBuffer, remainingCount); @@ -362,9 +363,10 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt inBytes = const_cast(reinterpret_cast(uc)); inBytesLeft = len * sizeof(QChar); + QByteArray in; if (convState && convState->remainingChars) { // we have one surrogate char to be prepended - QByteArray in(sizeof(QChar) + len, Qt::Uninitialized); + in.resize(sizeof(QChar) + len); inBytes = in.data(); QChar remaining = convState->state_data[0]; -- cgit v0.12 From 916b5c69e1ed5667e4fe97a21e7e15abfd60ec3d Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 9 Jul 2009 13:41:40 +0200 Subject: doc: Minor edits of reentrant/thread-safe expalantion. Task-number: 189232 --- doc/src/threads.qdoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/src/threads.qdoc b/doc/src/threads.qdoc index e3da0d4..8469f51 100644 --- a/doc/src/threads.qdoc +++ b/doc/src/threads.qdoc @@ -278,7 +278,7 @@ \e{reentrant} function is not always \e{thread-safe}. By extension, a class is said to be \e{reentrant} if its member - functions can be called safely from multiple threads as long as + functions can be called safely from multiple threads, as long as each thread uses a \e{different} instance of the class. The class is \e{thread-safe} if its member functions can be called safely from multiple threads, even if all the threads use the \e{same} @@ -325,14 +325,14 @@ declared with the \c mutable qualifier because we need to lock and unlock the mutex in \c value(), which is a const function. - Most Qt classes are \e{reentrant}, but they are not made + Many Qt classes are \e{reentrant}, but they are not made \e{thread-safe}, because making them thread-safe would incur the extra overhead of repeatedly locking and unlocking a QMutex. For example, QString is reentrant but not thread-safe. You can safely access \e{different} instances of QString from multiple threads - simultaneously, but you can't access the \e{same} instance of - QString from multiple threads simultaneously (unless you protect - the accesses yourself with a QMutex). + simultaneously, but you can't safely access the \e{same} instance + of QString from multiple threads simultaneously (unless you + protect the accesses yourself with a QMutex). Some Qt classes and functions are thread-safe. These are mainly the thread-related classes (e.g. QMutex) and fundamental functions @@ -345,7 +345,7 @@ standardized. POSIX uses definitions of reentrant and thread-safe that are somewhat different for its C APIs. When using other object-oriented C++ class libraries with Qt, be sure the - definitions in use are understood. + definitions are understood. \section1 Threads and QObjects -- cgit v0.12 From c5371bd1f3df4467ca17350ec7c3e3635d16e393 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 12:10:18 +0200 Subject: QTreeView: use QVariantAnimation over QTimeLine --- src/gui/itemviews/qabstractitemview_p.h | 3 -- src/gui/itemviews/qtreeview.cpp | 74 ++++++++++++++------------------- src/gui/itemviews/qtreeview.h | 2 - src/gui/itemviews/qtreeview_p.h | 43 ++++++++++--------- 4 files changed, 55 insertions(+), 67 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 2950bcd..3119c9d 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -61,8 +61,6 @@ #include "QtGui/qmime.h" #include "QtGui/qpainter.h" #include "QtCore/qpair.h" -#include "QtCore/qtimer.h" -#include "QtCore/qtimeline.h" #include "QtGui/qregion.h" #include "QtCore/qdebug.h" #include "QtGui/qpainter.h" @@ -376,7 +374,6 @@ public: QBasicTimer updateTimer; QBasicTimer delayedEditing; QBasicTimer delayedAutoScroll; //used when an item is clicked - QTimeLine timeline; QAbstractItemView::ScrollMode verticalScrollMode; QAbstractItemView::ScrollMode horizontalScrollMode; diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 7c319dc..ab700e9 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1267,10 +1267,13 @@ void QTreeView::paintEvent(QPaintEvent *event) Q_D(QTreeView); d->executePostedLayout(); QPainter painter(viewport()); +#ifndef QT_NO_ANIMATION if (d->isAnimating()) { - drawTree(&painter, event->region() - d->animationRect()); + drawTree(&painter, event->region() - d->animatedOperation.rect()); d->drawAnimatedOperation(&painter); - } else { + } else +#endif //QT_NO_ANIMATION + { drawTree(&painter, event->region()); #ifndef QT_NO_DRAGANDDROP d->paintDropIndicator(&painter); @@ -2851,10 +2854,6 @@ void QTreeViewPrivate::initialize() header->setStretchLastSection(true); header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter); q->setHeader(header); - - // animation - QObject::connect(&timeline, SIGNAL(frameChanged(int)), q, SLOT(_q_animate())); - QObject::connect(&timeline, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()), Qt::QueuedConnection); } void QTreeViewPrivate::expand(int item, bool emitSignal) @@ -2864,9 +2863,10 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) if (item == -1 || viewItems.at(item).expanded) return; +#ifndef QT_NO_ANIMATION if (emitSignal && animationsEnabled) - prepareAnimatedOperation(item, AnimatedOperation::Expand); - + prepareAnimatedOperation(item, QVariantAnimation::Forward); +#endif //QT_NO_ANIMATION QAbstractItemView::State oldState = q->state(); q->setState(QAbstractItemView::ExpandingState); const QModelIndex index = viewItems.at(item).index; @@ -2877,8 +2877,10 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) if (emitSignal) { emit q->expanded(index); +#ifndef QT_NO_ANIMATION if (animationsEnabled) beginAnimatedOperation(); +#endif //QT_NO_ANIMATION } if (model->canFetchMore(index)) model->fetchMore(index); @@ -2902,8 +2904,10 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) if (it == expandedIndexes.end() || viewItems.at(item).expanded == false) return; // nothing to do +#ifndef QT_NO_ANIMATION if (emitSignal && animationsEnabled) - prepareAnimatedOperation(item, AnimatedOperation::Collapse); + prepareAnimatedOperation(item, QVariantAnimation::Backward); +#endif //QT_NO_ANIMATION QAbstractItemView::State oldState = q->state(); q->setState(QAbstractItemView::CollapsingState); @@ -2922,29 +2926,33 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) if (emitSignal) { emit q->collapsed(modelIndex); +#ifndef QT_NO_ANIMATION if (animationsEnabled) beginAnimatedOperation(); +#endif //QT_NO_ANIMATION } } -void QTreeViewPrivate::prepareAnimatedOperation(int item, AnimatedOperation::Type type) +#ifndef QT_NO_ANIMATION +void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction) { animatedOperation.item = item; - animatedOperation.type = type; + animatedOperation.view = q_func(); + animatedOperation.setDirection(direction); int top = coordinateForItem(item) + itemHeight(item); QRect rect = viewport->rect(); rect.setTop(top); - if (type == AnimatedOperation::Collapse) { + if (direction == QVariantAnimation::Backward) { const int limit = rect.height() * 2; int h = 0; int c = item + viewItems.at(item).total + 1; for (int i = item + 1; i < c && h < limit; ++i) h += itemHeight(i); rect.setHeight(h); - animatedOperation.duration = h; + animatedOperation.setEndValue(top + h); } - animatedOperation.top = top; + animatedOperation.setStartValue(top); animatedOperation.before = renderTreeToPixmapForAnimation(rect); } @@ -2953,50 +2961,29 @@ void QTreeViewPrivate::beginAnimatedOperation() Q_Q(QTreeView); QRect rect = viewport->rect(); - rect.setTop(animatedOperation.top); - if (animatedOperation.type == AnimatedOperation::Expand) { + rect.setTop(animatedOperation.top()); + if (animatedOperation.direction() == QVariantAnimation::Forward) { const int limit = rect.height() * 2; int h = 0; int c = animatedOperation.item + viewItems.at(animatedOperation.item).total + 1; for (int i = animatedOperation.item + 1; i < c && h < limit; ++i) h += itemHeight(i); rect.setHeight(h); - animatedOperation.duration = h; + animatedOperation.setEndValue(animatedOperation.top() + h); } animatedOperation.after = renderTreeToPixmapForAnimation(rect); q->setState(QAbstractItemView::AnimatingState); - - timeline.stop(); - timeline.setDuration(250); - timeline.setFrameRange(animatedOperation.top, animatedOperation.top + animatedOperation.duration); - timeline.start(); -} - -void QTreeViewPrivate::_q_endAnimatedOperation() -{ - Q_Q(QTreeView); - animatedOperation.before = QPixmap(); - animatedOperation.after = QPixmap(); - q->setState(QAbstractItemView::NoState); - q->updateGeometries(); - viewport->update(); -} - -void QTreeViewPrivate::_q_animate() -{ - QRect rect = viewport->rect(); - rect.moveTop(animatedOperation.top); - viewport->repaint(rect); + animatedOperation.start(); //let's start the animation } void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const { - int start = timeline.startFrame(); - int end = timeline.endFrame(); - bool collapsing = animatedOperation.type == AnimatedOperation::Collapse; - int current = collapsing ? end - timeline.currentFrame() + start : timeline.currentFrame(); + const int start = animatedOperation.startValue().toInt(), + end = animatedOperation.endValue().toInt(), + current = animatedOperation.currentValue().toInt(); + bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward; const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after; painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height()); const QPixmap bottom = collapsing ? animatedOperation.after : animatedOperation.before; @@ -3038,6 +3025,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons return pixmap; } +#endif //QT_NO_ANIMATION void QTreeViewPrivate::_q_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index 0347645..34f7630 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -223,8 +223,6 @@ private: Q_DECLARE_PRIVATE(QTreeView) Q_DISABLE_COPY(QTreeView) - Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation()) - Q_PRIVATE_SLOT(d_func(), void _q_animate()) Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &)) Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 6a1dfe5..77e57d6 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -54,6 +54,7 @@ // #include "private/qabstractitemview_p.h" +#include #ifndef QT_NO_TREEVIEW @@ -81,42 +82,48 @@ public: uniformRowHeights(false), rootDecoration(true), itemsExpandable(true), sortingEnabled(false), expandsOnDoubleClick(true), - allColumnsShowFocus(false), + allColumnsShowFocus(false), current(0), animationsEnabled(false), columnResizeTimerID(0), autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false) {} ~QTreeViewPrivate() {} void initialize(); - struct AnimatedOperation +#ifndef QT_NO_ANIMATION + struct AnimatedOperation : public QVariantAnimation { - enum Type { Expand, Collapse }; int item; - int top; - int duration; - Type type; QPixmap before; QPixmap after; - }; - - void expand(int item, bool emitSignal); - void collapse(int item, bool emitSignal); - - void prepareAnimatedOperation(int item, AnimatedOperation::Type type); + QTreeView *view; + AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); } + int top() const { return startValue().toInt(); } + QRect rect() const { QRect rect = view->viewport()->rect(); rect.moveTop(top()); return rect; } + void updateCurrentValue(const QVariant &) { view->viewport()->update(rect()); } + void updateState(State, State state) + { + if (state == Stopped) { + before = after = QPixmap(); + view->setState(QAbstractItemView::NoState); + view->updateGeometries(); + view->viewport()->update(); + } + } + } animatedOperation; + void prepareAnimatedOperation(int item, QVariantAnimation::Direction d); void beginAnimatedOperation(); - void _q_endAnimatedOperation(); void drawAnimatedOperation(QPainter *painter) const; QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const; +#endif //QT_NO_ANIMATION + + void expand(int item, bool emitSignal); + void collapse(int item, bool emitSignal); - inline QRect animationRect() const - { return QRect(0, animatedOperation.top, viewport->width(), - viewport->height() - animatedOperation.top); } void _q_currentChanged(const QModelIndex&, const QModelIndex&); void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int); void _q_columnsRemoved(const QModelIndex &, int, int); void _q_modelAboutToBeReset(); - void _q_animate(); void _q_sortIndicatorChanged(int column, Qt::SortOrder order); void _q_modelDestroyed(); @@ -177,8 +184,6 @@ public: // used when expanding and collapsing items QSet expandedIndexes; - QStack expandParent; - AnimatedOperation animatedOperation; bool animationsEnabled; inline bool storeExpanded(const QPersistentModelIndex &idx) { -- cgit v0.12 From 17cd046cfd7ab8ff3eaf0c09ae083ff8b2c89c89 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 13:45:35 +0200 Subject: QTreeView: cleanup of useless private slots currentChange is slot in the public class (QAbstractItemView --- src/gui/dialogs/qfiledialog_p.h | 1 - src/gui/itemviews/qtreeview.cpp | 63 +++++++++++++---------------------------- src/gui/itemviews/qtreeview.h | 2 -- src/gui/itemviews/qtreeview_p.h | 2 -- 4 files changed, 20 insertions(+), 48 deletions(-) diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/gui/dialogs/qfiledialog_p.h index d798f9d..4c599cc 100644 --- a/src/gui/dialogs/qfiledialog_p.h +++ b/src/gui/dialogs/qfiledialog_p.h @@ -73,7 +73,6 @@ #include #include #include -#include #include #include "qsidebar_p.h" diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index ab700e9..e4c7cd3 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -262,10 +262,6 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel) Q_D(QTreeView); Q_ASSERT(selectionModel); if (d->selectionModel) { - if (d->allColumnsShowFocus) { - QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } // support row editing disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), d->model, SLOT(submit())); @@ -275,10 +271,6 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel) QAbstractItemView::setSelectionModel(selectionModel); if (d->selectionModel) { - if (d->allColumnsShowFocus) { - QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } // support row editing connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), d->model, SLOT(submit())); @@ -901,15 +893,6 @@ void QTreeView::setAllColumnsShowFocus(bool enable) Q_D(QTreeView); if (d->allColumnsShowFocus == enable) return; - if (d->selectionModel) { - if (enable) { - QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } else { - QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } - } d->allColumnsShowFocus = enable; d->viewport->update(); } @@ -1309,13 +1292,13 @@ bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos) { Q_Q(QTreeView); // we want to handle mousePress in EditingState (persistent editors) - if ((q->state() != QAbstractItemView::NoState - && q->state() != QAbstractItemView::EditingState) + if ((state != QAbstractItemView::NoState + && state != QAbstractItemView::EditingState) || !viewport->rect().contains(pos)) return true; int i = itemDecorationAt(pos); - if ((i != -1) && q->itemsExpandable() && hasVisibleChildren(viewItems.at(i).index)) { + if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) { if (viewItems.at(i).expanded) collapse(i, true); else @@ -2867,7 +2850,7 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) if (emitSignal && animationsEnabled) prepareAnimatedOperation(item, QVariantAnimation::Forward); #endif //QT_NO_ANIMATION - QAbstractItemView::State oldState = q->state(); + QAbstractItemView::State oldState = state; q->setState(QAbstractItemView::ExpandingState); const QModelIndex index = viewItems.at(item).index; storeExpanded(index); @@ -2909,7 +2892,7 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) prepareAnimatedOperation(item, QVariantAnimation::Backward); #endif //QT_NO_ANIMATION - QAbstractItemView::State oldState = q->state(); + QAbstractItemView::State oldState = state; q->setState(QAbstractItemView::CollapsingState); expandedIndexes.erase(it); viewItems[item].expanded = false; @@ -3027,27 +3010,6 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons } #endif //QT_NO_ANIMATION -void QTreeViewPrivate::_q_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) -{ - Q_Q(QTreeView); - if (previous.isValid()) { - QRect previousRect = q->visualRect(previous); - if (allColumnsShowFocus) { - previousRect.setX(0); - previousRect.setWidth(viewport->width()); - } - viewport->update(previousRect); - } - if (current.isValid()) { - QRect currentRect = q->visualRect(current); - if (allColumnsShowFocus) { - currentRect.setX(0); - currentRect.setWidth(viewport->width()); - } - viewport->update(currentRect); - } -} - void QTreeViewPrivate::_q_modelAboutToBeReset() { viewItems.clear(); @@ -3775,6 +3737,21 @@ void QTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr } #endif QAbstractItemView::currentChanged(current, previous); + + if (allColumnsShowFocus()) { + if (previous.isValid()) { + QRect previousRect = visualRect(previous); + previousRect.setX(0); + previousRect.setWidth(viewport()->width()); + viewport()->update(previousRect); + } + if (current.isValid()) { + QRect currentRect = visualRect(current); + currentRect.setX(0); + currentRect.setWidth(viewport()->width()); + viewport()->update(currentRect); + } + } } /*! diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index 34f7630..b2a9de2f 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -223,10 +223,8 @@ private: Q_DECLARE_PRIVATE(QTreeView) Q_DISABLE_COPY(QTreeView) - Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &)) Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) - Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) }; #endif // QT_NO_TREEVIEW diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 77e57d6..38f6fd3 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -119,8 +119,6 @@ public: void expand(int item, bool emitSignal); void collapse(int item, bool emitSignal); - - void _q_currentChanged(const QModelIndex&, const QModelIndex&); void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int); void _q_columnsRemoved(const QModelIndex &, int, int); void _q_modelAboutToBeReset(); -- cgit v0.12 From 8b5f25ef98d29859e14d992ed90d976e64dc6382 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 15:23:58 +0200 Subject: autotest: removed tons of warnings --- tests/auto/qmenubar/tst_qmenubar.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 500465c..1245de1 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -1576,8 +1576,9 @@ void tst_QMenuBar::menubarSizeHint() return 11; case PM_MenuBarPanelWidth: return 1; + default: + return QWindowsStyle::pixelMetric(metric, option, widget); } - return QWindowsStyle::pixelMetric(metric, option, widget); } } style; -- cgit v0.12 From 43760604b1e08792938449885a938a641669c11d Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 9 Jul 2009 14:20:54 +0200 Subject: Added some links to the appropriate functions to the doc. Reviewed-by: trustme --- doc/src/dnd.qdoc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/src/dnd.qdoc b/doc/src/dnd.qdoc index b5039f6..5ede20c 100644 --- a/doc/src/dnd.qdoc +++ b/doc/src/dnd.qdoc @@ -141,15 +141,17 @@ types of data that the widget accepts. You must reimplement this function if you want to receive either QDragMoveEvent or QDropEvent in your reimplementations of - \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and dropEvent(). + \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and + \l{QWidget::dropEvent()}{dropEvent()}. - The following code shows how dragEnterEvent() can be reimplemented to + The following code shows how \l{QWidget::dragEnterEvent()}{dragEnterEvent()} + can be reimplemented to tell the drag and drop system that we can only handle plain text: \snippet doc/src/snippets/dropevents/window.cpp 3 - The dropEvent() is used to unpack dropped data and handle it in way that - is suitable for your application. + The \l{QWidget::dropEvent()}{dropEvent()} is used to unpack dropped data + and handle it in way that is suitable for your application. In the following code, the text supplied in the event is passed to a QTextBrowser and a QComboBox is filled with the list of MIME types that @@ -159,7 +161,8 @@ In this case, we accept the proposed action without checking what it is. In a real world application, it may be necessary to return from the - dropEvent() function without accepting the proposed action or handling + \l{QWidget::dropEvent()}{dropEvent()} function without accepting the + proposed action or handling the data if the action is not relevant. For example, we may choose to ignore Qt::LinkAction actions if we do not support links to external sources in our application. -- cgit v0.12 From b89e878003c5732482a8afb1be66a42cb9122b9e Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Thu, 9 Jul 2009 16:12:49 +0200 Subject: Updated the french phrasebook (some translations from Qt Creator) Reviewed-by: TrustMe --- tools/linguist/phrasebooks/french.qph | 227 +++++++++++++++++++++++++++++++++- 1 file changed, 226 insertions(+), 1 deletion(-) diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph index f244013..d38da5a 100644 --- a/tools/linguist/phrasebooks/french.qph +++ b/tools/linguist/phrasebooks/french.qph @@ -1,4 +1,5 @@ - + + About A propos @@ -1101,4 +1102,228 @@ Yes Oui + + Split + Scinder + + + &Edit + &Édition + + + &Redo + Re&faire + + + debugger + débogueur + + + Start Debugger + Lancer le débogueur + + + Executable: + Exécutable: + + + Filter: + Filtre: + + + Clear + Effacer + + + Host and port: + Hôte et port: + + + Architecture: + Architecture: + + + Server start script: + Script de démarrage du serveur: + + + &Undo + Annu&ler + + + Add Bookmark + Ajouter un signet + + + Bookmark: + Signet: + + + Add in Folder: + Ajouter dans le dossier: + + + + + + + + + New Folder + Nouveau dossier + + + Bookmarks + Signets + + + Rename Folder + Renommer le dossier + + + Bookmark + Signet + + + Remove + Retirer + + + Delete Folder + Supprimer le dossier + + + Add + Ajouter + + + Move Up + Vers le Haut + + + Move Down + Vers le Bas + + + Show Bookmark + Afficher le signet + + + Show Bookmark in New Tab + Afficher le signet dans un nouvel onglet + + + Delete Bookmark + Supprimer le signet + + + Rename Bookmark + Renommer le signet + + + Previous Bookmark + Signet précédent + + + Next Bookmark + Signet suivant + + + Condition: + Condition: + + + Working Directory: + Répertoire de travail: + + + Environment + Environnement + + + Arguments + Arguments + + + Build directory: + Répertoire de compilation: + + + Path: + Chemin: + + + General + Général + + + Username: + Nom d'utilisateur: + + + User interface + Interface utilisateur + + + Open Link + Ouvrir le lien + + + [read only] + [lecture seule] + + + [directory] + [répertoire] + + + Close All + Fermer tout + + + Failed! + Échec! + + + Proceed + Continuer + + + Make writable + Rendre inscriptible + + + Qt Creator + Qt Creator + + + &File + &Fichier + + + Activate %1 + Activer %1 + + + New Project + Nouveau projet + + + Close %1 + Fermer %1 + + + * + * + + + &Change + &Modifier + + + Close Other Editors + Fermer les autres éditeurs + + + Close All Except %1 + Fermer tout sauf %1 + -- cgit v0.12 From e96c108e7f71f3e1bd08dc739e6ec46fe4603332 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 15:58:20 +0200 Subject: QTabBar: now uses QVariantAnimation over QTimeLine QTimeLine is now no more used in private APIs --- src/gui/widgets/qprogressbar.cpp | 2 +- src/gui/widgets/qtabbar.cpp | 66 ++++++++++++++------------------------ src/gui/widgets/qtabbar.h | 2 -- src/gui/widgets/qtabbar_p.h | 68 ++++++++++++++++++++++++---------------- 4 files changed, 65 insertions(+), 73 deletions(-) diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp index ac3338b..d168028 100644 --- a/src/gui/widgets/qprogressbar.cpp +++ b/src/gui/widgets/qprogressbar.cpp @@ -204,7 +204,7 @@ bool QProgressBarPrivate::repaintRequired() const \o A progress bar shown in the Plastique widget style. \endtable - \sa QTimeLine, QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator} + \sa QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator} */ /*! diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 11cb6a1..690e624 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -663,7 +663,7 @@ void QTabBarPrivate::refresh() if (pressedIndex != -1 && movable && QApplication::mouseButtons() == Qt::NoButton) { - _q_moveTabFinished(pressedIndex); + moveTabFinished(pressedIndex); if (!validIndex(pressedIndex)) pressedIndex = -1; } @@ -1662,26 +1662,17 @@ void QTabBarPrivate::slide(int from, int to) q->setUpdatesEnabled(true); int postLocation = vertical ? q->tabRect(to).y() : q->tabRect(to).x(); int length = postLocation - preLocation; - tabList[to].makeTimeLine(q); - tabList[to].dragOffset += -1 * length; - tabList[to].timeLine->setFrameRange(tabList[to].dragOffset, 0); - animations[tabList[to].timeLine] = to; - tabList[to].timeLine->setDuration(ANIMATION_DURATION); - if (tabList[to].timeLine->state() != QTimeLine::Running) - tabList[to].timeLine->start(); + tabList[to].dragOffset -= length; + tabList[to].startAnimation(this, ANIMATION_DURATION); } -void QTabBarPrivate::_q_moveTab(int offset) +void QTabBarPrivate::moveTab(int index, int offset) { - Q_Q(QTabBar); - if (QTimeLine *timeLine = qobject_cast(q->sender())) { - int index = animations[timeLine]; - if (!validIndex(index)) - return; - tabList[index].dragOffset = offset; - layoutTab(index); // Make buttons follow tab - q->update(); - } + if (!validIndex(index)) + return; + tabList[index].dragOffset = offset; + layoutTab(index); // Make buttons follow tab + q_func()->update(); } /*!\reimp @@ -1695,7 +1686,7 @@ void QTabBar::mousePressEvent(QMouseEvent *event) } // Be safe! if (d->pressedIndex != -1 && d->movable) - d->_q_moveTabFinished(d->pressedIndex); + d->moveTabFinished(d->pressedIndex); d->pressedIndex = d->indexAtPos(event->pos()); if (d->validIndex(d->pressedIndex)) { @@ -1721,7 +1712,7 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) // Be safe! if (d->pressedIndex != -1 && event->buttons() == Qt::NoButton) - d->_q_moveTabFinished(d->pressedIndex); + d->moveTabFinished(d->pressedIndex); // Start drag if (!d->dragInProgress && d->pressedIndex != -1) { @@ -1789,16 +1780,6 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) optTabBase.documentMode = d->documentMode; } -void QTabBarPrivate::_q_moveTabFinished() -{ - Q_Q(QTabBar); - if (QTimeLine *timeLine = qobject_cast(q->sender())) { - int index = animations[timeLine]; - animations.remove(timeLine); - _q_moveTabFinished(index); - } -} - void QTabBarPrivate::setupMovableTab() { Q_Q(QTabBar); @@ -1838,11 +1819,19 @@ void QTabBarPrivate::setupMovableTab() movingTab->setVisible(true); } -void QTabBarPrivate::_q_moveTabFinished(int index) +void QTabBarPrivate::moveTabFinished(int index) { Q_Q(QTabBar); bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index); - if (animations.isEmpty() && cleanup) { + bool allAnimationsFinished = true; +#ifndef QT_NO_ANIMATION + for(int i = 0; allAnimationsFinished && i < tabList.count(); ++i) { + const Tab &t = tabList.at(i); + if (t.animation && t.animation->state() == QAbstractAnimation::Running) + allAnimationsFinished = false; + } +#endif //QT_NO_ANIMATION + if (allAnimationsFinished && cleanup) { movingTab->setVisible(false); // We might not get a mouse release for (int i = 0; i < tabList.count(); ++i) { tabList[i].dragOffset = 0; @@ -1877,17 +1866,8 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event) ? tabRect(d->pressedIndex).height() : tabRect(d->pressedIndex).width(); int duration = qMin(ANIMATION_DURATION, - ((length < 0 ? (-1 * length) : length) * ANIMATION_DURATION) / width); - if (duration > 0) { - d->tabList[d->pressedIndex].makeTimeLine(this); - d->tabList[d->pressedIndex].timeLine->setFrameRange(length, 0); - d->animations[d->tabList[d->pressedIndex].timeLine] = d->pressedIndex; - d->tabList[d->pressedIndex].timeLine->setDuration(duration); - if (d->tabList[d->pressedIndex].timeLine->state() != QTimeLine::Running) - d->tabList[d->pressedIndex].timeLine->start(); - } else { - d->_q_moveTabFinished(d->pressedIndex); - } + (qAbs(length) * ANIMATION_DURATION) / width); + d->tabList[d->pressedIndex].startAnimation(d, duration); d->dragInProgress = false; d->movingTab->setVisible(false); d->dragStartPosition = QPoint(); diff --git a/src/gui/widgets/qtabbar.h b/src/gui/widgets/qtabbar.h index 7514486..402f54b 100644 --- a/src/gui/widgets/qtabbar.h +++ b/src/gui/widgets/qtabbar.h @@ -215,8 +215,6 @@ private: Q_DECLARE_PRIVATE(QTabBar) Q_PRIVATE_SLOT(d_func(), void _q_scrollTabs()) Q_PRIVATE_SLOT(d_func(), void _q_closeTab()) - Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int)) - Q_PRIVATE_SLOT(d_func(), void _q_moveTabFinished()) }; #endif // QT_NO_TABBAR diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h index dbae055..b9b9fba 100644 --- a/src/gui/widgets/qtabbar_p.h +++ b/src/gui/widgets/qtabbar_p.h @@ -58,9 +58,8 @@ #include #include -#include -#include #include +#include #ifndef QT_NO_TABBAR @@ -75,9 +74,10 @@ class QTabBarPrivate : public QWidgetPrivate Q_DECLARE_PUBLIC(QTabBar) public: QTabBarPrivate() - :currentIndex(-1), pressedIndex(-1), - shape(QTabBar::RoundedNorth), - layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), movingTab(0) {} + :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false), + drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), + selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), + dragInProgress(false), documentMode(false), movingTab(0) {} int currentIndex; int pressedIndex; @@ -88,16 +88,13 @@ public: struct Tab { inline Tab(const QIcon &ico, const QString &txt) - : enabled(true) - , shortcutId(0) - , text(txt) - , icon(ico) - , leftWidget(0) - , rightWidget(0) - , lastTab(-1) - , timeLine(0) - , dragOffset(0) + : enabled(true) , shortcutId(0), text(txt), icon(ico), + leftWidget(0), rightWidget(0), lastTab(-1), dragOffset(0) +#ifndef QT_NO_ANIMATION + , animation(0) +#endif //QT_NO_ANIMATION {} + bool operator==(const Tab &other) const { return &other == this; } bool enabled; int shortcutId; QString text; @@ -117,21 +114,39 @@ public: QWidget *leftWidget; QWidget *rightWidget; int lastTab; - - QTimeLine *timeLine; int dragOffset; - void makeTimeLine(QWidget *q) { - if (timeLine) - return; - timeLine = new QTimeLine(ANIMATION_DURATION, q); - q->connect(timeLine, SIGNAL(frameChanged(int)), q, SLOT(_q_moveTab(int))); - q->connect(timeLine, SIGNAL(finished()), q, SLOT(_q_moveTabFinished())); +#ifndef QT_NO_ANIMATION + ~Tab() { delete animation; } + struct TabBarAnimation : public QVariantAnimation { + TabBarAnimation(Tab *t, QTabBarPrivate *_priv) : tab(t), priv(_priv) + { setEasingCurve(QEasingCurve::InOutQuad); } + + void updateCurrentValue(const QVariant ¤t) + { priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); } + + void updateState(State, State newState) + { if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab)); } + private: + //these are needed for the callbacks + Tab *tab; + QTabBarPrivate *priv; + } *animation; + + void startAnimation(QTabBarPrivate *priv, int duration) { + if (!animation) + animation = new TabBarAnimation(this, priv); + animation->setStartValue(dragOffset); + animation->setEndValue(0); + animation->setDuration(duration); + animation->start(); } - +#else + void startAnimation(QTabBarPrivate *priv, int duration) + { Q_UNUSED(duration); priv->moveTabFinished(priv->tabList.indexOf(*this)); } +#endif //QT_NO_ANIMATION }; QList tabList; - QHash animations; int calculateNewPosition(int from, int to, int index) const; void slide(int from, int to); @@ -152,9 +167,8 @@ public: void _q_scrollTabs(); void _q_closeTab(); - void _q_moveTab(int); - void _q_moveTabFinished(); - void _q_moveTabFinished(int offset); + void moveTab(int index, int offset); + void moveTabFinished(int index); QRect hoverRect; void refresh(); -- cgit v0.12 From 93c5eddcead6d0fa9601d3ec992086ddcc5656e9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 16:23:26 +0200 Subject: Fix compile issue --- src/gui/itemviews/qtreeview.cpp | 13 ++++++++++++- src/gui/itemviews/qtreeview.h | 3 +++ src/gui/itemviews/qtreeview_p.h | 17 +++++------------ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index e4c7cd3..f13ff0c 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2837,6 +2837,9 @@ void QTreeViewPrivate::initialize() header->setStretchLastSection(true); header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter); q->setHeader(header); +#ifndef QT_NO_ANIMATION + QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation())); +#endif //QT_NO_ANIMATION } void QTreeViewPrivate::expand(int item, bool emitSignal) @@ -2920,7 +2923,7 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction) { animatedOperation.item = item; - animatedOperation.view = q_func(); + animatedOperation.viewport = viewport; animatedOperation.setDirection(direction); int top = coordinateForItem(item) + itemHeight(item); @@ -3008,6 +3011,14 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons return pixmap; } + +void QTreeViewPrivate::_q_endAnimatedOperation() +{ + Q_Q(QTreeView); + q->setState(QAbstractItemView::NoState); + q->updateGeometries(); + viewport->update(); +} #endif //QT_NO_ANIMATION void QTreeViewPrivate::_q_modelAboutToBeReset() diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index b2a9de2f..4411781 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -223,6 +223,9 @@ private: Q_DECLARE_PRIVATE(QTreeView) Q_DISABLE_COPY(QTreeView) +#ifndef QT_NO_ANIMATION + Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation()) +#endif //QT_NO_ANIMATION Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) }; diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 38f6fd3..6fb2e41 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -95,25 +95,18 @@ public: int item; QPixmap before; QPixmap after; - QTreeView *view; + QWidget *viewport; AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); } int top() const { return startValue().toInt(); } - QRect rect() const { QRect rect = view->viewport()->rect(); rect.moveTop(top()); return rect; } - void updateCurrentValue(const QVariant &) { view->viewport()->update(rect()); } - void updateState(State, State state) - { - if (state == Stopped) { - before = after = QPixmap(); - view->setState(QAbstractItemView::NoState); - view->updateGeometries(); - view->viewport()->update(); - } - } + QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; } + void updateCurrentValue(const QVariant &) { viewport->update(rect()); } + void updateState(State, State state) { if (state == Stopped) before = after = QPixmap(); } } animatedOperation; void prepareAnimatedOperation(int item, QVariantAnimation::Direction d); void beginAnimatedOperation(); void drawAnimatedOperation(QPainter *painter) const; QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const; + void _q_endAnimatedOperation(); #endif //QT_NO_ANIMATION void expand(int item, bool emitSignal); -- cgit v0.12 From f4fb6207a91b62526b31e0f77c0713bdc243e4f2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 9 Jul 2009 16:51:59 +0200 Subject: Compile fix. --- src/gui/itemviews/qabstractitemview_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 3119c9d..00647f6 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -64,6 +64,7 @@ #include "QtGui/qregion.h" #include "QtCore/qdebug.h" #include "QtGui/qpainter.h" +#include "QtCore/qbasictimer.h" #ifndef QT_NO_ITEMVIEWS -- cgit v0.12 From 4bec76fceb2297cdbde765b74075046b94bfaf75 Mon Sep 17 00:00:00 2001 From: Nils Christian Roscher-Nielsen Date: Thu, 9 Jul 2009 17:29:46 +0200 Subject: Add the complex control SC_SpinBoxEditField to style option Reviewed-by: Thierry --- src/gui/widgets/qabstractspinbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index da18d13..433406c 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1577,7 +1577,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const option->initFrom(this); option->activeSubControls = QStyle::SC_None; option->buttonSymbols = d->buttonSymbols; - option->subControls = QStyle::SC_SpinBoxFrame; + option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField; if (d->buttonSymbols != QAbstractSpinBox::NoButtons) { option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown; if (d->buttonState & Up) { -- cgit v0.12 From 020ed5b7caaba5cf877cdb9ebaa575db1d15b7f0 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 9 Jul 2009 18:09:12 +0200 Subject: QLocalSocket WriteOnly mode fixed on Windows Write only local sockets silently disconnected after some time. Reason: we cannot call PeekNamedPipe on a write only pipe. Task-number: 257714 Reviewed-by: ossi Autotest: tst_QLocalSocket::writeOnlySocket --- src/network/socket/qlocalsocket_win.cpp | 10 ++++++---- tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 1a971f0..794b2b7 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -168,7 +168,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) // we have a valid handle d->serverName = name; - if (setSocketDescriptor((quintptr)localSocket), openMode) { + if (setSocketDescriptor((quintptr)localSocket, ConnectedState, openMode)) { d->handle = localSocket; emit connected(); } @@ -299,8 +299,6 @@ void QLocalSocket::abort() DWORD QLocalSocketPrivate::bytesAvailable() { Q_Q(QLocalSocket); - if (q->state() != QLocalSocket::ConnectedState) - return 0; DWORD bytes; if (PeekNamedPipe(handle, NULL, 0, NULL, &bytes, NULL)) { return bytes; @@ -410,7 +408,7 @@ bool QLocalSocket::setSocketDescriptor(quintptr socketDescriptor, d->handle = (int*)socketDescriptor; d->state = socketState; emit stateChanged(d->state); - if (d->state == ConnectedState) { + if (d->state == ConnectedState && openMode.testFlag(QIODevice::ReadOnly)) { d->startAsyncRead(); d->checkReadyRead(); } @@ -471,6 +469,10 @@ bool QLocalSocket::waitForDisconnected(int msecs) Q_D(QLocalSocket); if (state() == UnconnectedState) return false; + if (!openMode().testFlag(QIODevice::ReadOnly)) { + qWarning("QLocalSocket::waitForDisconnected isn't supported for write only pipes."); + return false; + } QIncrementalSleepTimer timer(msecs); forever { d->bytesAvailable(); // to check if PeekNamedPipe fails diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index 0f636a4..a41eecd 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -104,6 +104,7 @@ private slots: void recycleServer(); void multiConnect(); + void writeOnlySocket(); void debug(); @@ -906,6 +907,22 @@ void tst_QLocalSocket::multiConnect() QVERIFY(server.nextPendingConnection() != 0); } +void tst_QLocalSocket::writeOnlySocket() +{ + QLocalServer server; + QVERIFY(server.listen("writeOnlySocket")); + + QLocalSocket client; + client.connectToServer("writeOnlySocket", QIODevice::WriteOnly); + QVERIFY(client.waitForConnected()); + + QVERIFY(server.waitForNewConnection()); + QLocalSocket* serverSocket = server.nextPendingConnection(); + + QCOMPARE(client.bytesAvailable(), qint64(0)); + QCOMPARE(client.state(), QLocalSocket::ConnectedState); +} + void tst_QLocalSocket::debug() { // Make sure this compiles -- cgit v0.12 From 5c11a5a38bcc68c17da8fe59e8db03d43ea55ac1 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 8 Jul 2009 17:21:51 +0200 Subject: Ensure that when we hide QToolBar in unified, unified follows. Basically if you would hide a toolbar in the unified toolbar, you would still see a little bit of area at the top instead of having everything flush with the titlebar. This change basically unsures that the unified toolbar makes a decision to hide itself if all the toolbars inside it are hidden. It makes the behavior of clicking on the toolbar button behave more or less correctly since we are going to show the unified toolbar whether we want to or not. This all will get the toolbar button switch event to be dispatched in Cocoa as well. Also add an optimization for checking if we need to change the geometry. If we don't have any items the other toolbar areas, we can skip the set geometry call, which wrecks havoc with things in Cocoa. We still don't solve the case of someone who has hidden the items with the toolbar button then goes full-screen, then goes back out. I'm not motivated to solve it as is because we need to keep track of the hides we do on the button press vs. other hides from the user and still people can workaround it easy enough by handling window state change and doing what is recommended in the docs. Task-number: 208439 Rev-by: Denis --- src/gui/kernel/qcocoapanel_mac.mm | 6 +++ src/gui/kernel/qcocoawindow_mac.mm | 6 +++ src/gui/kernel/qt_cocoa_helpers_mac.mm | 34 +++++++------- src/gui/kernel/qt_cocoa_helpers_mac_p.h | 3 +- src/gui/kernel/qwidget_mac.mm | 3 +- src/gui/widgets/qmainwindow.cpp | 13 ++++-- src/gui/widgets/qmainwindowlayout.cpp | 76 ++++++++++++++++++++++++++++---- src/gui/widgets/qmainwindowlayout_mac.mm | 31 ++++++++++--- src/gui/widgets/qmainwindowlayout_p.h | 2 + src/gui/widgets/qtoolbar.cpp | 29 +++++++++--- 10 files changed, 161 insertions(+), 42 deletions(-) diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index bdc7ecb..1e0bbdf 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -85,6 +85,12 @@ QT_USE_NAMESPACE last resort (i.e., this is code that can potentially be removed). */ +- (void)toggleToolbarShown:(id)sender +{ + macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); + [super toggleToolbarShown:sender]; +} + - (void)keyDown:(NSEvent *)theEvent { bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index 7084416..eb08982 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -104,6 +104,12 @@ QT_USE_NAMESPACE last resort (i.e., this is code that can potentially be removed). */ +- (void)toggleToolbarShown:(id)sender +{ + macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); + [super toggleToolbarShown:sender]; +} + - (void)keyDown:(NSEvent *)theEvent { bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 13b0e50..a98a7f8 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -177,11 +177,10 @@ void macWindowToolbarShow(const QWidget *widget, bool show ) { OSWindowRef wnd = qt_mac_window_for(widget); #if QT_MAC_USE_COCOA - NSToolbar *toolbar = [wnd toolbar]; - if (toolbar) { + if (NSToolbar *toolbar = [wnd toolbar]) { QMacCocoaAutoReleasePool pool; if (show != [toolbar isVisible]) { - [wnd toggleToolbarShown:wnd]; + [toolbar setVisible:show]; } else { // The toolbar may be in sync, but we are not, update our framestrut. qt_widget_private(const_cast(widget))->updateFrameStrut(); @@ -197,22 +196,21 @@ void macWindowToolbarSet( void * /*OSWindowRef*/ window, void *toolbarRef ) { OSWindowRef wnd = static_cast(window); #if QT_MAC_USE_COCOA - [wnd setToolbar:static_cast(toolbarRef)]; + [wnd setToolbar:static_cast(toolbarRef)]; #else SetWindowToolbar(wnd, static_cast(toolbarRef)); #endif } -bool macWindowToolbarVisible( void * /*OSWindowRef*/ window ) +bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window ) { OSWindowRef wnd = static_cast(window); #if QT_MAC_USE_COCOA - NSToolbar *toolbar = [wnd toolbar]; - if (toolbar) + if (NSToolbar *toolbar = [wnd toolbar]) return [toolbar isVisible]; return false; #else - return IsWindowToolbarVisible(wnd); + return IsWindowToolbarVisible(wnd); #endif } @@ -220,12 +218,12 @@ void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow ) { OSWindowRef wnd = static_cast(window); #if QT_MAC_USE_COCOA - [wnd setHasShadow:BOOL(hasShadow)]; + [wnd setHasShadow:BOOL(hasShadow)]; #else - if (hasShadow) - ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute); - else - ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0); + if (hasShadow) + ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute); + else + ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0); #endif } @@ -233,9 +231,9 @@ void macWindowFlush(void * /*OSWindowRef*/ window) { OSWindowRef wnd = static_cast(window); #if QT_MAC_USE_COCOA - [wnd flushWindowIfNeeded]; + [wnd flushWindowIfNeeded]; #else - HIWindowFlush(wnd); + HIWindowFlush(wnd); #endif } @@ -352,6 +350,12 @@ Qt::MouseButton qt_mac_get_button(EventMouseButton button) return Qt::NoButton; } +void macSendToolbarChangeEvent(QWidget *widget) +{ + QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey)); + qt_sendSpontaneousEvent(widget, &ev); +} + Q_GLOBAL_STATIC(QMacTabletHash, tablet_hash) QMacTabletHash *qt_mac_tablet_hash() { diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 3881ccd..5f6204f 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -118,9 +118,10 @@ void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0); bool macWindowIsTextured(void * /*OSWindowRef*/ window); void macWindowToolbarShow(const QWidget *widget, bool show ); void macWindowToolbarSet( void * /*OSWindowRef*/ window, void* toolbarRef ); -bool macWindowToolbarVisible( void * /*OSWindowRef*/ window ); +bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window ); void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow ); void macWindowFlush(void * /*OSWindowRef*/ window); +void macSendToolbarChangeEvent(QWidget *widget); struct HIContentBorderMetrics; void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics); void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm); diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index dcc5056..5e2dfb6 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -843,8 +843,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, extern QPointer qt_button_down; //qapplication_mac.cpp qt_button_down = 0; } else if(ekind == kEventWindowToolbarSwitchMode) { - QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey)); - QApplication::sendSpontaneousEvent(widget, &ev); + macSendToolbarChangeEvent(widget); HIToolbarRef toolbar; if (GetWindowToolbar(wid, &toolbar) == noErr) { if (toolbar) { diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 0c841eb..c51bed9 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1369,20 +1369,25 @@ bool QMainWindow::event(QEvent *event) #ifdef Q_WS_MAC case QEvent::Show: if (unifiedTitleAndToolBarOnMac()) - macWindowToolbarShow(this, true); + d->layout->syncUnifiedToolbarVisibility(); + d->layout->blockVisiblityCheck = false; break; -# ifdef QT_MAC_USE_COCOA case QEvent::WindowStateChange: { + if (isHidden()) { + // We are coming out of a minimize, leave things as is. + d->layout->blockVisiblityCheck = true; + } +# ifdef QT_MAC_USE_COCOA // We need to update the HIToolbar status when we go out of or into fullscreen. QWindowStateChangeEvent *wce = static_cast(event); if ((windowState() & Qt::WindowFullScreen) || (wce->oldState() & Qt::WindowFullScreen)) { d->layout->updateHIToolBarStatus(); } +# endif // Cocoa } break; -# endif // Cocoa -#endif +#endif // Q_WS_MAC #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR) case QEvent::CursorChange: if (d->cursorAdjusted) { diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index aba9120..541907e 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -939,15 +939,70 @@ void QMainWindowLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar void QMainWindowLayout::toggleToolBarsVisible() { - layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible; - if (!layoutState.mainWindow->isMaximized()){ - QPoint topLeft = parentWidget()->geometry().topLeft(); - QRect r = parentWidget()->geometry(); - r = layoutState.toolBarAreaLayout.rectHint(r); - r.moveTo(topLeft); - parentWidget()->setGeometry(r); - } else{ - update(); + bool updateNonUnifiedParts = true; +#ifdef Q_WS_MAC + if (layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) { + // If we hit this case, someone has pressed the "toolbar button" which will + // toggle the unified toolbar visiblity, because that's what the user wants. + // We might be in a situation where someone has hidden all the toolbars + // beforehand (maybe in construction), but now they've hit this button and + // and are expecting the items to show. What do we do? + // 1) Check the visibility of all the toolbars, if one is visible, do nothing, this + // preserves what people would expect (these toolbars were visible when I clicked last time). + // 2) If NONE are visible, then show them all. Again, this preserves the user expectation + // of, "I want to see the toolbars." The user may get more toolbars than expected, but this + // is better seeing nothing. + // Don't worry about any of this if we are going invisible. This does mean we may get + // into issues when switching into and out of fullscreen mode, but this is probably minor. + // If we ever need to do hiding, that would have to be taken care of after the unified toolbar + // has finished hiding. + // People can of course handle the QEvent::ToolBarChange event themselves and do + // WHATEVER they want if they don't like what we are doing (though the unified toolbar + // will fire regardless). + + // Check if we REALLY need to update the geometry below. If we only have items in the + // unified toolbar, all the docks will be empty, so there's very little point + // in doing the geometry as Apple will do it (we also avoid flicker in Cocoa as well). + // FWIW, layoutState.toolBarAreaLayout.visible and the state of the unified toolbar + // visibility can get out of sync. I really don't think it's a big issue. It is kept + // to a minimum because we only change the visibility if we absolutely must. + // update the "non unified parts." + updateNonUnifiedParts = !layoutState.toolBarAreaLayout.isEmpty(); + + // We get this function before the unified toolbar does its thing. + // So, the value will be opposite of what we expect. + bool goingVisible = !macWindowToolbarIsVisible(qt_mac_window_for(layoutState.mainWindow)); + if (goingVisible) { + const int ToolBarCount = qtoolbarsInUnifiedToolbarList.size(); + bool needAllVisible = true; + for (int i = 0; i < ToolBarCount; ++i) { + if (!qtoolbarsInUnifiedToolbarList.at(i)->isHidden()) { + needAllVisible = false; + break; + } + } + if (needAllVisible) { + QBoolBlocker blocker(blockVisiblityCheck); // Disable the visibilty check because + // the toggle has already happened. + for (int i = 0; i < ToolBarCount; ++i) + qtoolbarsInUnifiedToolbarList.at(i)->setVisible(true); + } + } + if (!updateNonUnifiedParts) + layoutState.toolBarAreaLayout.visible = goingVisible; + } +#endif + if (updateNonUnifiedParts) { + layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible; + if (!layoutState.mainWindow->isMaximized()) { + QPoint topLeft = parentWidget()->geometry().topLeft(); + QRect r = parentWidget()->geometry(); + r = layoutState.toolBarAreaLayout.rectHint(r); + r.moveTo(topLeft); + parentWidget()->setGeometry(r); + } else { + update(); + } } } @@ -1641,6 +1696,9 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) #ifndef QT_NO_RUBBERBAND , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) #endif //QT_NO_RUBBERBAND +#ifdef Q_WS_MAC + , blockVisiblityCheck(false) +#endif { #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 6632be7..61719c2 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -338,18 +338,16 @@ void QMainWindowLayout::updateHIToolBarStatus() 0, kWindowUnifiedTitleAndToolbarAttribute); } #endif - macWindowToolbarShow(layoutState.mainWindow, useMacToolbar); layoutState.mainWindow->setUpdatesEnabled(false); // reduces a little bit of flicker, not all though if (!useMacToolbar) { - OSWindowRef windowRef = qt_mac_window_for(parentWidget()); - macWindowToolbarShow(parentWidget(), false); + macWindowToolbarShow(layoutState.mainWindow, false); // Move everything out of the HIToolbar into the main toolbar. while (!qtoolbarsInUnifiedToolbarList.isEmpty()) { // Should shrink the list by one every time. layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, qtoolbarsInUnifiedToolbarList.first()); } - macWindowToolbarSet(windowRef, NULL); + macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0); } else { QList toolbars = layoutState.mainWindow->findChildren(); for (int i = 0; i < toolbars.size(); ++i) { @@ -359,6 +357,7 @@ void QMainWindowLayout::updateHIToolBarStatus() layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar); } } + syncUnifiedToolbarVisibility(); } layoutState.mainWindow->setUpdatesEnabled(true); } @@ -439,7 +438,7 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar #else NSString *toolbarID = kQToolBarNSToolbarIdentifier; toolbarID = [toolbarID stringByAppendingFormat:@"%p", toolbar]; - cocoaItemIDToToolbarHash.insert(QCFString::toQString(CFStringRef(toolbarID)), toolbar); + cocoaItemIDToToolbarHash.insert(qt_mac_NSStringToQString(toolbarID), toolbar); [macToolbar insertItemWithItemIdentifier:toolbarID atIndex:beforeIndex]; #endif } @@ -487,6 +486,7 @@ void QMainWindowLayout::cleanUpMacToolbarItems() void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const { +#ifdef QT_MAC_USE_COCOA QHash::const_iterator it = unifiedToolbarHash.constBegin(); NSToolbarItem *item = nil; while (it != unifiedToolbarHash.constEnd()) { @@ -507,5 +507,26 @@ void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const nssize.height = size.height() - 2; [item setMinSize:nssize]; } +#else + Q_UNUSED(tb); +#endif } + +void QMainWindowLayout::syncUnifiedToolbarVisibility() +{ + if (blockVisiblityCheck) + return; + + Q_ASSERT(layoutState.mainWindow->unifiedTitleAndToolBarOnMac()); + bool show = false; + const int ToolBarCount = qtoolbarsInUnifiedToolbarList.count(); + for (int i = 0; i < ToolBarCount; ++i) { + if (qtoolbarsInUnifiedToolbarList.at(i)->isVisible()) { + show = true; + break; + } + } + macWindowToolbarShow(layoutState.mainWindow, show); +} + QT_END_NAMESPACE diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 45f62cd..524fdbf 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -335,6 +335,8 @@ public: void cleanUpMacToolbarItems(); void fixSizeInUnifiedToolbar(QToolBar *tb) const; bool useHIToolBar; + void syncUnifiedToolbarVisibility(); + bool blockVisiblityCheck; #endif }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index b249915..b65f1ba 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -1074,6 +1074,15 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup) return false; } +#if defined(Q_WS_MAC) +static bool toolbarInUnifiedToolBar(QToolBar *toolbar) +{ + const QMainWindow *mainWindow = qobject_cast(toolbar->parentWidget()); + return mainWindow && mainWindow->unifiedTitleAndToolBarOnMac() + && mainWindow->toolBarArea(toolbar) == Qt::TopToolBarArea; +} +#endif + /*! \reimp */ bool QToolBar::event(QEvent *event) { @@ -1096,7 +1105,15 @@ bool QToolBar::event(QEvent *event) // fallthrough intended case QEvent::Show: d->toggleViewAction->setChecked(event->type() == QEvent::Show); -#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) +#if defined(Q_WS_MAC) + if (toolbarInUnifiedToolBar(this)) { + // I can static_cast because I did the qobject_cast in the if above, therefore + // we must have a QMainWindowLayout here. + QMainWindowLayout *mwLayout = static_cast(parentWidget()->layout()); + mwLayout->fixSizeInUnifiedToolbar(this); + mwLayout->syncUnifiedToolbarVisibility(); + } +# if !defined(QT_MAC_USE_COCOA) // Fall through case QEvent::LayoutRequest: { // There's currently no way to invalidate the size and let @@ -1111,10 +1128,9 @@ bool QToolBar::event(QEvent *event) } if (needUpdate) { - OSWindowRef windowRef = qt_mac_window_for(this); - if (mainWindow->unifiedTitleAndToolBarOnMac() - && mainWindow->toolBarArea(this) == Qt::TopToolBarArea - && macWindowToolbarVisible(windowRef)) { + OSWindowRef windowRef = qt_mac_window_for(mainWindow); + if (toolbarInUnifiedToolBar(this) + && macWindowToolbarIsVisible(windowRef)) { DisableScreenUpdates(); macWindowToolbarShow(this, false); macWindowToolbarShow(this, true); @@ -1126,7 +1142,8 @@ bool QToolBar::event(QEvent *event) return earlyResult; } } -#endif +# endif // !QT_MAC_USE_COCOA +#endif // Q_WS_MAC break; case QEvent::ParentChange: d->layout->checkUsePopupMenu(); -- cgit v0.12 From 17f814ce07a4d82563012a15a46dfe6acb2edcc5 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Fri, 3 Jul 2009 09:41:00 +0200 Subject: Add a specialization for QByteArray It tries to keep the semantics of QString::append(QByteArray) as much as possible. --- src/corelib/tools/qstringbuilder.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 4d6b64b..127c183 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -202,6 +202,18 @@ template <> struct QConcatenable *out++ = QLatin1Char(*a++); } }; + +template <> struct QConcatenable +{ + typedef QByteArray type; + static int size(const QByteArray &ba) { qstrnlen(ba.constData(), ba.size()); } + static inline void appendTo(const QByteArray &ba, QChar *&out) + { + const char *data = ba.constData(); + while (*data) + *out++ = *data++; + } +}; #endif template -- cgit v0.12 From 8a0b05f71d2a9481a21143d1b87e2b18d427d1d5 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Fri, 3 Jul 2009 10:08:52 +0200 Subject: fix the test _and_ the class :) --- src/corelib/tools/qstringbuilder.h | 2 +- tests/auto/qstringbuilder/tst_qstringbuilder.cpp | 17 ++++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 127c183..97f13ee 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -206,7 +206,7 @@ template <> struct QConcatenable template <> struct QConcatenable { typedef QByteArray type; - static int size(const QByteArray &ba) { qstrnlen(ba.constData(), ba.size()); } + static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); } static inline void appendTo(const QByteArray &ba, QChar *&out) { const char *data = ba.constData(); diff --git a/tests/auto/qstringbuilder/tst_qstringbuilder.cpp b/tests/auto/qstringbuilder/tst_qstringbuilder.cpp index fdbaf21..72889bc 100644 --- a/tests/auto/qstringbuilder/tst_qstringbuilder.cpp +++ b/tests/auto/qstringbuilder/tst_qstringbuilder.cpp @@ -85,28 +85,18 @@ #undef QT_NO_CAST_TO_ASCII #endif - #include //TESTED_CLASS=QStringBuilder //TESTED_FILES=qstringbuilder.cpp -#include - #define LITERAL "some literal" class tst_QStringBuilder : public QObject { Q_OBJECT -public: - tst_QStringBuilder() {} - ~tst_QStringBuilder() {} - -public slots: - void init() {} - void cleanup() {} - +private slots: void scenario(); }; @@ -119,6 +109,7 @@ void tst_QStringBuilder::scenario() QLatin1Char achar('c'); QString r2(QLatin1String(LITERAL LITERAL)); QString r; + QByteArray ba(LITERAL); r = l1literal P l1literal; QCOMPARE(r, r2); @@ -139,6 +130,10 @@ void tst_QStringBuilder::scenario() QCOMPARE(r, r2); r = LITERAL P string; QCOMPARE(r, r2); + r = ba P string; + QCOMPARE(r, r2); + r = string P ba; + QCOMPARE(r, r2); #endif } -- cgit v0.12 From a21230152c4ea8cd2e641f436230e76a835384c2 Mon Sep 17 00:00:00 2001 From: Bill King Date: Fri, 10 Jul 2009 12:07:38 +1000 Subject: Fixes a heisenbug when using two ODBC connections with diff quoters. Can have situations where 2 odbc connections are active, that have differing quoting charachters. Before this fix, everything fell over. Reviewed-by: Justin McPherson --- src/sql/drivers/odbc/qsql_odbc.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 50defdf..fa9031a 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -89,7 +89,8 @@ public: enum DefaultCase{Lower, Mixed, Upper, Sensitive}; QODBCDriverPrivate() : hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false), - isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false) + isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false), + isQuoteInitialized(false), quote(QLatin1Char('"')) { unicode = false; } @@ -116,7 +117,10 @@ public: QString &schema, QString &table); DefaultCase defaultCase() const; QString adjustCase(const QString&) const; - QChar quoteChar() const; + QChar quoteChar(); +private: + bool isQuoteInitialized; + QChar quote; }; class QODBCPrivate @@ -566,10 +570,8 @@ static int qGetODBCVersion(const QString &connOpts) return SQL_OV_ODBC2; } -QChar QODBCDriverPrivate::quoteChar() const +QChar QODBCDriverPrivate::quoteChar() { - static bool isQuoteInitialized = false; - static QChar quote = QChar::fromLatin1('"'); if (!isQuoteInitialized) { char driverResponse[4]; SQLSMALLINT length; @@ -579,9 +581,9 @@ QChar QODBCDriverPrivate::quoteChar() const sizeof(driverResponse), &length); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { - quote = QChar::fromLatin1(driverResponse[0]); + quote = QLatin1Char(driverResponse[0]); } else { - quote = QChar::fromLatin1('"'); + quote = QLatin1Char('"'); } isQuoteInitialized = true; } -- cgit v0.12 From 0d156972b868c951fa33f21735040ab1e7a76f21 Mon Sep 17 00:00:00 2001 From: Bill King Date: Fri, 10 Jul 2009 12:12:45 +1000 Subject: Get more sql autotests passing or expect-failing. --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 2 ++ .../tst_qsqlrelationaltablemodel.cpp | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 9a873cb..f3dd920 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -495,7 +495,9 @@ void tst_QSqlQuery::mysqlOutValues() QVERIFY_SQL( q, exec( "create procedure " + qTableName( "qtestproc" ) + " () " "BEGIN select * from " + qTableName( "qtest" ) + " order by id; END" ) ); QVERIFY_SQL( q, exec( "call " + qTableName( "qtestproc" ) + "()" ) ); + QEXPECT_FAIL("", "There's a mysql bug that means only selects think they return data when running in prepared mode", Continue); QVERIFY_SQL( q, next() ); + QEXPECT_FAIL("", "There's a mysql bug that means only selects think they return data when running in prepared mode", Continue); QCOMPARE( q.value( 1 ).toString(), QString( "VarChar1" ) ); QVERIFY_SQL( q, exec( "drop procedure " + qTableName( "qtestproc" ) ) ); diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index d934b35..1e23d3d 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -145,8 +145,17 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) void tst_QSqlRelationalTableModel::initTestCase() { - foreach (const QString &dbname, dbs.dbNames) - recreateTestTables(QSqlDatabase::database(dbname)); + foreach (const QString &dbname, dbs.dbNames) { + QSqlDatabase db=QSqlDatabase::database(dbname); + if (db.driverName().startsWith("QIBASE")) + db.exec("SET DIALECT 3"); + else if (tst_Databases::isSqlServer(db)) { + QSqlQuery q(db); + QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON")); + QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF")); + } + recreateTestTables(db); + } } void tst_QSqlRelationalTableModel::cleanupTestCase() @@ -490,6 +499,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); if (!db.driverName().startsWith("QTDS")) model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); @@ -914,8 +924,8 @@ void tst_QSqlRelationalTableModel::casing() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - if (db.driverName().startsWith("QSQLITE")) - QSKIP("The casing test for SQLITE is irrelevant since SQLITE is case insensitive", SkipAll); + if (db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QIBASE") || tst_Databases::isSqlServer(db)) + QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities", SkipAll); QSqlQuery q(db); QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() + -- cgit v0.12