Merge remote-tracking branch 'origin/5.7' into dev

Change-Id: I36e6b890b65d12bf6931757540bcc9c553b5eb8f
This commit is contained in:
Liang Qi 2016-08-09 17:59:51 +02:00
commit 22e96c4d34
64 changed files with 1197 additions and 707 deletions

View File

@ -70,7 +70,7 @@
\title Qt Quarterly: Another Look at Events \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 \title Livecoding video effects with Qt5
*/ */
/*! /*!

View File

@ -55,8 +55,8 @@ RasterWindow::RasterWindow(QWindow *parent)
: QWindow(parent) : QWindow(parent)
, m_update_pending(false) , m_update_pending(false)
{ {
m_backingStore = new QBackingStore(this);
create(); create();
m_backingStore = new QBackingStore(this);
setGeometry(100, 100, 300, 200); setGeometry(100, 100, 300, 200);

View File

@ -52,51 +52,72 @@
#include "window.h" #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] //! [0]
Window::Window(QWidget *parent) Window::Window(QWidget *parent)
: QWidget(parent) : QWidget(parent)
{ {
browseButton = new QPushButton(tr("&Browse..."), this); QPushButton *browseButton = new QPushButton(tr("&Browse..."), this);
connect(browseButton, &QAbstractButton::clicked, this, &Window::browse); connect(browseButton, &QAbstractButton::clicked, this, &Window::browse);
findButton = new QPushButton(tr("&Find"), this); findButton = new QPushButton(tr("&Find"), this);
connect(findButton, &QAbstractButton::clicked, this, &Window::find); connect(findButton, &QAbstractButton::clicked, this, &Window::find);
fileComboBox = createComboBox(tr("*")); fileComboBox = createComboBox(tr("*"));
connect(fileComboBox->lineEdit(), &QLineEdit::returnPressed,
this, &Window::animateFindClick);
textComboBox = createComboBox(); 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; filesFoundLabel = new QLabel;
createFilesTable(); createFilesTable();
//! [0] //! [0]
//! [1] //! [1]
QGridLayout *mainLayout = new QGridLayout; QGridLayout *mainLayout = new QGridLayout(this);
mainLayout->addWidget(fileLabel, 0, 0); mainLayout->addWidget(new QLabel(tr("Named:")), 0, 0);
mainLayout->addWidget(fileComboBox, 0, 1, 1, 2); 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(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(directoryComboBox, 2, 1);
mainLayout->addWidget(browseButton, 2, 2); mainLayout->addWidget(browseButton, 2, 2);
mainLayout->addWidget(filesTable, 3, 0, 1, 3); mainLayout->addWidget(filesTable, 3, 0, 1, 3);
mainLayout->addWidget(filesFoundLabel, 4, 0, 1, 2); mainLayout->addWidget(filesFoundLabel, 4, 0, 1, 2);
mainLayout->addWidget(findButton, 4, 2); mainLayout->addWidget(findButton, 4, 2);
setLayout(mainLayout);
setWindowTitle(tr("Find Files")); setWindowTitle(tr("Find Files"));
resize(700, 300); const QRect screenGeometry = QApplication::desktop()->screenGeometry(this);
resize(screenGeometry.width() / 2, screenGeometry.height() / 3);
} }
//! [1] //! [1]
//! [2] //! [2]
void Window::browse() void Window::browse()
{ {
QString directory = QFileDialog::getExistingDirectory(this, QString directory =
tr("Find Files"), QDir::currentPath()); QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this, tr("Find Files"), QDir::currentPath()));
if (!directory.isEmpty()) { if (!directory.isEmpty()) {
if (directoryComboBox->findText(directory) == -1) if (directoryComboBox->findText(directory) == -1)
@ -112,14 +133,28 @@ static void updateComboBox(QComboBox *comboBox)
comboBox->addItem(comboBox->currentText()); 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] //! [3]
void Window::find() void Window::find()
{ {
filesTable->setRowCount(0); filesTable->setRowCount(0);
QString fileName = fileComboBox->currentText(); QString fileName = fileComboBox->currentText();
QString text = textComboBox->currentText(); QString text = textComboBox->currentText();
QString path = directoryComboBox->currentText(); QString path = QDir::cleanPath(directoryComboBox->currentText());
//! [3] //! [3]
updateComboBox(fileComboBox); updateComboBox(fileComboBox);
@ -127,19 +162,21 @@ void Window::find()
updateComboBox(directoryComboBox); updateComboBox(directoryComboBox);
//! [4] //! [4]
currentDir = QDir(path); currentDir = QDir(path);
QStringList files; QStringList files;
if (fileName.isEmpty()) findRecursion(path, fileName.isEmpty() ? QStringLiteral("*") : fileName, &files);
fileName = "*";
files = currentDir.entryList(QStringList(fileName),
QDir::Files | QDir::NoSymLinks);
if (!text.isEmpty()) if (!text.isEmpty())
files = findFiles(files, text); files = findFiles(files, text);
showFiles(files); showFiles(files);
} }
//! [4] //! [4]
void Window::animateFindClick()
{
findButton->animateClick();
}
//! [5] //! [5]
QStringList Window::findFiles(const QStringList &files, const QString &text) 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")); progressDialog.setWindowTitle(tr("Find Files"));
//! [5] //! [6] //! [5] //! [6]
QMimeDatabase mimeDatabase;
QStringList foundFiles; QStringList foundFiles;
for (int i = 0; i < files.size(); ++i) { for (int i = 0; i < files.size(); ++i) {
progressDialog.setValue(i); progressDialog.setValue(i);
progressDialog.setLabelText(tr("Searching file number %1 of %2...") progressDialog.setLabelText(tr("Searching file number %1 of %n...", 0, files.size()).arg(i));
.arg(i).arg(files.size())); QCoreApplication::processEvents();
qApp->processEvents();
//! [6] //! [6]
if (progressDialog.wasCanceled()) if (progressDialog.wasCanceled())
break; break;
//! [7] //! [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)) { if (file.open(QIODevice::ReadOnly)) {
QString line; QString line;
QTextStream in(&file); QTextStream in(&file);
@ -171,7 +213,7 @@ QStringList Window::findFiles(const QStringList &files, const QString &text)
if (progressDialog.wasCanceled()) if (progressDialog.wasCanceled())
break; break;
line = in.readLine(); line = in.readLine();
if (line.contains(text)) { if (line.contains(text, Qt::CaseInsensitive)) {
foundFiles << files[i]; foundFiles << files[i];
break; break;
} }
@ -186,13 +228,18 @@ QStringList Window::findFiles(const QStringList &files, const QString &text)
void Window::showFiles(const QStringList &files) void Window::showFiles(const QStringList &files)
{ {
for (int i = 0; i < files.size(); ++i) { for (int i = 0; i < files.size(); ++i) {
QFile file(currentDir.absoluteFilePath(files[i])); const QString &fileName = files.at(i);
qint64 size = QFileInfo(file).size(); const QString toolTip = QDir::toNativeSeparators(fileName);
const QString relativePath = QDir::toNativeSeparators(currentDir.relativeFilePath(fileName));
QTableWidgetItem *fileNameItem = new QTableWidgetItem(files[i]); 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); fileNameItem->setFlags(fileNameItem->flags() ^ Qt::ItemIsEditable);
QTableWidgetItem *sizeItem = new QTableWidgetItem(tr("%1 KB") QTableWidgetItem *sizeItem = new QTableWidgetItem(tr("%1 KB")
.arg(int((size + 1023) / 1024))); .arg(int((size + 1023) / 1024)));
sizeItem->setData(absoluteFileNameRole, QVariant(fileName));
sizeItem->setToolTip(toolTip);
sizeItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); sizeItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
sizeItem->setFlags(sizeItem->flags() ^ Qt::ItemIsEditable); sizeItem->setFlags(sizeItem->flags() ^ Qt::ItemIsEditable);
@ -201,8 +248,7 @@ void Window::showFiles(const QStringList &files)
filesTable->setItem(row, 0, fileNameItem); filesTable->setItem(row, 0, fileNameItem);
filesTable->setItem(row, 1, sizeItem); filesTable->setItem(row, 1, sizeItem);
} }
filesFoundLabel->setText(tr("%1 file(s) found").arg(files.size()) + filesFoundLabel->setText(tr("%n file(s) found (Double click on a file to open it)", 0, files.size()));
(" (Double click on a file to open it)"));
filesFoundLabel->setWordWrap(true); filesFoundLabel->setWordWrap(true);
} }
//! [8] //! [8]
@ -230,20 +276,43 @@ void Window::createFilesTable()
filesTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); filesTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
filesTable->verticalHeader()->hide(); filesTable->verticalHeader()->hide();
filesTable->setShowGrid(false); filesTable->setShowGrid(false);
//! [15]
filesTable->setContextMenuPolicy(Qt::CustomContextMenu);
connect(filesTable, &QTableWidget::customContextMenuRequested,
this, &Window::contextMenu);
connect(filesTable, &QTableWidget::cellActivated, connect(filesTable, &QTableWidget::cellActivated,
this, &Window::openFileOfItem); this, &Window::openFileOfItem);
//! [15]
} }
//! [11] //! [11]
//! [12] //! [12]
void Window::openFileOfItem(int row, int /* column */) void Window::openFileOfItem(int row, int /* column */)
{ {
QTableWidgetItem *item = filesTable->item(row, 0); const QTableWidgetItem *item = filesTable->item(row, 0);
openFile(fileNameOfItem(item));
QDesktopServices::openUrl(QUrl::fromLocalFile(currentDir.absoluteFilePath(item->text())));
} }
//! [12] //! [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]

View File

@ -73,7 +73,9 @@ public:
private slots: private slots:
void browse(); void browse();
void find(); void find();
void animateFindClick();
void openFileOfItem(int row, int column); void openFileOfItem(int row, int column);
void contextMenu(const QPoint &pos);
private: private:
QStringList findFiles(const QStringList &files, const QString &text); QStringList findFiles(const QStringList &files, const QString &text);
@ -84,11 +86,7 @@ private:
QComboBox *fileComboBox; QComboBox *fileComboBox;
QComboBox *textComboBox; QComboBox *textComboBox;
QComboBox *directoryComboBox; QComboBox *directoryComboBox;
QLabel *fileLabel;
QLabel *textLabel;
QLabel *directoryLabel;
QLabel *filesFoundLabel; QLabel *filesFoundLabel;
QPushButton *browseButton;
QPushButton *findButton; QPushButton *findButton;
QTableWidget *filesTable; QTableWidget *filesTable;

View File

@ -120,10 +120,12 @@
\snippet dialogs/findfiles/window.cpp 4 \snippet dialogs/findfiles/window.cpp 4
We use the directory's path to create a QDir; the QDir class We use the directory's path to create a QDir; the QDir class
provides access to directory structures and their contents. We provides access to directory structures and their contents.
create a list of the files (contained in the newly created QDir)
that match the specified file name. If the file name is empty \snippet dialogs/findfiles/window.cpp 13
the list will contain all the files in the directory.
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 Then we search through all the files in the list, using the private
\c findFiles() function, eliminating the ones that don't contain \c findFiles() function, eliminating the ones that don't contain
@ -173,9 +175,7 @@
\snippet dialogs/findfiles/window.cpp 7 \snippet dialogs/findfiles/window.cpp 7
After updating the QProgressDialog, we create a QFile using the After updating the QProgressDialog, we open the file in read-only
QDir::absoluteFilePath() function which returns the absolute path
name of a file in the directory. We open the file in read-only
mode, and read one line at a time using QTextStream. mode, and read one line at a time using QTextStream.
The QTextStream class provides a convenient interface for reading The QTextStream class provides a convenient interface for reading
@ -194,9 +194,18 @@
Both the \c findFiles() and \c showFiles() functions are called from Both the \c findFiles() and \c showFiles() functions are called from
the \c find() slot. In the \c showFiles() function we run through 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 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. We also update the total number of files found.
@ -236,8 +245,19 @@
\snippet dialogs/findfiles/window.cpp 12 \snippet dialogs/findfiles/window.cpp 12
\snippet dialogs/findfiles/window.cpp 14
The \c openFileOfItem() slot is invoked when the user double The \c openFileOfItem() slot is invoked when the user double
clicks on a cell in the table. The QDesktopServices::openUrl() clicks on a cell in the table. The QDesktopServices::openUrl()
knows how to open a file given the file name. 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.
*/ */

