tools/assistant/lib/qhelpsearchquerywidget.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Assistant of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qhelpsearchquerywidget.h"
       
    43 
       
    44 #include <QtCore/QDebug>
       
    45 
       
    46 #include <QtCore/QAbstractListModel>
       
    47 #include <QtCore/QObject>
       
    48 #include <QtCore/QStringList>
       
    49 #include <QtCore/QtGlobal>
       
    50 
       
    51 #include <QtGui/QCompleter>
       
    52 #include <QtGui/QLabel>
       
    53 #include <QtGui/QLayout>
       
    54 #include <QtGui/QLineEdit>
       
    55 #include <QtGui/QFocusEvent>
       
    56 #include <QtGui/QPushButton>
       
    57 #include <QtGui/QToolButton>
       
    58 
       
    59 QT_BEGIN_NAMESPACE
       
    60 
       
    61 class QHelpSearchQueryWidgetPrivate : public QObject
       
    62 {
       
    63     Q_OBJECT
       
    64 
       
    65 private:
       
    66     struct QueryHistory {
       
    67         explicit QueryHistory() : curQuery(-1) {}
       
    68         QList<QList<QHelpSearchQuery> > queries;
       
    69         int curQuery;
       
    70     };
       
    71 
       
    72     class CompleterModel : public QAbstractListModel
       
    73     {
       
    74     public:
       
    75         explicit CompleterModel(QObject *parent)
       
    76           : QAbstractListModel(parent) {}
       
    77 
       
    78         int rowCount(const QModelIndex &parent = QModelIndex()) const
       
    79         {
       
    80             return parent.isValid() ? 0 : termList.size();
       
    81         }
       
    82 
       
    83         QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
       
    84         {
       
    85             if (!index.isValid() || index.row() >= termList.count()||
       
    86                 (role != Qt::EditRole && role != Qt::DisplayRole))
       
    87                 return QVariant();
       
    88             return termList.at(index.row());
       
    89         }
       
    90 
       
    91         void addTerm(const QString &term)
       
    92         {
       
    93             if (!termList.contains(term)) {
       
    94                 termList.append(term);
       
    95                 reset();
       
    96             }
       
    97         }
       
    98 
       
    99     private:
       
   100         QStringList termList;
       
   101     };
       
   102 
       
   103     QHelpSearchQueryWidgetPrivate()
       
   104         : QObject(), simpleSearch(true),
       
   105           searchCompleter(new CompleterModel(this), this)
       
   106     {
       
   107         searchButton = 0;
       
   108         advancedSearchWidget = 0;
       
   109         showHideAdvancedSearchButton = 0;
       
   110         defaultQuery = 0;
       
   111         exactQuery = 0;
       
   112         similarQuery = 0;
       
   113         withoutQuery = 0;
       
   114         allQuery = 0;
       
   115         atLeastQuery = 0;
       
   116     }
       
   117 
       
   118     ~QHelpSearchQueryWidgetPrivate()
       
   119     {
       
   120         // nothing todo
       
   121     }
       
   122 
       
   123     QString escapeString(const QString &text)
       
   124     {
       
   125         QString retValue = text;
       
   126         const QString escape(QLatin1String("\\"));
       
   127         QStringList escapableCharsList;
       
   128         escapableCharsList << QLatin1String("\\") << QLatin1String("+")
       
   129             << QLatin1String("-") << QLatin1String("!") << QLatin1String("(")
       
   130             << QLatin1String(")") << QLatin1String(":") << QLatin1String("^")
       
   131             << QLatin1String("[") << QLatin1String("]") << QLatin1String("{")
       
   132             << QLatin1String("}") << QLatin1String("~");
       
   133 
       
   134         // make sure we won't end up with an empty string
       
   135         foreach (const QString escapeChar, escapableCharsList) {
       
   136             if (retValue.contains(escapeChar))
       
   137                 retValue.replace(escapeChar, QLatin1String(""));
       
   138         }
       
   139         if (retValue.trimmed().isEmpty())
       
   140             return retValue;
       
   141 
       
   142         retValue = text; // now realy escape the string...
       
   143         foreach (const QString escapeChar, escapableCharsList) {
       
   144             if (retValue.contains(escapeChar))
       
   145                 retValue.replace(escapeChar, escape + escapeChar);
       
   146         }
       
   147         return retValue;
       
   148     }
       
   149 
       
   150     QStringList buildTermList(const QString query)
       
   151     {
       
   152         bool s = false;
       
   153         QString phrase;
       
   154         QStringList wordList;
       
   155         QString searchTerm = query;
       
   156 
       
   157         for (int i = 0; i < searchTerm.length(); ++i) {
       
   158             if (searchTerm[i] == QLatin1Char('\"') && !s) {
       
   159                 s = true;
       
   160                 phrase = searchTerm[i];
       
   161                 continue;
       
   162             }
       
   163             if (searchTerm[i] != QLatin1Char('\"') && s)
       
   164                 phrase += searchTerm[i];
       
   165             if (searchTerm[i] == QLatin1Char('\"') && s) {
       
   166                 s = false;
       
   167                 phrase += searchTerm[i];
       
   168                 wordList.append(phrase);
       
   169                 searchTerm.remove(phrase);
       
   170             }
       
   171         }
       
   172         if (s)
       
   173             searchTerm.replace(phrase, phrase.mid(1));
       
   174 
       
   175         const QRegExp exp(QLatin1String("\\s+"));
       
   176         wordList += searchTerm.split(exp, QString::SkipEmptyParts);
       
   177         return wordList;
       
   178     }
       
   179 
       
   180     void saveQuery(const QList<QHelpSearchQuery> &query, QueryHistory &queryHist)
       
   181     {
       
   182         // We only add the query to the list if it is different from the last one.
       
   183         bool insert = false;
       
   184         if (queryHist.queries.empty())
       
   185             insert = true;
       
   186         else {
       
   187             const QList<QHelpSearchQuery> &lastQuery = queryHist.queries.last();
       
   188             if (lastQuery.size() != query.size()) {
       
   189                 insert = true;
       
   190             } else {
       
   191                 for (int i = 0; i < query.size(); ++i) {
       
   192                     if (query.at(i).fieldName != lastQuery.at(i).fieldName
       
   193                         || query.at(i).wordList != lastQuery.at(i).wordList) {
       
   194                         insert = true;
       
   195                         break;
       
   196                     }
       
   197                 }
       
   198             }
       
   199         }
       
   200         if (insert) {
       
   201             queryHist.queries.append(query);
       
   202             foreach (const QHelpSearchQuery &queryPart, query) {
       
   203                 static_cast<CompleterModel *>(searchCompleter.model())->
       
   204                         addTerm(queryPart.wordList.join(" "));
       
   205             }
       
   206         }
       
   207     }
       
   208 
       
   209     void nextOrPrevQuery(int maxOrMinIndex, int addend,
       
   210                          QToolButton *thisButton, QToolButton *otherButton)
       
   211     {
       
   212         QueryHistory *queryHist;
       
   213         QList<QLineEdit *> lineEdits;
       
   214         if (simpleSearch) {
       
   215             queryHist = &simpleQueries;
       
   216             lineEdits << defaultQuery;
       
   217         } else {
       
   218             queryHist = &complexQueries;
       
   219             lineEdits << allQuery << atLeastQuery << similarQuery
       
   220                     << withoutQuery << exactQuery;
       
   221         }
       
   222         foreach (QLineEdit *lineEdit, lineEdits)
       
   223             lineEdit->clear();
       
   224 
       
   225         // Otherwise, the respective button would be disabled.
       
   226         Q_ASSERT(queryHist->curQuery != maxOrMinIndex);
       
   227 
       
   228         queryHist->curQuery += addend;
       
   229         const QList<QHelpSearchQuery> &query =
       
   230                 queryHist->queries.at(queryHist->curQuery);
       
   231         foreach (const QHelpSearchQuery &queryPart, query) {
       
   232             QLineEdit *lineEdit = 0;
       
   233             switch (queryPart.fieldName) {
       
   234             case QHelpSearchQuery::DEFAULT:
       
   235                 lineEdit = defaultQuery;
       
   236                 break;
       
   237             case QHelpSearchQuery::ALL:
       
   238                 lineEdit = allQuery;
       
   239                 break;
       
   240             case QHelpSearchQuery::ATLEAST:
       
   241                 lineEdit = atLeastQuery;
       
   242                 break;
       
   243             case QHelpSearchQuery::FUZZY:
       
   244                 lineEdit = similarQuery;
       
   245                 break;
       
   246             case QHelpSearchQuery::WITHOUT:
       
   247                 lineEdit = withoutQuery;
       
   248                 break;
       
   249             case QHelpSearchQuery::PHRASE:
       
   250                 lineEdit = exactQuery;
       
   251                 break;
       
   252             default:
       
   253                 Q_ASSERT(0);
       
   254             }
       
   255             lineEdit->setText(queryPart.wordList.join(" "));
       
   256         }
       
   257 
       
   258         if (queryHist->curQuery == maxOrMinIndex)
       
   259             thisButton->setEnabled(false);
       
   260         otherButton->setEnabled(true);
       
   261     }
       
   262 
       
   263     void enableOrDisableToolButtons()
       
   264     {
       
   265         const QueryHistory &queryHist =
       
   266                 simpleSearch ? simpleQueries : complexQueries;
       
   267         prevQueryButton->setEnabled(queryHist.curQuery > 0);
       
   268         nextQueryButton->setEnabled(queryHist.curQuery <
       
   269                                     queryHist.queries.size() - 1);
       
   270     }
       
   271 
       
   272 private slots:
       
   273     void showHideAdvancedSearch()
       
   274     {
       
   275         if (simpleSearch) {
       
   276             advancedSearchWidget->show();
       
   277             showHideAdvancedSearchButton->setText((QLatin1String("-")));
       
   278         } else {
       
   279             advancedSearchWidget->hide();
       
   280             showHideAdvancedSearchButton->setText((QLatin1String("+")));
       
   281         }
       
   282 
       
   283         simpleSearch = !simpleSearch;
       
   284         defaultQuery->setEnabled(simpleSearch);
       
   285         enableOrDisableToolButtons();
       
   286     }
       
   287 
       
   288     void searchRequested()
       
   289     {
       
   290         QList<QHelpSearchQuery> queryList;
       
   291 #if !defined(QT_CLUCENE_SUPPORT)
       
   292         queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
       
   293                                           QStringList(defaultQuery->text())));
       
   294 
       
   295 #else
       
   296         if (defaultQuery->isEnabled()) {
       
   297             queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
       
   298                                               buildTermList(escapeString(defaultQuery->text()))));
       
   299         } else {
       
   300             const QRegExp exp(QLatin1String("\\s+"));
       
   301             QStringList lst = similarQuery->text().split(exp, QString::SkipEmptyParts);
       
   302             if (!lst.isEmpty()) {
       
   303                 QStringList fuzzy;
       
   304                 foreach (const QString term, lst)
       
   305                     fuzzy += buildTermList(escapeString(term));
       
   306                 queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY, fuzzy));
       
   307             }
       
   308 
       
   309             lst = withoutQuery->text().split(exp, QString::SkipEmptyParts);
       
   310             if (!lst.isEmpty()) {
       
   311                 QStringList without;
       
   312                 foreach (const QString term, lst)
       
   313                     without.append(escapeString(term));
       
   314                 queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT, without));
       
   315             }
       
   316 
       
   317             if (!exactQuery->text().isEmpty()) {
       
   318                 QString phrase = exactQuery->text().remove(QLatin1Char('\"'));
       
   319                 phrase = escapeString(phrase.simplified());
       
   320                 queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE, QStringList(phrase)));
       
   321             }
       
   322 
       
   323             lst = allQuery->text().split(exp, QString::SkipEmptyParts);
       
   324             if (!lst.isEmpty()) {
       
   325                 QStringList all;
       
   326                 foreach (const QString term, lst)
       
   327                     all.append(escapeString(term));
       
   328                 queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all));
       
   329             }
       
   330 
       
   331             lst = atLeastQuery->text().split(exp, QString::SkipEmptyParts);
       
   332             if (!lst.isEmpty()) {
       
   333                 QStringList atLeast;
       
   334                 foreach (const QString term, lst)
       
   335                     atLeast += buildTermList(escapeString(term));
       
   336                 queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST, atLeast));
       
   337             }
       
   338         }
       
   339 #endif
       
   340         QueryHistory &queryHist = simpleSearch ? simpleQueries : complexQueries;
       
   341         saveQuery(queryList, queryHist);
       
   342         queryHist.curQuery = queryHist.queries.size() - 1;
       
   343         if (queryHist.curQuery > 0)
       
   344             prevQueryButton->setEnabled(true);
       
   345         nextQueryButton->setEnabled(false);
       
   346     }
       
   347 
       
   348     void nextQuery()
       
   349     {
       
   350         nextOrPrevQuery((simpleSearch ? simpleQueries : complexQueries).queries.size() - 1,
       
   351                         1, nextQueryButton, prevQueryButton);
       
   352     }
       
   353 
       
   354     void prevQuery()
       
   355     {
       
   356         nextOrPrevQuery(0, -1, prevQueryButton, nextQueryButton);
       
   357     }
       
   358 
       
   359 private:
       
   360     friend class QHelpSearchQueryWidget;
       
   361 
       
   362     bool simpleSearch;
       
   363     QPushButton *searchButton;
       
   364     QWidget* advancedSearchWidget;
       
   365     QToolButton *showHideAdvancedSearchButton;
       
   366     QLineEdit *defaultQuery;
       
   367     QLineEdit *exactQuery;
       
   368     QLineEdit *similarQuery;
       
   369     QLineEdit *withoutQuery;
       
   370     QLineEdit *allQuery;
       
   371     QLineEdit *atLeastQuery;
       
   372     QToolButton *nextQueryButton;
       
   373     QToolButton *prevQueryButton;
       
   374     QueryHistory simpleQueries;
       
   375     QueryHistory complexQueries;
       
   376     QCompleter searchCompleter;
       
   377 };
       
   378 
       
   379 #include "qhelpsearchquerywidget.moc"
       
   380 
       
   381 
       
   382 /*!
       
   383     \class QHelpSearchQueryWidget
       
   384     \since 4.4
       
   385     \inmodule QtHelp
       
   386     \brief The QHelpSearchQueryWidget class provides a simple line edit or
       
   387     an advanced widget to enable the user to input a search term in a
       
   388     standardized input mask.
       
   389 */
       
   390 
       
   391 /*!
       
   392     \fn void QHelpSearchQueryWidget::search()
       
   393 
       
   394     This signal is emitted when a the user has the search button invoked.
       
   395     After reciving the signal you can ask the QHelpSearchQueryWidget for the build list
       
   396     of QHelpSearchQuery's that you may pass to the QHelpSearchEngine's search() function.
       
   397 */
       
   398 
       
   399 /*!
       
   400     Constructs a new search query widget with the given \a parent.
       
   401 */
       
   402 QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent)
       
   403     : QWidget(parent)
       
   404 {
       
   405     d = new QHelpSearchQueryWidgetPrivate();
       
   406 
       
   407     QVBoxLayout *vLayout = new QVBoxLayout(this);
       
   408     vLayout->setMargin(0);
       
   409 
       
   410     QHBoxLayout* hBoxLayout = new QHBoxLayout();
       
   411     QLabel *label = new QLabel(tr("Search for:"), this);
       
   412     d->defaultQuery = new QLineEdit(this);
       
   413     d->defaultQuery->setCompleter(&d->searchCompleter);
       
   414     d->prevQueryButton = new QToolButton(this);
       
   415     d->prevQueryButton->setArrowType(Qt::LeftArrow);
       
   416     d->prevQueryButton->setToolTip(tr("Previous search"));
       
   417     d->prevQueryButton->setEnabled(false);
       
   418     d->nextQueryButton = new QToolButton(this);
       
   419     d->nextQueryButton->setArrowType(Qt::RightArrow);
       
   420     d->nextQueryButton->setToolTip(tr("Next search"));
       
   421     d->nextQueryButton->setEnabled(false);
       
   422     d->searchButton = new QPushButton(tr("Search"), this);
       
   423     hBoxLayout->addWidget(label);
       
   424     hBoxLayout->addWidget(d->defaultQuery);
       
   425     hBoxLayout->addWidget(d->prevQueryButton);
       
   426     hBoxLayout->addWidget(d->nextQueryButton);
       
   427     hBoxLayout->addWidget(d->searchButton);
       
   428 
       
   429     vLayout->addLayout(hBoxLayout);
       
   430 
       
   431     connect(d->prevQueryButton, SIGNAL(clicked()), d, SLOT(prevQuery()));
       
   432     connect(d->nextQueryButton, SIGNAL(clicked()), d, SLOT(nextQuery()));
       
   433     connect(d->searchButton, SIGNAL(clicked()), this, SIGNAL(search()));
       
   434     connect(d->defaultQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
       
   435 
       
   436 #if defined(QT_CLUCENE_SUPPORT)
       
   437     hBoxLayout = new QHBoxLayout();
       
   438     d->showHideAdvancedSearchButton = new QToolButton(this);
       
   439     d->showHideAdvancedSearchButton->setText(QLatin1String("+"));
       
   440     d->showHideAdvancedSearchButton->setMinimumSize(25, 20);
       
   441 
       
   442     label = new QLabel(tr("Advanced search"), this);
       
   443     QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
       
   444     sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
       
   445     label->setSizePolicy(sizePolicy);
       
   446 
       
   447     QFrame* hLine = new QFrame(this);
       
   448     hLine->setFrameStyle(QFrame::HLine);
       
   449     hBoxLayout->addWidget(d->showHideAdvancedSearchButton);
       
   450     hBoxLayout->addWidget(label);
       
   451     hBoxLayout->addWidget(hLine);
       
   452 
       
   453     vLayout->addLayout(hBoxLayout);
       
   454 
       
   455     // setup advanced search layout
       
   456     d->advancedSearchWidget = new QWidget(this);
       
   457     QGridLayout *gLayout = new QGridLayout(d->advancedSearchWidget);
       
   458     gLayout->setMargin(0);
       
   459 
       
   460     label = new QLabel(tr("words <B>similar</B> to:"), this);
       
   461     gLayout->addWidget(label, 0, 0);
       
   462     d->similarQuery = new QLineEdit(this);
       
   463     d->similarQuery->setCompleter(&d->searchCompleter);
       
   464     gLayout->addWidget(d->similarQuery, 0, 1);
       
   465 
       
   466     label = new QLabel(tr("<B>without</B> the words:"), this);
       
   467     gLayout->addWidget(label, 1, 0);
       
   468     d->withoutQuery = new QLineEdit(this);
       
   469     d->withoutQuery->setCompleter(&d->searchCompleter);
       
   470     gLayout->addWidget(d->withoutQuery, 1, 1);
       
   471 
       
   472     label = new QLabel(tr("with <B>exact phrase</B>:"), this);
       
   473     gLayout->addWidget(label, 2, 0);
       
   474     d->exactQuery = new QLineEdit(this);
       
   475     d->exactQuery->setCompleter(&d->searchCompleter);
       
   476     gLayout->addWidget(d->exactQuery, 2, 1);
       
   477 
       
   478     label = new QLabel(tr("with <B>all</B> of the words:"), this);
       
   479     gLayout->addWidget(label, 3, 0);
       
   480     d->allQuery = new QLineEdit(this);
       
   481     d->allQuery->setCompleter(&d->searchCompleter);
       
   482     gLayout->addWidget(d->allQuery, 3, 1);
       
   483 
       
   484     label = new QLabel(tr("with <B>at least one</B> of the words:"), this);
       
   485     gLayout->addWidget(label, 4, 0);
       
   486     d->atLeastQuery = new QLineEdit(this);
       
   487     d->atLeastQuery->setCompleter(&d->searchCompleter);
       
   488     gLayout->addWidget(d->atLeastQuery, 4, 1);
       
   489 
       
   490     vLayout->addWidget(d->advancedSearchWidget);
       
   491     d->advancedSearchWidget->hide();
       
   492 
       
   493     connect(d->exactQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
       
   494     connect(d->similarQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
       
   495     connect(d->withoutQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
       
   496     connect(d->allQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
       
   497     connect(d->atLeastQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
       
   498     connect(d->showHideAdvancedSearchButton, SIGNAL(clicked()),
       
   499         d, SLOT(showHideAdvancedSearch()));
       
   500 #endif
       
   501     connect(this, SIGNAL(search()), d, SLOT(searchRequested()));
       
   502 }
       
   503 
       
   504 /*!
       
   505     Destroys the search query widget.
       
   506 */
       
   507 QHelpSearchQueryWidget::~QHelpSearchQueryWidget()
       
   508 {
       
   509     delete d;
       
   510 }
       
   511 
       
   512 /*!
       
   513     Returns a list of querys to use in combination with the search engines
       
   514     search(QList<QHelpSearchQuery> &query) function.
       
   515 */
       
   516 QList<QHelpSearchQuery> QHelpSearchQueryWidget::query() const
       
   517 {
       
   518     const QHelpSearchQueryWidgetPrivate::QueryHistory &queryHist =
       
   519         d->simpleSearch ? d->simpleQueries : d->complexQueries;
       
   520     return queryHist.queries.isEmpty() ?
       
   521         QList<QHelpSearchQuery>() : queryHist.queries.last();
       
   522 }
       
   523 
       
   524 /*! \reimp
       
   525 */
       
   526 void QHelpSearchQueryWidget::focusInEvent(QFocusEvent *focusEvent)
       
   527 {
       
   528     if (focusEvent->reason() != Qt::MouseFocusReason) {
       
   529         d->defaultQuery->selectAll();
       
   530         d->defaultQuery->setFocus();
       
   531     }
       
   532 }
       
   533 
       
   534 QT_END_NAMESPACE