diff options
author | Liang Qi <liang.qi@qt.io> | 2016-08-09 17:59:51 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-08-09 17:59:51 +0200 |
commit | 22e96c4d342de3bfe4fc27f4cd7233edcfe737cc (patch) | |
tree | 6bdd02cdd8603cf16383fb339a2cfdbce82491da | |
parent | bd79c4e28c307ba87aca02155b845774c7ffec1f (diff) | |
parent | fa95eb055401f5264cbc6aca761cb9b5feb4affc (diff) |
Merge remote-tracking branch 'origin/5.7' into dev
Change-Id: I36e6b890b65d12bf6931757540bcc9c553b5eb8f
64 files changed, 1201 insertions, 711 deletions
diff --git a/doc/global/externalsites/qt-webpages.qdoc b/doc/global/externalsites/qt-webpages.qdoc index 706fcc3a97..5eea92c601 100644 --- a/doc/global/externalsites/qt-webpages.qdoc +++ b/doc/global/externalsites/qt-webpages.qdoc @@ -70,7 +70,7 @@ \title Qt Quarterly: Another Look at Events */ /*! - \externalpage http://qt-project.org/videos/watch/livecoding-video-effects-with-qt5 + \externalpage https://www.youtube.com/watch?v=P4kv-AoAJ-Q \title Livecoding video effects with Qt5 */ /*! diff --git a/examples/gui/rasterwindow/rasterwindow.cpp b/examples/gui/rasterwindow/rasterwindow.cpp index c44222b13d..eb34bec252 100644 --- a/examples/gui/rasterwindow/rasterwindow.cpp +++ b/examples/gui/rasterwindow/rasterwindow.cpp @@ -55,8 +55,8 @@ RasterWindow::RasterWindow(QWindow *parent) : QWindow(parent) , m_update_pending(false) { - m_backingStore = new QBackingStore(this); create(); + m_backingStore = new QBackingStore(this); setGeometry(100, 100, 300, 200); diff --git a/examples/widgets/dialogs/findfiles/window.cpp b/examples/widgets/dialogs/findfiles/window.cpp index 2f9b187bf0..05e160ed87 100644 --- a/examples/widgets/dialogs/findfiles/window.cpp +++ b/examples/widgets/dialogs/findfiles/window.cpp @@ -52,51 +52,72 @@ #include "window.h" +//! [17] +enum { absoluteFileNameRole = Qt::UserRole + 1 }; +//! [17] + +//! [18] +static inline QString fileNameOfItem(const QTableWidgetItem *item) +{ + return item->data(absoluteFileNameRole).toString(); +} +//! [18] + +//! [14] +static inline void openFile(const QString &fileName) +{ + QDesktopServices::openUrl(QUrl::fromLocalFile(fileName)); +} +//! [14] + //! [0] Window::Window(QWidget *parent) : QWidget(parent) { - browseButton = new QPushButton(tr("&Browse..."), this); + QPushButton *browseButton = new QPushButton(tr("&Browse..."), this); connect(browseButton, &QAbstractButton::clicked, this, &Window::browse); findButton = new QPushButton(tr("&Find"), this); connect(findButton, &QAbstractButton::clicked, this, &Window::find); fileComboBox = createComboBox(tr("*")); + connect(fileComboBox->lineEdit(), &QLineEdit::returnPressed, + this, &Window::animateFindClick); textComboBox = createComboBox(); - directoryComboBox = createComboBox(QDir::currentPath()); + connect(textComboBox->lineEdit(), &QLineEdit::returnPressed, + this, &Window::animateFindClick); + directoryComboBox = createComboBox(QDir::toNativeSeparators(QDir::currentPath())); + connect(directoryComboBox->lineEdit(), &QLineEdit::returnPressed, + this, &Window::animateFindClick); - fileLabel = new QLabel(tr("Named:")); - textLabel = new QLabel(tr("Containing text:")); - directoryLabel = new QLabel(tr("In directory:")); filesFoundLabel = new QLabel; createFilesTable(); //! [0] //! [1] - QGridLayout *mainLayout = new QGridLayout; - mainLayout->addWidget(fileLabel, 0, 0); + QGridLayout *mainLayout = new QGridLayout(this); + mainLayout->addWidget(new QLabel(tr("Named:")), 0, 0); mainLayout->addWidget(fileComboBox, 0, 1, 1, 2); - mainLayout->addWidget(textLabel, 1, 0); + mainLayout->addWidget(new QLabel(tr("Containing text:")), 1, 0); mainLayout->addWidget(textComboBox, 1, 1, 1, 2); - mainLayout->addWidget(directoryLabel, 2, 0); + mainLayout->addWidget(new QLabel(tr("In directory:")), 2, 0); mainLayout->addWidget(directoryComboBox, 2, 1); mainLayout->addWidget(browseButton, 2, 2); mainLayout->addWidget(filesTable, 3, 0, 1, 3); mainLayout->addWidget(filesFoundLabel, 4, 0, 1, 2); mainLayout->addWidget(findButton, 4, 2); - setLayout(mainLayout); setWindowTitle(tr("Find Files")); - resize(700, 300); + const QRect screenGeometry = QApplication::desktop()->screenGeometry(this); + resize(screenGeometry.width() / 2, screenGeometry.height() / 3); } //! [1] //! [2] void Window::browse() { - QString directory = QFileDialog::getExistingDirectory(this, - tr("Find Files"), QDir::currentPath()); + QString directory = + QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this, tr("Find Files"), QDir::currentPath())); if (!directory.isEmpty()) { if (directoryComboBox->findText(directory) == -1) @@ -112,14 +133,28 @@ static void updateComboBox(QComboBox *comboBox) comboBox->addItem(comboBox->currentText()); } +//! [13] + +static void findRecursion(const QString &path, const QString &pattern, QStringList *result) +{ + QDir currentDir(path); + const QString prefix = path + QLatin1Char('/'); + foreach (const QString &match, currentDir.entryList(QStringList(pattern), QDir::Files | QDir::NoSymLinks)) + result->append(prefix + match); + foreach (const QString &dir, currentDir.entryList(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot)) + findRecursion(prefix + dir, pattern, result); +} + +//! [13] //! [3] + void Window::find() { filesTable->setRowCount(0); QString fileName = fileComboBox->currentText(); QString text = textComboBox->currentText(); - QString path = directoryComboBox->currentText(); + QString path = QDir::cleanPath(directoryComboBox->currentText()); //! [3] updateComboBox(fileComboBox); @@ -127,19 +162,21 @@ void Window::find() updateComboBox(directoryComboBox); //! [4] + currentDir = QDir(path); QStringList files; - if (fileName.isEmpty()) - fileName = "*"; - files = currentDir.entryList(QStringList(fileName), - QDir::Files | QDir::NoSymLinks); - + findRecursion(path, fileName.isEmpty() ? QStringLiteral("*") : fileName, &files); if (!text.isEmpty()) files = findFiles(files, text); showFiles(files); } //! [4] +void Window::animateFindClick() +{ + findButton->animateClick(); +} + //! [5] QStringList Window::findFiles(const QStringList &files, const QString &text) { @@ -149,21 +186,26 @@ QStringList Window::findFiles(const QStringList &files, const QString &text) progressDialog.setWindowTitle(tr("Find Files")); //! [5] //! [6] + QMimeDatabase mimeDatabase; QStringList foundFiles; for (int i = 0; i < files.size(); ++i) { progressDialog.setValue(i); - progressDialog.setLabelText(tr("Searching file number %1 of %2...") - .arg(i).arg(files.size())); - qApp->processEvents(); + progressDialog.setLabelText(tr("Searching file number %1 of %n...", 0, files.size()).arg(i)); + QCoreApplication::processEvents(); //! [6] if (progressDialog.wasCanceled()) break; //! [7] - QFile file(currentDir.absoluteFilePath(files[i])); - + const QString fileName = files.at(i); + const QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileName); + if (mimeType.isValid() && !mimeType.inherits(QStringLiteral("text/plain"))) { + qWarning() << "Not searching binary file " << QDir::toNativeSeparators(fileName); + continue; + } + QFile file(fileName); if (file.open(QIODevice::ReadOnly)) { QString line; QTextStream in(&file); @@ -171,7 +213,7 @@ QStringList Window::findFiles(const QStringList &files, const QString &text) if (progressDialog.wasCanceled()) break; line = in.readLine(); - if (line.contains(text)) { + if (line.contains(text, Qt::CaseInsensitive)) { foundFiles << files[i]; break; } @@ -186,13 +228,18 @@ QStringList Window::findFiles(const QStringList &files, const QString &text) void Window::showFiles(const QStringList &files) { for (int i = 0; i < files.size(); ++i) { - QFile file(currentDir.absoluteFilePath(files[i])); - qint64 size = QFileInfo(file).size(); - - QTableWidgetItem *fileNameItem = new QTableWidgetItem(files[i]); + const QString &fileName = files.at(i); + const QString toolTip = QDir::toNativeSeparators(fileName); + const QString relativePath = QDir::toNativeSeparators(currentDir.relativeFilePath(fileName)); + const qint64 size = QFileInfo(fileName).size(); + QTableWidgetItem *fileNameItem = new QTableWidgetItem(relativePath); + fileNameItem->setData(absoluteFileNameRole, QVariant(fileName)); + fileNameItem->setToolTip(toolTip); fileNameItem->setFlags(fileNameItem->flags() ^ Qt::ItemIsEditable); QTableWidgetItem *sizeItem = new QTableWidgetItem(tr("%1 KB") .arg(int((size + 1023) / 1024))); + sizeItem->setData(absoluteFileNameRole, QVariant(fileName)); + sizeItem->setToolTip(toolTip); sizeItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); sizeItem->setFlags(sizeItem->flags() ^ Qt::ItemIsEditable); @@ -201,8 +248,7 @@ void Window::showFiles(const QStringList &files) filesTable->setItem(row, 0, fileNameItem); filesTable->setItem(row, 1, sizeItem); } - filesFoundLabel->setText(tr("%1 file(s) found").arg(files.size()) + - (" (Double click on a file to open it)")); + filesFoundLabel->setText(tr("%n file(s) found (Double click on a file to open it)", 0, files.size())); filesFoundLabel->setWordWrap(true); } //! [8] @@ -230,20 +276,43 @@ void Window::createFilesTable() filesTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); filesTable->verticalHeader()->hide(); filesTable->setShowGrid(false); - +//! [15] + filesTable->setContextMenuPolicy(Qt::CustomContextMenu); + connect(filesTable, &QTableWidget::customContextMenuRequested, + this, &Window::contextMenu); connect(filesTable, &QTableWidget::cellActivated, this, &Window::openFileOfItem); +//! [15] } //! [11] + //! [12] void Window::openFileOfItem(int row, int /* column */) { - QTableWidgetItem *item = filesTable->item(row, 0); - - QDesktopServices::openUrl(QUrl::fromLocalFile(currentDir.absoluteFilePath(item->text()))); + const QTableWidgetItem *item = filesTable->item(row, 0); + openFile(fileNameOfItem(item)); } //! [12] +//! [16] +void Window::contextMenu(const QPoint &pos) +{ + const QTableWidgetItem *item = filesTable->itemAt(pos); + if (!item) + return; + QMenu menu; + QAction *copyAction = menu.addAction("Copy Name"); + QAction *openAction = menu.addAction("Open"); + QAction *action = menu.exec(filesTable->mapToGlobal(pos)); + if (!action) + return; + const QString fileName = fileNameOfItem(item); + if (action == copyAction) + QGuiApplication::clipboard()->setText(QDir::toNativeSeparators(fileName)); + else if (action == openAction) + openFile(fileName); +} +//! [16] diff --git a/examples/widgets/dialogs/findfiles/window.h b/examples/widgets/dialogs/findfiles/window.h index ae4f49b726..fe217381e2 100644 --- a/examples/widgets/dialogs/findfiles/window.h +++ b/examples/widgets/dialogs/findfiles/window.h @@ -73,7 +73,9 @@ public: private slots: void browse(); void find(); + void animateFindClick(); void openFileOfItem(int row, int column); + void contextMenu(const QPoint &pos); private: QStringList findFiles(const QStringList &files, const QString &text); @@ -84,11 +86,7 @@ private: QComboBox *fileComboBox; QComboBox *textComboBox; QComboBox *directoryComboBox; - QLabel *fileLabel; - QLabel *textLabel; - QLabel *directoryLabel; QLabel *filesFoundLabel; - QPushButton *browseButton; QPushButton *findButton; QTableWidget *filesTable; diff --git a/examples/widgets/doc/src/findfiles.qdoc b/examples/widgets/doc/src/findfiles.qdoc index 700105e100..b8363dc698 100644 --- a/examples/widgets/doc/src/findfiles.qdoc +++ b/examples/widgets/doc/src/findfiles.qdoc @@ -120,10 +120,12 @@ \snippet dialogs/findfiles/window.cpp 4 We use the directory's path to create a QDir; the QDir class - provides access to directory structures and their contents. We - create a list of the files (contained in the newly created QDir) - that match the specified file name. If the file name is empty - the list will contain all the files in the directory. + provides access to directory structures and their contents. + + \snippet dialogs/findfiles/window.cpp 13 + + We recursively create a list of the files (contained in the newl + created QDir) that match the specified file name. Then we search through all the files in the list, using the private \c findFiles() function, eliminating the ones that don't contain @@ -173,9 +175,7 @@ \snippet dialogs/findfiles/window.cpp 7 - After updating the QProgressDialog, we create a QFile using the - QDir::absoluteFilePath() function which returns the absolute path - name of a file in the directory. We open the file in read-only + After updating the QProgressDialog, we open the file in read-only mode, and read one line at a time using QTextStream. The QTextStream class provides a convenient interface for reading @@ -194,9 +194,18 @@ Both the \c findFiles() and \c showFiles() functions are called from the \c find() slot. In the \c showFiles() function we run through - the provided list of file names, adding each file name to the + the provided list of file names, adding each relative file name to the first column in the table widget and retrieving the file's size using - QFile and QFileInfo for the second column. + QFileInfo for the second column. For later use, we set + the absolute path as a data on the QTableWidget using the + the role absoluteFileNameRole defined to be Qt::UserRole + 1. + + \snippet dialogs/findfiles/window.cpp 17 + + This allows for retrieving the name of an item using a + convenience function: + + \snippet dialogs/findfiles/window.cpp 18 We also update the total number of files found. @@ -236,8 +245,19 @@ \snippet dialogs/findfiles/window.cpp 12 + \snippet dialogs/findfiles/window.cpp 14 + The \c openFileOfItem() slot is invoked when the user double clicks on a cell in the table. The QDesktopServices::openUrl() knows how to open a file given the file name. + + \snippet dialogs/findfiles/window.cpp 15 + \snippet dialogs/findfiles/window.cpp 16 + + We set the context menu policy to of the table view to Qt::CustomContextMenu + and connect a slot contextMenu() to its signal + customContextMenuRequested(). We retrieve the absolute file name + from the data of the QTableWidgetItem and populate the context menu + with actions offering to copy the file name and to open the file. */ diff --git a/examples/widgets/tools/codecs/mainwindow.cpp b/examples/widgets/tools/codecs/mainwindow.cpp index fe29eeffa3..5e4810dd4d 100644 --- a/examples/widgets/tools/codecs/mainwindow.cpp +++ b/examples/widgets/tools/codecs/mainwindow.cpp @@ -55,8 +55,8 @@ MainWindow::MainWindow() { - textEdit = new QTextEdit; - textEdit->setLineWrapMode(QTextEdit::NoWrap); + textEdit = new QPlainTextEdit; + textEdit->setLineWrapMode(QPlainTextEdit::NoWrap); setCentralWidget(textEdit); findCodecs(); @@ -64,54 +64,57 @@ MainWindow::MainWindow() previewForm = new PreviewForm(this); previewForm->setCodecList(codecs); - createActions(); createMenus(); setWindowTitle(tr("Codecs")); - resize(500, 400); + + const QRect screenGeometry = QApplication::desktop()->screenGeometry(this); + resize(screenGeometry.width() / 2, screenGeometry.height() * 2 / 3); } void MainWindow::open() { - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) { - QFile file(fileName); - if (!file.open(QFile::ReadOnly)) { - QMessageBox::warning(this, tr("Codecs"), - tr("Cannot read file %1:\n%2") - .arg(fileName) - .arg(file.errorString())); - return; - } + const QString fileName = QFileDialog::getOpenFileName(this); + if (fileName.isEmpty()) + return; + QFile file(fileName); + if (!file.open(QFile::ReadOnly)) { + QMessageBox::warning(this, tr("Codecs"), + tr("Cannot read file %1:\n%2") + .arg(QDir::toNativeSeparators(fileName), + file.errorString())); + return; + } - QByteArray data = file.readAll(); + const QByteArray data = file.readAll(); - previewForm->setEncodedData(data); - if (previewForm->exec()) - textEdit->setPlainText(previewForm->decodedString()); - } + previewForm->setWindowTitle(tr("Choose Encoding for %1").arg(QFileInfo(fileName).fileName())); + previewForm->setEncodedData(data); + if (previewForm->exec()) + textEdit->setPlainText(previewForm->decodedString()); } void MainWindow::save() { - QString fileName = QFileDialog::getSaveFileName(this); - if (!fileName.isEmpty()) { - QFile file(fileName); - if (!file.open(QFile::WriteOnly | QFile::Text)) { - QMessageBox::warning(this, tr("Codecs"), - tr("Cannot write file %1:\n%2") - .arg(fileName) - .arg(file.errorString())); - return; - } - - QAction *action = qobject_cast<QAction *>(sender()); - QByteArray codecName = action->data().toByteArray(); - - QTextStream out(&file); - out.setCodec(codecName.constData()); - out << textEdit->toPlainText(); + const QAction *action = qobject_cast<const QAction *>(sender()); + const QByteArray codecName = action->data().toByteArray(); + const QString title = tr("Save As (%1)").arg(QLatin1String(codecName)); + + QString fileName = QFileDialog::getSaveFileName(this, title); + if (fileName.isEmpty()) + return; + QFile file(fileName); + if (!file.open(QFile::WriteOnly | QFile::Text)) { + QMessageBox::warning(this, tr("Codecs"), + tr("Cannot write file %1:\n%2") + .arg(QDir::toNativeSeparators(fileName), + file.errorString())); + return; } + + QTextStream out(&file); + out.setCodec(codecName.constData()); + out << textEdit->toPlainText(); } void MainWindow::about() @@ -143,9 +146,9 @@ void MainWindow::findCodecs() QString sortKey = codec->name().toUpper(); int rank; - if (sortKey.startsWith("UTF-8")) { + if (sortKey.startsWith(QLatin1String("UTF-8"))) { rank = 1; - } else if (sortKey.startsWith("UTF-16")) { + } else if (sortKey.startsWith(QLatin1String("UTF-16"))) { rank = 2; } else if (iso8859RegExp.exactMatch(sortKey)) { if (iso8859RegExp.cap(1).size() == 1) @@ -155,58 +158,38 @@ void MainWindow::findCodecs() } else { rank = 5; } - sortKey.prepend(QChar('0' + rank)); + sortKey.prepend(QLatin1Char('0' + rank)); codecMap.insert(sortKey, codec); } codecs = codecMap.values(); } -void MainWindow::createActions() +void MainWindow::createMenus() { - openAct = new QAction(tr("&Open..."), this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QAction *openAct = + fileMenu->addAction(tr("&Open..."), this, &MainWindow::open); openAct->setShortcuts(QKeySequence::Open); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); - - foreach (QTextCodec *codec, codecs) { - QString text = tr("%1...").arg(QString(codec->name())); - QAction *action = new QAction(text, this); - action->setData(codec->name()); - connect(action, SIGNAL(triggered()), this, SLOT(save())); + QMenu *saveAsMenu = fileMenu->addMenu(tr("&Save As")); + connect(saveAsMenu, &QMenu::aboutToShow, + this, &MainWindow::aboutToShowSaveAsMenu); + foreach (const QTextCodec *codec, codecs) { + const QByteArray name = codec->name(); + QAction *action = saveAsMenu->addAction(tr("%1...").arg(QLatin1String(name))); + action->setData(QVariant(name)); + connect(action, &QAction::triggered, this, &MainWindow::save); saveAsActs.append(action); } - exitAct = new QAction(tr("E&xit"), this); - exitAct->setShortcuts(QKeySequence::Quit); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); - - aboutAct = new QAction(tr("&About"), this); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - saveAsMenu = new QMenu(tr("&Save As"), this); - foreach (QAction *action, saveAsActs) - saveAsMenu->addAction(action); - connect(saveAsMenu, SIGNAL(aboutToShow()), - this, SLOT(aboutToShowSaveAsMenu())); - - fileMenu = new QMenu(tr("&File"), this); - fileMenu->addAction(openAct); - fileMenu->addMenu(saveAsMenu); fileMenu->addSeparator(); - fileMenu->addAction(exitAct); - - helpMenu = new QMenu(tr("&Help"), this); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); + QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close); + exitAct->setShortcuts(QKeySequence::Quit); - menuBar()->addMenu(fileMenu); menuBar()->addSeparator(); - menuBar()->addMenu(helpMenu); + + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu->addAction(tr("&About"), this, &MainWindow::about); + helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); } diff --git a/examples/widgets/tools/codecs/mainwindow.h b/examples/widgets/tools/codecs/mainwindow.h index 1e8b440a02..7121c0b122 100644 --- a/examples/widgets/tools/codecs/mainwindow.h +++ b/examples/widgets/tools/codecs/mainwindow.h @@ -56,9 +56,8 @@ QT_BEGIN_NAMESPACE class QAction; -class QMenu; class QTextCodec; -class QTextEdit; +class QPlainTextEdit; QT_END_NAMESPACE class PreviewForm; @@ -77,21 +76,12 @@ private slots: private: void findCodecs(); - void createActions(); void createMenus(); - QTextEdit *textEdit; + QList<QAction *> saveAsActs; + QPlainTextEdit *textEdit; PreviewForm *previewForm; QList<QTextCodec *> codecs; - - QMenu *fileMenu; - QMenu *helpMenu; - QMenu *saveAsMenu; - QAction *openAct; - QList<QAction *> saveAsActs; - QAction *exitAct; - QAction *aboutAct; - QAction *aboutQtAct; }; #endif diff --git a/examples/widgets/tools/codecs/previewform.cpp b/examples/widgets/tools/codecs/previewform.cpp index 82203175ca..e5ca13f011 100644 --- a/examples/widgets/tools/codecs/previewform.cpp +++ b/examples/widgets/tools/codecs/previewform.cpp @@ -52,47 +52,159 @@ #include "previewform.h" +// Helpers for creating hex dumps +static void indent(QTextStream &str, int indent) +{ + for (int i = 0; i < indent; ++i) + str << ' '; +} + +static void formatHex(QTextStream &str, const QByteArray &data) +{ + const int fieldWidth = str.fieldWidth(); + const QTextStream::FieldAlignment alignment = str.fieldAlignment(); + const int base = str.integerBase(); + const QChar padChar = str.padChar(); + str.setIntegerBase(16); + str.setPadChar(QLatin1Char('0')); + str.setFieldAlignment(QTextStream::AlignRight); + + const unsigned char *p = reinterpret_cast<const unsigned char *>(data.constBegin()); + for (const unsigned char *end = p + data.size(); p < end; ++p) { + str << ' '; + str.setFieldWidth(2); + str << unsigned(*p); + str.setFieldWidth(fieldWidth); + } + str.setFieldAlignment(alignment); + str.setPadChar(padChar); + str.setIntegerBase(base); +} + +static void formatPrintableCharacters(QTextStream &str, const QByteArray &data) +{ + for (int i = 0, size = data.size(); i < size; ++i) { + const char c = data.at(i); + switch (c) { + case '\0': + str << "\\0"; + break; + case '\t': + str << "\\t"; + break; + case '\r': + str << "\\r"; + break; + case '\n': + str << "\\n"; + break; + default: + if (c >= 32 && uchar(c) < 127) + str << ' ' << c; + else + str << ".."; + break; + } + } +} + +static QString formatHexDump(const QByteArray &data) +{ + enum { lineWidth = 16 }; + QString result; + QTextStream str(&result); + str.setIntegerBase(16); + str.setPadChar(QLatin1Char('0')); + const int fieldWidth = str.fieldWidth(); + const QTextStream::FieldAlignment alignment = str.fieldAlignment(); + for (int a = 0, size = data.size(); a < size; a += lineWidth) { + str.setFieldAlignment(QTextStream::AlignRight); + str.setFieldWidth(8); + str << a; + str.setFieldWidth(fieldWidth); + str.setFieldAlignment(alignment); + + const int end = qMin(a + lineWidth, size); + const QByteArray line = data.mid(a, end - a); + + formatHex(str, line); + indent(str, 3 * (lineWidth - line.size())); + + str << ' '; + formatPrintableCharacters(str, line); + indent(str, 2 * (lineWidth - line.size())); + str << '\n'; + } + return result; +} + PreviewForm::PreviewForm(QWidget *parent) : QDialog(parent) { + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); encodingComboBox = new QComboBox; - encodingLabel = new QLabel(tr("&Encoding:")); + QLabel *encodingLabel = new QLabel(tr("&Encoding:")); encodingLabel->setBuddy(encodingComboBox); - textEdit = new QTextEdit; - textEdit->setLineWrapMode(QTextEdit::NoWrap); + textEdit = new QPlainTextEdit; + textEdit->setLineWrapMode(QPlainTextEdit::NoWrap); textEdit->setReadOnly(true); + hexDumpEdit = new QPlainTextEdit; + hexDumpEdit->setLineWrapMode(QPlainTextEdit::NoWrap); + hexDumpEdit->setReadOnly(true); + hexDumpEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok - | QDialogButtonBox::Cancel); + QDialogButtonBox *buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + okButton = buttonBox->button(QDialogButtonBox::Ok); - connect(encodingComboBox, SIGNAL(activated(int)), - this, SLOT(updateTextEdit())); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + typedef void(QComboBox::*ComboBoxIntSignal)(int); + connect(encodingComboBox, static_cast<ComboBoxIntSignal>(&QComboBox::activated), + this, &PreviewForm::updateTextEdit); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - QGridLayout *mainLayout = new QGridLayout; + QGridLayout *mainLayout = new QGridLayout(this); mainLayout->addWidget(encodingLabel, 0, 0); mainLayout->addWidget(encodingComboBox, 0, 1); - mainLayout->addWidget(textEdit, 1, 0, 1, 2); - mainLayout->addWidget(buttonBox, 2, 0, 1, 2); - setLayout(mainLayout); + tabWidget = new QTabWidget; + tabWidget->addTab(textEdit, tr("Preview")); + tabWidget->addTab(hexDumpEdit, tr("Hex Dump")); + mainLayout->addWidget(tabWidget, 1, 0, 1, 2); + statusLabel = new QLabel; + mainLayout->addWidget(statusLabel, 2, 0, 1, 2); + mainLayout->addWidget(buttonBox, 3, 0, 1, 2); - setWindowTitle(tr("Choose Encoding")); - resize(400, 300); + const QRect screenGeometry = QApplication::desktop()->screenGeometry(this); + resize(screenGeometry.width() * 2 / 5, screenGeometry.height() / 2); } void PreviewForm::setCodecList(const QList<QTextCodec *> &list) { encodingComboBox->clear(); - foreach (QTextCodec *codec, list) - encodingComboBox->addItem(codec->name(), codec->mibEnum()); + foreach (const QTextCodec *codec, list) { + encodingComboBox->addItem(QLatin1String(codec->name()), + QVariant(codec->mibEnum())); + } +} + +void PreviewForm::reset() +{ + decodedStr.clear(); + textEdit->clear(); + hexDumpEdit->clear(); + statusLabel->clear(); + statusLabel->setStyleSheet(QString()); + okButton->setEnabled(false); + tabWidget->setCurrentIndex(0); } void PreviewForm::setEncodedData(const QByteArray &data) { + reset(); encodedData = data; + hexDumpEdit->setPlainText(formatHexDump(data)); updateTextEdit(); } @@ -100,12 +212,30 @@ void PreviewForm::updateTextEdit() { int mib = encodingComboBox->itemData( encodingComboBox->currentIndex()).toInt(); - QTextCodec *codec = QTextCodec::codecForMib(mib); + const QTextCodec *codec = QTextCodec::codecForMib(mib); + const QString name = QLatin1String(codec->name()); - QTextStream in(&encodedData); - in.setAutoDetectUnicode(false); - in.setCodec(codec); - decodedStr = in.readAll(); + QTextCodec::ConverterState state; + decodedStr = codec->toUnicode(encodedData.constData(), encodedData.size(), &state); - textEdit->setPlainText(decodedStr); + bool success = true; + if (state.remainingChars) { + success = false; + const QString message = + tr("%1: conversion error at character %2") + .arg(name).arg(encodedData.size() - state.remainingChars + 1); + statusLabel->setText(message); + statusLabel->setStyleSheet(QStringLiteral("background-color: \"red\";")); + } else if (state.invalidChars) { + statusLabel->setText(tr("%1: %n invalid characters", 0, state.invalidChars).arg(name)); + statusLabel->setStyleSheet(QStringLiteral("background-color: \"yellow\";")); + } else { + statusLabel->setText(tr("%1: %n bytes converted", 0, encodedData.size()).arg(name)); + statusLabel->setStyleSheet(QString()); + } + if (success) + textEdit->setPlainText(decodedStr); + else + textEdit->clear(); + okButton->setEnabled(success); } diff --git a/examples/widgets/tools/codecs/previewform.h b/examples/widgets/tools/codecs/previewform.h index f3e13233b4..1846b976de 100644 --- a/examples/widgets/tools/codecs/previewform.h +++ b/examples/widgets/tools/codecs/previewform.h @@ -58,8 +58,10 @@ QT_BEGIN_NAMESPACE class QComboBox; class QDialogButtonBox; class QLabel; +class QPlainTextEdit; +class QPushButton; +class QTabWidget; class QTextCodec; -class QTextEdit; QT_END_NAMESPACE class PreviewForm : public QDialog @@ -67,7 +69,7 @@ class PreviewForm : public QDialog Q_OBJECT public: - PreviewForm(QWidget *parent = 0); + explicit PreviewForm(QWidget *parent = Q_NULLPTR); void setCodecList(const QList<QTextCodec *> &list); void setEncodedData(const QByteArray &data); @@ -77,13 +79,17 @@ private slots: void updateTextEdit(); private: + void reset(); + QByteArray encodedData; QString decodedStr; + QPushButton *okButton; + QTabWidget *tabWidget; QComboBox *encodingComboBox; - QLabel *encodingLabel; - QTextEdit *textEdit; - QDialogButtonBox *buttonBox; + QPlainTextEdit *textEdit; + QPlainTextEdit *hexDumpEdit; + QLabel *statusLabel; }; #endif diff --git a/examples/widgets/widgets/charactermap/characterwidget.cpp b/examples/widgets/widgets/charactermap/characterwidget.cpp index 07912da6ff..55d45501f1 100644 --- a/examples/widgets/widgets/charactermap/characterwidget.cpp +++ b/examples/widgets/widgets/charactermap/characterwidget.cpp @@ -54,11 +54,9 @@ //! [0] CharacterWidget::CharacterWidget(QWidget *parent) - : QWidget(parent) + : QWidget(parent), columns(16), lastKey(-1) { - squareSize = 24; - columns = 16; - lastKey = -1; + calculateSquareSize(); setMouseTracking(true); } //! [0] @@ -67,7 +65,7 @@ CharacterWidget::CharacterWidget(QWidget *parent) void CharacterWidget::updateFont(const QFont &font) { displayFont.setFamily(font.family()); - squareSize = qMax(24, QFontMetrics(displayFont).xHeight() * 3); + calculateSquareSize(); adjustSize(); update(); } @@ -77,7 +75,7 @@ void CharacterWidget::updateFont(const QFont &font) void CharacterWidget::updateSize(const QString &fontSize) { displayFont.setPointSize(fontSize.toInt()); - squareSize = qMax(24, QFontMetrics(displayFont).xHeight() * 3); + calculateSquareSize(); adjustSize(); update(); } @@ -89,7 +87,7 @@ void CharacterWidget::updateStyle(const QString &fontStyle) const QFont::StyleStrategy oldStrategy = displayFont.styleStrategy(); displayFont = fontDatabase.font(displayFont.family(), fontStyle, displayFont.pointSize()); displayFont.setStyleStrategy(oldStrategy); - squareSize = qMax(24, QFontMetrics(displayFont).xHeight() * 3); + calculateSquareSize(); adjustSize(); update(); } @@ -104,6 +102,11 @@ void CharacterWidget::updateFontMerging(bool enable) update(); } +void CharacterWidget::calculateSquareSize() +{ + squareSize = qMax(16, 4 + QFontMetrics(displayFont, this).height()); +} + //! [3] QSize CharacterWidget::sizeHint() const { diff --git a/examples/widgets/widgets/charactermap/characterwidget.h b/examples/widgets/widgets/charactermap/characterwidget.h index 8a33d69628..53add51e6f 100644 --- a/examples/widgets/widgets/charactermap/characterwidget.h +++ b/examples/widgets/widgets/charactermap/characterwidget.h @@ -86,6 +86,8 @@ protected: void paintEvent(QPaintEvent *event) override; private: + void calculateSquareSize(); + QFont displayFont; int columns; int lastKey; diff --git a/examples/widgets/widgets/charactermap/mainwindow.cpp b/examples/widgets/widgets/charactermap/mainwindow.cpp index 2141850f16..8b406ba1ca 100644 --- a/examples/widgets/widgets/charactermap/mainwindow.cpp +++ b/examples/widgets/widgets/charactermap/mainwindow.cpp @@ -54,10 +54,30 @@ #include "mainwindow.h" //! [0] + +Q_DECLARE_METATYPE(QFontComboBox::FontFilter) + MainWindow::MainWindow() { + QMenu *fileMenu = menuBar()->addMenu(tr("File")); + fileMenu->addAction(tr("Quit"), this, &QWidget::close); + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu->addAction(tr("Show Font Info"), this, &MainWindow::showInfo); + helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); + QWidget *centralWidget = new QWidget; + QLabel *filterLabel = new QLabel(tr("Filter:")); + filterCombo = new QComboBox; + filterCombo->addItem(tr("All"), QVariant::fromValue(QFontComboBox::AllFonts)); + filterCombo->addItem(tr("Scalable"), QVariant::fromValue(QFontComboBox::ScalableFonts)); + filterCombo->addItem(tr("Monospaced"), QVariant::fromValue(QFontComboBox::MonospacedFonts)); + filterCombo->addItem(tr("Proportional"), QVariant::fromValue(QFontComboBox::ProportionalFonts)); + filterCombo->setCurrentIndex(0); + typedef void (QComboBox::*QComboBoxIntSignal)(int); + connect(filterCombo, static_cast<QComboBoxIntSignal>(&QComboBox::currentIndexChanged), + this, &MainWindow::filterChanged); + QLabel *fontLabel = new QLabel(tr("Font:")); fontCombo = new QFontComboBox; QLabel *sizeLabel = new QLabel(tr("Size:")); @@ -80,38 +100,39 @@ MainWindow::MainWindow() //! [2] lineEdit = new QLineEdit; + lineEdit->setClearButtonEnabled(true); #ifndef QT_NO_CLIPBOARD QPushButton *clipboardButton = new QPushButton(tr("&To clipboard")); //! [2] -//! [3] - clipboard = QApplication::clipboard(); -//! [3] #endif //! [4] - connect(fontCombo, SIGNAL(currentFontChanged(QFont)), - this, SLOT(findStyles(QFont))); - connect(fontCombo, SIGNAL(currentFontChanged(QFont)), - this, SLOT(findSizes(QFont))); - connect(fontCombo, SIGNAL(currentFontChanged(QFont)), - characterWidget, SLOT(updateFont(QFont))); - connect(sizeCombo, SIGNAL(currentIndexChanged(QString)), - characterWidget, SLOT(updateSize(QString))); - connect(styleCombo, SIGNAL(currentIndexChanged(QString)), - characterWidget, SLOT(updateStyle(QString))); + connect(fontCombo, &QFontComboBox::currentFontChanged, + this, &MainWindow::findStyles); + connect(fontCombo, &QFontComboBox::currentFontChanged, + this, &MainWindow::findSizes); + connect(fontCombo, &QFontComboBox::currentFontChanged, + characterWidget, &CharacterWidget::updateFont); + typedef void (QComboBox::*QComboBoxStringSignal)(const QString &); + connect(sizeCombo, static_cast<QComboBoxStringSignal>(&QComboBox::currentIndexChanged), + characterWidget, &CharacterWidget::updateSize); + connect(styleCombo, static_cast<QComboBoxStringSignal>(&QComboBox::currentIndexChanged), + characterWidget, &CharacterWidget::updateStyle); //! [4] //! [5] - connect(characterWidget, SIGNAL(characterSelected(QString)), - this, SLOT(insertCharacter(QString))); + connect(characterWidget, &CharacterWidget::characterSelected, + this, &MainWindow::insertCharacter); #ifndef QT_NO_CLIPBOARD - connect(clipboardButton, SIGNAL(clicked()), this, SLOT(updateClipboard())); + connect(clipboardButton, &QAbstractButton::clicked, this, &MainWindow::updateClipboard); #endif //! [5] - connect(fontMerging, SIGNAL(toggled(bool)), characterWidget, SLOT(updateFontMerging(bool))); + connect(fontMerging, &QAbstractButton::toggled, characterWidget, &CharacterWidget::updateFontMerging); //! [6] QHBoxLayout *controlsLayout = new QHBoxLayout; + controlsLayout->addWidget(filterLabel); + controlsLayout->addWidget(filterCombo, 1); controlsLayout->addWidget(fontLabel); controlsLayout->addWidget(fontCombo, 1); controlsLayout->addWidget(sizeLabel); @@ -163,6 +184,14 @@ void MainWindow::findStyles(const QFont &font) } //! [8] +void MainWindow::filterChanged(int f) +{ + const QFontComboBox::FontFilter filter = + filterCombo->itemData(f).value<QFontComboBox::FontFilter>(); + fontCombo->setFontFilters(filter); + statusBar()->showMessage(tr("%n font(s) found", 0, fontCombo->count())); +} + void MainWindow::findSizes(const QFont &font) { QFontDatabase fontDatabase; @@ -208,9 +237,63 @@ void MainWindow::insertCharacter(const QString &character) void MainWindow::updateClipboard() { //! [11] - clipboard->setText(lineEdit->text(), QClipboard::Clipboard); + QGuiApplication::clipboard()->setText(lineEdit->text(), QClipboard::Clipboard); //! [11] - clipboard->setText(lineEdit->text(), QClipboard::Selection); + QGuiApplication::clipboard()->setText(lineEdit->text(), QClipboard::Selection); } #endif + +class FontInfoDialog : public QDialog +{ +public: + explicit FontInfoDialog(QWidget *parent = Q_NULLPTR); + +private: + QString text() const; +}; + +FontInfoDialog::FontInfoDialog(QWidget *parent) : QDialog(parent) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + QVBoxLayout *mainLayout = new QVBoxLayout(this); + QPlainTextEdit *textEdit = new QPlainTextEdit(text(), this); + textEdit->setReadOnly(true); + textEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + mainLayout->addWidget(textEdit); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + mainLayout->addWidget(buttonBox); +} + +QString FontInfoDialog::text() const +{ + QString text; + QTextStream str(&text); + const QFont defaultFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont); + const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); + const QFont titleFont = QFontDatabase::systemFont(QFontDatabase::TitleFont); + const QFont smallestReadableFont = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont); + + str << "Qt " << QT_VERSION_STR << " on " << QGuiApplication::platformName() + << ", " << logicalDpiX() << "DPI"; + if (!qFuzzyCompare(devicePixelRatioF(), qreal(1))) + str << ", device pixel ratio: " << devicePixelRatioF(); + str << "\n\nDefault font : " << defaultFont.family() << ", " << defaultFont.pointSizeF() << "pt\n" + << "Fixed font : " << fixedFont.family() << ", " << fixedFont.pointSizeF() << "pt\n" + << "Title font : " << titleFont.family() << ", " << titleFont.pointSizeF() << "pt\n" + << "Smallest font: " << smallestReadableFont.family() << ", " << smallestReadableFont.pointSizeF() << "pt\n"; + + return text; +} + +void MainWindow::showInfo() +{ + const QRect screenGeometry = QApplication::desktop()->screenGeometry(this); + FontInfoDialog *dialog = new FontInfoDialog(this); + dialog->setWindowTitle(tr("Fonts")); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->resize(screenGeometry.width() / 4, screenGeometry.height() / 4); + dialog->show(); +} + //! [10] diff --git a/examples/widgets/widgets/charactermap/mainwindow.h b/examples/widgets/widgets/charactermap/mainwindow.h index 2865eacc00..eac16b35fa 100644 --- a/examples/widgets/widgets/charactermap/mainwindow.h +++ b/examples/widgets/widgets/charactermap/mainwindow.h @@ -73,18 +73,18 @@ public: MainWindow(); public slots: + void filterChanged(int); void findStyles(const QFont &font); void findSizes(const QFont &font); void insertCharacter(const QString &character); #ifndef QT_NO_CLIPBOARD void updateClipboard(); #endif + void showInfo(); private: CharacterWidget *characterWidget; -#ifndef QT_NO_CLIPBOARD - QClipboard *clipboard; -#endif + QComboBox *filterCombo; QComboBox *styleCombo; QComboBox *sizeCombo; QFontComboBox *fontCombo; diff --git a/mkspecs/devices/linux-drive-cx-g++/qmake.conf b/mkspecs/devices/linux-drive-cx-g++/qmake.conf index cb43c9e2f6..c8e85e449c 100644 --- a/mkspecs/devices/linux-drive-cx-g++/qmake.conf +++ b/mkspecs/devices/linux-drive-cx-g++/qmake.conf @@ -7,7 +7,8 @@ # -device-option VIBRANTE_SDK_TOPDIR=/opt/nvidia/vibrante-t186ref-linux # -device-option CROSS_COMPILE=/opt/nvidia/toolchains/tegra-4.9-nv/usr/bin/aarch64-gnu-linux/aarch64-gnu-linux- \ # -sysroot /opt/nvidia/vibrante-t186ref-linux/targetfs \ -# -no-gcc-sysroot +# -no-gcc-sysroot \ +# -opengl es2 include(../common/linux_device_pre.conf) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 4d958b1a20..38e80f7a2d 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -28,7 +28,7 @@ /*! \page qmake-manual.html \title qmake Manual - \startpage {Qt Reference Documentation} + \startpage index.html \nextpage Overview \ingroup qttools diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 71a0228eeb..9cf1be58d8 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3169,8 +3169,8 @@ QUrl QUrl::resolved(const QUrl &relative) const if (!relative.d) return *this; QUrl t; - // be non strict and allow scheme in relative url - if (!relative.d->scheme.isEmpty() && relative.d->scheme != d->scheme) { + // Compatibility hack (mostly for qtdeclarative) : treat "file:relative.txt" as relative even though QUrl::isRelative() says false + if (!relative.d->scheme.isEmpty() && (!relative.isLocalFile() || QDir::isAbsolutePath(relative.d->path))) { t = relative; t.detach(); } else { diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 2b684b855b..b0ddfa879d 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -1328,6 +1328,7 @@ void QSortFilterProxyModelPrivate::_q_sourceReset() void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint) { Q_Q(QSortFilterProxyModel); + Q_UNUSED(hint); // We can't forward Hint because we might filter additional rows or columns saved_persistent_indexes.clear(); QList<QPersistentModelIndex> parents; @@ -1346,7 +1347,7 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<Q if (!sourceParents.isEmpty() && parents.isEmpty()) return; - emit q->layoutAboutToBeChanged(parents, hint); + emit q->layoutAboutToBeChanged(parents); if (persistent.indexes.isEmpty()) return; @@ -1356,6 +1357,7 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<Q void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint) { Q_Q(QSortFilterProxyModel); + Q_UNUSED(hint); // We can't forward Hint because we might filter additional rows or columns // Optimize: We only actually have to clear the mapping related to the contents of // sourceParents, not everything. @@ -1385,7 +1387,7 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersisten if (!sourceParents.isEmpty() && parents.isEmpty()) return; - emit q->layoutChanged(parents, hint); + emit q->layoutChanged(parents); } void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted( diff --git a/src/corelib/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp index f70c318ff7..407419edb2 100644 --- a/src/corelib/itemmodels/qstringlistmodel.cpp +++ b/src/corelib/itemmodels/qstringlistmodel.cpp @@ -307,9 +307,9 @@ QStringList QStringListModel::stringList() const */ void QStringListModel::setStringList(const QStringList &strings) { - emit beginResetModel(); + beginResetModel(); lst = strings; - emit endResetModel(); + endResetModel(); } /*! diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index f1d38db96c..7d3f4a6e44 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3560,6 +3560,8 @@ int QVariant::compare(const QVariant &v) const return v1.toTime() < v2.toTime() ? -1 : 1; case QVariant::DateTime: return v1.toDateTime() < v2.toDateTime() ? -1 : 1; + case QVariant::StringList: + return v1.toStringList() < v2.toStringList() ? -1 : 1; } int r = v1.toString().compare(v2.toString(), Qt::CaseInsensitive); if (r == 0) { diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp index 7482315909..c2b86014ba 100644 --- a/src/corelib/tools/qcommandlineoption.cpp +++ b/src/corelib/tools/qcommandlineoption.cpp @@ -147,7 +147,7 @@ QCommandLineOption::QCommandLineOption(const QStringList &names) The description is set to \a description. It is customary to add a "." at the end of the description. - In addition, the \a valueName can be set if the option expects a value. + In addition, the \a valueName needs to be set if the option expects a value. The default value for the option is set to \a defaultValue. In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4 @@ -183,7 +183,7 @@ QCommandLineOption::QCommandLineOption(const QString &name, const QString &descr The description is set to \a description. It is customary to add a "." at the end of the description. - In addition, the \a valueName can be set if the option expects a value. + In addition, the \a valueName needs to be set if the option expects a value. The default value for the option is set to \a defaultValue. In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4 diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 7c4280d36b..6b054126dd 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -9478,7 +9478,7 @@ QString &QString::append(const QStringRef &str) { if (str.string() == this) { str.appendTo(this); - } else if (str.string()) { + } else if (!str.isNull()) { int oldSize = size(); resize(oldSize + str.size()); memcpy(data() + oldSize, str.unicode(), str.size() * sizeof(QChar)); diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index 6e717f2233..96d04df0e2 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -909,13 +909,12 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch && !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) { const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year(); - const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0; - QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, - year + 1, lastMSecs); + QVector<QTimeZonePrivate::Data> posixTrans = + calculatePosixTransitions(m_posixRule, year - 1, year + 1, + m_tranTimes.last().atMSecsSinceEpoch); for (int i = posixTrans.size() - 1; i >= 0; --i) { if (posixTrans.at(i).atMSecsSinceEpoch <= forMSecsSinceEpoch) { - QTimeZonePrivate::Data data; - data = posixTrans.at(i); + QTimeZonePrivate::Data data = posixTrans.at(i); data.atMSecsSinceEpoch = forMSecsSinceEpoch; return data; } @@ -953,9 +952,9 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch && !m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) { const int year = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch, Qt::UTC).date().year(); - const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0; - QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, - year + 1, lastMSecs); + QVector<QTimeZonePrivate::Data> posixTrans = + calculatePosixTransitions(m_posixRule, year - 1, year + 1, + m_tranTimes.last().atMSecsSinceEpoch); for (int i = 0; i < posixTrans.size(); ++i) { if (posixTrans.at(i).atMSecsSinceEpoch > afterMSecsSinceEpoch) return posixTrans.at(i); @@ -979,9 +978,9 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch && !m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) { const int year = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch, Qt::UTC).date().year(); - const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0; - QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, - year + 1, lastMSecs); + QVector<QTimeZonePrivate::Data> posixTrans = + calculatePosixTransitions(m_posixRule, year - 1, year + 1, + m_tranTimes.last().atMSecsSinceEpoch); for (int i = posixTrans.size() - 1; i >= 0; --i) { if (posixTrans.at(i).atMSecsSinceEpoch < beforeMSecsSinceEpoch) return posixTrans.at(i); diff --git a/src/gui/doc/images/qcolor-saturation.png b/src/gui/doc/images/qcolor-saturation.png Binary files differindex f28776aff5..9c104f7389 100644 --- a/src/gui/doc/images/qcolor-saturation.png +++ b/src/gui/doc/images/qcolor-saturation.png diff --git a/src/gui/doc/images/qcolor-saturation.svg b/src/gui/doc/images/qcolor-saturation.svg new file mode 100644 index 0000000000..608c2555e8 --- /dev/null +++ b/src/gui/doc/images/qcolor-saturation.svg @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + version="1.1" + id="svg2" + viewBox="0 0 186.82259 45.046909" + height="12.713239mm" + width="52.725487mm"> + <defs + id="defs4"> + <linearGradient + id="linearGradient3346"> + <stop + id="stop3348" + offset="0" + style="stop-color:#808080;stop-opacity:1" /> + <stop + id="stop3350" + offset="1" + style="stop-color:#0000ff;stop-opacity:1" /> + </linearGradient> + <linearGradient + gradientTransform="translate(109.31384,222.16879)" + gradientUnits="userSpaceOnUse" + y2="16.118341" + x2="200.35715" + y1="16.118341" + x1="3.7246187" + id="linearGradient3352" + xlink:href="#linearGradient3346" /> + </defs> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + transform="translate(-109.31384,-222.16879)" + id="layer1"> + <rect + y="225.7121" + x="112.85714" + height="25.221529" + width="179.73599" + id="rect3336" + style="opacity:1;fill:url(#linearGradient3352);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <text + id="text3338" + y="263.53079" + x="113.03048" + style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="263.53079" + x="113.03048" + id="tspan3340">0</tspan></text> + <text + id="text3342" + y="263.53079" + x="271.76645" + style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="263.53079" + x="271.76645" + id="tspan3344">255</tspan></text> + </g> +</svg> diff --git a/src/gui/doc/images/qcolor-value.png b/src/gui/doc/images/qcolor-value.png Binary files differindex 0e069123a9..add9b7f83d 100644 --- a/src/gui/doc/images/qcolor-value.png +++ b/src/gui/doc/images/qcolor-value.png diff --git a/src/gui/doc/images/qcolor-value.svg b/src/gui/doc/images/qcolor-value.svg new file mode 100644 index 0000000000..51c2de0338 --- /dev/null +++ b/src/gui/doc/images/qcolor-value.svg @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="52.725487mm" + height="12.713239mm" + viewBox="0 0 186.82259 45.046909" + id="svg2" + version="1.1"> + <defs + id="defs4"> + <linearGradient + id="linearGradient3346"> + <stop + style="stop-color:#000000;stop-opacity:1" + offset="0" + id="stop3348" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3350" /> + </linearGradient> + <linearGradient + xlink:href="#linearGradient3346" + id="linearGradient3352" + x1="3.7246187" + y1="16.118341" + x2="183.57143" + y2="15.761199" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(109.31384,222.16879)" /> + </defs> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1" + transform="translate(-109.31384,-222.16879)"> + <rect + style="opacity:1;fill:url(#linearGradient3352);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3336" + width="179.73599" + height="25.221529" + x="112.85714" + y="225.7121" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="113.03048" + y="263.53079" + id="text3338"><tspan + id="tspan3340" + x="113.03048" + y="263.53079">0</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="271.76645" + y="263.53079" + id="text3342"><tspan + id="tspan3344" + x="271.76645" + y="263.53079">255</tspan></text> + </g> +</svg> diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h index 546e2fef79..9889cfb8ec 100644 --- a/src/gui/image/qpixmap_blitter_p.h +++ b/src/gui/image/qpixmap_blitter_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class Q_GUI_EXPORT QBlittablePlatformPixmap : public QPlatformPixmap { -// Q_DECLARE_PRIVATE(QBlittablePlatformPixmap); +// Q_DECLARE_PRIVATE(QBlittablePlatformPixmap) public: QBlittablePlatformPixmap(); ~QBlittablePlatformPixmap(); diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index e7b1f9e073..51857602d7 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -225,9 +225,9 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni code point of the character; for example, 'A' gives the same key sequence as Qt::Key_A. - \b{Note:} On OS X, references to "Ctrl", Qt::CTRL, Qt::Control + \note On OS X, references to "Ctrl", Qt::CTRL, Qt::Key_Control and Qt::ControlModifier correspond to the \uicontrol Command keys on the - Macintosh keyboard, and references to "Meta", Qt::META, Qt::Meta and + Macintosh keyboard, and references to "Meta", Qt::META, Qt::Key_Meta and Qt::MetaModifier correspond to the \uicontrol Control keys. Developers on OS X can use the same shortcut descriptions across all platforms, and their applications will automatically work as expected on OS X. diff --git a/src/gui/painting/qblittable_p.h b/src/gui/painting/qblittable_p.h index d5e2e22799..24440c3c61 100644 --- a/src/gui/painting/qblittable_p.h +++ b/src/gui/painting/qblittable_p.h @@ -64,7 +64,7 @@ class QBlittablePrivate; class Q_GUI_EXPORT QBlittable { - Q_DECLARE_PRIVATE(QBlittable); + Q_DECLARE_PRIVATE(QBlittable) public: enum Capability { diff --git a/src/gui/painting/qcolor_p.cpp b/src/gui/painting/qcolor_p.cpp index 84874bb75f..773e4096ee 100644 --- a/src/gui/painting/qcolor_p.cpp +++ b/src/gui/painting/qcolor_p.cpp @@ -40,31 +40,37 @@ #include "qglobal.h" #include "qrgb.h" #include "qstringlist.h" +#include "private/qtools_p.h" #include <algorithm> QT_BEGIN_NAMESPACE -static inline int h2i(char hex) -{ - if (hex >= '0' && hex <= '9') - return hex - '0'; - if (hex >= 'a' && hex <= 'f') - return hex - 'a' + 10; - if (hex >= 'A' && hex <= 'F') - return hex - 'A' + 10; - return -1; -} - +/*! + \internal + If s[0..1] is a valid hex number, returns its integer value, + otherwise returns -1. + */ static inline int hex2int(const char *s) { - return (h2i(s[0]) << 4) | h2i(s[1]); + const int hi = QtMiscUtils::fromHex(s[0]); + if (hi < 0) + return -1; + const int lo = QtMiscUtils::fromHex(s[1]); + if (lo < 0) + return -1; + return (hi << 4) | lo; } +/*! + \internal + If s is a valid hex digit, returns its integer value, + multiplied by 0x11, otherwise returns -1. + */ static inline int hex2int(char s) { - int h = h2i(s); - return (h << 4) | h; + const int h = QtMiscUtils::fromHex(s); + return h < 0 ? h : (h << 4) | h; } bool qt_get_hex_rgb(const char *name, QRgb *rgb) @@ -130,7 +136,7 @@ bool qt_get_hex_rgb(const QChar *str, int len, QRgb *rgb) #define rgb(r,g,b) (0xff000000 | (r << 16) | (g << 8) | b) static const struct RGBData { - const char *name; + const char name[21]; uint value; } rgbTbl[] = { { "aliceblue", rgb(240, 248, 255) }, diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h index 631584989a..77b5be0c4c 100644 --- a/src/gui/painting/qdatabuffer_p.h +++ b/src/gui/painting/qdatabuffer_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE template <typename Type> class QDataBuffer { - Q_DISABLE_COPY(QDataBuffer); + Q_DISABLE_COPY(QDataBuffer) public: QDataBuffer(int res) { diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index f0d0ac0283..4812cee9bb 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -2897,10 +2897,16 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co sbuf2[i * 2 + 1] = ((const uint*)s2)[x2]; fx += fdx; } + int fastLen; + if (fdx > 0) + fastLen = qMin(len, int((image_x2 - (fx >> 16)) / data->m11)); + else + fastLen = qMin(len, int((image_x1 - (fx >> 16)) / data->m11)); + fastLen -= 3; const __m128i v_fdx = _mm_set1_epi32(fdx*4); __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx); - for (; i < len-3; i+=4) { + for (; i < fastLen; i += 4) { int offset = _mm_extract_epi16(v_fx, 1); sbuf1[i * 2 + 0] = ((const uint*)s1)[offset]; sbuf1[i * 2 + 1] = ((const uint*)s1)[offset + 1]; diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 2b850cfb2a..db3453898f 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -208,13 +208,13 @@ #define ONE_PIXEL ( 1L << PIXEL_BITS ) #define PIXEL_MASK ( -1L << PIXEL_BITS ) #define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) -#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) +#define SUBPIXELS( x ) ( (TPos)(x) * ( 1 << PIXEL_BITS ) ) #define FLOOR( x ) ( (x) & -ONE_PIXEL ) #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) #define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) #if PIXEL_BITS >= 6 -#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) +#define UPSCALE( x ) ( (x) * ( 1 << ( PIXEL_BITS - 6 ) ) ) #define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) #else #define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) diff --git a/src/gui/painting/qpaintengine_blitter_p.h b/src/gui/painting/qpaintengine_blitter_p.h index 0aa2901b88..40f5347b26 100644 --- a/src/gui/painting/qpaintengine_blitter_p.h +++ b/src/gui/painting/qpaintengine_blitter_p.h @@ -63,7 +63,7 @@ class QBlittable; class Q_GUI_EXPORT QBlitterPaintEngine : public QRasterPaintEngine { - Q_DECLARE_PRIVATE(QBlitterPaintEngine); + Q_DECLARE_PRIVATE(QBlitterPaintEngine) public: QBlitterPaintEngine(QBlittablePlatformPixmap *p); diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index eca1cb590c..52501880e4 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE typedef int Q16Dot16; #define Q16Dot16ToFloat(i) ((i)/65536.) #define FloatToQ16Dot16(i) (int)((i) * 65536.) -#define IntToQ16Dot16(i) ((i) << 16) +#define IntToQ16Dot16(i) ((i) * (1 << 16)) #define Q16Dot16ToInt(i) ((i) >> 16) #define Q16Dot16Factor 65536 @@ -612,7 +612,7 @@ void QScanConverter::mergeLine(QT_FT_Vector a, QT_FT_Vector b) int iBottom = qMin(m_bottom, int((b.y - 32 - rounding) >> 6)); if (iTop <= iBottom) { - Q16Dot16 aFP = Q16Dot16Factor/2 + (a.x << 10) - rounding; + Q16Dot16 aFP = Q16Dot16Factor/2 + (a.x * (1 << 10)) - rounding; if (b.x == a.x) { Line line = { qBound(m_leftFP, aFP, m_rightFP), 0, iTop, iBottom, winding }; @@ -624,7 +624,7 @@ void QScanConverter::mergeLine(QT_FT_Vector a, QT_FT_Vector b) Q16Dot16 xFP = aFP + Q16Dot16Multiply(slopeFP, IntToQ16Dot16(iTop) - + Q16Dot16Factor/2 - (a.y << 10)); + + Q16Dot16Factor/2 - (a.y * (1 << 10))); if (clip(xFP, iTop, iBottom, slopeFP, m_leftFP, winding)) return; diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 51b1418bc3..75e30b9552 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1827,7 +1827,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEngine::GlyphFormat glyphFormat) { - if (glyph == Q_NULLPTR) + if (glyph == Q_NULLPTR || glyph->height == 0 || glyph->width == 0) return QImage(); QImage::Format format = QImage::Format_Invalid; @@ -1875,11 +1875,15 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe currentlyLockedAlphaMap = alphaMapFromGlyphData(glyph, neededFormat); + const bool glyphHasGeometry = glyph != Q_NULLPTR && glyph->height != 0 && glyph->width != 0; if (!cacheEnabled && glyph != &emptyGlyph) { currentlyLockedAlphaMap = currentlyLockedAlphaMap.copy(); delete glyph; } + if (!glyphHasGeometry) + return Q_NULLPTR; + if (currentlyLockedAlphaMap.isNull()) return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index d11f8c34b1..cad30b0c77 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1567,12 +1567,13 @@ void QTextEngine::validate() const layoutData = new LayoutData(); if (block.docHandle()) { layoutData->string = block.text(); - if (block.next().isValid()) { - if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) - layoutData->string += QChar(0xb6); - } else if (option.flags() & QTextOption::ShowDocumentTerminator) { + const bool nextBlockValid = block.next().isValid(); + if (!nextBlockValid && option.flags() & QTextOption::ShowDocumentTerminator) { layoutData->string += QChar(0xA7); + } else if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) { + layoutData->string += QLatin1Char(nextBlockValid ? 0xb6 : 0x20); } + } else { layoutData->string = text; } diff --git a/src/network/socket/qlocalsocket_tcp.cpp b/src/network/socket/qlocalsocket_tcp.cpp index 4348b819d9..379cdd096d 100644 --- a/src/network/socket/qlocalsocket_tcp.cpp +++ b/src/network/socket/qlocalsocket_tcp.cpp @@ -245,8 +245,8 @@ void QLocalSocket::connectToServer(OpenMode openMode) QLatin1String("QLocalSocket::connectToServer")); return; } - d->tcpSocket->connectToHost(QHostAddress::LocalHost, port, openMode); QIODevice::open(openMode); + d->tcpSocket->connectToHost(QHostAddress::LocalHost, port, openMode); } bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor, diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h index 5210fb7f30..9e1d18981e 100644 --- a/src/network/ssl/qsslsocket_mac_p.h +++ b/src/network/ssl/qsslsocket_mac_p.h @@ -75,7 +75,7 @@ public: private: SSLContextRef context; - Q_DISABLE_COPY(QSecureTransportContext); + Q_DISABLE_COPY(QSecureTransportContext) }; class QSslSocketBackendPrivate : public QSslSocketPrivate @@ -122,7 +122,7 @@ private: QSecureTransportContext context; - Q_DISABLE_COPY(QSslSocketBackendPrivate); + Q_DISABLE_COPY(QSslSocketBackendPrivate) }; QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 652a9f4add..02b7e1bd63 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -365,6 +365,7 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style) static void populateFromPattern(FcPattern *pattern) { QString familyName; + QString familyNameLang; FcChar8 *value = 0; int weight_value; int slant_value; @@ -382,6 +383,9 @@ static void populateFromPattern(FcPattern *pattern) familyName = QString::fromUtf8((const char *)value); + if (FcPatternGetString(pattern, FC_FAMILYLANG, 0, &value) == FcResultMatch) + familyNameLang = QString::fromUtf8((const char *)value); + slant_value = FC_SLANT_ROMAN; weight_value = FC_WEIGHT_REGULAR; spacing_value = FC_PROPORTIONAL; @@ -471,8 +475,30 @@ static void populateFromPattern(FcPattern *pattern) QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile); // qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size; - for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k) - QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value)); + for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k) { + const QString altFamilyName = QString::fromUtf8((const char *)value); + // Extra family names can be aliases or subfamilies. + // If it is a subfamily, register it as a separate font, so only members of the subfamily are + // matched when the subfamily is requested. + QString altStyleName; + if (FcPatternGetString(pattern, FC_STYLE, k, &value) == FcResultMatch) + altStyleName = QString::fromUtf8((const char *)value); + else + altStyleName = styleName; + + QString altFamilyNameLang; + if (FcPatternGetString(pattern, FC_FAMILYLANG, k, &value) == FcResultMatch) + altFamilyNameLang = QString::fromUtf8((const char *)value); + else + altFamilyNameLang = familyNameLang; + + if (familyNameLang == altFamilyNameLang && altStyleName != styleName) { + FontFile *altFontFile = new FontFile(*fontFile); + QPlatformFontDatabase::registerFont(altFamilyName, altStyleName, QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile); + } else { + QPlatformFontDatabase::registerAliasToFontFamily(familyName, altFamilyName); + } + } } @@ -488,7 +514,7 @@ void QFontconfigDatabase::populateFontDatabase() FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT, FC_SPACING, FC_FILE, FC_INDEX, FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, - FC_WIDTH, + FC_WIDTH, FC_FAMILYLANG, #if FC_VERSION >= 20297 FC_CAPABILITY, #endif diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp index 0667a9073f..a14271c8f5 100644 --- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp +++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp @@ -60,7 +60,8 @@ void QAndroidPlatformFontDatabase::populateFontDatabase() QStringList nameFilters; nameFilters << QLatin1String("*.ttf") - << QLatin1String("*.otf"); + << QLatin1String("*.otf") + << QLatin1String("*.ttc"); const auto entries = dir.entryInfoList(nameFilters, QDir::Files); for (const QFileInfo &fi : entries) { diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp index 363fce2214..4e811a1dfe 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp @@ -93,9 +93,23 @@ void QEglFSBrcmIntegration::platformInit() bcm_host_init(); } +static int getDisplayId() +{ + // As defined in vc_dispmanx_types.h + // DISPMANX_ID_MAIN_LCD 0 + // DISPMANX_ID_AUX_LCD 1 + // DISPMANX_ID_HDMI 2 + // DISPMANX_ID_SDTV 3 + // DISPMANX_ID_FORCE_LCD 4 + // DISPMANX_ID_FORCE_TV 5 + // DISPMANX_ID_FORCE_OTHER 6 /* non-default display */ + static const int dispmanxId = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISPMANX_ID"); + return (dispmanxId >= 0 && dispmanxId <= 6) ? dispmanxId : 0; +} + EGLNativeDisplayType QEglFSBrcmIntegration::platformDisplay() const { - dispman_display = vc_dispmanx_display_open(0/* LCD */); + dispman_display = vc_dispmanx_display_open(getDisplayId()); return EGL_DEFAULT_DISPLAY; } @@ -107,7 +121,7 @@ void QEglFSBrcmIntegration::platformDestroy() QSize QEglFSBrcmIntegration::screenSize() const { uint32_t width, height; - graphics_get_display_size(0 /* LCD */, &width, &height); + graphics_get_display_size(getDisplayId(), &width, &height); return QSize(width, height); } diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 5e75cbf37e..65f2cd14f6 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -40,6 +40,7 @@ #include "qwindowsfontdatabase.h" #include "qwindowsfontdatabase_ft.h" // for default font #include "qwindowscontext.h" +#include "qwindowsintegration.h" #include "qwindowsfontengine.h" #include "qwindowsfontenginedirectwrite.h" #include <QtCore/qt_windows.h> @@ -108,6 +109,18 @@ static void createDirectWriteFactory(IDWriteFactory **factory) *factory = static_cast<IDWriteFactory *>(result); } + +static inline bool useDirectWrite(QFont::HintingPreference hintingPreference, bool isColorFont = false) +{ + const unsigned options = QWindowsIntegration::instance()->options(); + if (Q_UNLIKELY(options & QWindowsIntegration::DontUseDirectWriteFonts)) + return false; + if (isColorFont) + return (options & QWindowsIntegration::DontUseColorFonts) == 0; + return hintingPreference == QFont::PreferNoHinting + || hintingPreference == QFont::PreferVerticalHinting + || (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting); +} #endif // !QT_NO_DIRECTWRITE // Helper classes for creating font engines directly from font data @@ -1199,11 +1212,7 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal QFontEngine *fontEngine = 0; #if !defined(QT_NO_DIRECTWRITE) - bool useDirectWrite = (hintingPreference == QFont::PreferNoHinting) - || (hintingPreference == QFont::PreferVerticalHinting) - || (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting); - - if (!useDirectWrite) + if (!useDirectWrite(hintingPreference)) #endif { GUID guid; @@ -1838,15 +1847,16 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, if (SUCCEEDED(directWriteFontFace->QueryInterface(__uuidof(IDWriteFontFace2), reinterpret_cast<void **>(&directWriteFontFace2)))) { if (directWriteFontFace2->IsColorFont()) - isColorFont = true; + isColorFont = directWriteFontFace2->GetPaletteEntryCount() > 0; } #endif - - bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting) - || (request.hintingPreference == QFont::PreferVerticalHinting) - || (QHighDpiScaling::isActive() && request.hintingPreference == QFont::PreferDefaultHinting) - || isColorFont; - if (useDirectWrite) { + const QFont::HintingPreference hintingPreference = + static_cast<QFont::HintingPreference>(request.hintingPreference); + const bool useDw = useDirectWrite(hintingPreference, isColorFont); + qCDebug(lcQpaFonts) << __FUNCTION__ << request.family << request.pointSize + << "pt" << "hintingPreference=" << hintingPreference << "color=" << isColorFont + << dpi << "dpi" << "useDirectWrite=" << useDw; + if (useDw) { QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace, request.pixelSize, data); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 90aa3fef16..b9a63c7a89 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -192,6 +192,10 @@ static inline unsigned parseOptions(const QStringList ¶mList, } } else if (param == QLatin1String("gl=gdi")) { options |= QWindowsIntegration::DisableArb; + } else if (param == QLatin1String("nodirectwrite")) { + options |= QWindowsIntegration::DontUseDirectWriteFonts; + } else if (param == QLatin1String("nocolorfonts")) { + options |= QWindowsIntegration::DontUseColorFonts; } else if (param == QLatin1String("nomousefromtouch")) { options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch; } else if (parseIntOption(param, QLatin1String("verbose"), 0, INT_MAX, &QWindowsContext::verbose) @@ -304,7 +308,7 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons if (window->type() == Qt::ForeignWindow) { const HWND hwnd = reinterpret_cast<HWND>(window->winId()); if (!IsWindow(hwnd)) { - qWarning("Windows QPA: Invalid foreign window ID %p."); + qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd); return nullptr; } QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd); diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index 437253cedc..4258f908e7 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -60,7 +60,9 @@ public: DisableArb = 0x4, NoNativeDialogs = 0x8, XpNativeDialogs = 0x10, - DontPassOsMouseEventsSynthesizedFromTouch = 0x20 // Do not pass OS-generated mouse events from touch. + DontPassOsMouseEventsSynthesizedFromTouch = 0x20, // Do not pass OS-generated mouse events from touch. + DontUseDirectWriteFonts = 0x40, + DontUseColorFonts = 0x80 }; explicit QWindowsIntegration(const QStringList ¶mList); diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 8d6e83298e..79b5bbae41 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -43,6 +43,7 @@ #include "qwindowswindow.h" #include "qwindowsinputcontext.h" +#include <QtGui/QGuiApplication> #include <QtGui/QWindow> #include <qpa/qwindowsysteminterface.h> #include <private/qguiapplication_p.h> @@ -1048,6 +1049,21 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) { // Found a ?_CHAR uch = QChar(ushort(wm_char.wParam)); + if (uch.isHighSurrogate()) { + m_lastHighSurrogate = uch; + return true; + } else if (uch.isLowSurrogate() && !m_lastHighSurrogate.isNull()) { + if (QObject *focusObject = QGuiApplication::focusObject()) { + const QChar chars[2] = {m_lastHighSurrogate, uch}; + QInputMethodEvent event; + event.setCommitString(QString(chars, 2)); + QCoreApplication::sendEvent(focusObject, &event); + } + m_lastHighSurrogate = QChar(); + return true; + } else { + m_lastHighSurrogate = QChar(); + } if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN)) uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter if (!code && !uch.row()) diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h index 069f78197e..2657644780 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.h +++ b/src/plugins/platforms/windows/qwindowskeymapper.h @@ -103,6 +103,7 @@ private: void deleteLayouts(); QWindow *m_keyGrabber; + QChar m_lastHighSurrogate; static const size_t NumKeyboardLayoutItems = 256; KeyboardLayoutItem keyLayout[NumKeyboardLayoutItems]; }; diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp index 8fc54794bc..e58f194b72 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -27,6 +27,8 @@ ****************************************************************************/ #include <qbytearray.h> +#include <qcommandlineparser.h> +#include <qcoreapplication.h> #include <qdebug.h> #include <qfile.h> #include <qfileinfo.h> @@ -59,30 +61,6 @@ static QString commandLine; static QStringList includes; static QStringList wantedInterfaces; -static const char help[] = - "Usage: " PROGRAMNAME " [options...] [xml-or-xml-file] [interfaces...]\n" - "Produces the C++ code to implement the interfaces defined in the input file.\n" - "\n" - "Options:\n" - " -a <filename> Write the adaptor code to <filename>\n" - " -c <classname> Use <classname> as the class name for the generated classes\n" - " -h Show this information\n" - " -i <filename> Add #include to the output\n" - " -l <classname> When generating an adaptor, use <classname> as the parent class\n" - " -m Generate #include \"filename.moc\" statements in the .cpp files\n" - " -N Don't use namespaces\n" - " -p <filename> Write the proxy code to <filename>\n" - " -v Be verbose.\n" - " -V Show the program version and quit.\n" - "\n" - "If the file name given to the options -a and -p does not end in .cpp or .h, the\n" - "program will automatically append the suffixes and produce both files.\n" - "You can also use a colon (:) to separate the header name from the source file\n" - "name, as in '-a filename_p.h:filename.cpp'.\n" - "\n" - "If you pass a dash (-) as the argument to either -p or -a, the output is written\n" - "to the standard output\n"; - static const char includeList[] = "#include <QtCore/QByteArray>\n" "#include <QtCore/QList>\n" @@ -101,105 +79,6 @@ static const char forwardDeclarations[] = "class QVariant;\n" "QT_END_NAMESPACE\n"; -static void showHelp() -{ - printf("%s", help); - exit(0); -} - -static void showVersion() -{ - printf("%s version %s\n", PROGRAMNAME, PROGRAMVERSION); - printf("D-Bus binding tool for Qt\n"); - exit(0); -} - -static QString nextArg(QStringList &args, int i, char opt) -{ - QString arg = args.value(i); - if (arg.isEmpty()) { - printf("-%c needs at least one argument\n", opt); - exit(1); - } - return args.takeAt(i); -} - -static void parseCmdLine(QStringList args) -{ - args.takeFirst(); - - commandLine = QLatin1String(PROGRAMNAME " "); - commandLine += args.join(QLatin1Char(' ')); - - int i = 0; - while (i < args.count()) { - - if (!args.at(i).startsWith(QLatin1Char('-'))) { - ++i; - continue; - } - QString arg = args.takeAt(i); - - char c = '\0'; - if (arg.length() == 2) - c = arg.at(1).toLatin1(); - else if (arg == QLatin1String("--help")) - c = 'h'; - - switch (c) { - case 'a': - adaptorFile = nextArg(args, i, 'a'); - break; - - case 'c': - globalClassName = nextArg(args, i, 'c'); - break; - - case 'v': - verbose = true; - break; - - case 'i': - includes << nextArg(args, i, 'i'); - break; - - case 'l': - parentClassName = nextArg(args, i, 'l'); - break; - - case 'm': - includeMocs = true; - break; - - case 'N': - skipNamespaces = true; - break; - - case '?': - case 'h': - showHelp(); - break; - - case 'V': - showVersion(); - break; - - case 'p': - proxyFile = nextArg(args, i, 'p'); - break; - - default: - printf("unknown option: '%s'\n", qPrintable(arg)); - exit(1); - } - } - - if (!args.isEmpty()) - inputFile = args.takeFirst(); - - wantedInterfaces << args; -} - static QDBusIntrospection::Interfaces readInput() { QFile input(inputFile); @@ -1139,13 +1018,79 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte int main(int argc, char **argv) { - QStringList arguments; - arguments.reserve(argc); - for (int i = 0; i < argc; ++i) { - arguments.append(QString::fromLocal8Bit(argv[i])); - } + QCoreApplication app(argc, argv); + QCoreApplication::setApplicationName(QStringLiteral(PROGRAMNAME)); + QCoreApplication::setApplicationVersion(QStringLiteral(PROGRAMVERSION)); + + QCommandLineParser parser; + parser.setApplicationDescription(QLatin1String( + "Produces the C++ code to implement the interfaces defined in the input file.\n\n" + "If the file name given to the options -a and -p does not end in .cpp or .h, the\n" + "program will automatically append the suffixes and produce both files.\n" + "You can also use a colon (:) to separate the header name from the source file\n" + "name, as in '-a filename_p.h:filename.cpp'.\n\n" + "If you pass a dash (-) as the argument to either -p or -a, the output is written\n" + "to the standard output.")); + + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument(QStringLiteral("xml-or-xml-file"), QStringLiteral("XML file to use.")); + parser.addPositionalArgument(QStringLiteral("interfaces"), QStringLiteral("List of interfaces to use."), + QStringLiteral("[interfaces ...]")); + + QCommandLineOption adapterCodeOption(QStringList() << QStringLiteral("a") << QStringLiteral("adaptor"), + QStringLiteral("Write the adaptor code to <filename>"), QStringLiteral("filename")); + parser.addOption(adapterCodeOption); + + QCommandLineOption classNameOption(QStringList() << QStringLiteral("c") << QStringLiteral("classname"), + QStringLiteral("Use <classname> as the class name for the generated classes"), QStringLiteral("classname")); + parser.addOption(classNameOption); + + QCommandLineOption addIncludeOption(QStringList() << QStringLiteral("i") << QStringLiteral("include"), + QStringLiteral("Add #include to the output"), QStringLiteral("filename")); + parser.addOption(addIncludeOption); + + QCommandLineOption adapterParentOption(QStringLiteral("l"), + QStringLiteral("When generating an adaptor, use <classname> as the parent class"), QStringLiteral("classname")); + parser.addOption(adapterParentOption); + + QCommandLineOption mocIncludeOption(QStringList() << QStringLiteral("m") << QStringLiteral("moc"), + QStringLiteral("Generate #include \"filename.moc\" statements in the .cpp files")); + parser.addOption(mocIncludeOption); + + QCommandLineOption noNamespaceOption(QStringList() << QStringLiteral("N") << QStringLiteral("no-namespaces"), + QStringLiteral("Don't use namespaces")); + parser.addOption(noNamespaceOption); + + QCommandLineOption proxyCodeOption(QStringList() << QStringLiteral("p") << QStringLiteral("proxy"), + QStringLiteral("Write the proxy code to <filename>"), QStringLiteral("filename")); + parser.addOption(proxyCodeOption); + + QCommandLineOption verboseOption(QStringList() << QStringLiteral("V") << QStringLiteral("verbose"), + QStringLiteral("Be verbose.")); + parser.addOption(verboseOption); + + parser.process(app); + + adaptorFile = parser.value(adapterCodeOption); + globalClassName = parser.value(classNameOption); + includes = parser.values(addIncludeOption); + parentClassName = parser.value(adapterParentOption); + includeMocs = parser.isSet(mocIncludeOption); + skipNamespaces = parser.isSet(noNamespaceOption); + proxyFile = parser.value(proxyCodeOption); + verbose = parser.isSet(verboseOption); + + wantedInterfaces = parser.positionalArguments(); + if (!wantedInterfaces.isEmpty()) { + inputFile = wantedInterfaces.takeFirst(); - parseCmdLine(arguments); + QFileInfo inputInfo(inputFile); + if (!inputInfo.exists() || !inputInfo.isFile() || !inputInfo.isReadable()) { + qCritical("Error: Input %s is not a file or cannot be accessed\n", qPrintable(inputFile)); + return 1; + } + } QDBusIntrospection::Interfaces interfaces = readInput(); cleanInterfaces(interfaces); diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 689704884f..73aeb24cc0 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -667,7 +667,7 @@ void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button If the \l{QMessageBox::StandardButtons} {standard buttons} are not flexible enough for your message box, you can use the addButton() - overload that takes a text and a ButtonRoleto to add custom + overload that takes a text and a ButtonRole to add custom buttons. The ButtonRole is used by QMessageBox to determine the ordering of the buttons on screen (which varies according to the platform). You can test the value of clickedButton() after calling diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 221511f38d..42b35ac644 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -788,8 +788,10 @@ void QAbstractItemView::setSelectionModel(QItemSelectionModel *selectionModel) QModelIndex oldCurrentIndex; if (d->selectionModel) { - oldSelection = d->selectionModel->selection(); - oldCurrentIndex = d->selectionModel->currentIndex(); + if (d->selectionModel->model() == selectionModel->model()) { + oldSelection = d->selectionModel->selection(); + oldCurrentIndex = d->selectionModel->currentIndex(); + } disconnect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection))); @@ -3871,7 +3873,7 @@ void QAbstractItemView::doAutoScroll() int horizontalValue = horizontalScroll->value(); QPoint pos = d->viewport->mapFromGlobal(QCursor::pos()); - QRect area = static_cast<QAbstractItemView*>(d->viewport)->d_func()->clipRect(); // access QWidget private by bending C++ rules + QRect area = QWidgetPrivate::get(d->viewport)->clipRect(); // do the scrolling if we are in the scroll margins if (pos.y() - area.top() < margin) diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h index b080f84e90..d6c5d58934 100644 --- a/src/widgets/itemviews/qabstractitemview.h +++ b/src/widgets/itemviews/qabstractitemview.h @@ -46,6 +46,9 @@ #include <QtCore/qitemselectionmodel.h> #include <QtWidgets/qabstractitemdelegate.h> +class tst_QAbstractItemView; +class tst_QTreeView; + QT_BEGIN_NAMESPACE @@ -368,6 +371,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged()) #endif + friend class ::tst_QAbstractItemView; + friend class ::tst_QTreeView; friend class QTreeViewPrivate; // needed to compile with MSVC friend class QListModeViewBase; friend class QListViewPrivate; diff --git a/src/widgets/itemviews/qdatawidgetmapper.cpp b/src/widgets/itemviews/qdatawidgetmapper.cpp index 4bf7406f92..b213a0859c 100644 --- a/src/widgets/itemviews/qdatawidgetmapper.cpp +++ b/src/widgets/itemviews/qdatawidgetmapper.cpp @@ -205,20 +205,6 @@ void QDataWidgetMapperPrivate::_q_commitData(QWidget *w) commit(widgetMap.at(idx)); } -class QFocusHelper: public QWidget -{ -public: - bool focusNextPrevChild(bool next) Q_DECL_OVERRIDE - { - return QWidget::focusNextPrevChild(next); - } - - static inline void focusNextPrevChild(QWidget *w, bool next) - { - static_cast<QFocusHelper *>(w)->focusNextPrevChild(next); - } -}; - void QDataWidgetMapperPrivate::_q_closeEditor(QWidget *w, QAbstractItemDelegate::EndEditHint hint) { int idx = findWidget(w); @@ -230,10 +216,10 @@ void QDataWidgetMapperPrivate::_q_closeEditor(QWidget *w, QAbstractItemDelegate: populate(widgetMap[idx]); break; } case QAbstractItemDelegate::EditNextItem: - QFocusHelper::focusNextPrevChild(w, true); + w->focusNextChild(); break; case QAbstractItemDelegate::EditPreviousItem: - QFocusHelper::focusNextPrevChild(w, false); + w->focusPreviousChild(); break; case QAbstractItemDelegate::SubmitModelCache: case QAbstractItemDelegate::NoHint: diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 7b393463a6..1a0b417034 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3465,6 +3465,7 @@ void QHeaderViewPrivate::clear() sectionSelected.clear(); hiddenSectionSize.clear(); sectionItems.clear(); + lastSectionLogicalIdx = -1; invalidateCachedSizeHint(); } } diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h index b3a88db005..3c7cbddfbb 100644 --- a/src/widgets/itemviews/qtreeview.h +++ b/src/widgets/itemviews/qtreeview.h @@ -43,6 +43,8 @@ #include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qabstractitemview.h> +class tst_QTreeView; + QT_BEGIN_NAMESPACE @@ -220,6 +222,7 @@ protected: void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) Q_DECL_OVERRIDE; private: + friend class ::tst_QTreeView; friend class QAccessibleTable; friend class QAccessibleTree; friend class QAccessibleTableCell; diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index 74ca7d2827..31d60c06d7 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -146,6 +146,7 @@ QTreeModel::QTreeModel(QTreeModelPrivate &dd, QTreeWidget *parent) QTreeModel::~QTreeModel() { clear(); + headerItem->view = Q_NULLPTR; delete headerItem; rootItem->view = 0; delete rootItem; diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 2a71710143..bca89fe2c5 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -676,6 +676,7 @@ protected: void destroy(bool destroyWindow = true, bool destroySubWindows = true); + friend class QDataWidgetMapperPrivate; // for access to focusNextPrevChild virtual bool focusNextPrevChild(bool next); inline bool focusNextChild() { return focusNextPrevChild(true); } inline bool focusPreviousChild() { return focusNextPrevChild(false); } diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index e982660bef..f589fe1d6d 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -898,13 +898,11 @@ void tst_QUrl::resolving_data() // Some parsers allow the scheme name to be present in a relative URI // reference if it is the same as the base URI scheme. This is - // considered to be a loophole in prior specifications of partial URI - // [RFC1630]. Its use should be avoided, but is allowed for backward - // compatibility. - // For strict parsers : -// QTest::newRow("http:g [for strict parsers]") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("http:g") << QString::fromLatin1("http:g"); - // For backward compatibility : - QTest::newRow("http:g [for backward compatibility]") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("http:g") << QString::fromLatin1("http://a/b/c/g"); + // considered to be a loophole in prior specifications of partial URI [RFC1630], + //QTest::newRow("http:g [for backward compatibility]") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("http:g") << QString::fromLatin1("http://a/b/c/g"); + // However we don't do that anymore, as per RFC3986, in order for the data:subpage testcase below to work. + QTest::newRow("http:g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("http:g") << QString::fromLatin1("http:g"); + QTest::newRow("data:subpage") << QString::fromLatin1("data:text/plain, main page") << QString::fromLatin1("data:text/plain, subpage") << QString::fromLatin1("data:text/plain, subpage"); // Resolve relative with relative QTest::newRow("../a (1)") << QString::fromLatin1("b") << QString::fromLatin1("../a") << QString::fromLatin1("a"); @@ -916,6 +914,10 @@ void tst_QUrl::resolving_data() QTest::newRow("../a (6)") << QString::fromLatin1("/b/a") << QString::fromLatin1("../a") << QString::fromLatin1("/a"); QTest::newRow("../a (7)") << QString::fromLatin1("/b/c/a") << QString::fromLatin1("../a") << QString::fromLatin1("/b/a"); QTest::newRow("../a (8)") << QString::fromLatin1("/b") << QString::fromLatin1("/a") << QString::fromLatin1("/a"); + + // More tests from KDE + QTest::newRow("brackets") << QString::fromLatin1("http://www.calorieking.com/personal/diary/") << QString::fromLatin1("/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458") << QString::fromLatin1("http://www.calorieking.com/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458"); + QTest::newRow("javascript")<< QString::fromLatin1("http://www.youtube.com/?v=JvOSnRD5aNk") << QString::fromLatin1("javascript:window.location+\"__flashplugin_unique__\"") << QString::fromLatin1("javascript:window.location+%22__flashplugin_unique__%22"); } void tst_QUrl::resolving() diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 8e2d583961..04a7129f01 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -143,6 +143,7 @@ private slots: void noMapAfterSourceDelete(); void forwardDropApi(); void canDropMimeData(); + void filterHint(); protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); @@ -3802,6 +3803,12 @@ void tst_QSortFilterProxyModel::moveSourceRows() QCOMPARE(filterBeforeParents.size(), 1); QCOMPARE(filterAfterParents.size(), 1); + QCOMPARE( + filterBeforeParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(), + QAbstractItemModel::NoLayoutChangeHint); + QCOMPARE(filterAfterParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(), + QAbstractItemModel::NoLayoutChangeHint); + QCOMPARE(filterBothBeforeParentLayoutSpy.size(), 0); QCOMPARE(filterBothAfterParentLayoutSpy.size(), 0); } @@ -4123,5 +4130,50 @@ void tst_QSortFilterProxyModel::resortingDoesNotBreakTreeModels() QCOMPARE(proxy.rowCount(pi1), 1); } +void tst_QSortFilterProxyModel::filterHint() +{ + // test that a filtering model does not emit layoutChanged with a hint + QStringListModel model(QStringList() << "one" + << "two" + << "three" + << "four" + << "five" + << "six"); + QSortFilterProxyModel proxy1; + proxy1.setSourceModel(&model); + proxy1.setSortRole(Qt::DisplayRole); + proxy1.setDynamicSortFilter(true); + proxy1.sort(0); + + QSortFilterProxyModel proxy2; + proxy2.setSourceModel(&proxy1); + proxy2.setFilterRole(Qt::DisplayRole); + proxy2.setFilterRegExp("^[^ ]*$"); + proxy2.setDynamicSortFilter(true); + + QSignalSpy proxy1BeforeSpy(&proxy1, &QSortFilterProxyModel::layoutAboutToBeChanged); + QSignalSpy proxy1AfterSpy(&proxy1, &QSortFilterProxyModel::layoutChanged); + QSignalSpy proxy2BeforeSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged); + QSignalSpy proxy2AfterSpy(&proxy2, &QSortFilterProxyModel::layoutChanged); + + model.setData(model.index(2), QStringLiteral("modified three"), Qt::DisplayRole); + + // The first proxy was re-sorted as one item as changed. + QCOMPARE(proxy1BeforeSpy.size(), 1); + QCOMPARE(proxy1BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(), + QAbstractItemModel::VerticalSortHint); + QCOMPARE(proxy1AfterSpy.size(), 1); + QCOMPARE(proxy1AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(), + QAbstractItemModel::VerticalSortHint); + + // But the second proxy must not have the VerticalSortHint since an item was filtered + QCOMPARE(proxy2BeforeSpy.size(), 1); + QCOMPARE(proxy2BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(), + QAbstractItemModel::NoLayoutChangeHint); + QCOMPARE(proxy2AfterSpy.size(), 1); + QCOMPARE(proxy2AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(), + QAbstractItemModel::NoLayoutChangeHint); +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 262d8ad44b..75fa424ab1 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -275,6 +275,7 @@ private slots: void metaEnums(); void compareSanity_data(); void compareSanity(); + void compareRich(); void accessSequentialContainerKey(); @@ -4775,6 +4776,60 @@ void tst_QVariant::compareSanity() } } +static void richComparison(const QVariant& less, const QVariant& more) +{ + QVERIFY(less.type() == more.type()); + + QVERIFY(less < more); + QVERIFY(!(more < less)); + + QVERIFY(more > less); + QVERIFY(!(less > more)); + + QVERIFY(less <= more); + QVERIFY(!(more <= less)); + QVERIFY(less <= less); + + QVERIFY(more >= less); + QVERIFY(!(less >= more)); + QVERIFY(more >= more); +} + +void tst_QVariant::compareRich() +{ + richComparison(QUuid("{49d8ad2a-2ee8-4c3d-949f-1b5a3765ddf0}"), + QUuid("{f6d56824-16e9-4543-a375-add2877c2d05}")); + richComparison(QByteArray::fromRawData("a", 1), + QByteArray::fromRawData("b", 1)); + richComparison(QStringLiteral("a"), QStringLiteral("b")); + richComparison(QLatin1String("a"), QLatin1String("b")); + richComparison(QChar('a'), QChar('b')); + richComparison(QDate(2016, 7, 23), QDate(2016, 7, 24)); + richComparison(QTime(0, 0), QTime(0, 1)); + richComparison(QDateTime(QDate(2016, 7, 23), QTime(0, 0)), + QDateTime(QDate(2016, 7, 23), QTime(0, 1))); + + richComparison(QStringList(), QStringList() << QStringLiteral("a")); + richComparison(QStringList(), QStringList() << QStringLiteral("a") + << QStringLiteral("b")); + richComparison(QStringList() << QStringLiteral("a"), + QStringList() << QStringLiteral("b")); + richComparison(QStringList() << QStringLiteral("a"), + QStringList() << QStringLiteral("b") + << QStringLiteral("c")); + richComparison(QStringList() << QStringLiteral("a") + << QStringLiteral("c"), + QStringList() << QStringLiteral("b")); + richComparison(QStringList() << QStringLiteral("a") + << QStringLiteral("c"), + QStringList() << QStringLiteral("b") + << QStringLiteral("d")); + richComparison(QStringList() << QStringLiteral("a") + << QStringLiteral("c"), + QStringList() << QStringLiteral("a") + << QStringLiteral("d")); +} + void tst_QVariant::accessSequentialContainerKey() { QString nameResult; diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 36784435b8..7a37fdfa46 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -123,7 +123,7 @@ template <> class Arg<QStringRef> : ArgBase { QStringRef ref() const - { return this->pinned.isNull() ? QStringRef() : this->pinned.midRef(0) ; } + { return QStringRef(&pinned); } public: explicit Arg(const char *str) : ArgBase(str) {} diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index 00e01094a4..8cc06a77ba 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -181,6 +181,7 @@ private slots: void slotConnected() { QCOMPARE(state(), QLocalSocket::ConnectedState); + QVERIFY(isOpen()); } void slotDisconnected() { diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 1050fa2561..7412637354 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -77,108 +77,6 @@ static inline void moveCursorAway(const QWidget *topLevel) #endif } -class TestView : public QAbstractItemView -{ - Q_OBJECT -public: - inline void tst_dataChanged(const QModelIndex &tl, const QModelIndex &br) - { dataChanged(tl, br); } - inline void tst_setHorizontalStepsPerItem(int steps) - { setHorizontalStepsPerItem(steps); } - inline int tst_horizontalStepsPerItem() const - { return horizontalStepsPerItem(); } - inline void tst_setVerticalStepsPerItem(int steps) - { setVerticalStepsPerItem(steps); } - inline int tst_verticalStepsPerItem() const - { return verticalStepsPerItem(); } - - inline void tst_rowsInserted(const QModelIndex &parent, int start, int end) - { rowsInserted(parent, start, end); } - inline void tst_rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) - { rowsAboutToBeRemoved(parent, start, end); } - inline void tst_selectionChanged(const QItemSelection &selected, - const QItemSelection &deselected) - { selectionChanged(selected, deselected); } - inline void tst_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) - { currentChanged(current, previous); } - inline void tst_updateEditorData() - { updateEditorData(); } - inline void tst_updateEditorGeometries() - { updateEditorGeometries(); } - inline void tst_updateGeometries() - { updateGeometries(); } - inline void tst_verticalScrollbarAction(int action) - { verticalScrollbarAction(action); } - inline void tst_horizontalScrollbarAction(int action) - { horizontalScrollbarAction(action); } - inline void tst_verticalScrollbarValueChanged(int value) - { verticalScrollbarValueChanged(value); } - inline void tst_horizontalScrollbarValueChanged(int value) - { horizontalScrollbarValueChanged(value); } - inline void tst_closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) - { closeEditor(editor, hint); } - inline void tst_commitData(QWidget *editor) - { commitData(editor); } - inline void tst_editorDestroyed(QObject *editor) - { editorDestroyed(editor); } - enum tst_CursorAction { - MoveUp = QAbstractItemView::MoveUp, - MoveDown = QAbstractItemView::MoveDown, - MoveLeft = QAbstractItemView::MoveLeft, - MoveRight = QAbstractItemView::MoveRight, - MoveHome = QAbstractItemView::MoveHome, - MoveEnd = QAbstractItemView::MoveEnd, - MovePageUp = QAbstractItemView::MovePageUp, - MovePageDown = QAbstractItemView::MovePageDown, - MoveNext = QAbstractItemView::MoveNext, - MovePrevious = QAbstractItemView::MovePrevious - }; - inline QModelIndex tst_moveCursor(tst_CursorAction cursorAction, - Qt::KeyboardModifiers modifiers) - { return moveCursor(QAbstractItemView::CursorAction(cursorAction), modifiers); } - inline int tst_horizontalOffset() const - { return horizontalOffset(); } - inline int tst_verticalOffset() const - { return verticalOffset(); } - inline bool tst_isIndexHidden(const QModelIndex &index) const - { return isIndexHidden(index); } - inline void tst_setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) - { setSelection(rect, command); } - inline QRegion tst_visualRegionForSelection(const QItemSelection &selection) const - { return visualRegionForSelection(selection); } - inline QModelIndexList tst_selectedIndexes() const - { return selectedIndexes(); } - inline bool tst_edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) - { return edit(index, trigger, event); } - inline QItemSelectionModel::SelectionFlags tst_selectionCommand(const QModelIndex &index, - const QEvent *event = 0) const - { return selectionCommand(index, event); } -#ifndef QT_NO_DRAGANDDROP - inline void tst_startDrag(Qt::DropActions supportedActions) - { startDrag(supportedActions); } -#endif - inline QStyleOptionViewItem tst_viewOptions() const - { return viewOptions(); } - enum tst_State { - NoState = QAbstractItemView::NoState, - DraggingState = QAbstractItemView::DraggingState, - DragSelectingState = QAbstractItemView::DragSelectingState, - EditingState = QAbstractItemView::EditingState, - ExpandingState = QAbstractItemView::ExpandingState, - CollapsingState = QAbstractItemView::CollapsingState - }; - inline tst_State tst_state() const - { return (tst_State)state(); } - inline void tst_setState(tst_State state) - { setState(QAbstractItemView::State(state)); } - inline void tst_startAutoScroll() - { startAutoScroll(); } - inline void tst_stopAutoScroll() - { stopAutoScroll(); } - inline void tst_doAutoScroll() - { doAutoScroll(); } -}; - class GeometriesTestView : public QTableView { Q_OBJECT @@ -194,7 +92,7 @@ class tst_QAbstractItemView : public QObject Q_OBJECT public: - void basic_tests(TestView *view); + void basic_tests(QAbstractItemView *view); private slots: void cleanup(); @@ -278,7 +176,7 @@ public: void tst_QAbstractItemView::getSetCheck() { QListView view; - TestView *obj1 = reinterpret_cast<TestView*>(&view); + QAbstractItemView *obj1 = &view; // QAbstractItemDelegate * QAbstractItemView::itemDelegate() // void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *) MyAbstractItemDelegate *var1 = new MyAbstractItemDelegate; @@ -329,18 +227,18 @@ void tst_QAbstractItemView::getSetCheck() // State QAbstractItemView::state() // void QAbstractItemView::setState(State) - obj1->tst_setState(TestView::tst_State(TestView::NoState)); - QCOMPARE(TestView::tst_State(TestView::NoState), obj1->tst_state()); - obj1->tst_setState(TestView::tst_State(TestView::DraggingState)); - QCOMPARE(TestView::tst_State(TestView::DraggingState), obj1->tst_state()); - obj1->tst_setState(TestView::tst_State(TestView::DragSelectingState)); - QCOMPARE(TestView::tst_State(TestView::DragSelectingState), obj1->tst_state()); - obj1->tst_setState(TestView::tst_State(TestView::EditingState)); - QCOMPARE(TestView::tst_State(TestView::EditingState), obj1->tst_state()); - obj1->tst_setState(TestView::tst_State(TestView::ExpandingState)); - QCOMPARE(TestView::tst_State(TestView::ExpandingState), obj1->tst_state()); - obj1->tst_setState(TestView::tst_State(TestView::CollapsingState)); - QCOMPARE(TestView::tst_State(TestView::CollapsingState), obj1->tst_state()); + obj1->setState(QAbstractItemView::NoState); + QCOMPARE(QAbstractItemView::NoState, obj1->state()); + obj1->setState(QAbstractItemView::DraggingState); + QCOMPARE(QAbstractItemView::DraggingState, obj1->state()); + obj1->setState(QAbstractItemView::DragSelectingState); + QCOMPARE(QAbstractItemView::DragSelectingState, obj1->state()); + obj1->setState(QAbstractItemView::EditingState); + QCOMPARE(QAbstractItemView::EditingState, obj1->state()); + obj1->setState(QAbstractItemView::ExpandingState); + QCOMPARE(QAbstractItemView::ExpandingState, obj1->state()); + obj1->setState(QAbstractItemView::CollapsingState); + QCOMPARE(QAbstractItemView::CollapsingState, obj1->state()); // QWidget QAbstractScrollArea::viewport() // void setViewport(QWidget*) @@ -394,7 +292,7 @@ void tst_QAbstractItemView::emptyModels() QVERIFY(!view->selectionModel()); //QVERIFY(view->itemDelegate() != 0); - basic_tests(reinterpret_cast<TestView*>(view.data())); + basic_tests(view.data()); } void tst_QAbstractItemView::setModel_data() @@ -431,10 +329,10 @@ void tst_QAbstractItemView::setModel() QStandardItemModel model(20,20); view->setModel(0); view->setModel(&model); - basic_tests(reinterpret_cast<TestView*>(view.data())); + basic_tests(view.data()); } -void tst_QAbstractItemView::basic_tests(TestView *view) +void tst_QAbstractItemView::basic_tests(QAbstractItemView *view) { // setSelectionModel // Will assert as it should @@ -559,73 +457,73 @@ void tst_QAbstractItemView::basic_tests(TestView *view) view->setCurrentIndex(QModelIndex()); // protected methods - view->tst_dataChanged(QModelIndex(), QModelIndex()); - view->tst_rowsInserted(QModelIndex(), -1, -1); - view->tst_rowsAboutToBeRemoved(QModelIndex(), -1, -1); - view->tst_selectionChanged(QItemSelection(), QItemSelection()); + view->dataChanged(QModelIndex(), QModelIndex()); + view->rowsInserted(QModelIndex(), -1, -1); + view->rowsAboutToBeRemoved(QModelIndex(), -1, -1); + view->selectionChanged(QItemSelection(), QItemSelection()); if (view->model()){ - view->tst_currentChanged(QModelIndex(), QModelIndex()); - view->tst_currentChanged(QModelIndex(), view->model()->index(0,0)); + view->currentChanged(QModelIndex(), QModelIndex()); + view->currentChanged(QModelIndex(), view->model()->index(0,0)); } - view->tst_updateEditorData(); - view->tst_updateEditorGeometries(); - view->tst_updateGeometries(); - view->tst_verticalScrollbarAction(QAbstractSlider::SliderSingleStepAdd); - view->tst_horizontalScrollbarAction(QAbstractSlider::SliderSingleStepAdd); - view->tst_verticalScrollbarValueChanged(10); - view->tst_horizontalScrollbarValueChanged(10); - view->tst_closeEditor(0, QAbstractItemDelegate::NoHint); - view->tst_commitData(0); - view->tst_editorDestroyed(0); - - view->tst_setHorizontalStepsPerItem(2); - view->tst_horizontalStepsPerItem(); - view->tst_setVerticalStepsPerItem(2); - view->tst_verticalStepsPerItem(); + view->updateEditorData(); + view->updateEditorGeometries(); + view->updateGeometries(); + view->verticalScrollbarAction(QAbstractSlider::SliderSingleStepAdd); + view->horizontalScrollbarAction(QAbstractSlider::SliderSingleStepAdd); + view->verticalScrollbarValueChanged(10); + view->horizontalScrollbarValueChanged(10); + view->closeEditor(0, QAbstractItemDelegate::NoHint); + view->commitData(0); + view->editorDestroyed(0); + + view->setHorizontalStepsPerItem(2); + view->horizontalStepsPerItem(); + view->setVerticalStepsPerItem(2); + view->verticalStepsPerItem(); // Will assert as it should // view->setIndexWidget(QModelIndex(), 0); - view->tst_moveCursor(TestView::MoveUp, Qt::NoModifier); - view->tst_horizontalOffset(); - view->tst_verticalOffset(); + view->moveCursor(QAbstractItemView::MoveUp, Qt::NoModifier); + view->horizontalOffset(); + view->verticalOffset(); -// view->tst_isIndexHidden(QModelIndex()); // will (correctly) assert +// view->isIndexHidden(QModelIndex()); // will (correctly) assert if(view->model()) - view->tst_isIndexHidden(view->model()->index(0,0)); + view->isIndexHidden(view->model()->index(0,0)); - view->tst_setSelection(QRect(0, 0, 10, 10), QItemSelectionModel::ClearAndSelect); - view->tst_setSelection(QRect(-1, -1, -1, -1), QItemSelectionModel::ClearAndSelect); - view->tst_visualRegionForSelection(QItemSelection()); - view->tst_selectedIndexes(); + view->setSelection(QRect(0, 0, 10, 10), QItemSelectionModel::ClearAndSelect); + view->setSelection(QRect(-1, -1, -1, -1), QItemSelectionModel::ClearAndSelect); + view->visualRegionForSelection(QItemSelection()); + view->selectedIndexes(); - view->tst_edit(QModelIndex(), QAbstractItemView::NoEditTriggers, 0); + view->edit(QModelIndex(), QAbstractItemView::NoEditTriggers, 0); - view->tst_selectionCommand(QModelIndex(), 0); + view->selectionCommand(QModelIndex(), 0); #ifndef QT_NO_DRAGANDDROP if (!view->model()) - view->tst_startDrag(Qt::CopyAction); - - view->tst_viewOptions(); - - view->tst_setState(TestView::NoState); - QVERIFY(view->tst_state()==TestView::NoState); - view->tst_setState(TestView::DraggingState); - QVERIFY(view->tst_state()==TestView::DraggingState); - view->tst_setState(TestView::DragSelectingState); - QVERIFY(view->tst_state()==TestView::DragSelectingState); - view->tst_setState(TestView::EditingState); - QVERIFY(view->tst_state()==TestView::EditingState); - view->tst_setState(TestView::ExpandingState); - QVERIFY(view->tst_state()==TestView::ExpandingState); - view->tst_setState(TestView::CollapsingState); - QVERIFY(view->tst_state()==TestView::CollapsingState); + view->startDrag(Qt::CopyAction); + + view->viewOptions(); + + view->setState(QAbstractItemView::NoState); + QVERIFY(view->state()==QAbstractItemView::NoState); + view->setState(QAbstractItemView::DraggingState); + QVERIFY(view->state()==QAbstractItemView::DraggingState); + view->setState(QAbstractItemView::DragSelectingState); + QVERIFY(view->state()==QAbstractItemView::DragSelectingState); + view->setState(QAbstractItemView::EditingState); + QVERIFY(view->state()==QAbstractItemView::EditingState); + view->setState(QAbstractItemView::ExpandingState); + QVERIFY(view->state()==QAbstractItemView::ExpandingState); + view->setState(QAbstractItemView::CollapsingState); + QVERIFY(view->state()==QAbstractItemView::CollapsingState); #endif - view->tst_startAutoScroll(); - view->tst_stopAutoScroll(); - view->tst_doAutoScroll(); + view->startAutoScroll(); + view->stopAutoScroll(); + view->doAutoScroll(); // testing mouseFoo and key functions // QTest::mousePress(view, Qt::LeftButton, Qt::NoModifier, QPoint(0,0)); @@ -760,11 +658,11 @@ void tst_QAbstractItemView::selectAll() QTableView view; view.setModel(&model); - TestView *tst_view = (TestView*)&view; + QAbstractItemView *tst_view = &view; - QCOMPARE(tst_view->tst_selectedIndexes().count(), 0); + QCOMPARE(tst_view->selectedIndexes().count(), 0); view.selectAll(); - QCOMPARE(tst_view->tst_selectedIndexes().count(), 4*4); + QCOMPARE(tst_view->selectedIndexes().count(), 4*4); } void tst_QAbstractItemView::ctrlA() @@ -773,11 +671,11 @@ void tst_QAbstractItemView::ctrlA() QTableView view; view.setModel(&model); - TestView *tst_view = (TestView*)&view; + QAbstractItemView *tst_view = &view; - QCOMPARE(tst_view->tst_selectedIndexes().count(), 0); + QCOMPARE(tst_view->selectedIndexes().count(), 0); QTest::keyClick(&view, Qt::Key_A, Qt::ControlModifier); - QCOMPARE(tst_view->tst_selectedIndexes().count(), 4*4); + QCOMPARE(tst_view->selectedIndexes().count(), 4*4); } void tst_QAbstractItemView::persistentEditorFocus() @@ -1590,9 +1488,9 @@ void tst_QAbstractItemView::testDelegateDestroyEditor() MyAbstractItemDelegate delegate; table.setItemDelegate(&delegate); table.edit(table.model()->index(1, 1)); - TestView *tv = reinterpret_cast<TestView*>(&table); + QAbstractItemView *tv = &table; QVERIFY(!delegate.calledVirtualDtor); - tv->tst_closeEditor(delegate.openedEditor, QAbstractItemDelegate::NoHint); + tv->closeEditor(delegate.openedEditor, QAbstractItemDelegate::NoHint); QVERIFY(delegate.calledVirtualDtor); } @@ -2069,11 +1967,18 @@ void tst_QAbstractItemView::QTBUG50535_update_on_new_selection_model() { public: ListView() - : m_paintEventsCount(0) + : m_paintEventsCount(0), m_deselectedMustBeEmpty(false), m_selectionChangedOk(true) { } + void setSelectionModel(QItemSelectionModel *model) Q_DECL_OVERRIDE + { + m_deselectedMustBeEmpty = !selectionModel() || !model || selectionModel()->model() != model->model(); + QListView::setSelectionModel(model); + m_deselectedMustBeEmpty = false; + } int m_paintEventsCount; + bool selectionChangedOk() const { return m_selectionChangedOk; } protected: bool viewportEvent(QEvent *event) Q_DECL_OVERRIDE @@ -2082,6 +1987,24 @@ void tst_QAbstractItemView::QTBUG50535_update_on_new_selection_model() ++m_paintEventsCount; return QListView::viewportEvent(event); } + + void selectionChanged(const QItemSelection &selected, + const QItemSelection &deselected) Q_DECL_OVERRIDE + { + if (m_deselectedMustBeEmpty && !deselected.isEmpty()) + m_selectionChangedOk = false; + + // Make sure both selections belong to the same model + foreach (const QModelIndex &nmi, selected.indexes()) { + foreach (const QModelIndex &omi, deselected.indexes()) { + m_selectionChangedOk = m_selectionChangedOk && (nmi.model() == omi.model()); + } + } + QListView::selectionChanged(selected, deselected); + } + private: + bool m_deselectedMustBeEmpty; + bool m_selectionChangedOk; }; // keep the current/selected row in the "low range", i.e. be sure it's visible, otherwise we @@ -2092,7 +2015,7 @@ void tst_QAbstractItemView::QTBUG50535_update_on_new_selection_model() view.selectionModel()->setCurrentIndex(model.index(1, 0), QItemSelectionModel::SelectCurrent); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); - + QVERIFY(view.selectionChangedOk()); QItemSelectionModel selectionModel(&model); selectionModel.setCurrentIndex(model.index(2, 0), QItemSelectionModel::Current); @@ -2100,6 +2023,7 @@ void tst_QAbstractItemView::QTBUG50535_update_on_new_selection_model() int oldPaintEventsCount = view.m_paintEventsCount; view.setSelectionModel(&selectionModel); QTRY_VERIFY(view.m_paintEventsCount > oldPaintEventsCount); + QVERIFY(view.selectionChangedOk()); QItemSelectionModel selectionModel2(&model); @@ -2109,6 +2033,19 @@ void tst_QAbstractItemView::QTBUG50535_update_on_new_selection_model() oldPaintEventsCount = view.m_paintEventsCount; view.setSelectionModel(&selectionModel2); QTRY_VERIFY(view.m_paintEventsCount > oldPaintEventsCount); + QVERIFY(view.selectionChangedOk()); + + // Tests QAbstractItemView::selectionChanged + QStandardItemModel model1; + for (int i = 0; i < 10; ++i) + model1.appendRow(new QStandardItem(QString::number(i))); + view.setModel(&model1); + + QItemSelectionModel selectionModel1(&model1); + selectionModel1.select(model1.index(0, 0), QItemSelectionModel::ClearAndSelect); + selectionModel1.setCurrentIndex(model1.index(1, 0), QItemSelectionModel::Current); + view.setSelectionModel(&selectionModel1); + QVERIFY(view.selectionChangedOk()); } void tst_QAbstractItemView::testSelectionModelInSyncWithView() diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index bc8b08997f..32a324b888 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -2991,6 +2991,11 @@ void tst_QHeaderView::stretchAndRestoreLastSection() header.swapSections(1, 11); QCOMPARE(header.sectionSize(1), someOtherSectionSize); + // Clear and re-add. This triggers a different code path than seColumnCount(0) + m.clear(); + m.setColumnCount(3); + QVERIFY(header.sectionSize(2) >= biggerSizeThanAnySection); + // Test import/export of the original (not stretched) sectionSize. m.setColumnCount(0); m.setColumnCount(10); diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 81ce1deca4..c7b7ffaf95 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -31,7 +31,7 @@ #include <QtTest/QtTest> #include <QtGui/QtGui> #include <QtWidgets/QtWidgets> -#include <private/qabstractitemview_p.h> +#include <private/qtreeview_p.h> #ifndef QT_NO_DRAGANDDROP Q_DECLARE_METATYPE(QAbstractItemView::DragDropMode) @@ -57,49 +57,6 @@ static void initStandardTreeModel(QStandardItemModel *model) model->insertRow(2, item); } -class tst_QTreeView; -struct PublicView : public QTreeView -{ - friend class tst_QTreeView; - inline void executeDelayedItemsLayout() - { QTreeView::executeDelayedItemsLayout(); } - - enum PublicCursorAction { - MoveUp = QAbstractItemView::MoveUp, - MoveDown = QAbstractItemView::MoveDown, - MoveLeft = QAbstractItemView::MoveLeft, - MoveRight = QAbstractItemView::MoveRight, - MoveHome = QAbstractItemView::MoveHome, - MoveEnd = QAbstractItemView::MoveEnd, - MovePageUp = QAbstractItemView::MovePageUp, - MovePageDown = QAbstractItemView::MovePageDown, - MoveNext = QAbstractItemView::MoveNext, - MovePrevious = QAbstractItemView::MovePrevious - }; - - // enum PublicCursorAction and moveCursor() are protected in QTreeView. - inline QModelIndex doMoveCursor(PublicCursorAction ca, Qt::KeyboardModifiers kbm) - { return QTreeView::moveCursor((CursorAction)ca, kbm); } - - inline void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) - { - QTreeView::setSelection(rect, command); - } - inline int state() - { - return QTreeView::state(); - } - - inline int rowHeight(QModelIndex idx) { return QTreeView::rowHeight(idx); } - inline int indexRowSizeHint(const QModelIndex &index) const { return QTreeView::indexRowSizeHint(index); } - - inline QModelIndexList selectedIndexes() const { return QTreeView::selectedIndexes(); } - - inline QStyleOptionViewItem viewOptions() const { return QTreeView::viewOptions(); } - inline int sizeHintForColumn(int column) const { return QTreeView::sizeHintForColumn(column); } - QAbstractItemViewPrivate* aiv_priv() { return static_cast<QAbstractItemViewPrivate*>(d_ptr.data()); } -}; - // Make a widget frameless to prevent size constraints of title bars // from interfering (Windows). static inline void setFrameless(QWidget *w) @@ -631,33 +588,34 @@ void tst_QTreeView::dragDropModeFromDragEnabledAndAcceptDrops_data() QTest::addColumn<bool>("dragEnabled"); QTest::addColumn<bool>("acceptDrops"); QTest::addColumn<QAbstractItemView::DragDropMode>("dragDropMode"); - QTest::addColumn<QAbstractItemView::DragDropMode>("setBehavior"); - - QTest::newRow("NoDragDrop -1") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DragDropMode(-1); - QTest::newRow("NoDragDrop 0") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::NoDragDrop; - QTest::newRow("NoDragDrop 1") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DragOnly; - QTest::newRow("NoDragDrop 2") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DropOnly; - QTest::newRow("NoDragDrop 3") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DragDrop; - QTest::newRow("NoDragDrop 4") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::InternalMove; - QTest::newRow("DragOnly -1") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DragDropMode(-1); - QTest::newRow("DragOnly 0") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::NoDragDrop; - QTest::newRow("DragOnly 1") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DragOnly; - QTest::newRow("DragOnly 2") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DropOnly; - QTest::newRow("DragOnly 3") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DragDrop; - QTest::newRow("DragOnly 4") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::InternalMove; - QTest::newRow("DropOnly -1") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DragDropMode(-1); - QTest::newRow("DropOnly 0") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::NoDragDrop; - QTest::newRow("DropOnly 1") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DragOnly; - QTest::newRow("DropOnly 2") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DropOnly; - QTest::newRow("DropOnly 3") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DragDrop; - QTest::newRow("DropOnly 4") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::InternalMove; - QTest::newRow("DragDrop -1") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragDropMode(-1); - QTest::newRow("DragDrop 0") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragDropMode(-1); - QTest::newRow("DragDrop 1") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::NoDragDrop; - QTest::newRow("DragDrop 2") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragOnly; - QTest::newRow("DragDrop 3") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DropOnly; - QTest::newRow("DragDrop 4") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragDrop; - QTest::newRow("DragDrop 5") << true << true << QAbstractItemView::InternalMove << QAbstractItemView::InternalMove; + QTest::addColumn<bool>("setBehavior"); + QTest::addColumn<QAbstractItemView::DragDropMode>("behavior"); + + QTest::newRow("NoDragDrop -1") << false << false << QAbstractItemView::NoDragDrop << false << QAbstractItemView::DragDropMode(); + QTest::newRow("NoDragDrop 0") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::NoDragDrop; + QTest::newRow("NoDragDrop 1") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::DragOnly; + QTest::newRow("NoDragDrop 2") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::DropOnly; + QTest::newRow("NoDragDrop 3") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::DragDrop; + QTest::newRow("NoDragDrop 4") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::InternalMove; + QTest::newRow("DragOnly -1") << true << false << QAbstractItemView::DragOnly << false << QAbstractItemView::DragDropMode(); + QTest::newRow("DragOnly 0") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::NoDragDrop; + QTest::newRow("DragOnly 1") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::DragOnly; + QTest::newRow("DragOnly 2") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::DropOnly; + QTest::newRow("DragOnly 3") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::DragDrop; + QTest::newRow("DragOnly 4") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::InternalMove; + QTest::newRow("DropOnly -1") << false << true << QAbstractItemView::DropOnly << false << QAbstractItemView::DragDropMode(); + QTest::newRow("DropOnly 0") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::NoDragDrop; + QTest::newRow("DropOnly 1") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::DragOnly; + QTest::newRow("DropOnly 2") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::DropOnly; + QTest::newRow("DropOnly 3") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::DragDrop; + QTest::newRow("DropOnly 4") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::InternalMove; + QTest::newRow("DragDrop -1") << true << true << QAbstractItemView::DragDrop << false << QAbstractItemView::DragDropMode(); + QTest::newRow("DragDrop 0") << true << true << QAbstractItemView::DragDrop << false << QAbstractItemView::DragDropMode(); + QTest::newRow("DragDrop 1") << true << true << QAbstractItemView::DragDrop << true << QAbstractItemView::NoDragDrop; + QTest::newRow("DragDrop 2") << true << true << QAbstractItemView::DragDrop << true << QAbstractItemView::DragOnly; + QTest::newRow("DragDrop 3") << true << true << QAbstractItemView::DragDrop << true << QAbstractItemView::DropOnly; + QTest::newRow("DragDrop 4") << true << true << QAbstractItemView::DragDrop << true << QAbstractItemView::DragDrop; + QTest::newRow("DragDrop 5") << true << true << QAbstractItemView::InternalMove << true << QAbstractItemView::InternalMove; } void tst_QTreeView::dragDropModeFromDragEnabledAndAcceptDrops() @@ -665,13 +623,14 @@ void tst_QTreeView::dragDropModeFromDragEnabledAndAcceptDrops() QFETCH(bool, acceptDrops); QFETCH(bool, dragEnabled); QFETCH(QAbstractItemView::DragDropMode, dragDropMode); - QFETCH(QAbstractItemView::DragDropMode, setBehavior); + QFETCH(bool, setBehavior); + QFETCH(QAbstractItemView::DragDropMode, behavior); QTreeView view; QCOMPARE(view.dragDropMode(), QAbstractItemView::NoDragDrop); - if (setBehavior != QAbstractItemView::DragDropMode(-1)) - view.setDragDropMode(setBehavior); + if (setBehavior) + view.setDragDropMode(behavior); view.setAcceptDrops(acceptDrops); view.setDragEnabled(dragEnabled); @@ -1743,7 +1702,7 @@ void tst_QTreeView::moveCursor() QFETCH(bool, scrollPerPixel); QtTestModel model(8, 6); - PublicView view; + QTreeView view; view.setUniformRowHeights(uniformRowHeights); view.setModel(&model); view.setRowHidden(0, QModelIndex(), true); @@ -1762,7 +1721,7 @@ void tst_QTreeView::moveCursor() QCOMPARE(view.currentIndex(), expected); //then pressing down should go to the next line - QModelIndex actual = view.doMoveCursor(PublicView::MoveDown, Qt::NoModifier); + QModelIndex actual = view.moveCursor(QTreeView::MoveDown, Qt::NoModifier); expected = model.index(2, 1, QModelIndex()); QCOMPARE(actual, expected); @@ -1771,7 +1730,7 @@ void tst_QTreeView::moveCursor() // PageUp was broken with uniform row heights turned on view.setCurrentIndex(model.index(1, 0)); - actual = view.doMoveCursor(PublicView::MovePageUp, Qt::NoModifier); + actual = view.moveCursor(QTreeView::MovePageUp, Qt::NoModifier); expected = model.index(0, 0, QModelIndex()); QCOMPARE(actual, expected); @@ -1870,7 +1829,7 @@ void tst_QTreeView::setSelection() QtTestModel model(10, 5); model.levels = 1; model.setDecorationsEnabled(true); - PublicView view; + QTreeView view; view.resize(400, 300); view.show(); view.setRootIsDecorated(false); @@ -2058,7 +2017,7 @@ void tst_QTreeView::rowsAboutToBeRemoved() } } - PublicView view; + QTreeView view; view.setModel(&model); view.show(); QModelIndex index = model.index(0,0, QModelIndex()); @@ -2072,7 +2031,7 @@ void tst_QTreeView::rowsAboutToBeRemoved() QSignalSpy spy1(&model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); model.removeRows(1,1); - QCOMPARE(view.state(), 0); + QCOMPARE(int(view.state()), 0); // Should not be 5 (or any other number for that sake :) QCOMPARE(spy1.count(), 1); @@ -2175,7 +2134,7 @@ void tst_QTreeView::rowsAboutToBeRemoved_move() view.resize(600,800); view.show(); view.doItemsLayout(); - static_cast<PublicView *>(&view)->executeDelayedItemsLayout(); + static_cast<QTreeView *>(&view)->executeDelayedItemsLayout(); parent = indexThatWantsToLiveButWillDieDieITellYou.parent(); QCOMPARE(view.isExpanded(indexThatWantsToLiveButWillDieDieITellYou), true); QCOMPARE(parent.isValid(), true); @@ -2283,7 +2242,7 @@ void tst_QTreeView::spanningItems() { QtTestModel model; model.rows = model.cols = 10; - PublicView view; + QTreeView view; view.setModel(&model); view.show(); @@ -2422,7 +2381,7 @@ void tst_QTreeView::selectionWithHiddenItems() void tst_QTreeView::selectAll() { QStandardItemModel model(4,4); - PublicView view2; + QTreeView view2; view2.setModel(&model); view2.setSelectionMode(QAbstractItemView::ExtendedSelection); view2.selectAll(); // Should work with an empty model @@ -2431,13 +2390,13 @@ void tst_QTreeView::selectAll() for (int i = 0; i < model.rowCount(); ++i) model.setData(model.index(i,0), QLatin1String("row ") + QString::number(i)); - PublicView view; + QTreeView view; view.setModel(&model); int selectedCount = view.selectedIndexes().count(); view.selectAll(); QCOMPARE(view.selectedIndexes().count(), selectedCount); - PublicView view3; + QTreeView view3; view3.setModel(&model); view3.setSelectionMode(QAbstractItemView::NoSelection); view3.selectAll(); @@ -2800,7 +2759,7 @@ void tst_QTreeView::evilModel() { QFETCH(bool, visible); // init - PublicView view; + QTreeView view; EvilModel model; view.setModel(&model); view.setVisible(visible); @@ -2858,7 +2817,7 @@ void tst_QTreeView::evilModel() view.setSelection(rect, QItemSelectionModel::Select); model.change(); - view.doMoveCursor(PublicView::MoveDown, Qt::NoModifier); + view.moveCursor(QTreeView::MoveDown, Qt::NoModifier); model.change(); view.resizeColumnToContents(1); @@ -2969,7 +2928,7 @@ void tst_QTreeView::evilModel() void tst_QTreeView::indexRowSizeHint() { QStandardItemModel model(10, 1); - PublicView view; + QTreeView view; view.setModel(&model); @@ -3015,7 +2974,7 @@ void tst_QTreeView::renderToPixmap_data() void tst_QTreeView::renderToPixmap() { QFETCH(int, row); - PublicView view; + QTreeView view; QStandardItemModel model; model.appendRow(new QStandardItem("Spanning")); @@ -3031,7 +2990,7 @@ void tst_QTreeView::renderToPixmap() // We select the index at row=1 for coverage. QItemSelection sel(model.index(row,0), model.index(row,1)); QRect rect; - view.aiv_priv()->renderToPixmap(sel.indexes(), &rect); + view.d_func()->renderToPixmap(sel.indexes(), &rect); } #endif } @@ -3093,7 +3052,7 @@ void tst_QTreeView::styleOptionViewItem() bool allCollapsed; }; - PublicView view; + QTreeView view; QStandardItemModel model; view.setModel(&model); MyDelegate delegate; @@ -3149,7 +3108,7 @@ void tst_QTreeView::styleOptionViewItem() delegate.count = 0; QItemSelection sel(model.index(0,0), model.index(0,modelColumns-1)); QRect rect; - view.aiv_priv()->renderToPixmap(sel.indexes(), &rect); + view.d_func()->renderToPixmap(sel.indexes(), &rect); if (delegate.count != visibleColumns) { qDebug() << rect << view.rect() << view.isVisible(); } @@ -3177,7 +3136,7 @@ void tst_QTreeView::styleOptionViewItem() delegate.count = 0; QItemSelection sel(model.index(0,0), model.index(0,modelColumns-1)); QRect rect; - view.aiv_priv()->renderToPixmap(sel.indexes(), &rect); + view.d_func()->renderToPixmap(sel.indexes(), &rect); if (delegate.count != visibleColumns) { qDebug() << rect << view.rect() << view.isVisible(); } @@ -4139,7 +4098,7 @@ void tst_QTreeView::taskQTBUG_13567_removeLastItemRegression() // Note: define QT_BUILD_INTERNAL to run this test void tst_QTreeView::taskQTBUG_25333_adjustViewOptionsForIndex() { - PublicView view; + QTreeView view; QStandardItemModel model; QStandardItem *item1 = new QStandardItem("Item1"); QStandardItem *item2 = new QStandardItem("Item2"); @@ -4165,9 +4124,9 @@ void tst_QTreeView::taskQTBUG_25333_adjustViewOptionsForIndex() { QStyleOptionViewItem option; - view.aiv_priv()->adjustViewOptionsForIndex(&option, model.indexFromItem(item1)); + view.d_func()->adjustViewOptionsForIndex(&option, model.indexFromItem(item1)); - view.aiv_priv()->adjustViewOptionsForIndex(&option, model.indexFromItem(item3)); + view.d_func()->adjustViewOptionsForIndex(&option, model.indexFromItem(item3)); } #endif @@ -4273,7 +4232,7 @@ void tst_QTreeView::quickExpandCollapse() //this unit tests makes sure the state after the animation is restored correctly //after starting a 2nd animation while the first one was still on-going //this tests that the stateBeforeAnimation is not set to AnimatingState - PublicView tree; + QTreeView tree; tree.setAnimated(true); QStandardItemModel model; QStandardItem *root = new QStandardItem("root"); @@ -4287,13 +4246,13 @@ void tst_QTreeView::quickExpandCollapse() tree.show(); QTest::qWaitForWindowExposed(&tree); - int initialState = tree.state(); + const QAbstractItemView::State initialState = tree.state(); tree.expand(rootIndex); - QCOMPARE(tree.state(), (int)PublicView::AnimatingState); + QCOMPARE(tree.state(), QTreeView::AnimatingState); tree.collapse(rootIndex); - QCOMPARE(tree.state(), (int)PublicView::AnimatingState); + QCOMPARE(tree.state(), QTreeView::AnimatingState); QTest::qWait(500); //the animation lasts for 250ms max so 500 should be enough |