View File

@ -55,8 +55,8 @@
MainWindow::MainWindow() MainWindow::MainWindow()
{ {
textEdit = new QTextEdit; textEdit = new QPlainTextEdit;
textEdit->setLineWrapMode(QTextEdit::NoWrap); textEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
setCentralWidget(textEdit); setCentralWidget(textEdit);
findCodecs(); findCodecs();
@ -64,54 +64,57 @@ MainWindow::MainWindow()
previewForm = new PreviewForm(this); previewForm = new PreviewForm(this);
previewForm->setCodecList(codecs); previewForm->setCodecList(codecs);
createActions();
createMenus(); createMenus();
setWindowTitle(tr("Codecs")); setWindowTitle(tr("Codecs"));
resize(500, 400);
const QRect screenGeometry = QApplication::desktop()->screenGeometry(this);
resize(screenGeometry.width() / 2, screenGeometry.height() * 2 / 3);
} }
void MainWindow::open() void MainWindow::open()
{ {
QString fileName = QFileDialog::getOpenFileName(this); const QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty()) { if (fileName.isEmpty())
QFile file(fileName); return;
if (!file.open(QFile::ReadOnly)) { QFile file(fileName);
QMessageBox::warning(this, tr("Codecs"), if (!file.open(QFile::ReadOnly)) {
tr("Cannot read file %1:\n%2") QMessageBox::warning(this, tr("Codecs"),
.arg(fileName) tr("Cannot read file %1:\n%2")
.arg(file.errorString())); .arg(QDir::toNativeSeparators(fileName),
return; file.errorString()));
} return;
QByteArray data = file.readAll();
previewForm->setEncodedData(data);
if (previewForm->exec())
textEdit->setPlainText(previewForm->decodedString());
} }
const QByteArray data = file.readAll();
previewForm->setWindowTitle(tr("Choose Encoding for %1").arg(QFileInfo(fileName).fileName()));
previewForm->setEncodedData(data);
if (previewForm->exec())
textEdit->setPlainText(previewForm->decodedString());
} }
void MainWindow::save() void MainWindow::save()
{ {
QString fileName = QFileDialog::getSaveFileName(this); const QAction *action = qobject_cast<const QAction *>(sender());
if (!fileName.isEmpty()) { const QByteArray codecName = action->data().toByteArray();
QFile file(fileName); const QString title = tr("Save As (%1)").arg(QLatin1String(codecName));
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()); QString fileName = QFileDialog::getSaveFileName(this, title);
QByteArray codecName = action->data().toByteArray(); if (fileName.isEmpty())
return;
QTextStream out(&file); QFile file(fileName);
out.setCodec(codecName.constData()); if (!file.open(QFile::WriteOnly | QFile::Text)) {
out << textEdit->toPlainText(); 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() void MainWindow::about()
@ -143,9 +146,9 @@ void MainWindow::findCodecs()
QString sortKey = codec->name().toUpper(); QString sortKey = codec->name().toUpper();
int rank; int rank;
if (sortKey.startsWith("UTF-8")) { if (sortKey.startsWith(QLatin1String("UTF-8"))) {
rank = 1; rank = 1;
} else if (sortKey.startsWith("UTF-16")) { } else if (sortKey.startsWith(QLatin1String("UTF-16"))) {
rank = 2; rank = 2;
} else if (iso8859RegExp.exactMatch(sortKey)) { } else if (iso8859RegExp.exactMatch(sortKey)) {
if (iso8859RegExp.cap(1).size() == 1) if (iso8859RegExp.cap(1).size() == 1)
@ -155,58 +158,38 @@ void MainWindow::findCodecs()
} else { } else {
rank = 5; rank = 5;
} }
sortKey.prepend(QChar('0' + rank)); sortKey.prepend(QLatin1Char('0' + rank));
codecMap.insert(sortKey, codec); codecMap.insert(sortKey, codec);
} }
codecs = codecMap.values(); 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); openAct->setShortcuts(QKeySequence::Open);
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
foreach (QTextCodec *codec, codecs) { QMenu *saveAsMenu = fileMenu->addMenu(tr("&Save As"));
QString text = tr("%1...").arg(QString(codec->name())); connect(saveAsMenu, &QMenu::aboutToShow,
this, &MainWindow::aboutToShowSaveAsMenu);
QAction *action = new QAction(text, this); foreach (const QTextCodec *codec, codecs) {
action->setData(codec->name()); const QByteArray name = codec->name();
connect(action, SIGNAL(triggered()), this, SLOT(save())); QAction *action = saveAsMenu->addAction(tr("%1...").arg(QLatin1String(name)));
action->setData(QVariant(name));
connect(action, &QAction::triggered, this, &MainWindow::save);
saveAsActs.append(action); 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->addSeparator();
fileMenu->addAction(exitAct); QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close);
exitAct->setShortcuts(QKeySequence::Quit);
helpMenu = new QMenu(tr("&Help"), this);
helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct);
menuBar()->addMenu(fileMenu);
menuBar()->addSeparator(); 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);
} }

View File

@ -56,9 +56,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QAction; class QAction;
class QMenu;
class QTextCodec; class QTextCodec;
class QTextEdit; class QPlainTextEdit;
QT_END_NAMESPACE QT_END_NAMESPACE
class PreviewForm; class PreviewForm;
@ -77,21 +76,12 @@ private slots:
private: private:
void findCodecs(); void findCodecs();
void createActions();
void createMenus(); void createMenus();
QTextEdit *textEdit; QList<QAction *> saveAsActs;
QPlainTextEdit *textEdit;
PreviewForm *previewForm; PreviewForm *previewForm;
QList<QTextCodec *> codecs; QList<QTextCodec *> codecs;
QMenu *fileMenu;
QMenu *helpMenu;
QMenu *saveAsMenu;
QAction *openAct;
QList<QAction *> saveAsActs;
QAction *exitAct;
QAction *aboutAct;
QAction *aboutQtAct;
}; };
#endif #endif

View File

@ -52,47 +52,159 @@
#include "previewform.h" #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) PreviewForm::PreviewForm(QWidget *parent)
: QDialog(parent) : QDialog(parent)
{ {
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
encodingComboBox = new QComboBox; encodingComboBox = new QComboBox;
encodingLabel = new QLabel(tr("&Encoding:")); QLabel *encodingLabel = new QLabel(tr("&Encoding:"));
encodingLabel->setBuddy(encodingComboBox); encodingLabel->setBuddy(encodingComboBox);
textEdit = new QTextEdit; textEdit = new QPlainTextEdit;
textEdit->setLineWrapMode(QTextEdit::NoWrap); textEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
textEdit->setReadOnly(true); 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 *buttonBox =
| QDialogButtonBox::Cancel); new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
okButton = buttonBox->button(QDialogButtonBox::Ok);
connect(encodingComboBox, SIGNAL(activated(int)), typedef void(QComboBox::*ComboBoxIntSignal)(int);
this, SLOT(updateTextEdit())); connect(encodingComboBox, static_cast<ComboBoxIntSignal>(&QComboBox::activated),
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); this, &PreviewForm::updateTextEdit);
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 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(encodingLabel, 0, 0);
mainLayout->addWidget(encodingComboBox, 0, 1); mainLayout->addWidget(encodingComboBox, 0, 1);
mainLayout->addWidget(textEdit, 1, 0, 1, 2); tabWidget = new QTabWidget;
mainLayout->addWidget(buttonBox, 2, 0, 1, 2); tabWidget->addTab(textEdit, tr("Preview"));
setLayout(mainLayout); 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")); const QRect screenGeometry = QApplication::desktop()->screenGeometry(this);
resize(400, 300); resize(screenGeometry.width() * 2 / 5, screenGeometry.height() / 2);
} }
void PreviewForm::setCodecList(const QList<QTextCodec *> &list) void PreviewForm::setCodecList(const QList<QTextCodec *> &list)
{ {
encodingComboBox->clear(); encodingComboBox->clear();
foreach (QTextCodec *codec, list) foreach (const QTextCodec *codec, list) {
encodingComboBox->addItem(codec->name(), codec->mibEnum()); 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) void PreviewForm::setEncodedData(const QByteArray &data)
{ {
reset();
encodedData = data; encodedData = data;
hexDumpEdit->setPlainText(formatHexDump(data));
updateTextEdit(); updateTextEdit();
} }
@ -100,12 +212,30 @@ void PreviewForm::updateTextEdit()
{ {
int mib = encodingComboBox->itemData( int mib = encodingComboBox->itemData(
encodingComboBox->currentIndex()).toInt(); encodingComboBox->currentIndex()).toInt();
QTextCodec *codec = QTextCodec::codecForMib(mib); const QTextCodec *codec = QTextCodec::codecForMib(mib);
const QString name = QLatin1String(codec->name());
QTextStream in(&encodedData); QTextCodec::ConverterState state;
in.setAutoDetectUnicode(false); decodedStr = codec->toUnicode(encodedData.constData(), encodedData.size(), &state);
in.setCodec(codec);
decodedStr = in.readAll();
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);
} }

View File

@ -58,8 +58,10 @@ QT_BEGIN_NAMESPACE
class QComboBox; class QComboBox;
class QDialogButtonBox; class QDialogButtonBox;
class QLabel; class QLabel;
class QPlainTextEdit;
class QPushButton;
class QTabWidget;
class QTextCodec; class QTextCodec;
class QTextEdit;
QT_END_NAMESPACE QT_END_NAMESPACE
class PreviewForm : public QDialog class PreviewForm : public QDialog
@ -67,7 +69,7 @@ class PreviewForm : public QDialog
Q_OBJECT Q_OBJECT
public: public:
PreviewForm(QWidget *parent = 0); explicit PreviewForm(QWidget *parent = Q_NULLPTR);
void setCodecList(const QList<QTextCodec *> &list); void setCodecList(const QList<QTextCodec *> &list);
void setEncodedData(const QByteArray &data); void setEncodedData(const QByteArray &data);
@ -77,13 +79,17 @@ private slots:
void updateTextEdit(); void updateTextEdit();
private: private:
void reset();
QByteArray encodedData; QByteArray encodedData;
QString decodedStr; QString decodedStr;
QPushButton *okButton;
QTabWidget *tabWidget;
QComboBox *encodingComboBox; QComboBox *encodingComboBox;
QLabel *encodingLabel; QPlainTextEdit *textEdit;
QTextEdit *textEdit; QPlainTextEdit *hexDumpEdit;
QDialogButtonBox *buttonBox; QLabel *statusLabel;
}; };
#endif #endif

View File

@ -54,11 +54,9 @@
//! [0] //! [0]
CharacterWidget::CharacterWidget(QWidget *parent) CharacterWidget::CharacterWidget(QWidget *parent)
: QWidget(parent) : QWidget(parent), columns(16), lastKey(-1)
{ {
squareSize = 24; calculateSquareSize();
columns = 16;
lastKey = -1;
setMouseTracking(true); setMouseTracking(true);
} }
//! [0] //! [0]
@ -67,7 +65,7 @@ CharacterWidget::CharacterWidget(QWidget *parent)
void CharacterWidget::updateFont(const QFont &font) void CharacterWidget::updateFont(const QFont &font)
{ {
displayFont.setFamily(font.family()); displayFont.setFamily(font.family());
squareSize = qMax(24, QFontMetrics(displayFont).xHeight() * 3); calculateSquareSize();
adjustSize(); adjustSize();
update(); update();
} }
@ -77,7 +75,7 @@ void CharacterWidget::updateFont(const QFont &font)
void CharacterWidget::updateSize(const QString &fontSize) void CharacterWidget::updateSize(const QString &fontSize)
{ {
displayFont.setPointSize(fontSize.toInt()); displayFont.setPointSize(fontSize.toInt());
squareSize = qMax(24, QFontMetrics(displayFont).xHeight() * 3); calculateSquareSize();
adjustSize(); adjustSize();
update(); update();
} }
@ -89,7 +87,7 @@ void CharacterWidget::updateStyle(const QString &fontStyle)
const QFont::StyleStrategy oldStrategy = displayFont.styleStrategy(); const QFont::StyleStrategy oldStrategy = displayFont.styleStrategy();
displayFont = fontDatabase.font(displayFont.family(), fontStyle, displayFont.pointSize()); displayFont = fontDatabase.font(displayFont.family(), fontStyle, displayFont.pointSize());
displayFont.setStyleStrategy(oldStrategy); displayFont.setStyleStrategy(oldStrategy);
squareSize = qMax(24, QFontMetrics(displayFont).xHeight() * 3); calculateSquareSize();
adjustSize(); adjustSize();
update(); update();
} }
@ -104,6 +102,11 @@ void CharacterWidget::updateFontMerging(bool enable)
update(); update();
} }
void CharacterWidget::calculateSquareSize()
{
squareSize = qMax(16, 4 + QFontMetrics(displayFont, this).height());
}
//! [3] //! [3]
QSize CharacterWidget::sizeHint() const QSize CharacterWidget::sizeHint() const
{ {

View File

@ -86,6 +86,8 @@ protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
private: private:
void calculateSquareSize();
QFont displayFont; QFont displayFont;
int columns; int columns;
int lastKey; int lastKey;

View File

@ -54,10 +54,30 @@
#include "mainwindow.h" #include "mainwindow.h"
//! [0] //! [0]
Q_DECLARE_METATYPE(QFontComboBox::FontFilter)
MainWindow::MainWindow() 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; 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:")); QLabel *fontLabel = new QLabel(tr("Font:"));
fontCombo = new QFontComboBox; fontCombo = new QFontComboBox;
QLabel *sizeLabel = new QLabel(tr("Size:")); QLabel *sizeLabel = new QLabel(tr("Size:"));
@ -80,38 +100,39 @@ MainWindow::MainWindow()
//! [2] //! [2]
lineEdit = new QLineEdit; lineEdit = new QLineEdit;
lineEdit->setClearButtonEnabled(true);
#ifndef QT_NO_CLIPBOARD #ifndef QT_NO_CLIPBOARD
QPushButton *clipboardButton = new QPushButton(tr("&To clipboard")); QPushButton *clipboardButton = new QPushButton(tr("&To clipboard"));
//! [2] //! [2]
//! [3]
clipboard = QApplication::clipboard();
//! [3]
#endif #endif
//! [4] //! [4]
connect(fontCombo, SIGNAL(currentFontChanged(QFont)), connect(fontCombo, &QFontComboBox::currentFontChanged,
this, SLOT(findStyles(QFont))); this, &MainWindow::findStyles);
connect(fontCombo, SIGNAL(currentFontChanged(QFont)), connect(fontCombo, &QFontComboBox::currentFontChanged,
this, SLOT(findSizes(QFont))); this, &MainWindow::findSizes);
connect(fontCombo, SIGNAL(currentFontChanged(QFont)), connect(fontCombo, &QFontComboBox::currentFontChanged,
characterWidget, SLOT(updateFont(QFont))); characterWidget, &CharacterWidget::updateFont);
connect(sizeCombo, SIGNAL(currentIndexChanged(QString)), typedef void (QComboBox::*QComboBoxStringSignal)(const QString &);
characterWidget, SLOT(updateSize(QString))); connect(sizeCombo, static_cast<QComboBoxStringSignal>(&QComboBox::currentIndexChanged),
connect(styleCombo, SIGNAL(currentIndexChanged(QString)), characterWidget, &CharacterWidget::updateSize);
characterWidget, SLOT(updateStyle(QString))); connect(styleCombo, static_cast<QComboBoxStringSignal>(&QComboBox::currentIndexChanged),
characterWidget, &CharacterWidget::updateStyle);
//! [4] //! [5] //! [4] //! [5]
connect(characterWidget, SIGNAL(characterSelected(QString)), connect(characterWidget, &CharacterWidget::characterSelected,
this, SLOT(insertCharacter(QString))); this, &MainWindow::insertCharacter);
#ifndef QT_NO_CLIPBOARD #ifndef QT_NO_CLIPBOARD
connect(clipboardButton, SIGNAL(clicked()), this, SLOT(updateClipboard())); connect(clipboardButton, &QAbstractButton::clicked, this, &MainWindow::updateClipboard);
#endif #endif
//! [5] //! [5]
connect(fontMerging, SIGNAL(toggled(bool)), characterWidget, SLOT(updateFontMerging(bool))); connect(fontMerging, &QAbstractButton::toggled, characterWidget, &CharacterWidget::updateFontMerging);
//! [6] //! [6]
QHBoxLayout *controlsLayout = new QHBoxLayout; QHBoxLayout *controlsLayout = new QHBoxLayout;
controlsLayout->addWidget(filterLabel);
controlsLayout->addWidget(filterCombo, 1);
controlsLayout->addWidget(fontLabel); controlsLayout->addWidget(fontLabel);
controlsLayout->addWidget(fontCombo, 1); controlsLayout->addWidget(fontCombo, 1);
controlsLayout->addWidget(sizeLabel); controlsLayout->addWidget(sizeLabel);
@ -163,6 +184,14 @@ void MainWindow::findStyles(const QFont &font)
} }
//! [8] //! [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) void MainWindow::findSizes(const QFont &font)
{ {
QFontDatabase fontDatabase; QFontDatabase fontDatabase;
@ -208,9 +237,63 @@ void MainWindow::insertCharacter(const QString &character)
void MainWindow::updateClipboard() void MainWindow::updateClipboard()
{ {
//! [11] //! [11]
clipboard->setText(lineEdit->text(), QClipboard::Clipboard); QGuiApplication::clipboard()->setText(lineEdit->text(), QClipboard::Clipboard);
//! [11] //! [11]
clipboard->setText(lineEdit->text(), QClipboard::Selection); QGuiApplication::clipboard()->setText(lineEdit->text(), QClipboard::Selection);
} }
#endif #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] //! [10]

View File

@ -73,18 +73,18 @@ public:
MainWindow(); MainWindow();
public slots: public slots:
void filterChanged(int);
void findStyles(const QFont &font); void findStyles(const QFont &font);
void findSizes(const QFont &font); void findSizes(const QFont &font);
void insertCharacter(const QString &character); void insertCharacter(const QString &character);
#ifndef QT_NO_CLIPBOARD #ifndef QT_NO_CLIPBOARD
void updateClipboard(); void updateClipboard();
#endif #endif
void showInfo();
private: private:
CharacterWidget *characterWidget; CharacterWidget *characterWidget;
#ifndef QT_NO_CLIPBOARD QComboBox *filterCombo;
QClipboard *clipboard;
#endif
QComboBox *styleCombo; QComboBox *styleCombo;
QComboBox *sizeCombo; QComboBox *sizeCombo;
QFontComboBox *fontCombo; QFontComboBox *fontCombo;

View File

@ -7,7 +7,8 @@
# -device-option VIBRANTE_SDK_TOPDIR=/opt/nvidia/vibrante-t186ref-linux # -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- \ # -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 \ # -sysroot /opt/nvidia/vibrante-t186ref-linux/targetfs \
# -no-gcc-sysroot # -no-gcc-sysroot \
# -opengl es2
include(../common/linux_device_pre.conf) include(../common/linux_device_pre.conf)

View File

@ -28,7 +28,7 @@
/*! /*!
\page qmake-manual.html \page qmake-manual.html
\title qmake Manual \title qmake Manual
\startpage {Qt Reference Documentation} \startpage index.html
\nextpage Overview \nextpage Overview
\ingroup qttools \ingroup qttools

View File

@ -3169,8 +3169,8 @@ QUrl QUrl::resolved(const QUrl &relative) const
if (!relative.d) return *this; if (!relative.d) return *this;
QUrl t; QUrl t;
// be non strict and allow scheme in relative url // Compatibility hack (mostly for qtdeclarative) : treat "file:relative.txt" as relative even though QUrl::isRelative() says false
if (!relative.d->scheme.isEmpty() && relative.d->scheme != d->scheme) { if (!relative.d->scheme.isEmpty() && (!relative.isLocalFile() || QDir::isAbsolutePath(relative.d->path))) {
t = relative; t = relative;
t.detach(); t.detach();
} else { } else {

View File

@ -1328,6 +1328,7 @@ void QSortFilterProxyModelPrivate::_q_sourceReset()
void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint) void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint)
{ {
Q_Q(QSortFilterProxyModel); Q_Q(QSortFilterProxyModel);
Q_UNUSED(hint); // We can't forward Hint because we might filter additional rows or columns
saved_persistent_indexes.clear(); saved_persistent_indexes.clear();
QList<QPersistentModelIndex> parents; QList<QPersistentModelIndex> parents;
@ -1346,7 +1347,7 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<Q
if (!sourceParents.isEmpty() && parents.isEmpty()) if (!sourceParents.isEmpty() && parents.isEmpty())
return; return;
emit q->layoutAboutToBeChanged(parents, hint); emit q->layoutAboutToBeChanged(parents);
if (persistent.indexes.isEmpty()) if (persistent.indexes.isEmpty())
return; return;
@ -1356,6 +1357,7 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<Q
void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint) void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint)
{ {
Q_Q(QSortFilterProxyModel); 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 // Optimize: We only actually have to clear the mapping related to the contents of
// sourceParents, not everything. // sourceParents, not everything.
@ -1385,7 +1387,7 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersisten
if (!sourceParents.isEmpty() && parents.isEmpty()) if (!sourceParents.isEmpty() && parents.isEmpty())
return; return;
emit q->layoutChanged(parents, hint); emit q->layoutChanged(parents);
} }
void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted( void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted(

View File

@ -307,9 +307,9 @@ QStringList QStringListModel::stringList() const
*/ */
void QStringListModel::setStringList(const QStringList &strings) void QStringListModel::setStringList(const QStringList &strings)
{ {
emit beginResetModel(); beginResetModel();
lst = strings; lst = strings;
emit endResetModel(); endResetModel();
} }
/*! /*!

View File

@ -3560,6 +3560,8 @@ int QVariant::compare(const QVariant &v) const
return v1.toTime() < v2.toTime() ? -1 : 1; return v1.toTime() < v2.toTime() ? -1 : 1;
case QVariant::DateTime: case QVariant::DateTime:
return v1.toDateTime() < v2.toDateTime() ? -1 : 1; 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); int r = v1.toString().compare(v2.toString(), Qt::CaseInsensitive);
if (r == 0) { if (r == 0) {

View File

@ -147,7 +147,7 @@ QCommandLineOption::QCommandLineOption(const QStringList &names)
The description is set to \a description. It is customary to add a "." The description is set to \a description. It is customary to add a "."
at the end of the description. 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. 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 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 "." The description is set to \a description. It is customary to add a "."
at the end of the description. 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. 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 In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4

View File

@ -9478,7 +9478,7 @@ QString &QString::append(const QStringRef &str)
{ {
if (str.string() == this) { if (str.string() == this) {
str.appendTo(this); str.appendTo(this);
} else if (str.string()) { } else if (!str.isNull()) {
int oldSize = size(); int oldSize = size();
resize(oldSize + str.size()); resize(oldSize + str.size());
memcpy(data() + oldSize, str.unicode(), str.size() * sizeof(QChar)); memcpy(data() + oldSize, str.unicode(), str.size() * sizeof(QChar));

View File

@ -909,13 +909,12 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch
&& !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) { && !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) {
const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year(); 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 =
QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, calculatePosixTransitions(m_posixRule, year - 1, year + 1,
year + 1, lastMSecs); m_tranTimes.last().atMSecsSinceEpoch);
for (int i = posixTrans.size() - 1; i >= 0; --i) { for (int i = posixTrans.size() - 1; i >= 0; --i) {
if (posixTrans.at(i).atMSecsSinceEpoch <= forMSecsSinceEpoch) { if (posixTrans.at(i).atMSecsSinceEpoch <= forMSecsSinceEpoch) {
QTimeZonePrivate::Data data; QTimeZonePrivate::Data data = posixTrans.at(i);
data = posixTrans.at(i);
data.atMSecsSinceEpoch = forMSecsSinceEpoch; data.atMSecsSinceEpoch = forMSecsSinceEpoch;
return data; return data;
} }
@ -953,9 +952,9 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch
&& !m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) { && !m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) {
const int year = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch, Qt::UTC).date().year(); 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 =
QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, calculatePosixTransitions(m_posixRule, year - 1, year + 1,
year + 1, lastMSecs); m_tranTimes.last().atMSecsSinceEpoch);
for (int i = 0; i < posixTrans.size(); ++i) { for (int i = 0; i < posixTrans.size(); ++i) {
if (posixTrans.at(i).atMSecsSinceEpoch > afterMSecsSinceEpoch) if (posixTrans.at(i).atMSecsSinceEpoch > afterMSecsSinceEpoch)
return posixTrans.at(i); return posixTrans.at(i);
@ -979,9 +978,9 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch
&& !m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) { && !m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) {
const int year = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch, Qt::UTC).date().year(); 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 =
QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, calculatePosixTransitions(m_posixRule, year - 1, year + 1,
year + 1, lastMSecs); m_tranTimes.last().atMSecsSinceEpoch);
for (int i = posixTrans.size() - 1; i >= 0; --i) { for (int i = posixTrans.size() - 1; i >= 0; --i) {
if (posixTrans.at(i).atMSecsSinceEpoch < beforeMSecsSinceEpoch) if (posixTrans.at(i).atMSecsSinceEpoch < beforeMSecsSinceEpoch)
return posixTrans.at(i); return posixTrans.at(i);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -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>

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 909 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QBlittablePlatformPixmap : public QPlatformPixmap class Q_GUI_EXPORT QBlittablePlatformPixmap : public QPlatformPixmap
{ {
// Q_DECLARE_PRIVATE(QBlittablePlatformPixmap); // Q_DECLARE_PRIVATE(QBlittablePlatformPixmap)
public: public:
QBlittablePlatformPixmap(); QBlittablePlatformPixmap();
~QBlittablePlatformPixmap(); ~QBlittablePlatformPixmap();

View File

@ -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 code point of the character; for example, 'A' gives the same key sequence
as Qt::Key_A. 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 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 Qt::MetaModifier correspond to the \uicontrol Control keys. Developers on
OS X can use the same shortcut descriptions across all platforms, OS X can use the same shortcut descriptions across all platforms,
and their applications will automatically work as expected on OS X. and their applications will automatically work as expected on OS X.

View File

@ -64,7 +64,7 @@ class QBlittablePrivate;
class Q_GUI_EXPORT QBlittable class Q_GUI_EXPORT QBlittable
{ {
Q_DECLARE_PRIVATE(QBlittable); Q_DECLARE_PRIVATE(QBlittable)
public: public:
enum Capability { enum Capability {

View File

@ -40,31 +40,37 @@
#include "qglobal.h" #include "qglobal.h"
#include "qrgb.h" #include "qrgb.h"
#include "qstringlist.h" #include "qstringlist.h"
#include "private/qtools_p.h"
#include <algorithm> #include <algorithm>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
static inline int h2i(char hex) /*!
{ \internal
if (hex >= '0' && hex <= '9') If s[0..1] is a valid hex number, returns its integer value,
return hex - '0'; otherwise returns -1.
if (hex >= 'a' && hex <= 'f') */
return hex - 'a' + 10;
if (hex >= 'A' && hex <= 'F')
return hex - 'A' + 10;
return -1;
}
static inline int hex2int(const char *s) 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) static inline int hex2int(char s)
{ {
int h = h2i(s); const int h = QtMiscUtils::fromHex(s);
return (h << 4) | h; return h < 0 ? h : (h << 4) | h;
} }
bool qt_get_hex_rgb(const char *name, QRgb *rgb) 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) #define rgb(r,g,b) (0xff000000 | (r << 16) | (g << 8) | b)
static const struct RGBData { static const struct RGBData {
const char *name; const char name[21];
uint value; uint value;
} rgbTbl[] = { } rgbTbl[] = {
{ "aliceblue", rgb(240, 248, 255) }, { "aliceblue", rgb(240, 248, 255) },

View File

@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
template <typename Type> class QDataBuffer template <typename Type> class QDataBuffer
{ {
Q_DISABLE_COPY(QDataBuffer); Q_DISABLE_COPY(QDataBuffer)
public: public:
QDataBuffer(int res) QDataBuffer(int res)
{ {

View File

@ -2897,10 +2897,16 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
sbuf2[i * 2 + 1] = ((const uint*)s2)[x2]; sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
fx += fdx; 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); 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); __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); int offset = _mm_extract_epi16(v_fx, 1);
sbuf1[i * 2 + 0] = ((const uint*)s1)[offset]; sbuf1[i * 2 + 0] = ((const uint*)s1)[offset];
sbuf1[i * 2 + 1] = ((const uint*)s1)[offset + 1]; sbuf1[i * 2 + 1] = ((const uint*)s1)[offset + 1];

View File

@ -208,13 +208,13 @@
#define ONE_PIXEL ( 1L << PIXEL_BITS ) #define ONE_PIXEL ( 1L << PIXEL_BITS )
#define PIXEL_MASK ( -1L << PIXEL_BITS ) #define PIXEL_MASK ( -1L << PIXEL_BITS )
#define TRUNC( x ) ( (TCoord)( (x) >> 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 FLOOR( x ) ( (x) & -ONE_PIXEL )
#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) #define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
#if PIXEL_BITS >= 6 #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 ) ) #define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) )
#else #else
#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) #define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) )

View File

@ -63,7 +63,7 @@ class QBlittable;
class Q_GUI_EXPORT QBlitterPaintEngine : public QRasterPaintEngine class Q_GUI_EXPORT QBlitterPaintEngine : public QRasterPaintEngine
{ {
Q_DECLARE_PRIVATE(QBlitterPaintEngine); Q_DECLARE_PRIVATE(QBlitterPaintEngine)
public: public:
QBlitterPaintEngine(QBlittablePlatformPixmap *p); QBlitterPaintEngine(QBlittablePlatformPixmap *p);

View File

@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
typedef int Q16Dot16; typedef int Q16Dot16;
#define Q16Dot16ToFloat(i) ((i)/65536.) #define Q16Dot16ToFloat(i) ((i)/65536.)
#define FloatToQ16Dot16(i) (int)((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 Q16Dot16ToInt(i) ((i) >> 16)
#define Q16Dot16Factor 65536 #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)); int iBottom = qMin(m_bottom, int((b.y - 32 - rounding) >> 6));
if (iTop <= iBottom) { 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) { if (b.x == a.x) {
Line line = { qBound(m_leftFP, aFP, m_rightFP), 0, iTop, iBottom, winding }; 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, Q16Dot16 xFP = aFP + Q16Dot16Multiply(slopeFP,
IntToQ16Dot16(iTop) IntToQ16Dot16(iTop)
+ Q16Dot16Factor/2 - (a.y << 10)); + Q16Dot16Factor/2 - (a.y * (1 << 10)));
if (clip(xFP, iTop, iBottom, slopeFP, m_leftFP, winding)) if (clip(xFP, iTop, iBottom, slopeFP, m_leftFP, winding))
return; return;

View File

@ -1827,7 +1827,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe
static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEngine::GlyphFormat glyphFormat) 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(); return QImage();
QImage::Format format = QImage::Format_Invalid; QImage::Format format = QImage::Format_Invalid;
@ -1875,11 +1875,15 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe
currentlyLockedAlphaMap = alphaMapFromGlyphData(glyph, neededFormat); currentlyLockedAlphaMap = alphaMapFromGlyphData(glyph, neededFormat);
const bool glyphHasGeometry = glyph != Q_NULLPTR && glyph->height != 0 && glyph->width != 0;
if (!cacheEnabled && glyph != &emptyGlyph) { if (!cacheEnabled && glyph != &emptyGlyph) {
currentlyLockedAlphaMap = currentlyLockedAlphaMap.copy(); currentlyLockedAlphaMap = currentlyLockedAlphaMap.copy();
delete glyph; delete glyph;
} }
if (!glyphHasGeometry)
return Q_NULLPTR;
if (currentlyLockedAlphaMap.isNull()) if (currentlyLockedAlphaMap.isNull())
return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset); return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset);

View File

@ -1567,12 +1567,13 @@ void QTextEngine::validate() const
layoutData = new LayoutData(); layoutData = new LayoutData();
if (block.docHandle()) { if (block.docHandle()) {
layoutData->string = block.text(); layoutData->string = block.text();
if (block.next().isValid()) { const bool nextBlockValid = block.next().isValid();
if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) if (!nextBlockValid && option.flags() & QTextOption::ShowDocumentTerminator) {
layoutData->string += QChar(0xb6);
} else if (option.flags() & QTextOption::ShowDocumentTerminator) {
layoutData->string += QChar(0xA7); layoutData->string += QChar(0xA7);
} else if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) {
layoutData->string += QLatin1Char(nextBlockValid ? 0xb6 : 0x20);
} }
} else { } else {
layoutData->string = text; layoutData->string = text;
} }

View File

@ -245,8 +245,8 @@ void QLocalSocket::connectToServer(OpenMode openMode)
QLatin1String("QLocalSocket::connectToServer")); QLatin1String("QLocalSocket::connectToServer"));
return; return;
} }
d->tcpSocket->connectToHost(QHostAddress::LocalHost, port, openMode);
QIODevice::open(openMode); QIODevice::open(openMode);
d->tcpSocket->connectToHost(QHostAddress::LocalHost, port, openMode);
} }
bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor, bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor,

View File

@ -75,7 +75,7 @@ public:
private: private:
SSLContextRef context; SSLContextRef context;
Q_DISABLE_COPY(QSecureTransportContext); Q_DISABLE_COPY(QSecureTransportContext)
}; };
class QSslSocketBackendPrivate : public QSslSocketPrivate class QSslSocketBackendPrivate : public QSslSocketPrivate
@ -122,7 +122,7 @@ private:
QSecureTransportContext context; QSecureTransportContext context;
Q_DISABLE_COPY(QSslSocketBackendPrivate); Q_DISABLE_COPY(QSslSocketBackendPrivate)
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -365,6 +365,7 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
static void populateFromPattern(FcPattern *pattern) static void populateFromPattern(FcPattern *pattern)
{ {
QString familyName; QString familyName;
QString familyNameLang;
FcChar8 *value = 0; FcChar8 *value = 0;
int weight_value; int weight_value;
int slant_value; int slant_value;
@ -382,6 +383,9 @@ static void populateFromPattern(FcPattern *pattern)
familyName = QString::fromUtf8((const char *)value); 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; slant_value = FC_SLANT_ROMAN;
weight_value = FC_WEIGHT_REGULAR; weight_value = FC_WEIGHT_REGULAR;
spacing_value = FC_PROPORTIONAL; 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); 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; // 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) for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k) {
QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value)); 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_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
FC_SPACING, FC_FILE, FC_INDEX, FC_SPACING, FC_FILE, FC_INDEX,
FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
FC_WIDTH, FC_WIDTH, FC_FAMILYLANG,
#if FC_VERSION >= 20297 #if FC_VERSION >= 20297
FC_CAPABILITY, FC_CAPABILITY,
#endif #endif

View File

@ -60,7 +60,8 @@ void QAndroidPlatformFontDatabase::populateFontDatabase()
QStringList nameFilters; QStringList nameFilters;
nameFilters << QLatin1String("*.ttf") nameFilters << QLatin1String("*.ttf")
<< QLatin1String("*.otf"); << QLatin1String("*.otf")
<< QLatin1String("*.ttc");
const auto entries = dir.entryInfoList(nameFilters, QDir::Files); const auto entries = dir.entryInfoList(nameFilters, QDir::Files);
for (const QFileInfo &fi : entries) { for (const QFileInfo &fi : entries) {

View File

@ -93,9 +93,23 @@ void QEglFSBrcmIntegration::platformInit()
bcm_host_init(); 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 EGLNativeDisplayType QEglFSBrcmIntegration::platformDisplay() const
{ {
dispman_display = vc_dispmanx_display_open(0/* LCD */); dispman_display = vc_dispmanx_display_open(getDisplayId());
return EGL_DEFAULT_DISPLAY; return EGL_DEFAULT_DISPLAY;
} }
@ -107,7 +121,7 @@ void QEglFSBrcmIntegration::platformDestroy()
QSize QEglFSBrcmIntegration::screenSize() const QSize QEglFSBrcmIntegration::screenSize() const
{ {
uint32_t width, height; uint32_t width, height;
graphics_get_display_size(0 /* LCD */, &width, &height); graphics_get_display_size(getDisplayId(), &width, &height);
return QSize(width, height); return QSize(width, height);
} }

View File

@ -40,6 +40,7 @@
#include "qwindowsfontdatabase.h" #include "qwindowsfontdatabase.h"
#include "qwindowsfontdatabase_ft.h" // for default font #include "qwindowsfontdatabase_ft.h" // for default font
#include "qwindowscontext.h" #include "qwindowscontext.h"
#include "qwindowsintegration.h"
#include "qwindowsfontengine.h" #include "qwindowsfontengine.h"
#include "qwindowsfontenginedirectwrite.h" #include "qwindowsfontenginedirectwrite.h"
#include <QtCore/qt_windows.h> #include <QtCore/qt_windows.h>
@ -108,6 +109,18 @@ static void createDirectWriteFactory(IDWriteFactory **factory)
*factory = static_cast<IDWriteFactory *>(result); *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 #endif // !QT_NO_DIRECTWRITE
// Helper classes for creating font engines directly from font data // Helper classes for creating font engines directly from font data
@ -1199,11 +1212,7 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal
QFontEngine *fontEngine = 0; QFontEngine *fontEngine = 0;
#if !defined(QT_NO_DIRECTWRITE) #if !defined(QT_NO_DIRECTWRITE)
bool useDirectWrite = (hintingPreference == QFont::PreferNoHinting) if (!useDirectWrite(hintingPreference))
|| (hintingPreference == QFont::PreferVerticalHinting)
|| (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting);
if (!useDirectWrite)
#endif #endif
{ {
GUID guid; GUID guid;
@ -1838,15 +1847,16 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request,
if (SUCCEEDED(directWriteFontFace->QueryInterface(__uuidof(IDWriteFontFace2), if (SUCCEEDED(directWriteFontFace->QueryInterface(__uuidof(IDWriteFontFace2),
reinterpret_cast<void **>(&directWriteFontFace2)))) { reinterpret_cast<void **>(&directWriteFontFace2)))) {
if (directWriteFontFace2->IsColorFont()) if (directWriteFontFace2->IsColorFont())
isColorFont = true; isColorFont = directWriteFontFace2->GetPaletteEntryCount() > 0;
} }
#endif #endif
const QFont::HintingPreference hintingPreference =
bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting) static_cast<QFont::HintingPreference>(request.hintingPreference);
|| (request.hintingPreference == QFont::PreferVerticalHinting) const bool useDw = useDirectWrite(hintingPreference, isColorFont);
|| (QHighDpiScaling::isActive() && request.hintingPreference == QFont::PreferDefaultHinting) qCDebug(lcQpaFonts) << __FUNCTION__ << request.family << request.pointSize
|| isColorFont; << "pt" << "hintingPreference=" << hintingPreference << "color=" << isColorFont
if (useDirectWrite) { << dpi << "dpi" << "useDirectWrite=" << useDw;
if (useDw) {
QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace, QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace,
request.pixelSize, request.pixelSize,
data); data);

View File

@ -192,6 +192,10 @@ static inline unsigned parseOptions(const QStringList &paramList,
} }
} else if (param == QLatin1String("gl=gdi")) { } else if (param == QLatin1String("gl=gdi")) {
options |= QWindowsIntegration::DisableArb; options |= QWindowsIntegration::DisableArb;
} else if (param == QLatin1String("nodirectwrite")) {
options |= QWindowsIntegration::DontUseDirectWriteFonts;
} else if (param == QLatin1String("nocolorfonts")) {
options |= QWindowsIntegration::DontUseColorFonts;
} else if (param == QLatin1String("nomousefromtouch")) { } else if (param == QLatin1String("nomousefromtouch")) {
options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch; options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch;
} else if (parseIntOption(param, QLatin1String("verbose"), 0, INT_MAX, &QWindowsContext::verbose) } 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) { if (window->type() == Qt::ForeignWindow) {
const HWND hwnd = reinterpret_cast<HWND>(window->winId()); const HWND hwnd = reinterpret_cast<HWND>(window->winId());
if (!IsWindow(hwnd)) { if (!IsWindow(hwnd)) {
qWarning("Windows QPA: Invalid foreign window ID %p."); qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd);
return nullptr; return nullptr;
} }
QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd); QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd);

View File

@ -60,7 +60,9 @@ public:
DisableArb = 0x4, DisableArb = 0x4,
NoNativeDialogs = 0x8, NoNativeDialogs = 0x8,
XpNativeDialogs = 0x10, 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 &paramList); explicit QWindowsIntegration(const QStringList &paramList);

View File

@ -43,6 +43,7 @@
#include "qwindowswindow.h" #include "qwindowswindow.h"
#include "qwindowsinputcontext.h" #include "qwindowsinputcontext.h"
#include <QtGui/QGuiApplication>
#include <QtGui/QWindow> #include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface.h>
#include <private/qguiapplication_p.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)) { if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) {
// Found a ?_CHAR // Found a ?_CHAR
uch = QChar(ushort(wm_char.wParam)); 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)) if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN))
uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter
if (!code && !uch.row()) if (!code && !uch.row())

View File

@ -103,6 +103,7 @@ private:
void deleteLayouts(); void deleteLayouts();
QWindow *m_keyGrabber; QWindow *m_keyGrabber;
QChar m_lastHighSurrogate;
static const size_t NumKeyboardLayoutItems = 256; static const size_t NumKeyboardLayoutItems = 256;
KeyboardLayoutItem keyLayout[NumKeyboardLayoutItems]; KeyboardLayoutItem keyLayout[NumKeyboardLayoutItems];
}; };

View File

@ -27,6 +27,8 @@
****************************************************************************/ ****************************************************************************/
#include <qbytearray.h> #include <qbytearray.h>
#include <qcommandlineparser.h>
#include <qcoreapplication.h>
#include <qdebug.h> #include <qdebug.h>
#include <qfile.h> #include <qfile.h>
#include <qfileinfo.h> #include <qfileinfo.h>
@ -59,30 +61,6 @@ static QString commandLine;
static QStringList includes; static QStringList includes;
static QStringList wantedInterfaces; 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[] = static const char includeList[] =
"#include <QtCore/QByteArray>\n" "#include <QtCore/QByteArray>\n"
"#include <QtCore/QList>\n" "#include <QtCore/QList>\n"
@ -101,105 +79,6 @@ static const char forwardDeclarations[] =
"class QVariant;\n" "class QVariant;\n"
"QT_END_NAMESPACE\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() static QDBusIntrospection::Interfaces readInput()
{ {
QFile input(inputFile); QFile input(inputFile);
@ -1139,13 +1018,79 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
QStringList arguments; QCoreApplication app(argc, argv);
arguments.reserve(argc); QCoreApplication::setApplicationName(QStringLiteral(PROGRAMNAME));
for (int i = 0; i < argc; ++i) { QCoreApplication::setApplicationVersion(QStringLiteral(PROGRAMVERSION));
arguments.append(QString::fromLocal8Bit(argv[i]));
}
parseCmdLine(arguments); 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();
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(); QDBusIntrospection::Interfaces interfaces = readInput();
cleanInterfaces(interfaces); cleanInterfaces(interfaces);

View File

@ -667,7 +667,7 @@ void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button
If the \l{QMessageBox::StandardButtons} {standard buttons} are not If the \l{QMessageBox::StandardButtons} {standard buttons} are not
flexible enough for your message box, you can use the addButton() 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 buttons. The ButtonRole is used by QMessageBox to determine the
ordering of the buttons on screen (which varies according to the ordering of the buttons on screen (which varies according to the
platform). You can test the value of clickedButton() after calling platform). You can test the value of clickedButton() after calling

View File

@ -788,8 +788,10 @@ void QAbstractItemView::setSelectionModel(QItemSelectionModel *selectionModel)
QModelIndex oldCurrentIndex; QModelIndex oldCurrentIndex;
if (d->selectionModel) { if (d->selectionModel) {
oldSelection = d->selectionModel->selection(); if (d->selectionModel->model() == selectionModel->model()) {
oldCurrentIndex = d->selectionModel->currentIndex(); oldSelection = d->selectionModel->selection();
oldCurrentIndex = d->selectionModel->currentIndex();
}
disconnect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), disconnect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(selectionChanged(QItemSelection,QItemSelection))); this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
@ -3871,7 +3873,7 @@ void QAbstractItemView::doAutoScroll()
int horizontalValue = horizontalScroll->value(); int horizontalValue = horizontalScroll->value();
QPoint pos = d->viewport->mapFromGlobal(QCursor::pos()); 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 // do the scrolling if we are in the scroll margins
if (pos.y() - area.top() < margin) if (pos.y() - area.top() < margin)

View File

@ -46,6 +46,9 @@
#include <QtCore/qitemselectionmodel.h> #include <QtCore/qitemselectionmodel.h>
#include <QtWidgets/qabstractitemdelegate.h> #include <QtWidgets/qabstractitemdelegate.h>
class tst_QAbstractItemView;
class tst_QTreeView;
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -368,6 +371,8 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged()) Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged())
#endif #endif
friend class ::tst_QAbstractItemView;
friend class ::tst_QTreeView;
friend class QTreeViewPrivate; // needed to compile with MSVC friend class QTreeViewPrivate; // needed to compile with MSVC
friend class QListModeViewBase; friend class QListModeViewBase;
friend class QListViewPrivate; friend class QListViewPrivate;

View File

@ -205,20 +205,6 @@ void QDataWidgetMapperPrivate::_q_commitData(QWidget *w)
commit(widgetMap.at(idx)); 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) void QDataWidgetMapperPrivate::_q_closeEditor(QWidget *w, QAbstractItemDelegate::EndEditHint hint)
{ {
int idx = findWidget(w); int idx = findWidget(w);
@ -230,10 +216,10 @@ void QDataWidgetMapperPrivate::_q_closeEditor(QWidget *w, QAbstractItemDelegate:
populate(widgetMap[idx]); populate(widgetMap[idx]);
break; } break; }
case QAbstractItemDelegate::EditNextItem: case QAbstractItemDelegate::EditNextItem:
QFocusHelper::focusNextPrevChild(w, true); w->focusNextChild();
break; break;
case QAbstractItemDelegate::EditPreviousItem: case QAbstractItemDelegate::EditPreviousItem:
QFocusHelper::focusNextPrevChild(w, false); w->focusPreviousChild();
break; break;
case QAbstractItemDelegate::SubmitModelCache: case QAbstractItemDelegate::SubmitModelCache:
case QAbstractItemDelegate::NoHint: case QAbstractItemDelegate::NoHint:

View File

@ -3465,6 +3465,7 @@ void QHeaderViewPrivate::clear()
sectionSelected.clear(); sectionSelected.clear();
hiddenSectionSize.clear(); hiddenSectionSize.clear();
sectionItems.clear(); sectionItems.clear();
lastSectionLogicalIdx = -1;
invalidateCachedSizeHint(); invalidateCachedSizeHint();
} }
} }

View File

@ -43,6 +43,8 @@
#include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qabstractitemview.h> #include <QtWidgets/qabstractitemview.h>
class tst_QTreeView;
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -220,6 +222,7 @@ protected:
void currentChanged(const QModelIndex &current, const QModelIndex &previous) Q_DECL_OVERRIDE; void currentChanged(const QModelIndex &current, const QModelIndex &previous) Q_DECL_OVERRIDE;
private: private:
friend class ::tst_QTreeView;
friend class QAccessibleTable; friend class QAccessibleTable;
friend class QAccessibleTree; friend class QAccessibleTree;
friend class QAccessibleTableCell; friend class QAccessibleTableCell;

View File

@ -146,6 +146,7 @@ QTreeModel::QTreeModel(QTreeModelPrivate &dd, QTreeWidget *parent)
QTreeModel::~QTreeModel() QTreeModel::~QTreeModel()
{ {
clear(); clear();
headerItem->view = Q_NULLPTR;
delete headerItem; delete headerItem;
rootItem->view = 0; rootItem->view = 0;
delete rootItem; delete rootItem;

View File

@ -676,6 +676,7 @@ protected:
void destroy(bool destroyWindow = true, void destroy(bool destroyWindow = true,
bool destroySubWindows = true); bool destroySubWindows = true);
friend class QDataWidgetMapperPrivate; // for access to focusNextPrevChild
virtual bool focusNextPrevChild(bool next); virtual bool focusNextPrevChild(bool next);
inline bool focusNextChild() { return focusNextPrevChild(true); } inline bool focusNextChild() { return focusNextPrevChild(true); }
inline bool focusPreviousChild() { return focusNextPrevChild(false); } inline bool focusPreviousChild() { return focusNextPrevChild(false); }

View File

@ -898,13 +898,11 @@ void tst_QUrl::resolving_data()
// Some parsers allow the scheme name to be present in a relative URI // 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 // reference if it is the same as the base URI scheme. This is
// considered to be a loophole in prior specifications of partial URI // considered to be a loophole in prior specifications of partial URI [RFC1630],
// [RFC1630]. Its use should be avoided, but is allowed for backward //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");
// compatibility. // However we don't do that anymore, as per RFC3986, in order for the data:subpage testcase below to work.
// For strict parsers : QTest::newRow("http:g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("http:g") << QString::fromLatin1("http:g");
// QTest::newRow("http:g [for strict parsers]") << 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");
// 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");
// Resolve relative with relative // Resolve relative with relative
QTest::newRow("../a (1)") << QString::fromLatin1("b") << QString::fromLatin1("../a") << QString::fromLatin1("a"); 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 (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 (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"); 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() void tst_QUrl::resolving()

View File

@ -143,6 +143,7 @@ private slots:
void noMapAfterSourceDelete(); void noMapAfterSourceDelete();
void forwardDropApi(); void forwardDropApi();
void canDropMimeData(); void canDropMimeData();
void filterHint();
protected: protected:
void buildHierarchy(const QStringList &data, QAbstractItemModel *model); void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
@ -3802,6 +3803,12 @@ void tst_QSortFilterProxyModel::moveSourceRows()
QCOMPARE(filterBeforeParents.size(), 1); QCOMPARE(filterBeforeParents.size(), 1);
QCOMPARE(filterAfterParents.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(filterBothBeforeParentLayoutSpy.size(), 0);
QCOMPARE(filterBothAfterParentLayoutSpy.size(), 0); QCOMPARE(filterBothAfterParentLayoutSpy.size(), 0);
} }
@ -4123,5 +4130,50 @@ void tst_QSortFilterProxyModel::resortingDoesNotBreakTreeModels()
QCOMPARE(proxy.rowCount(pi1), 1); 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) QTEST_MAIN(tst_QSortFilterProxyModel)
#include "tst_qsortfilterproxymodel.moc" #include "tst_qsortfilterproxymodel.moc"

View File

@ -275,6 +275,7 @@ private slots:
void metaEnums(); void metaEnums();
void compareSanity_data(); void compareSanity_data();
void compareSanity(); void compareSanity();
void compareRich();
void accessSequentialContainerKey(); 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() void tst_QVariant::accessSequentialContainerKey()
{ {
QString nameResult; QString nameResult;

View File

@ -123,7 +123,7 @@ template <>
class Arg<QStringRef> : ArgBase class Arg<QStringRef> : ArgBase
{ {
QStringRef ref() const QStringRef ref() const
{ return this->pinned.isNull() ? QStringRef() : this->pinned.midRef(0) ; } { return QStringRef(&pinned); }
public: public:
explicit Arg(const char *str) : ArgBase(str) {} explicit Arg(const char *str) : ArgBase(str) {}

View File

@ -181,6 +181,7 @@ private slots:
void slotConnected() void slotConnected()
{ {
QCOMPARE(state(), QLocalSocket::ConnectedState); QCOMPARE(state(), QLocalSocket::ConnectedState);
QVERIFY(isOpen());
} }
void slotDisconnected() void slotDisconnected()
{ {

View File

@ -77,108 +77,6 @@ static inline void moveCursorAway(const QWidget *topLevel)
#endif #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 &current, 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 class GeometriesTestView : public QTableView
{ {
Q_OBJECT Q_OBJECT
@ -194,7 +92,7 @@ class tst_QAbstractItemView : public QObject
Q_OBJECT Q_OBJECT
public: public:
void basic_tests(TestView *view); void basic_tests(QAbstractItemView *view);
private slots: private slots:
void cleanup(); void cleanup();
@ -278,7 +176,7 @@ public:
void tst_QAbstractItemView::getSetCheck() void tst_QAbstractItemView::getSetCheck()
{ {
QListView view; QListView view;
TestView *obj1 = reinterpret_cast<TestView*>(&view); QAbstractItemView *obj1 = &view;
// QAbstractItemDelegate * QAbstractItemView::itemDelegate() // QAbstractItemDelegate * QAbstractItemView::itemDelegate()
// void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *) // void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *)
MyAbstractItemDelegate *var1 = new MyAbstractItemDelegate; MyAbstractItemDelegate *var1 = new MyAbstractItemDelegate;
@ -329,18 +227,18 @@ void tst_QAbstractItemView::getSetCheck()
// State QAbstractItemView::state() // State QAbstractItemView::state()
// void QAbstractItemView::setState(State) // void QAbstractItemView::setState(State)
obj1->tst_setState(TestView::tst_State(TestView::NoState)); obj1->setState(QAbstractItemView::NoState);
QCOMPARE(TestView::tst_State(TestView::NoState), obj1->tst_state()); QCOMPARE(QAbstractItemView::NoState, obj1->state());
obj1->tst_setState(TestView::tst_State(TestView::DraggingState)); obj1->setState(QAbstractItemView::DraggingState);
QCOMPARE(TestView::tst_State(TestView::DraggingState), obj1->tst_state()); QCOMPARE(QAbstractItemView::DraggingState, obj1->state());
obj1->tst_setState(TestView::tst_State(TestView::DragSelectingState)); obj1->setState(QAbstractItemView::DragSelectingState);
QCOMPARE(TestView::tst_State(TestView::DragSelectingState), obj1->tst_state()); QCOMPARE(QAbstractItemView::DragSelectingState, obj1->state());
obj1->tst_setState(TestView::tst_State(TestView::EditingState)); obj1->setState(QAbstractItemView::EditingState);
QCOMPARE(TestView::tst_State(TestView::EditingState), obj1->tst_state()); QCOMPARE(QAbstractItemView::EditingState, obj1->state());
obj1->tst_setState(TestView::tst_State(TestView::ExpandingState)); obj1->setState(QAbstractItemView::ExpandingState);
QCOMPARE(TestView::tst_State(TestView::ExpandingState), obj1->tst_state()); QCOMPARE(QAbstractItemView::ExpandingState, obj1->state());
obj1->tst_setState(TestView::tst_State(TestView::CollapsingState)); obj1->setState(QAbstractItemView::CollapsingState);
QCOMPARE(TestView::tst_State(TestView::CollapsingState), obj1->tst_state()); QCOMPARE(QAbstractItemView::CollapsingState, obj1->state());
// QWidget QAbstractScrollArea::viewport() // QWidget QAbstractScrollArea::viewport()
// void setViewport(QWidget*) // void setViewport(QWidget*)
@ -394,7 +292,7 @@ void tst_QAbstractItemView::emptyModels()
QVERIFY(!view->selectionModel()); QVERIFY(!view->selectionModel());
//QVERIFY(view->itemDelegate() != 0); //QVERIFY(view->itemDelegate() != 0);
basic_tests(reinterpret_cast<TestView*>(view.data())); basic_tests(view.data());
} }
void tst_QAbstractItemView::setModel_data() void tst_QAbstractItemView::setModel_data()
@ -431,10 +329,10 @@ void tst_QAbstractItemView::setModel()
QStandardItemModel model(20,20); QStandardItemModel model(20,20);
view->setModel(0); view->setModel(0);
view->setModel(&model); 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 // setSelectionModel
// Will assert as it should // Will assert as it should
@ -559,73 +457,73 @@ void tst_QAbstractItemView::basic_tests(TestView *view)
view->setCurrentIndex(QModelIndex()); view->setCurrentIndex(QModelIndex());
// protected methods // protected methods
view->tst_dataChanged(QModelIndex(), QModelIndex()); view->dataChanged(QModelIndex(), QModelIndex());
view->tst_rowsInserted(QModelIndex(), -1, -1); view->rowsInserted(QModelIndex(), -1, -1);
view->tst_rowsAboutToBeRemoved(QModelIndex(), -1, -1); view->rowsAboutToBeRemoved(QModelIndex(), -1, -1);
view->tst_selectionChanged(QItemSelection(), QItemSelection()); view->selectionChanged(QItemSelection(), QItemSelection());
if (view->model()){ if (view->model()){
view->tst_currentChanged(QModelIndex(), QModelIndex()); view->currentChanged(QModelIndex(), QModelIndex());
view->tst_currentChanged(QModelIndex(), view->model()->index(0,0)); view->currentChanged(QModelIndex(), view->model()->index(0,0));
} }
view->tst_updateEditorData(); view->updateEditorData();
view->tst_updateEditorGeometries(); view->updateEditorGeometries();
view->tst_updateGeometries(); view->updateGeometries();
view->tst_verticalScrollbarAction(QAbstractSlider::SliderSingleStepAdd); view->verticalScrollbarAction(QAbstractSlider::SliderSingleStepAdd);
view->tst_horizontalScrollbarAction(QAbstractSlider::SliderSingleStepAdd); view->horizontalScrollbarAction(QAbstractSlider::SliderSingleStepAdd);
view->tst_verticalScrollbarValueChanged(10); view->verticalScrollbarValueChanged(10);
view->tst_horizontalScrollbarValueChanged(10); view->horizontalScrollbarValueChanged(10);
view->tst_closeEditor(0, QAbstractItemDelegate::NoHint); view->closeEditor(0, QAbstractItemDelegate::NoHint);
view->tst_commitData(0); view->commitData(0);
view->tst_editorDestroyed(0); view->editorDestroyed(0);
view->tst_setHorizontalStepsPerItem(2); view->setHorizontalStepsPerItem(2);
view->tst_horizontalStepsPerItem(); view->horizontalStepsPerItem();
view->tst_setVerticalStepsPerItem(2); view->setVerticalStepsPerItem(2);
view->tst_verticalStepsPerItem(); view->verticalStepsPerItem();
// Will assert as it should // Will assert as it should
// view->setIndexWidget(QModelIndex(), 0); // view->setIndexWidget(QModelIndex(), 0);
view->tst_moveCursor(TestView::MoveUp, Qt::NoModifier); view->moveCursor(QAbstractItemView::MoveUp, Qt::NoModifier);
view->tst_horizontalOffset(); view->horizontalOffset();
view->tst_verticalOffset(); view->verticalOffset();
// view->tst_isIndexHidden(QModelIndex()); // will (correctly) assert // view->isIndexHidden(QModelIndex()); // will (correctly) assert
if(view->model()) 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->setSelection(QRect(0, 0, 10, 10), QItemSelectionModel::ClearAndSelect);
view->tst_setSelection(QRect(-1, -1, -1, -1), QItemSelectionModel::ClearAndSelect); view->setSelection(QRect(-1, -1, -1, -1), QItemSelectionModel::ClearAndSelect);
view->tst_visualRegionForSelection(QItemSelection()); view->visualRegionForSelection(QItemSelection());
view->tst_selectedIndexes(); 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 #ifndef QT_NO_DRAGANDDROP
if (!view->model()) if (!view->model())
view->tst_startDrag(Qt::CopyAction); view->startDrag(Qt::CopyAction);
view->tst_viewOptions(); view->viewOptions();
view->tst_setState(TestView::NoState); view->setState(QAbstractItemView::NoState);
QVERIFY(view->tst_state()==TestView::NoState); QVERIFY(view->state()==QAbstractItemView::NoState);
view->tst_setState(TestView::DraggingState); view->setState(QAbstractItemView::DraggingState);
QVERIFY(view->tst_state()==TestView::DraggingState); QVERIFY(view->state()==QAbstractItemView::DraggingState);
view->tst_setState(TestView::DragSelectingState); view->setState(QAbstractItemView::DragSelectingState);
QVERIFY(view->tst_state()==TestView::DragSelectingState); QVERIFY(view->state()==QAbstractItemView::DragSelectingState);
view->tst_setState(TestView::EditingState); view->setState(QAbstractItemView::EditingState);
QVERIFY(view->tst_state()==TestView::EditingState); QVERIFY(view->state()==QAbstractItemView::EditingState);
view->tst_setState(TestView::ExpandingState); view->setState(QAbstractItemView::ExpandingState);
QVERIFY(view->tst_state()==TestView::ExpandingState); QVERIFY(view->state()==QAbstractItemView::ExpandingState);
view->tst_setState(TestView::CollapsingState); view->setState(QAbstractItemView::CollapsingState);
QVERIFY(view->tst_state()==TestView::CollapsingState); QVERIFY(view->state()==QAbstractItemView::CollapsingState);
#endif #endif
view->tst_startAutoScroll(); view->startAutoScroll();
view->tst_stopAutoScroll(); view->stopAutoScroll();
view->tst_doAutoScroll(); view->doAutoScroll();
// testing mouseFoo and key functions // testing mouseFoo and key functions
// QTest::mousePress(view, Qt::LeftButton, Qt::NoModifier, QPoint(0,0)); // QTest::mousePress(view, Qt::LeftButton, Qt::NoModifier, QPoint(0,0));
@ -760,11 +658,11 @@ void tst_QAbstractItemView::selectAll()
QTableView view; QTableView view;
view.setModel(&model); 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(); view.selectAll();
QCOMPARE(tst_view->tst_selectedIndexes().count(), 4*4); QCOMPARE(tst_view->selectedIndexes().count(), 4*4);
} }
void tst_QAbstractItemView::ctrlA() void tst_QAbstractItemView::ctrlA()
@ -773,11 +671,11 @@ void tst_QAbstractItemView::ctrlA()
QTableView view; QTableView view;
view.setModel(&model); 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); 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() void tst_QAbstractItemView::persistentEditorFocus()
@ -1590,9 +1488,9 @@ void tst_QAbstractItemView::testDelegateDestroyEditor()
MyAbstractItemDelegate delegate; MyAbstractItemDelegate delegate;
table.setItemDelegate(&delegate); table.setItemDelegate(&delegate);
table.edit(table.model()->index(1, 1)); table.edit(table.model()->index(1, 1));
TestView *tv = reinterpret_cast<TestView*>(&table); QAbstractItemView *tv = &table;
QVERIFY(!delegate.calledVirtualDtor); QVERIFY(!delegate.calledVirtualDtor);
tv->tst_closeEditor(delegate.openedEditor, QAbstractItemDelegate::NoHint); tv->closeEditor(delegate.openedEditor, QAbstractItemDelegate::NoHint);
QVERIFY(delegate.calledVirtualDtor); QVERIFY(delegate.calledVirtualDtor);
} }
@ -2069,11 +1967,18 @@ void tst_QAbstractItemView::QTBUG50535_update_on_new_selection_model()
{ {
public: public:
ListView() 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; int m_paintEventsCount;
bool selectionChangedOk() const { return m_selectionChangedOk; }
protected: protected:
bool viewportEvent(QEvent *event) Q_DECL_OVERRIDE bool viewportEvent(QEvent *event) Q_DECL_OVERRIDE
@ -2082,6 +1987,24 @@ void tst_QAbstractItemView::QTBUG50535_update_on_new_selection_model()
++m_paintEventsCount; ++m_paintEventsCount;
return QListView::viewportEvent(event); 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 // 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.selectionModel()->setCurrentIndex(model.index(1, 0), QItemSelectionModel::SelectCurrent);
view.show(); view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(view.selectionChangedOk());
QItemSelectionModel selectionModel(&model); QItemSelectionModel selectionModel(&model);
selectionModel.setCurrentIndex(model.index(2, 0), QItemSelectionModel::Current); 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; int oldPaintEventsCount = view.m_paintEventsCount;
view.setSelectionModel(&selectionModel); view.setSelectionModel(&selectionModel);
QTRY_VERIFY(view.m_paintEventsCount > oldPaintEventsCount); QTRY_VERIFY(view.m_paintEventsCount > oldPaintEventsCount);
QVERIFY(view.selectionChangedOk());
QItemSelectionModel selectionModel2(&model); QItemSelectionModel selectionModel2(&model);
@ -2109,6 +2033,19 @@ void tst_QAbstractItemView::QTBUG50535_update_on_new_selection_model()
oldPaintEventsCount = view.m_paintEventsCount; oldPaintEventsCount = view.m_paintEventsCount;
view.setSelectionModel(&selectionModel2); view.setSelectionModel(&selectionModel2);
QTRY_VERIFY(view.m_paintEventsCount > oldPaintEventsCount); 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() void tst_QAbstractItemView::testSelectionModelInSyncWithView()

View File

@ -2991,6 +2991,11 @@ void tst_QHeaderView::stretchAndRestoreLastSection()
header.swapSections(1, 11); header.swapSections(1, 11);
QCOMPARE(header.sectionSize(1), someOtherSectionSize); 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. // Test import/export of the original (not stretched) sectionSize.
m.setColumnCount(0); m.setColumnCount(0);
m.setColumnCount(10); m.setColumnCount(10);

View File

@ -31,7 +31,7 @@
#include <QtTest/QtTest> #include <QtTest/QtTest>
#include <QtGui/QtGui> #include <QtGui/QtGui>
#include <QtWidgets/QtWidgets> #include <QtWidgets/QtWidgets>
#include <private/qabstractitemview_p.h> #include <private/qtreeview_p.h>
#ifndef QT_NO_DRAGANDDROP #ifndef QT_NO_DRAGANDDROP
Q_DECLARE_METATYPE(QAbstractItemView::DragDropMode) Q_DECLARE_METATYPE(QAbstractItemView::DragDropMode)
@ -57,49 +57,6 @@ static void initStandardTreeModel(QStandardItemModel *model)
model->insertRow(2, item); 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 // Make a widget frameless to prevent size constraints of title bars
// from interfering (Windows). // from interfering (Windows).
static inline void setFrameless(QWidget *w) static inline void setFrameless(QWidget *w)
@ -631,33 +588,34 @@ void tst_QTreeView::dragDropModeFromDragEnabledAndAcceptDrops_data()
QTest::addColumn<bool>("dragEnabled"); QTest::addColumn<bool>("dragEnabled");
QTest::addColumn<bool>("acceptDrops"); QTest::addColumn<bool>("acceptDrops");
QTest::addColumn<QAbstractItemView::DragDropMode>("dragDropMode"); QTest::addColumn<QAbstractItemView::DragDropMode>("dragDropMode");
QTest::addColumn<QAbstractItemView::DragDropMode>("setBehavior"); QTest::addColumn<bool>("setBehavior");
QTest::addColumn<QAbstractItemView::DragDropMode>("behavior");
QTest::newRow("NoDragDrop -1") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DragDropMode(-1); QTest::newRow("NoDragDrop -1") << false << false << QAbstractItemView::NoDragDrop << false << QAbstractItemView::DragDropMode();
QTest::newRow("NoDragDrop 0") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::NoDragDrop; QTest::newRow("NoDragDrop 0") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::NoDragDrop;
QTest::newRow("NoDragDrop 1") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DragOnly; QTest::newRow("NoDragDrop 1") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::DragOnly;
QTest::newRow("NoDragDrop 2") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DropOnly; QTest::newRow("NoDragDrop 2") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::DropOnly;
QTest::newRow("NoDragDrop 3") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DragDrop; QTest::newRow("NoDragDrop 3") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::DragDrop;
QTest::newRow("NoDragDrop 4") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::InternalMove; QTest::newRow("NoDragDrop 4") << false << false << QAbstractItemView::NoDragDrop << true << QAbstractItemView::InternalMove;
QTest::newRow("DragOnly -1") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DragDropMode(-1); QTest::newRow("DragOnly -1") << true << false << QAbstractItemView::DragOnly << false << QAbstractItemView::DragDropMode();
QTest::newRow("DragOnly 0") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::NoDragDrop; QTest::newRow("DragOnly 0") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::NoDragDrop;
QTest::newRow("DragOnly 1") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DragOnly; QTest::newRow("DragOnly 1") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::DragOnly;
QTest::newRow("DragOnly 2") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DropOnly; QTest::newRow("DragOnly 2") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::DropOnly;
QTest::newRow("DragOnly 3") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DragDrop; QTest::newRow("DragOnly 3") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::DragDrop;
QTest::newRow("DragOnly 4") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::InternalMove; QTest::newRow("DragOnly 4") << true << false << QAbstractItemView::DragOnly << true << QAbstractItemView::InternalMove;
QTest::newRow("DropOnly -1") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DragDropMode(-1); QTest::newRow("DropOnly -1") << false << true << QAbstractItemView::DropOnly << false << QAbstractItemView::DragDropMode();
QTest::newRow("DropOnly 0") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::NoDragDrop; QTest::newRow("DropOnly 0") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::NoDragDrop;
QTest::newRow("DropOnly 1") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DragOnly; QTest::newRow("DropOnly 1") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::DragOnly;
QTest::newRow("DropOnly 2") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DropOnly; QTest::newRow("DropOnly 2") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::DropOnly;
QTest::newRow("DropOnly 3") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DragDrop; QTest::newRow("DropOnly 3") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::DragDrop;
QTest::newRow("DropOnly 4") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::InternalMove; QTest::newRow("DropOnly 4") << false << true << QAbstractItemView::DropOnly << true << QAbstractItemView::InternalMove;
QTest::newRow("DragDrop -1") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragDropMode(-1); QTest::newRow("DragDrop -1") << true << true << QAbstractItemView::DragDrop << false << QAbstractItemView::DragDropMode();
QTest::newRow("DragDrop 0") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragDropMode(-1); QTest::newRow("DragDrop 0") << true << true << QAbstractItemView::DragDrop << false << QAbstractItemView::DragDropMode();
QTest::newRow("DragDrop 1") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::NoDragDrop; QTest::newRow("DragDrop 1") << true << true << QAbstractItemView::DragDrop << true << QAbstractItemView::NoDragDrop;
QTest::newRow("DragDrop 2") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragOnly; QTest::newRow("DragDrop 2") << true << true << QAbstractItemView::DragDrop << true << QAbstractItemView::DragOnly;
QTest::newRow("DragDrop 3") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DropOnly; QTest::newRow("DragDrop 3") << true << true << QAbstractItemView::DragDrop << true << QAbstractItemView::DropOnly;
QTest::newRow("DragDrop 4") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragDrop; QTest::newRow("DragDrop 4") << true << true << QAbstractItemView::DragDrop << true << QAbstractItemView::DragDrop;
QTest::newRow("DragDrop 5") << true << true << QAbstractItemView::InternalMove << QAbstractItemView::InternalMove; QTest::newRow("DragDrop 5") << true << true << QAbstractItemView::InternalMove << true << QAbstractItemView::InternalMove;
} }
void tst_QTreeView::dragDropModeFromDragEnabledAndAcceptDrops() void tst_QTreeView::dragDropModeFromDragEnabledAndAcceptDrops()
@ -665,13 +623,14 @@ void tst_QTreeView::dragDropModeFromDragEnabledAndAcceptDrops()
QFETCH(bool, acceptDrops); QFETCH(bool, acceptDrops);
QFETCH(bool, dragEnabled); QFETCH(bool, dragEnabled);
QFETCH(QAbstractItemView::DragDropMode, dragDropMode); QFETCH(QAbstractItemView::DragDropMode, dragDropMode);
QFETCH(QAbstractItemView::DragDropMode, setBehavior); QFETCH(bool, setBehavior);
QFETCH(QAbstractItemView::DragDropMode, behavior);
QTreeView view; QTreeView view;
QCOMPARE(view.dragDropMode(), QAbstractItemView::NoDragDrop); QCOMPARE(view.dragDropMode(), QAbstractItemView::NoDragDrop);
if (setBehavior != QAbstractItemView::DragDropMode(-1)) if (setBehavior)
view.setDragDropMode(setBehavior); view.setDragDropMode(behavior);
view.setAcceptDrops(acceptDrops); view.setAcceptDrops(acceptDrops);
view.setDragEnabled(dragEnabled); view.setDragEnabled(dragEnabled);
@ -1743,7 +1702,7 @@ void tst_QTreeView::moveCursor()
QFETCH(bool, scrollPerPixel); QFETCH(bool, scrollPerPixel);
QtTestModel model(8, 6); QtTestModel model(8, 6);
PublicView view; QTreeView view;
view.setUniformRowHeights(uniformRowHeights); view.setUniformRowHeights(uniformRowHeights);
view.setModel(&model); view.setModel(&model);
view.setRowHidden(0, QModelIndex(), true); view.setRowHidden(0, QModelIndex(), true);
@ -1762,7 +1721,7 @@ void tst_QTreeView::moveCursor()
QCOMPARE(view.currentIndex(), expected); QCOMPARE(view.currentIndex(), expected);
//then pressing down should go to the next line //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()); expected = model.index(2, 1, QModelIndex());
QCOMPARE(actual, expected); QCOMPARE(actual, expected);
@ -1771,7 +1730,7 @@ void tst_QTreeView::moveCursor()
// PageUp was broken with uniform row heights turned on // PageUp was broken with uniform row heights turned on
view.setCurrentIndex(model.index(1, 0)); 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()); expected = model.index(0, 0, QModelIndex());
QCOMPARE(actual, expected); QCOMPARE(actual, expected);
@ -1870,7 +1829,7 @@ void tst_QTreeView::setSelection()
QtTestModel model(10, 5); QtTestModel model(10, 5);
model.levels = 1; model.levels = 1;
model.setDecorationsEnabled(true); model.setDecorationsEnabled(true);
PublicView view; QTreeView view;
view.resize(400, 300); view.resize(400, 300);
view.show(); view.show();
view.setRootIsDecorated(false); view.setRootIsDecorated(false);
@ -2058,7 +2017,7 @@ void tst_QTreeView::rowsAboutToBeRemoved()
} }
} }
PublicView view; QTreeView view;
view.setModel(&model); view.setModel(&model);
view.show(); view.show();
QModelIndex index = model.index(0,0, QModelIndex()); QModelIndex index = model.index(0,0, QModelIndex());
@ -2072,7 +2031,7 @@ void tst_QTreeView::rowsAboutToBeRemoved()
QSignalSpy spy1(&model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); QSignalSpy spy1(&model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
model.removeRows(1,1); model.removeRows(1,1);
QCOMPARE(view.state(), 0); QCOMPARE(int(view.state()), 0);
// Should not be 5 (or any other number for that sake :) // Should not be 5 (or any other number for that sake :)
QCOMPARE(spy1.count(), 1); QCOMPARE(spy1.count(), 1);
@ -2175,7 +2134,7 @@ void tst_QTreeView::rowsAboutToBeRemoved_move()
view.resize(600,800); view.resize(600,800);
view.show(); view.show();
view.doItemsLayout(); view.doItemsLayout();
static_cast<PublicView *>(&view)->executeDelayedItemsLayout(); static_cast<QTreeView *>(&view)->executeDelayedItemsLayout();
parent = indexThatWantsToLiveButWillDieDieITellYou.parent(); parent = indexThatWantsToLiveButWillDieDieITellYou.parent();
QCOMPARE(view.isExpanded(indexThatWantsToLiveButWillDieDieITellYou), true); QCOMPARE(view.isExpanded(indexThatWantsToLiveButWillDieDieITellYou), true);
QCOMPARE(parent.isValid(), true); QCOMPARE(parent.isValid(), true);
@ -2283,7 +2242,7 @@ void tst_QTreeView::spanningItems()
{ {
QtTestModel model; QtTestModel model;
model.rows = model.cols = 10; model.rows = model.cols = 10;
PublicView view; QTreeView view;
view.setModel(&model); view.setModel(&model);
view.show(); view.show();
@ -2422,7 +2381,7 @@ void tst_QTreeView::selectionWithHiddenItems()
void tst_QTreeView::selectAll() void tst_QTreeView::selectAll()
{ {
QStandardItemModel model(4,4); QStandardItemModel model(4,4);
PublicView view2; QTreeView view2;
view2.setModel(&model); view2.setModel(&model);
view2.setSelectionMode(QAbstractItemView::ExtendedSelection); view2.setSelectionMode(QAbstractItemView::ExtendedSelection);
view2.selectAll(); // Should work with an empty model view2.selectAll(); // Should work with an empty model
@ -2431,13 +2390,13 @@ void tst_QTreeView::selectAll()
for (int i = 0; i < model.rowCount(); ++i) for (int i = 0; i < model.rowCount(); ++i)
model.setData(model.index(i,0), QLatin1String("row ") + QString::number(i)); model.setData(model.index(i,0), QLatin1String("row ") + QString::number(i));
PublicView view; QTreeView view;
view.setModel(&model); view.setModel(&model);
int selectedCount = view.selectedIndexes().count(); int selectedCount = view.selectedIndexes().count();
view.selectAll(); view.selectAll();
QCOMPARE(view.selectedIndexes().count(), selectedCount); QCOMPARE(view.selectedIndexes().count(), selectedCount);
PublicView view3; QTreeView view3;
view3.setModel(&model); view3.setModel(&model);
view3.setSelectionMode(QAbstractItemView::NoSelection); view3.setSelectionMode(QAbstractItemView::NoSelection);
view3.selectAll(); view3.selectAll();
@ -2800,7 +2759,7 @@ void tst_QTreeView::evilModel()
{ {
QFETCH(bool, visible); QFETCH(bool, visible);
// init // init
PublicView view; QTreeView view;
EvilModel model; EvilModel model;
view.setModel(&model); view.setModel(&model);
view.setVisible(visible); view.setVisible(visible);
@ -2858,7 +2817,7 @@ void tst_QTreeView::evilModel()
view.setSelection(rect, QItemSelectionModel::Select); view.setSelection(rect, QItemSelectionModel::Select);
model.change(); model.change();
view.doMoveCursor(PublicView::MoveDown, Qt::NoModifier); view.moveCursor(QTreeView::MoveDown, Qt::NoModifier);
model.change(); model.change();
view.resizeColumnToContents(1); view.resizeColumnToContents(1);
@ -2969,7 +2928,7 @@ void tst_QTreeView::evilModel()
void tst_QTreeView::indexRowSizeHint() void tst_QTreeView::indexRowSizeHint()
{ {
QStandardItemModel model(10, 1); QStandardItemModel model(10, 1);
PublicView view; QTreeView view;
view.setModel(&model); view.setModel(&model);
@ -3015,7 +2974,7 @@ void tst_QTreeView::renderToPixmap_data()
void tst_QTreeView::renderToPixmap() void tst_QTreeView::renderToPixmap()
{ {
QFETCH(int, row); QFETCH(int, row);
PublicView view; QTreeView view;
QStandardItemModel model; QStandardItemModel model;
model.appendRow(new QStandardItem("Spanning")); model.appendRow(new QStandardItem("Spanning"));
@ -3031,7 +2990,7 @@ void tst_QTreeView::renderToPixmap()
// We select the index at row=1 for coverage. // We select the index at row=1 for coverage.
QItemSelection sel(model.index(row,0), model.index(row,1)); QItemSelection sel(model.index(row,0), model.index(row,1));
QRect rect; QRect rect;
view.aiv_priv()->renderToPixmap(sel.indexes(), &rect); view.d_func()->renderToPixmap(sel.indexes(), &rect);
} }
#endif #endif
} }
@ -3093,7 +3052,7 @@ void tst_QTreeView::styleOptionViewItem()
bool allCollapsed; bool allCollapsed;
}; };
PublicView view; QTreeView view;
QStandardItemModel model; QStandardItemModel model;
view.setModel(&model); view.setModel(&model);
MyDelegate delegate; MyDelegate delegate;
@ -3149,7 +3108,7 @@ void tst_QTreeView::styleOptionViewItem()
delegate.count = 0; delegate.count = 0;
QItemSelection sel(model.index(0,0), model.index(0,modelColumns-1)); QItemSelection sel(model.index(0,0), model.index(0,modelColumns-1));
QRect rect; QRect rect;
view.aiv_priv()->renderToPixmap(sel.indexes(), &rect); view.d_func()->renderToPixmap(sel.indexes(), &rect);
if (delegate.count != visibleColumns) { if (delegate.count != visibleColumns) {
qDebug() << rect << view.rect() << view.isVisible(); qDebug() << rect << view.rect() << view.isVisible();
} }
@ -3177,7 +3136,7 @@ void tst_QTreeView::styleOptionViewItem()
delegate.count = 0; delegate.count = 0;
QItemSelection sel(model.index(0,0), model.index(0,modelColumns-1)); QItemSelection sel(model.index(0,0), model.index(0,modelColumns-1));
QRect rect; QRect rect;
view.aiv_priv()->renderToPixmap(sel.indexes(), &rect); view.d_func()->renderToPixmap(sel.indexes(), &rect);
if (delegate.count != visibleColumns) { if (delegate.count != visibleColumns) {
qDebug() << rect << view.rect() << view.isVisible(); 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 // Note: define QT_BUILD_INTERNAL to run this test
void tst_QTreeView::taskQTBUG_25333_adjustViewOptionsForIndex() void tst_QTreeView::taskQTBUG_25333_adjustViewOptionsForIndex()
{ {
PublicView view; QTreeView view;
QStandardItemModel model; QStandardItemModel model;
QStandardItem *item1 = new QStandardItem("Item1"); QStandardItem *item1 = new QStandardItem("Item1");
QStandardItem *item2 = new QStandardItem("Item2"); QStandardItem *item2 = new QStandardItem("Item2");
@ -4165,9 +4124,9 @@ void tst_QTreeView::taskQTBUG_25333_adjustViewOptionsForIndex()
{ {
QStyleOptionViewItem option; 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 #endif
@ -4273,7 +4232,7 @@ void tst_QTreeView::quickExpandCollapse()
//this unit tests makes sure the state after the animation is restored correctly //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 //after starting a 2nd animation while the first one was still on-going
//this tests that the stateBeforeAnimation is not set to AnimatingState //this tests that the stateBeforeAnimation is not set to AnimatingState
PublicView tree; QTreeView tree;
tree.setAnimated(true); tree.setAnimated(true);
QStandardItemModel model; QStandardItemModel model;
QStandardItem *root = new QStandardItem("root"); QStandardItem *root = new QStandardItem("root");
@ -4287,13 +4246,13 @@ void tst_QTreeView::quickExpandCollapse()
tree.show(); tree.show();
QTest::qWaitForWindowExposed(&tree); QTest::qWaitForWindowExposed(&tree);
int initialState = tree.state(); const QAbstractItemView::State initialState = tree.state();
tree.expand(rootIndex); tree.expand(rootIndex);
QCOMPARE(tree.state(), (int)PublicView::AnimatingState); QCOMPARE(tree.state(), QTreeView::AnimatingState);
tree.collapse(rootIndex); 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 QTest::qWait(500); //the animation lasts for 250ms max so 500 should be enough