qt 6.5.1 original
91
tests/manual/CMakeLists.txt
Normal file
@ -0,0 +1,91 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Don't build manual tests when targeting iOS.
|
||||
if(UIKIT)
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_subdirectory(filetest)
|
||||
# diaglib is broken in dev due to missing
|
||||
# QtOpenGL/QGLFunctions headers
|
||||
# add_subdirectory(embeddedintoforeignwindow)
|
||||
# add_subdirectory(foreignwindows)
|
||||
add_subdirectory(gestures)
|
||||
add_subdirectory(highdpi)
|
||||
add_subdirectory(inputmethodhints)
|
||||
add_subdirectory(keypadnavigation)
|
||||
#add_subdirectory(lance) # special case qgl.h missing
|
||||
add_subdirectory(qcursor)
|
||||
add_subdirectory(qdesktopservices)
|
||||
add_subdirectory(qgraphicsitem)
|
||||
add_subdirectory(qgraphicsitemgroup)
|
||||
add_subdirectory(qgraphicslayout/flicker)
|
||||
add_subdirectory(qhttpnetworkconnection)
|
||||
add_subdirectory(qimagereader)
|
||||
add_subdirectory(qlayout)
|
||||
add_subdirectory(qlocale)
|
||||
add_subdirectory(qmimedatabase)
|
||||
add_subdirectory(qnetconmonitor)
|
||||
add_subdirectory(qnetworkaccessmanager/qget)
|
||||
add_subdirectory(qnetworkinformation)
|
||||
#special case begin
|
||||
if (QT_FEATURE_openssl AND UNIX)
|
||||
add_subdirectory(qnetworkreply)
|
||||
endif()
|
||||
#special case end
|
||||
if(QT_FEATURE_permissions)
|
||||
add_subdirectory(permissions)
|
||||
endif()
|
||||
add_subdirectory(qstorageinfo)
|
||||
add_subdirectory(qscreen)
|
||||
add_subdirectory(qscreen_xrandr)
|
||||
add_subdirectory(qsslsocket)
|
||||
add_subdirectory(qsysinfo)
|
||||
add_subdirectory(qtabletevent)
|
||||
add_subdirectory(qtexteditlist)
|
||||
add_subdirectory(qtexttableborders)
|
||||
add_subdirectory(qtbug-8933)
|
||||
add_subdirectory(qtbug-52641)
|
||||
add_subdirectory(qtouchevent)
|
||||
add_subdirectory(touch)
|
||||
add_subdirectory(qwidget_zorder)
|
||||
add_subdirectory(repaint)
|
||||
add_subdirectory(socketengine)
|
||||
add_subdirectory(textrendering)
|
||||
add_subdirectory(widgets)
|
||||
add_subdirectory(windowflags)
|
||||
add_subdirectory(windowgeometry)
|
||||
add_subdirectory(windowmodality)
|
||||
add_subdirectory(widgetgrab)
|
||||
if(QT_FEATURE_xcb)
|
||||
add_subdirectory(xembed)
|
||||
endif()
|
||||
add_subdirectory(xmlstreamlint)
|
||||
add_subdirectory(shortcuts)
|
||||
add_subdirectory(dialogs)
|
||||
add_subdirectory(windowmask)
|
||||
add_subdirectory(windowtransparency)
|
||||
add_subdirectory(unc)
|
||||
add_subdirectory(qtabbar)
|
||||
add_subdirectory(rhi)
|
||||
if(UNIX)
|
||||
add_subdirectory(network_remote_stresstest)
|
||||
add_subdirectory(network_stresstest)
|
||||
endif()
|
||||
if(QT_FEATURE_openssl)
|
||||
add_subdirectory(qssloptions)
|
||||
endif()
|
||||
if(QT_FEATURE_opengl)
|
||||
# add_subdirectory(qopengltextureblitter) special case broken in dev
|
||||
endif()
|
||||
if(QT_FEATURE_egl AND QT_FEATURE_opengl)
|
||||
# add_subdirectory(qopenglcontext) # special case broken in dev
|
||||
endif()
|
||||
if(QT_FEATURE_vulkan)
|
||||
add_subdirectory(qvulkaninstance)
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
add_subdirectory(android_content_uri)
|
||||
endif()
|
7
tests/manual/android_content_uri/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
qt_internal_add_test(tst_content_uris
|
||||
SOURCES
|
||||
tst_content_uris.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Widgets
|
||||
)
|
252
tests/manual/android_content_uri/tst_content_uris.cpp
Normal file
@ -0,0 +1,252 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QTest>
|
||||
#include <QDirIterator>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
class tst_ContentUris: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void dirFacilities();
|
||||
void readWriteFile();
|
||||
void readWriteNonExistingFile_data();
|
||||
void readWriteNonExistingFile();
|
||||
void createFileFromDirUrl_data();
|
||||
void createFileFromDirUrl();
|
||||
void fileOperations();
|
||||
};
|
||||
|
||||
static QStringList listFiles(const QDir &dir, QDirIterator::IteratorFlag flag = {})
|
||||
{
|
||||
QDirIterator it(dir, flag);
|
||||
QStringList dirs;
|
||||
while (it.hasNext())
|
||||
dirs << it.next();
|
||||
return dirs;
|
||||
}
|
||||
|
||||
void showInstructionsDialog(const QString &message)
|
||||
{
|
||||
QMessageBox::information(nullptr, "Instructions", message);
|
||||
}
|
||||
|
||||
void tst_ContentUris::dirFacilities()
|
||||
{
|
||||
showInstructionsDialog("Choose a folder with no content/files/subdirs");
|
||||
|
||||
auto url = QFileDialog::getExistingDirectory();
|
||||
QVERIFY(url.startsWith("content"_L1));
|
||||
QDir dir(url);
|
||||
|
||||
QVERIFY(dir.exists());
|
||||
QVERIFY(!dir.dirName().isEmpty());
|
||||
QVERIFY(listFiles(dir).isEmpty());
|
||||
|
||||
QVERIFY(dir.mkdir("Sub"));
|
||||
const auto dirList = listFiles(dir);
|
||||
QVERIFY(dirList.size() == 1);
|
||||
const QDir subDir = dirList.first();
|
||||
|
||||
QVERIFY(subDir.dirName() == "Sub"_L1);
|
||||
qWarning() << "subDir.absolutePath()" << subDir.absolutePath() << dirList.first();
|
||||
QVERIFY(subDir.absolutePath() == dirList.first());
|
||||
QVERIFY(subDir.path() == dirList.first());
|
||||
|
||||
QVERIFY(listFiles(dir, QDirIterator::Subdirectories).size() == 1);
|
||||
QVERIFY(dir.mkdir("Sub")); // Create an existing dir
|
||||
QVERIFY(dir.rmdir("Sub"));
|
||||
|
||||
QVERIFY(dir.mkpath("Sub/Sub2/Sub3"));
|
||||
QVERIFY(listFiles(dir).size() == 1);
|
||||
QVERIFY(listFiles(dir, QDirIterator::Subdirectories).size() == 3);
|
||||
QVERIFY(dir.mkpath("Sub/Sub2/Sub3")); // Create an existing dir hierarchy
|
||||
QVERIFY(dir.rmdir("Sub"));
|
||||
}
|
||||
|
||||
void tst_ContentUris::readWriteFile()
|
||||
{
|
||||
const QByteArray content = "Written to file";
|
||||
const QString fileName = "new_file.txt";
|
||||
|
||||
{
|
||||
showInstructionsDialog("Choose a name for new file to create");
|
||||
|
||||
auto url = QFileDialog::getSaveFileName(nullptr, tr("Save File"), fileName);
|
||||
QFile file(url);
|
||||
QVERIFY(file.exists());
|
||||
QVERIFY(file.size() == 0);
|
||||
QVERIFY(file.fileName() == url);
|
||||
QVERIFY(QFileInfo(url).fileName() == fileName);
|
||||
|
||||
QVERIFY(file.open(QFile::WriteOnly));
|
||||
QVERIFY(file.isOpen());
|
||||
QVERIFY(file.isWritable());
|
||||
QVERIFY(file.fileTime(QFileDevice::FileModificationTime) != QDateTime());
|
||||
QVERIFY(file.write(content) > 0);
|
||||
QVERIFY(file.size() == content.size());
|
||||
file.close();
|
||||
|
||||
// NOTE: The native file cursor is not returning an updated time or it takes long
|
||||
// for it to get updated, for now just check that we actually received a valid QDateTime
|
||||
QVERIFY(file.fileTime(QFileDevice::FileModificationTime) != QDateTime());
|
||||
}
|
||||
|
||||
{
|
||||
showInstructionsDialog("Choose the file that was created");
|
||||
|
||||
auto url = QFileDialog::getOpenFileName(nullptr, tr("Open File"), fileName);
|
||||
QFile file(url);
|
||||
QVERIFY(file.exists());
|
||||
|
||||
QVERIFY(file.open(QFile::ReadOnly));
|
||||
QVERIFY(file.isOpen());
|
||||
QVERIFY(file.isReadable());
|
||||
QVERIFY(file.readAll() == content);
|
||||
|
||||
QVERIFY(file.remove());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_ContentUris::readWriteNonExistingFile_data()
|
||||
{
|
||||
QTest::addColumn<QString>("path");
|
||||
|
||||
const QString fileName = "non-existing-file.txt";
|
||||
const QString uriSchemeAuthority = "content://com.android.externalstorage.documents";
|
||||
const QString id = "primary%3APictures";
|
||||
const QString encSlash = QUrl::toPercentEncoding("/"_L1);
|
||||
|
||||
const QString docSlash = uriSchemeAuthority + "/document/"_L1 + id + "/"_L1 + fileName;
|
||||
const QString docEncodedSlash = uriSchemeAuthority + "/document/"_L1 + id + encSlash + fileName;
|
||||
|
||||
QTest::newRow("document_with_slash") << docSlash;
|
||||
QTest::newRow("document_with_encoded_slash") << docEncodedSlash;
|
||||
}
|
||||
|
||||
void tst_ContentUris::readWriteNonExistingFile()
|
||||
{
|
||||
QFETCH(QString, path);
|
||||
|
||||
QFile file(path);
|
||||
QVERIFY(!file.exists());
|
||||
QVERIFY(file.size() == 0);
|
||||
|
||||
QVERIFY(!file.open(QFile::WriteOnly));
|
||||
QVERIFY(!file.isOpen());
|
||||
QVERIFY(!file.isWritable());
|
||||
}
|
||||
|
||||
void tst_ContentUris::createFileFromDirUrl_data()
|
||||
{
|
||||
QTest::addColumn<QString>("path");
|
||||
|
||||
showInstructionsDialog("Choose a folder with no content/files/subdirs");
|
||||
|
||||
const QString treeUrl = QFileDialog::getExistingDirectory();
|
||||
const QString fileName = "text.txt";
|
||||
const QString treeSlash = treeUrl + "/"_L1 + fileName;
|
||||
QTest::newRow("tree_with_slash") << treeSlash;
|
||||
|
||||
// TODO: This is not handled at the moment
|
||||
// const QString encSlash = QUrl::toPercentEncoding("/"_L1);
|
||||
// const QString treeEncodedSlash = treeUrl + encSlash + fileName;
|
||||
// QTest::newRow("tree_with_encoded_slash") << treeEncodedSlash;
|
||||
}
|
||||
|
||||
void tst_ContentUris::createFileFromDirUrl()
|
||||
{
|
||||
QFETCH(QString, path);
|
||||
|
||||
const QByteArray content = "Written to file";
|
||||
|
||||
QFile file(path);
|
||||
QVERIFY(!file.exists());
|
||||
QVERIFY(file.size() == 0);
|
||||
|
||||
QVERIFY(file.open(QFile::WriteOnly));
|
||||
QVERIFY(file.isOpen());
|
||||
QVERIFY(file.isWritable());
|
||||
QVERIFY(file.exists());
|
||||
QVERIFY(file.write(content));
|
||||
QVERIFY(file.size() == content.size());
|
||||
file.close();
|
||||
|
||||
QVERIFY(file.open(QFile::ReadOnly));
|
||||
QVERIFY(file.isOpen());
|
||||
QVERIFY(file.isReadable());
|
||||
QVERIFY(file.readAll() == content);
|
||||
|
||||
QVERIFY(file.remove());
|
||||
}
|
||||
|
||||
void tst_ContentUris::fileOperations()
|
||||
{
|
||||
showInstructionsDialog("Choose a name for new file to create");
|
||||
|
||||
const QString fileName = "new_file.txt";
|
||||
auto url = QFileDialog::getSaveFileName(nullptr, tr("Save File"), fileName);
|
||||
QFile file(url);
|
||||
QVERIFY(file.exists());
|
||||
|
||||
// Rename
|
||||
{
|
||||
const QString renamedFileName = "renamed_new_file.txt";
|
||||
QVERIFY(file.rename(renamedFileName));
|
||||
const auto renamedUrl = url.replace(fileName, renamedFileName);
|
||||
QVERIFY(file.fileName() == renamedUrl);
|
||||
|
||||
// NOTE: The uri doesn't seem to stay usable after a rename and it needs to get
|
||||
// permission again via the SAF picker.
|
||||
showInstructionsDialog("Choose the file that was renamed");
|
||||
QFileDialog::getOpenFileName(nullptr, tr("Open File"));
|
||||
QVERIFY(file.exists());
|
||||
|
||||
// rename now with full content uri
|
||||
const auto secondRenamedUrl = url.replace(renamedFileName, "second_nenamed_file.txt");
|
||||
QVERIFY(file.rename(secondRenamedUrl));
|
||||
QVERIFY(file.fileName() == secondRenamedUrl);
|
||||
|
||||
// NOTE: The uri doesn't seem to stay usable after a rename and it needs to get
|
||||
// permission again via the SAF picker.
|
||||
showInstructionsDialog("Choose the file that was renamed");
|
||||
QFileDialog::getOpenFileName(nullptr, tr("Open File"));
|
||||
QVERIFY(file.exists());
|
||||
}
|
||||
|
||||
// Remove
|
||||
QVERIFY(file.remove());
|
||||
QVERIFY(!file.exists());
|
||||
|
||||
// Move
|
||||
{
|
||||
showInstructionsDialog("Choose source directory of file to move");
|
||||
const QString srcDir = QFileDialog::getExistingDirectory(nullptr, tr("Choose Directory"));
|
||||
|
||||
const QString fileName = "file_to_move.txt"_L1;
|
||||
|
||||
// Create a file
|
||||
QFile file(srcDir + u'/' + fileName);
|
||||
QVERIFY(file.open(QFile::WriteOnly));
|
||||
QVERIFY(file.exists());
|
||||
|
||||
showInstructionsDialog("Choose target directory to where to move the file");
|
||||
const QString destDir = QFileDialog::getExistingDirectory(nullptr, tr("Choose Directory"));
|
||||
|
||||
QVERIFY(file.rename(destDir + u'/' + fileName));
|
||||
|
||||
// NOTE: The uri doesn't seem to stay usable after a rename and it needs to get
|
||||
// permission again via the SAF picker.
|
||||
showInstructionsDialog("Choose the file that was moved");
|
||||
QFileDialog::getOpenFileName(nullptr, tr("Open File"));
|
||||
|
||||
QVERIFY(file.remove());
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_ContentUris)
|
||||
#include "tst_content_uris.moc"
|
@ -0,0 +1,76 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# How to run the test:
|
||||
# 1. Create the build directory, e.g. /home/user/build_test_copy_file_if_different
|
||||
# 2. cd /home/user/build_test_copy_file_if_different
|
||||
# 3. /path/to/Qt/bin/qt-cmake /path/to/Qt/Sources/qtbase/tests/manual/cmake/test_copy_file_if_different_command
|
||||
# 4. cmake --build . --parallel
|
||||
# 5. ctest
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(test_copy_file_if_different_command
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
if(NOT CMAKE_HOST_WIN32)
|
||||
message("Test only applicable for WIN32 platform. Nothing to do.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
message("Test should only be run on host system. Crosscompiling is not supported.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_program(fsutil NAMES fsutil fsutil.exe)
|
||||
if(NOT fsutil)
|
||||
message(WARNING "Unable to find 'fsutil' executable. Skipping the test")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core)
|
||||
|
||||
function(test_copy_file_command output_file test_data_base_name size)
|
||||
set(testdatasrc1 "${CMAKE_CURRENT_BINARY_DIR}/${test_data_base_name}1.bin")
|
||||
set(testdatasrc2 "${CMAKE_CURRENT_BINARY_DIR}/${test_data_base_name}2.bin")
|
||||
set(testdatadst "${CMAKE_CURRENT_BINARY_DIR}/${test_data_base_name}.bin")
|
||||
|
||||
# Remove existing data first
|
||||
file(REMOVE "${testdatasrc1}" "${testdatasrc2}" "${testdatadst}")
|
||||
|
||||
file(TO_NATIVE_PATH "${testdatasrc1}" native_testdatasrc)
|
||||
execute_process(COMMAND ${fsutil} file createNew "${native_testdatasrc}" ${size}
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "Unable to allocate file ${native_testdatasrc}"
|
||||
" of size ${size} for test"
|
||||
)
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${testdatasrc1}" "${testdatasrc2}"
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "Unable to copy test data from ${testdatasrc1} to ${testdatasrc2}")
|
||||
endif()
|
||||
|
||||
foreach(src_file_num RANGE 1 2)
|
||||
set(src_file "${testdatasrc${src_file_num}}")
|
||||
file(APPEND "${src_file}" "${src_file_num}")
|
||||
_qt_internal_copy_file_if_different_command(copy_command "${src_file}" "${testdatadst}")
|
||||
execute_process(COMMAND ${copy_command} RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "Unable to execute the copy command ${copy_command}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(${output_file} "${testdatadst}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
test_copy_file_command(output_file1K testdata1K 1024)
|
||||
test_copy_file_command(output_file2GB testdata2GB 2147483648)
|
||||
|
||||
add_executable(test_copy_if_different_command main.cpp)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME "test_copy_if_different_command" COMMAND test_copy_if_different_command "${output_file1K}" "${output_file2GB}")
|
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
int checkFileLastByte(const std::string &filename, std::fstream::off_type offset)
|
||||
{
|
||||
std::ifstream file(filename, std::ios_base::in);
|
||||
if (!file.is_open()) {
|
||||
std::cerr << "Unable to open test data file: " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
file.seekg(offset, std::ios_base::beg);
|
||||
char data = 0;
|
||||
file.read(&data, sizeof(data));
|
||||
if (data != '2') { // We always expect it's the second copy of the file
|
||||
std::cerr << "Invalid data inside the file: " << filename << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 3) {
|
||||
std::cerr << "Test requires exact 2 arguments that point to the test data" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int result = checkFileLastByte(argv[1], 1024);
|
||||
if (result != 0)
|
||||
return result;
|
||||
return checkFileLastByte(argv[2], 2147483648);
|
||||
}
|
15
tests/manual/cocoa/appicon/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## appicon Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(appicon
|
||||
GUI
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
3
tests/manual/cocoa/appicon/README
Normal file
@ -0,0 +1,3 @@
|
||||
Test for checking that the dock icon is changed when
|
||||
QGuiApplication::setWindowIcon() is called. Clicking the
|
||||
buttong should change the entry in the dock to a red icon.
|
4
tests/manual/cocoa/appicon/appicon.pro
Normal file
@ -0,0 +1,4 @@
|
||||
QT += widgets
|
||||
TEMPLATE = app
|
||||
TARGET = appicon
|
||||
SOURCES += main.cpp
|
38
tests/manual/cocoa/appicon/main.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class TopWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TopWidget(QWidget *parent = nullptr) : QWidget(parent)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
QPushButton *button = new QPushButton("Change app icon");
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(changeIcon()));
|
||||
layout->addWidget(button);
|
||||
setLayout(layout);
|
||||
}
|
||||
public slots:
|
||||
void changeIcon()
|
||||
{
|
||||
QPixmap pix(32, 32);
|
||||
pix.fill(Qt::red);
|
||||
QIcon i(pix);
|
||||
qApp->setWindowIcon(i);
|
||||
}
|
||||
};
|
||||
|
||||
#include "main.moc"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
TopWidget w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
19
tests/manual/cocoa/menurama/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## Menurama Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(Menurama
|
||||
GUI
|
||||
SOURCES
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.h mainwindow.ui
|
||||
menuramaapplication.cpp menuramaapplication.h
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
ENABLE_AUTOGEN_TOOLS
|
||||
uic
|
||||
)
|
51
tests/manual/cocoa/menurama/main.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "menuramaapplication.h"
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtWidgets/QMenu>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
MenuramaApplication a(argc, argv);
|
||||
a.setQuitOnLastWindowClosed(false);
|
||||
|
||||
auto *dockMenu = new QMenu();
|
||||
dockMenu->setAsDockMenu();
|
||||
dockMenu->addAction(QLatin1String("New Window"), [=] {
|
||||
auto *w = new MainWindow;
|
||||
w->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
w->show();
|
||||
});
|
||||
auto *disabledAction = dockMenu->addAction(QLatin1String("Disabled Item"), [=] {
|
||||
qDebug() << "Should not happen!";
|
||||
Q_UNREACHABLE();
|
||||
});
|
||||
disabledAction->setEnabled(false);
|
||||
dockMenu->addAction(QLatin1String("Last Item Before Separator"), [=] {
|
||||
qDebug() << "Last Item triggered";
|
||||
});
|
||||
auto *hiddenAction = dockMenu->addAction(QLatin1String("Invisible Item (FIXME rdar:39615815)"), [=] {
|
||||
qDebug() << "Should not happen!";
|
||||
Q_UNREACHABLE();
|
||||
});
|
||||
hiddenAction->setVisible(false);
|
||||
dockMenu->addSeparator();
|
||||
auto *toolsMenu = dockMenu->addMenu(QLatin1String("Menurama Tools"));
|
||||
toolsMenu->addAction(QLatin1String("Hammer"), [=] {
|
||||
qDebug() << "Bang! Bang!";
|
||||
});
|
||||
toolsMenu->addAction(QLatin1String("Wrench"), [=] {
|
||||
qDebug() << "Clang! Clang!";
|
||||
});
|
||||
toolsMenu->addAction(QLatin1String("Screwdriver"), [=] {
|
||||
qDebug() << "Squeak! Squeak!";
|
||||
});
|
||||
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
73
tests/manual/cocoa/menurama/mainwindow.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "menuramaapplication.h"
|
||||
#include <QDebug>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
auto *a = ui->menuStuff->addAction("Enabled Submenu (QTBUG-63172)");
|
||||
auto *qtbug63172_Menu = new QMenu;
|
||||
qtbug63172_Menu->addAction("We're Good!");
|
||||
a->setMenu(qtbug63172_Menu);
|
||||
|
||||
startTimer(1000);
|
||||
|
||||
connect(ui->menuAfter_aboutToShow, &QMenu::aboutToShow, [=] {
|
||||
menuApp->populateMenu(ui->menuAfter_aboutToShow, true /*clear*/);
|
||||
});
|
||||
|
||||
connect(ui->menuDynamic_Stuff, &QMenu::aboutToShow, [=] {
|
||||
menuApp->addDynMenu(QLatin1String("Menu Added After aboutToShow()"), ui->menuDynamic_Stuff);
|
||||
|
||||
const QLatin1String itemTitle = QLatin1String("Disabled Item Added After aboutToShow()");
|
||||
if (QAction *a = menuApp->findAction(itemTitle, ui->menuDynamic_Stuff))
|
||||
ui->menuDynamic_Stuff->removeAction(a);
|
||||
QAction *a = ui->menuDynamic_Stuff->addAction(itemTitle);
|
||||
a->setEnabled(false);
|
||||
});
|
||||
|
||||
connect(ui->pushButton, &QPushButton::clicked, [=] {
|
||||
menuApp->populateMenu(ui->menuOn_Click, true /*clear*/);
|
||||
});
|
||||
|
||||
connect(ui->addManyButton, &QPushButton::clicked, [=] {
|
||||
QMenu *menu = new QMenu(QLatin1String("Many More ") +
|
||||
QString::number(ui->menuBar->actions().count()));
|
||||
ui->menuBar->insertMenu(ui->menuDynamic_Stuff->menuAction(), menu);
|
||||
for (int i = 0; i < 2000; i++) {
|
||||
auto *action = menu->addAction(QLatin1String("Item ") + QString::number(i));
|
||||
if (i & 0x1)
|
||||
action->setEnabled(false);
|
||||
if (i & 0x2)
|
||||
action->setVisible(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MainWindow::timerEvent(QTimerEvent *)
|
||||
{
|
||||
menuApp->populateMenu(ui->menuPopulated_by_Timer, true /*clear*/);
|
||||
menuApp->addDynMenu(QLatin1String("Added by Timer"), ui->menuDynamic_Stuff);
|
||||
}
|
||||
|
||||
void MainWindow::enableStuffMenu(bool enable)
|
||||
{
|
||||
ui->menuStuff->setEnabled(enable);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionQuit_triggered()
|
||||
{
|
||||
menuApp->exit();
|
||||
}
|
34
tests/manual/cocoa/menurama/mainwindow.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *) override;
|
||||
|
||||
public slots:
|
||||
void enableStuffMenu(bool enable);
|
||||
|
||||
private slots:
|
||||
void on_actionQuit_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
328
tests/manual/cocoa/menurama/mainwindow.ui
Normal file
@ -0,0 +1,328 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>486</width>
|
||||
<height>376</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>The "Help" menu should NOT be visible.
|
||||
|
||||
Click on "Dynamic Stuff" then move left and right to other menus. Disabled items should remain that way.</string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="text">
|
||||
<string>Enable "Stuff" Menu</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Populate Dynamic Submenu</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QPushButton" name="addManyButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add Many Items</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Adding hundreds of items should not block the UI for noticeable periods of time. Odd numbered items should be disabled, those with 2nd LSB on should be hidden.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Check out the dock menu. You can close this window to verify that its actions will trigger in the absence of any window. And you can add more windows from there too.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>486</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuStuff">
|
||||
<property name="title">
|
||||
<string>Stuff</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuSubmenu">
|
||||
<property name="title">
|
||||
<string>Submenu</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuMore_Submenu_2">
|
||||
<property name="title">
|
||||
<string>More Submenu</string>
|
||||
</property>
|
||||
<addaction name="actionMOARH"/>
|
||||
</widget>
|
||||
<addaction name="actionWith_More_Stuff"/>
|
||||
<addaction name="menuMore_Submenu_2"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuDisabled_Submenu">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Disabled Submenu</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuMore_Submenu">
|
||||
<property name="title">
|
||||
<string>More Submenu</string>
|
||||
</property>
|
||||
<addaction name="actionShould_be_Disabled_Too"/>
|
||||
</widget>
|
||||
<addaction name="actionShould_be_Disabled"/>
|
||||
<addaction name="menuMore_Submenu"/>
|
||||
</widget>
|
||||
<addaction name="actionItem"/>
|
||||
<addaction name="menuSubmenu"/>
|
||||
<addaction name="actionDisabled_Item"/>
|
||||
<addaction name="menuDisabled_Submenu"/>
|
||||
<addaction name="separator"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuDisabled_Stuff">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Disabled Stuff</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuSubmenu_2">
|
||||
<property name="title">
|
||||
<string>Disabled Submenu</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuSubsubmenu">
|
||||
<property name="title">
|
||||
<string>Disabled Subsubmenu</string>
|
||||
</property>
|
||||
<addaction name="actionWith_its_own_Stuff"/>
|
||||
</widget>
|
||||
<addaction name="actionMore_Disabled_Stuff"/>
|
||||
<addaction name="menuSubsubmenu"/>
|
||||
</widget>
|
||||
<addaction name="actionItem_2"/>
|
||||
<addaction name="menuSubmenu_2"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuShould_NOT_Be_Visible">
|
||||
<property name="title">
|
||||
<string>Should NOT Be Visible</string>
|
||||
</property>
|
||||
<addaction name="actionAbout"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuHelp">
|
||||
<property name="title">
|
||||
<string>Help</string>
|
||||
</property>
|
||||
<addaction name="actionAbout_Qt"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuDynamic_Stuff">
|
||||
<property name="title">
|
||||
<string>Dynamic Stuff</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuAfter_aboutToShow">
|
||||
<property name="title">
|
||||
<string>Populated After aboutToShow()</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuOn_Click">
|
||||
<property name="title">
|
||||
<string>Click Button to Populate</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuPopulated_by_Timer">
|
||||
<property name="title">
|
||||
<string>Populated by Timer</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menuOn_Click"/>
|
||||
<addaction name="menuAfter_aboutToShow"/>
|
||||
<addaction name="menuPopulated_by_Timer"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="actionNew"/>
|
||||
<addaction name="actionNo_Empty_Spaces_Below"/>
|
||||
<addaction name="actionQuit"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuStuff"/>
|
||||
<addaction name="menuDisabled_Stuff"/>
|
||||
<addaction name="menuShould_NOT_Be_Visible"/>
|
||||
<addaction name="menuDynamic_Stuff"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mainToolBar">
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<action name="actionWith_More_Stuff">
|
||||
<property name="text">
|
||||
<string>With More Stuff</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDisabled_Item">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disabled Item</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionItem">
|
||||
<property name="text">
|
||||
<string>Item</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShould_be_Disabled">
|
||||
<property name="text">
|
||||
<string>Should be Disabled</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShould_be_Disabled_Too">
|
||||
<property name="text">
|
||||
<string>Should be Disabled Too</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMOARH">
|
||||
<property name="text">
|
||||
<string>MOAR!!</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionItem_2">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disabled Item</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMore_Disabled_Stuff">
|
||||
<property name="text">
|
||||
<string>More Disabled Stuff</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionWith_its_own_Stuff">
|
||||
<property name="text">
|
||||
<string>With its own Disabled Stuff</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAbout">
|
||||
<property name="text">
|
||||
<string>About</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAbout_Qt">
|
||||
<property name="text">
|
||||
<string>About Qt</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQuit">
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNew">
|
||||
<property name="text">
|
||||
<string>New...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNo_Empty_Spaces_Below">
|
||||
<property name="text">
|
||||
<string>No Empty Spaces Below</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>checkBox</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>enableStuffMenu(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>62</x>
|
||||
<y>94</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>72</x>
|
||||
<y>73</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>enableStuffMenu(bool)</slot>
|
||||
</slots>
|
||||
</ui>
|
20
tests/manual/cocoa/menurama/menurama.pro
Normal file
@ -0,0 +1,20 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2016-08-10T14:21:46
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui widgets
|
||||
|
||||
TARGET = Menurama
|
||||
TEMPLATE = app
|
||||
|
||||
|
||||
SOURCES += main.cpp\
|
||||
mainwindow.cpp \
|
||||
menuramaapplication.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
menuramaapplication.h
|
||||
|
||||
FORMS += mainwindow.ui
|
50
tests/manual/cocoa/menurama/menuramaapplication.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "menuramaapplication.h"
|
||||
|
||||
MenuramaApplication::MenuramaApplication(int &argc, char **argv)
|
||||
: QApplication (argc, argv)
|
||||
{
|
||||
#if 0
|
||||
QMenuBar *mb = new QMenuBar();
|
||||
QMenu *menu = mb->addMenu("App Dynamic");
|
||||
QMenu *dynMenu = menu->addMenu("After aboutToShow()");
|
||||
connect(dynMenu, &QMenu::aboutToShow, [=] {
|
||||
qDebug() << "aboutToShow(), populating" << dynMenu;
|
||||
menuApp->populateMenu(dynMenu, true /*clear*/);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void MenuramaApplication::populateMenu(QMenu *menu, bool clear)
|
||||
{
|
||||
if (clear)
|
||||
menu->clear();
|
||||
|
||||
static const char *sym[] = { "Foo", "Bar", "Baz", "Huux" };
|
||||
static int id = 0;
|
||||
for (unsigned i = 0; i < sizeof(sym) / sizeof(sym[0]); i++)
|
||||
menu->addAction(QStringLiteral("%1 — %2 %3 ")
|
||||
.arg(menu->title()).arg(sym[i]).arg(id));
|
||||
++id;
|
||||
}
|
||||
|
||||
void MenuramaApplication::addDynMenu(QLatin1String title, QMenu *parentMenu)
|
||||
{
|
||||
if (QAction *a = findAction(title, parentMenu))
|
||||
parentMenu->removeAction(a);
|
||||
|
||||
QMenu *subMenu = new QMenu(title, parentMenu);
|
||||
populateMenu(subMenu, false /*clear*/);
|
||||
parentMenu->addMenu(subMenu);
|
||||
}
|
||||
|
||||
QAction *MenuramaApplication::findAction(QLatin1String title, QMenu *parentMenu)
|
||||
{
|
||||
foreach (QAction *a, parentMenu->actions())
|
||||
if (a->text() == title)
|
||||
return a;
|
||||
|
||||
return nullptr;
|
||||
}
|
22
tests/manual/cocoa/menurama/menuramaapplication.h
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef MENURAMAAPPLICATION_H
|
||||
#define MENURAMAAPPLICATION_H
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#define menuApp (static_cast<MenuramaApplication *>(QCoreApplication::instance()))
|
||||
|
||||
class MenuramaApplication : public QApplication
|
||||
{
|
||||
public:
|
||||
MenuramaApplication(int &argc, char **argv);
|
||||
void addDynMenu(QLatin1String title, QMenu *parentMenu);
|
||||
QAction *findAction(QLatin1String title, QMenu *parentMenu);
|
||||
|
||||
public slots:
|
||||
void populateMenu(QMenu *menu, bool clear);
|
||||
};
|
||||
|
||||
#endif // MENURAMAAPPLICATION_H
|
14
tests/manual/cocoa/menus/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## menus Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(menus
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
223
tests/manual/cocoa/menus/main.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
// Copyright (C) 2012 KDAB
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
#include <QApplication>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
|
||||
class Responder : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Responder(QObject *pr) :
|
||||
QObject(pr), visibleMenu(0), visibleSubMenu(0), enabledMenu(0), enabledSubMenu(0), visibleAction(0), enabledAction(0)
|
||||
{
|
||||
}
|
||||
void setVisibleObjects(QMenu *vm, QMenu *vsm, QAction *va)
|
||||
{
|
||||
visibleMenu = vm;
|
||||
visibleSubMenu = vsm;
|
||||
visibleAction = va;
|
||||
}
|
||||
void setEnabledObjects(QMenu *em, QMenu *esm, QAction *ea)
|
||||
{
|
||||
enabledMenu = em;
|
||||
enabledSubMenu = esm;
|
||||
enabledAction = ea;
|
||||
}
|
||||
public slots:
|
||||
void toggleVisiblity()
|
||||
{
|
||||
visibleMenu->menuAction()->setVisible(!visibleMenu->menuAction()->isVisible());
|
||||
visibleSubMenu->menuAction()->setVisible(!visibleSubMenu->menuAction()->isVisible());
|
||||
visibleAction->setVisible(!visibleAction->isVisible());
|
||||
}
|
||||
void toggleEnabled()
|
||||
{
|
||||
enabledMenu->menuAction()->setEnabled(!enabledMenu->menuAction()->isEnabled());
|
||||
enabledSubMenu->menuAction()->setEnabled(!enabledSubMenu->menuAction()->isEnabled());
|
||||
enabledAction->setEnabled(!enabledAction->isEnabled());
|
||||
}
|
||||
void toggleChecked(bool b)
|
||||
{
|
||||
QAction *a = qobject_cast<QAction *>(sender());
|
||||
}
|
||||
|
||||
void showModalDialog()
|
||||
{
|
||||
QMessageBox::information(NULL, "Something", "Something happened. Modally.");
|
||||
}
|
||||
|
||||
void doPreferences()
|
||||
{
|
||||
qDebug() << "show preferences";
|
||||
}
|
||||
|
||||
void aboutToShowSubmenu()
|
||||
{
|
||||
QMenu* m = (QMenu*) sender();
|
||||
qDebug() << "will show" << m;
|
||||
|
||||
m->clear();
|
||||
|
||||
for (int i=0; i<10; ++i) {
|
||||
m->addAction(QString("Recent File %1").arg(i + 1));
|
||||
}
|
||||
}
|
||||
private:
|
||||
QMenu *visibleMenu, *visibleSubMenu, *enabledMenu, *enabledSubMenu;
|
||||
QAction *visibleAction, *enabledAction;
|
||||
};
|
||||
|
||||
void createWindow1()
|
||||
{
|
||||
|
||||
QMainWindow *window = new QMainWindow;
|
||||
QMenu *menu = new QMenu("TestMenu", window);
|
||||
|
||||
window->menuBar()->addMenu(menu);
|
||||
|
||||
Responder *r = new Responder(window);
|
||||
|
||||
QAction *a = menu->addAction("TestMenuItem1");
|
||||
a->setShortcut( Qt::Key_A | Qt::SHIFT | Qt::CTRL );
|
||||
QObject::connect(a, SIGNAL(triggered()),
|
||||
r, SLOT(showModalDialog()));
|
||||
|
||||
|
||||
menu->addAction("T&estMenuItem2");
|
||||
a = menu->addAction("Preferences");
|
||||
a->setMenuRole(QAction::PreferencesRole);
|
||||
QObject::connect(a, SIGNAL(triggered()),
|
||||
r, SLOT(doPreferences()));
|
||||
|
||||
a = menu->addAction("TestMenuItem4");
|
||||
a->setShortcut( Qt::Key_W | Qt::CTRL);
|
||||
|
||||
QMenu *menu2 = new QMenu("SecondMenu", window);
|
||||
window->menuBar()->addMenu(menu2);
|
||||
|
||||
menu2->addAction("Yellow");
|
||||
a = menu2->addAction("Mau&ve");
|
||||
|
||||
QFont f;
|
||||
f.setPointSize(9);
|
||||
a->setFont(f);
|
||||
|
||||
menu2->addAction("Taupe");
|
||||
|
||||
QMenu *submenu1 = new QMenu("Submenu", window);
|
||||
submenu1->addAction("Sub Item 1");
|
||||
submenu1->addAction("Sub Item 2");
|
||||
submenu1->addAction("Sub Item 3");
|
||||
menu2->addMenu(submenu1);
|
||||
|
||||
QMenu *submenu2 = new QMenu("Deeper", window);
|
||||
submenu2->addAction("Sub Sub Item 1");
|
||||
submenu2->addAction("Sub Sub Item 2");
|
||||
submenu2->addAction("Sub Sub Item 3");
|
||||
submenu1->addMenu(submenu2);
|
||||
|
||||
QMenu *menu3 = new QMenu("A Third Menu", window);
|
||||
|
||||
menu3->addAction("Eins");
|
||||
|
||||
QMenu *submenu3 = new QMenu("Dynamic", window);
|
||||
QObject::connect(submenu3, SIGNAL(aboutToShow()), r, SLOT(aboutToShowSubmenu()));
|
||||
menu3->addMenu(submenu3);
|
||||
|
||||
a = menu3->addAction("Zwei");
|
||||
a->setShortcut( Qt::Key_3 | Qt::ALT);
|
||||
a = menu3->addAction("About Drei...");
|
||||
a->setMenuRole(QAction::AboutRole);
|
||||
|
||||
window->menuBar()->addMenu(menu3);
|
||||
|
||||
QAction *checkableAction = new QAction("Thing Enabled", window);
|
||||
checkableAction->setCheckable(true);
|
||||
checkableAction->setChecked(true);
|
||||
QObject::connect(checkableAction, SIGNAL(triggered(bool)),
|
||||
r, SLOT(toggleChecked(bool)));
|
||||
|
||||
menu2->addAction(checkableAction);
|
||||
|
||||
QMenu *menu4 = new QMenu("Toggle menu", window);
|
||||
QAction *toggleVisiblity = new QAction("Toggle visibility", window);
|
||||
QAction *toggleEnabled = new QAction("Toggle enabled", window);
|
||||
QObject::connect(toggleVisiblity, SIGNAL(triggered()), r, SLOT(toggleVisiblity()));
|
||||
QObject::connect(toggleEnabled, SIGNAL(triggered()), r, SLOT(toggleEnabled()));
|
||||
menu4->addAction(toggleVisiblity);
|
||||
menu4->addAction(toggleEnabled);
|
||||
window->menuBar()->addMenu(menu4);
|
||||
|
||||
QMenu *menu5 = new QMenu("Visible Menu", window);
|
||||
menu5->addAction("Dummy action");
|
||||
window->menuBar()->addMenu(menu5);
|
||||
QMenu *menu6 = new QMenu("Menu with visible action and submenu", window);
|
||||
QAction *visibleAction = new QAction("Visible action", window);
|
||||
menu6->addAction(visibleAction);
|
||||
QMenu *subMenu6 = new QMenu("Submenu");
|
||||
subMenu6->addAction("Dummy action");
|
||||
menu6->addMenu(subMenu6);
|
||||
window->menuBar()->addMenu(menu6);
|
||||
|
||||
QMenu *menu7 = new QMenu("Enabled Menu", window);
|
||||
menu7->addAction("Dummy action");
|
||||
window->menuBar()->addMenu(menu7);
|
||||
QMenu *menu8 = new QMenu("Menu with enabled action and submenu", window);
|
||||
QAction *enabledAction = new QAction("Enabled action", window);
|
||||
menu8->addAction(enabledAction);
|
||||
QMenu *subMenu8 = new QMenu("Submenu");
|
||||
subMenu8->addAction("Dummy action");
|
||||
menu8->addMenu(subMenu8);
|
||||
window->menuBar()->addMenu(menu8);
|
||||
|
||||
r->setVisibleObjects(menu5, subMenu6, visibleAction);
|
||||
r->setEnabledObjects(menu7, subMenu8, enabledAction);
|
||||
window->show();
|
||||
|
||||
}
|
||||
|
||||
void createWindow2()
|
||||
{
|
||||
QMainWindow *window = new QMainWindow;
|
||||
QMenu *menu = new QMenu("Nuts", window);
|
||||
|
||||
window->menuBar()->addMenu(menu);
|
||||
|
||||
menu->addAction("Peanuts");
|
||||
menu->addAction("Walnuts");
|
||||
|
||||
QMenu *menu2 = new QMenu("Colours", window);
|
||||
window->menuBar()->addMenu(menu2);
|
||||
|
||||
menu2->addAction("Pink");
|
||||
menu2->addAction("Yellow");
|
||||
menu2->addAction("Grape");
|
||||
|
||||
QMenu *menu3 = new QMenu("Edit", window);
|
||||
menu3->addAction("Cut");
|
||||
menu3->addAction("Copy boring way");
|
||||
menu3->addAction("Copy awesomely");
|
||||
menu3->addAction("Paste");
|
||||
|
||||
window->menuBar()->addMenu(menu3);
|
||||
window->show();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
QApplication app(argc, argv);
|
||||
|
||||
app.setApplicationName("Banana");
|
||||
|
||||
createWindow1();
|
||||
createWindow2();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
5
tests/manual/cocoa/menus/menus.pro
Normal file
@ -0,0 +1,5 @@
|
||||
TEMPLATE = app
|
||||
|
||||
SOURCES += main.cpp
|
||||
QT += gui widgets
|
||||
CONFIG -=app_bundle
|
15
tests/manual/cocoa/nativewidgets/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## nativewigets Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(nativewigets
|
||||
GUI
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
109
tests/manual/cocoa/nativewidgets/main.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtWidgets>
|
||||
|
||||
class ColorWidget : public QWidget
|
||||
{
|
||||
QColor color;
|
||||
int s;
|
||||
int v;
|
||||
|
||||
void changeColor()
|
||||
{
|
||||
color.setHsv(QRandomGenerator::global()->bounded(50) + 200, s, s);
|
||||
}
|
||||
|
||||
public:
|
||||
ColorWidget()
|
||||
{
|
||||
s = 150;
|
||||
v = 150;
|
||||
changeColor();
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
void mousePressEvent(QMouseEvent *)
|
||||
{
|
||||
changeColor();
|
||||
update();
|
||||
}
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *)
|
||||
{
|
||||
changeColor();
|
||||
update();
|
||||
}
|
||||
|
||||
void enterEvent(QEnterEvent *)
|
||||
{
|
||||
s = 200;
|
||||
v = 200;
|
||||
changeColor();
|
||||
update();
|
||||
}
|
||||
|
||||
void leaveEvent(QEvent *)
|
||||
{
|
||||
s = 75;
|
||||
v = 75;
|
||||
changeColor();
|
||||
update();
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent *){
|
||||
QPainter p(this);
|
||||
p.fillRect(QRect(QPoint(0, 0), size()), QBrush(color));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
ColorWidget window;
|
||||
|
||||
QWidget *w1 = new ColorWidget;
|
||||
QWidget *w2 = new ColorWidget;
|
||||
QWidget *w3 = new ColorWidget;
|
||||
|
||||
QHBoxLayout *layout = new QHBoxLayout;
|
||||
layout->addWidget(w1);
|
||||
layout->addWidget(w2);
|
||||
layout->addWidget(w3);
|
||||
|
||||
QWidget *w3_1 = new ColorWidget;
|
||||
QWidget *w3_2 = new ColorWidget;
|
||||
QWidget *w3_3 = new ColorWidget;
|
||||
|
||||
QVBoxLayout *layout3 = new QVBoxLayout;
|
||||
layout3->setMargin(0);
|
||||
layout3->addWidget(w3_1);
|
||||
layout3->addWidget(w3_2);
|
||||
layout3->addWidget(w3_3);
|
||||
w3->setLayout(layout3);
|
||||
|
||||
window.setLayout(layout);
|
||||
|
||||
bool native = 1;
|
||||
|
||||
if (native) {
|
||||
w1->winId();
|
||||
w2->winId();
|
||||
w3->winId();
|
||||
|
||||
w3_1->winId();
|
||||
w3_2->winId();
|
||||
w3_3->winId();
|
||||
}
|
||||
|
||||
window.resize(640, 480);
|
||||
window.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
|
||||
|
6
tests/manual/cocoa/nativewidgets/nativewigets.pro
Normal file
@ -0,0 +1,6 @@
|
||||
TEMPLATE = app
|
||||
|
||||
HEADERS +=
|
||||
SOURCES += main.cpp
|
||||
|
||||
QT += core widgets
|
14
tests/manual/cocoa/popups/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## popups Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(popups
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
122
tests/manual/cocoa/popups/main.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
class Window : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Window();
|
||||
|
||||
public slots:
|
||||
void triggered(QAction*);
|
||||
void clean();
|
||||
void showPoppWindow();
|
||||
|
||||
private:
|
||||
QLabel *explanation;
|
||||
QToolButton *toolButton;
|
||||
QMenu *menu;
|
||||
QLineEdit *echo;
|
||||
QComboBox *comboBox;
|
||||
QPushButton *pushButton;
|
||||
};
|
||||
|
||||
Window::Window()
|
||||
{
|
||||
QGroupBox* group = new QGroupBox(tr("test the popup"));
|
||||
|
||||
explanation = new QLabel(
|
||||
"This test is used to verify that popup windows will be closed "
|
||||
"as expected. This includes when clicking outside the popup or moving the "
|
||||
"parent window. Tested popups include context menus, combo box popups, tooltips "
|
||||
"and QWindow with Qt::Popup set."
|
||||
);
|
||||
explanation->setWordWrap(true);
|
||||
explanation->setToolTip("I'm a tool tip!");
|
||||
|
||||
menu = new QMenu(group);
|
||||
menu->addAction(tr("line one"));
|
||||
menu->addAction(tr("line two"));
|
||||
menu->addAction(tr("line three"));
|
||||
menu->addAction(tr("line four"));
|
||||
menu->addAction(tr("line five"));
|
||||
|
||||
QMenu *subMenu1 = new QMenu();
|
||||
subMenu1->addAction("1");
|
||||
subMenu1->addAction("2");
|
||||
subMenu1->addAction("3");
|
||||
menu->addMenu(subMenu1);
|
||||
|
||||
QMenu *subMenu2 = new QMenu();
|
||||
subMenu2->addAction("2 1");
|
||||
subMenu2->addAction("2 2");
|
||||
subMenu2->addAction("2 3");
|
||||
menu->addMenu(subMenu2);
|
||||
|
||||
toolButton = new QToolButton(group);
|
||||
toolButton->setMenu(menu);
|
||||
toolButton->setPopupMode( QToolButton::MenuButtonPopup );
|
||||
toolButton->setText("select me");
|
||||
|
||||
echo = new QLineEdit(group);
|
||||
echo->setPlaceholderText("not triggered");
|
||||
|
||||
connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*)));
|
||||
connect(menu, SIGNAL(aboutToShow()), this, SLOT(clean()));
|
||||
|
||||
comboBox = new QComboBox();
|
||||
comboBox->addItem("Item 1");
|
||||
comboBox->addItem("Item 2");
|
||||
comboBox->addItem("Item 3");
|
||||
|
||||
pushButton = new QPushButton("Show popup window");
|
||||
connect(pushButton, SIGNAL(clicked()), this, SLOT(showPoppWindow()));
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout;
|
||||
layout->addWidget(explanation);
|
||||
layout->addWidget(toolButton);
|
||||
layout->addWidget(echo);
|
||||
layout->addWidget(comboBox);
|
||||
layout->addWidget(pushButton);
|
||||
|
||||
group ->setLayout(layout);
|
||||
setLayout(layout);
|
||||
setWindowTitle(tr("Popup Window Testing"));
|
||||
}
|
||||
|
||||
void Window::clean()
|
||||
{
|
||||
echo->setText("");
|
||||
}
|
||||
|
||||
void Window::showPoppWindow()
|
||||
{
|
||||
QWindow *window = new QWindow();
|
||||
window->setTransientParent(this->windowHandle());
|
||||
window->setPosition(this->pos());
|
||||
window->setWidth(100);
|
||||
window->setHeight(100);
|
||||
window->setFlags(Qt::Window | Qt::Popup);
|
||||
window->show();
|
||||
}
|
||||
|
||||
void Window::triggered(QAction* act)
|
||||
{
|
||||
if (!act)
|
||||
return;
|
||||
echo->setText(act->text());
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
Window window;
|
||||
window.show();
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
4
tests/manual/cocoa/popups/popups.pro
Normal file
@ -0,0 +1,4 @@
|
||||
QT += widgets
|
||||
|
||||
SOURCES = main.cpp
|
||||
CONFIG -= app_bundle
|
35
tests/manual/cocoa/qsystemtrayicon/CMakeLists.txt
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## qsystemtrayicon Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(qsystemtrayicon
|
||||
GUI
|
||||
SOURCES
|
||||
main.cpp
|
||||
INCLUDE_DIRECTORIES
|
||||
.
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(icons_resource_files
|
||||
"macsystray16x16.png"
|
||||
"macsystray18x18.png"
|
||||
"macsystray25x15.png"
|
||||
"macsystray32x32.png"
|
||||
"macsystray36x36.png"
|
||||
"macsystray50x30.png"
|
||||
"macsystray64x64.png"
|
||||
)
|
||||
|
||||
qt_internal_add_resource(qsystemtrayicon "icons"
|
||||
PREFIX
|
||||
"/"
|
||||
FILES
|
||||
${icons_resource_files}
|
||||
)
|
11
tests/manual/cocoa/qsystemtrayicon/icons.qrc
Normal file
@ -0,0 +1,11 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>macsystray18x18.png</file>
|
||||
<file>macsystray36x36.png</file>
|
||||
<file>macsystray25x15.png</file>
|
||||
<file>macsystray50x30.png</file>
|
||||
<file>macsystray16x16.png</file>
|
||||
<file>macsystray32x32.png</file>
|
||||
<file>macsystray64x64.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
BIN
tests/manual/cocoa/qsystemtrayicon/macsystray16x16.png
Normal file
After Width: | Height: | Size: 101 B |
BIN
tests/manual/cocoa/qsystemtrayicon/macsystray18x18.png
Normal file
After Width: | Height: | Size: 108 B |
BIN
tests/manual/cocoa/qsystemtrayicon/macsystray25x15.png
Normal file
After Width: | Height: | Size: 109 B |
BIN
tests/manual/cocoa/qsystemtrayicon/macsystray32x32.png
Normal file
After Width: | Height: | Size: 117 B |
BIN
tests/manual/cocoa/qsystemtrayicon/macsystray36x36.png
Normal file
After Width: | Height: | Size: 151 B |
BIN
tests/manual/cocoa/qsystemtrayicon/macsystray50x30.png
Normal file
After Width: | Height: | Size: 167 B |
BIN
tests/manual/cocoa/qsystemtrayicon/macsystray64x64.png
Normal file
After Width: | Height: | Size: 204 B |
50
tests/manual/cocoa/qsystemtrayicon/main.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QtWidgets>
|
||||
|
||||
int main(int argc, char**argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QWidget window;
|
||||
window.show();
|
||||
|
||||
QSystemTrayIcon systrayIcon(&window);
|
||||
|
||||
|
||||
enum Iconset { Square, // square icons, reccomended size (18 device-independent pixels or less)
|
||||
Rectangular, // rectangular icons, good size
|
||||
PowerOfTwo, // standard pow-2 icons, not optimized for the OS X menu bar
|
||||
Small, // Not enough pixels
|
||||
UnreasonablyLarge // please do something reasonable with my unreasonably large pixmap
|
||||
};
|
||||
|
||||
// Select icon set and load images
|
||||
Iconset iconset = Square;
|
||||
QIcon icon;
|
||||
switch (iconset) {
|
||||
case Square:
|
||||
icon.addFile(":/macsystray36x36.png");
|
||||
icon.addFile(":/macsystray18x18.png");
|
||||
break;
|
||||
case Rectangular:
|
||||
icon.addFile(":/macsystray50x30.png");
|
||||
icon.addFile(":/macsystray25x15.png");
|
||||
break;
|
||||
case PowerOfTwo:
|
||||
icon.addFile(":/macsystray16x16.png");
|
||||
icon.addFile(":/macsystray32x32.png");
|
||||
icon.addFile(":/macsystray64x64.png");
|
||||
break;
|
||||
case Small:
|
||||
icon.addFile(":/macsystray16x16.png");
|
||||
case UnreasonablyLarge:
|
||||
icon.addFile(":/macsystray64x64.png");
|
||||
break;
|
||||
}
|
||||
|
||||
systrayIcon.setIcon(icon);
|
||||
systrayIcon.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
7
tests/manual/cocoa/qsystemtrayicon/qsystemtrayicon.pro
Normal file
@ -0,0 +1,7 @@
|
||||
TEMPLATE = app
|
||||
TARGET = qsystemtrayicon
|
||||
INCLUDEPATH += .
|
||||
QT += widgets
|
||||
|
||||
SOURCES += main.cpp
|
||||
RESOURCES += icons.qrc
|
18
tests/manual/cocoa/qt_on_cocoa/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## qt_on_cocoa Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(qt_on_cocoa
|
||||
GUI
|
||||
SOURCES
|
||||
main.mm
|
||||
rasterwindow.cpp rasterwindow.h
|
||||
LIBRARIES
|
||||
${FWAppKit}
|
||||
Qt::Gui
|
||||
Qt::Quick
|
||||
Qt::Widgets
|
||||
)
|
105
tests/manual/cocoa/qt_on_cocoa/main.mm
Normal file
@ -0,0 +1,105 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "rasterwindow.h"
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtWidgets/QtWidgets>
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
|
||||
@interface ContentView : NSView
|
||||
@end
|
||||
|
||||
@implementation ContentView
|
||||
- (void)drawRect:(NSRect)dirtyRect {
|
||||
[[NSColor whiteColor] setFill];
|
||||
NSRectFill(dirtyRect);
|
||||
}
|
||||
|
||||
- (void)cursorUpdate:(NSEvent *)theEvent
|
||||
{
|
||||
Q_UNUSED(theEvent);
|
||||
[[NSCursor pointingHandCursor] set];
|
||||
}
|
||||
@end
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
@end
|
||||
|
||||
@implementation AppDelegate {
|
||||
QGuiApplication *m_app;
|
||||
QWindow *m_window;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArgc:(int)argc argv:(const char **)argv
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
m_app = new QGuiApplication(argc, const_cast<char **>(argv));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)applicationWillFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
Q_UNUSED(notification);
|
||||
|
||||
// Create the NSWindow
|
||||
NSRect frame = NSMakeRect(500, 500, 500, 500);
|
||||
NSWindow *window = [[NSWindow alloc] initWithContentRect:frame
|
||||
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
|
||||
NSString *title = @"This the NSWindow window";
|
||||
[window setTitle:title];
|
||||
[window setBackgroundColor:[NSColor blueColor]];
|
||||
|
||||
NSView *contentView = [[[ContentView alloc] initWithFrame:frame] autorelease];
|
||||
[contentView addTrackingArea:[[NSTrackingArea alloc] initWithRect:[contentView frame]
|
||||
options:NSTrackingActiveInActiveApp | NSTrackingInVisibleRect | NSTrackingCursorUpdate
|
||||
owner:contentView userInfo:nil]];
|
||||
|
||||
// Create the QWindow, add its NSView to the content view
|
||||
m_window = new RasterWindow;
|
||||
m_window->setObjectName("RasterWindow");
|
||||
m_window->setCursor(Qt::CrossCursor);
|
||||
m_window->setGeometry(QRect(0, 0, 300, 300));
|
||||
|
||||
QWindow *childWindow = new RasterWindow;
|
||||
childWindow->setObjectName("RasterWindowChild");
|
||||
childWindow->setParent(m_window);
|
||||
childWindow->setCursor(Qt::BusyCursor);
|
||||
childWindow->setGeometry(50, 50, 100, 100);
|
||||
|
||||
NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 10, 80, 25)];
|
||||
[reinterpret_cast<NSView *>(childWindow->winId()) addSubview:textField];
|
||||
|
||||
[contentView addSubview:reinterpret_cast<NSView *>(m_window->winId())];
|
||||
|
||||
window.contentView = contentView;
|
||||
|
||||
// Show the NSWindow delayed, so that we can verify that Qt picks up the right
|
||||
// notifications to expose the window when it does become visible.
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[window makeKeyAndOrderFront:NSApp];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)notification
|
||||
{
|
||||
Q_UNUSED(notification);
|
||||
delete m_window;
|
||||
delete m_app;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
// Create NSApplicaiton with delgate
|
||||
NSApplication *app = [NSApplication sharedApplication];
|
||||
app.delegate = [[AppDelegate alloc] initWithArgc:argc argv:argv];
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
10
tests/manual/cocoa/qt_on_cocoa/qt_on_cocoa.pro
Normal file
@ -0,0 +1,10 @@
|
||||
TEMPLATE = app
|
||||
|
||||
OBJECTIVE_SOURCES += main.mm
|
||||
HEADERS += rasterwindow.h
|
||||
SOURCES += rasterwindow.cpp
|
||||
LIBS += -framework AppKit
|
||||
|
||||
QT += gui widgets quick
|
||||
|
||||
QT += quick
|
152
tests/manual/cocoa/qt_on_cocoa/rasterwindow.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "rasterwindow.h"
|
||||
|
||||
//#include <private/qguiapplication_p.h>
|
||||
|
||||
#include <QBackingStore>
|
||||
#include <QPainter>
|
||||
#include <QtWidgets>
|
||||
|
||||
static int colorIndexId = 0;
|
||||
|
||||
QColor colorTable[] =
|
||||
{
|
||||
QColor("#f09f8f"),
|
||||
QColor("#a2bff2"),
|
||||
QColor("#c0ef8f")
|
||||
};
|
||||
|
||||
RasterWindow::RasterWindow(QRasterWindow *parent)
|
||||
: QRasterWindow(parent)
|
||||
, m_backgroundColorIndex(colorIndexId++)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
void RasterWindow::initialize()
|
||||
{
|
||||
create();
|
||||
m_backingStore = new QBackingStore(this);
|
||||
|
||||
m_image = QImage(geometry().size(), QImage::Format_RGB32);
|
||||
m_image.fill(colorTable[m_backgroundColorIndex % (sizeof(colorTable) / sizeof(colorTable[0]))].rgba());
|
||||
|
||||
m_lastPos = QPoint(-1, -1);
|
||||
}
|
||||
|
||||
void RasterWindow::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
m_lastPos = event->pos();
|
||||
unsetCursor();
|
||||
}
|
||||
|
||||
void RasterWindow::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_lastPos != QPoint(-1, -1)) {
|
||||
QPainter p(&m_image);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.drawLine(m_lastPos, event->pos());
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
||||
scheduleRender();
|
||||
}
|
||||
|
||||
void RasterWindow::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_lastPos != QPoint(-1, -1)) {
|
||||
QPainter p(&m_image);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.drawLine(m_lastPos, event->pos());
|
||||
m_lastPos = QPoint(-1, -1);
|
||||
}
|
||||
|
||||
scheduleRender();
|
||||
}
|
||||
|
||||
void RasterWindow::exposeEvent(QExposeEvent *)
|
||||
{
|
||||
render();
|
||||
}
|
||||
|
||||
void RasterWindow::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
QImage old = m_image;
|
||||
|
||||
//qDebug() << "RasterWindow::resizeEvent" << width << height;
|
||||
|
||||
int width = qMax(geometry().width(), old.width());
|
||||
int height = qMax(geometry().height(), old.height());
|
||||
|
||||
if (width > old.width() || height > old.height()) {
|
||||
m_image = QImage(width, height, QImage::Format_RGB32);
|
||||
m_image.fill(colorTable[(m_backgroundColorIndex) % (sizeof(colorTable) / sizeof(colorTable[0]))].rgba());
|
||||
|
||||
QPainter p(&m_image);
|
||||
p.drawImage(0, 0, old);
|
||||
}
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
void RasterWindow::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
switch (event->key()) {
|
||||
case Qt::Key_Backspace:
|
||||
m_text.chop(1);
|
||||
break;
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
m_text.append('\n');
|
||||
break;
|
||||
default:
|
||||
m_text.append(event->text());
|
||||
break;
|
||||
}
|
||||
scheduleRender();
|
||||
}
|
||||
|
||||
void RasterWindow::scheduleRender()
|
||||
{
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
bool RasterWindow::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::UpdateRequest)
|
||||
render();
|
||||
|
||||
return QWindow::event(e);
|
||||
}
|
||||
|
||||
void RasterWindow::render()
|
||||
{
|
||||
if (!isExposed()) {
|
||||
qDebug() << "Skipping render, not exposed";
|
||||
return;
|
||||
}
|
||||
|
||||
QRect rect(QPoint(), geometry().size());
|
||||
|
||||
m_backingStore->resize(rect.size());
|
||||
|
||||
m_backingStore->beginPaint(rect);
|
||||
|
||||
QPaintDevice *device = m_backingStore->paintDevice();
|
||||
|
||||
QPainter p(device);
|
||||
p.drawImage(0, 0, m_image);
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(32);
|
||||
|
||||
p.setFont(font);
|
||||
p.drawText(rect, 0, m_text);
|
||||
|
||||
m_backingStore->endPaint();
|
||||
m_backingStore->flush(rect);
|
||||
}
|
||||
|
||||
|
34
tests/manual/cocoa/qt_on_cocoa/rasterwindow.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QRasterWindow>
|
||||
#include <QImage>
|
||||
|
||||
class RasterWindow : public QRasterWindow
|
||||
{
|
||||
public:
|
||||
RasterWindow(QRasterWindow *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
void mouseMoveEvent(QMouseEvent *);
|
||||
void mouseReleaseEvent(QMouseEvent *);
|
||||
|
||||
void keyPressEvent(QKeyEvent *);
|
||||
|
||||
void exposeEvent(QExposeEvent *);
|
||||
void resizeEvent(QResizeEvent *);
|
||||
|
||||
bool event(QEvent *);
|
||||
|
||||
private:
|
||||
void render();
|
||||
void scheduleRender();
|
||||
void initialize();
|
||||
|
||||
QString m_text;
|
||||
QImage m_image;
|
||||
QPoint m_lastPos;
|
||||
int m_backgroundColorIndex;
|
||||
QBackingStore *m_backingStore;
|
||||
};
|
1432
tests/manual/cocoa/textinput/Debug.keylayout
Normal file
14
tests/manual/cocoa/textinput/README
Normal file
@ -0,0 +1,14 @@
|
||||
# Debug keyboard layout
|
||||
|
||||
The keyboard layout in this directory can be enabled by
|
||||
copying it to "~/Library/Keyboard Layouts/" and adding it
|
||||
it as an input source in the macOS keyboard preferences.
|
||||
|
||||
The layout was created in Ukulele and tries to cover many
|
||||
corner cases of keyboard input related to e.g. modifier
|
||||
and dead key states.
|
||||
|
||||
# Useful tools
|
||||
|
||||
- https://software.sil.org/ukelele/
|
||||
- https://manytricks.com/keycodes/
|
18
tests/manual/cocoa/wheelevent/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## wheelevent Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(wheelevent
|
||||
GUI
|
||||
SOURCES
|
||||
main.cpp
|
||||
window.cpp window.h
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
)
|
21
tests/manual/cocoa/wheelevent/main.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "window.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
Window window;
|
||||
window.show();
|
||||
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
|
||||
|
6
tests/manual/cocoa/wheelevent/wheelevent.pro
Normal file
@ -0,0 +1,6 @@
|
||||
TEMPLATE = app
|
||||
|
||||
HEADERS += window.h
|
||||
SOURCES += window.cpp main.cpp
|
||||
|
||||
QT += core core-private gui gui-private widgets
|
217
tests/manual/cocoa/wheelevent/window.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "window.h"
|
||||
|
||||
#include <private/qguiapplication_p.h>
|
||||
|
||||
#include <QBackingStore>
|
||||
#include <QPainter>
|
||||
#include <QtWidgets>
|
||||
|
||||
static int colorIndexId = 0;
|
||||
|
||||
QColor colorTable[] =
|
||||
{
|
||||
QColor("#f09f8f"),
|
||||
QColor("#a2bff2"),
|
||||
QColor("#c0ef8f")
|
||||
};
|
||||
|
||||
Window::Window(QScreen *screen)
|
||||
: QWindow(screen)
|
||||
, m_backgroundColorIndex(colorIndexId++)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
Window::Window(QWindow *parent)
|
||||
: QWindow(parent)
|
||||
, m_backgroundColorIndex(colorIndexId++)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
void Window::initialize()
|
||||
{
|
||||
if (parent())
|
||||
setGeometry(QRect(160, 120, 320, 240));
|
||||
else {
|
||||
setGeometry(QRect(10, 10, 640, 480));
|
||||
|
||||
setSizeIncrement(QSize(10, 10));
|
||||
setBaseSize(QSize(640, 480));
|
||||
setMinimumSize(QSize(240, 160));
|
||||
}
|
||||
|
||||
create();
|
||||
m_backingStore = new QBackingStore(this);
|
||||
|
||||
m_image = QImage(geometry().size(), QImage::Format_RGB32);
|
||||
m_image.fill(colorTable[m_backgroundColorIndex % (sizeof(colorTable) / sizeof(colorTable[0]))].rgba());
|
||||
|
||||
m_lastPos = QPoint(-1, -1);
|
||||
m_renderTimer = 0;
|
||||
}
|
||||
|
||||
void Window::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
||||
void Window::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_lastPos != QPoint(-1, -1)) {
|
||||
QPainter p(&m_image);
|
||||
|
||||
QPen pen;
|
||||
pen.setCosmetic(true);
|
||||
pen.setWidth(1);
|
||||
p.setPen(pen);
|
||||
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.drawLine(m_lastPos, event->pos());
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
||||
scheduleRender();
|
||||
}
|
||||
|
||||
void Window::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
qDebug() << "wheelEvent delta" << event->delta() << "orientation" << event->orientation();
|
||||
qDebug() << "wheelEvent pixelDelta" << event->pixelDelta();
|
||||
qDebug() << "wheelEvent angleDelta" << event->angleDelta();
|
||||
|
||||
const bool useQt4API = false;
|
||||
|
||||
if (useQt4API) {
|
||||
if (event->orientation() == Qt::Horizontal)
|
||||
scrollOffset.setX(scrollOffset.x() + event->delta());
|
||||
else
|
||||
scrollOffset.setY(scrollOffset.y() + event->delta());
|
||||
scheduleRender();
|
||||
} else {
|
||||
if (!event->pixelDelta().isNull()) {
|
||||
scrollOffset += event->pixelDelta();
|
||||
scheduleRender();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Window::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_lastPos != QPoint(-1, -1)) {
|
||||
QPainter p(&m_image);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.drawLine(m_lastPos, event->pos());
|
||||
m_lastPos = QPoint(-1, -1);
|
||||
}
|
||||
|
||||
scheduleRender();
|
||||
}
|
||||
|
||||
void Window::exposeEvent(QExposeEvent *)
|
||||
{
|
||||
scheduleRender();
|
||||
}
|
||||
|
||||
void Window::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
QImage old = m_image;
|
||||
|
||||
qDebug() << "Window::resizeEvent" << geometry();
|
||||
|
||||
int width = qMax(geometry().width() * devicePixelRatio(), qreal(old.width()));
|
||||
int height = qMax(geometry().height() * devicePixelRatio(), qreal(old.height()));
|
||||
|
||||
qDebug() << "Window::resizeEvent" << width << height;
|
||||
|
||||
if (width > old.width() || height > old.height()) {
|
||||
m_image = QImage(width, height, QImage::Format_RGB32);
|
||||
m_image.setDevicePixelRatio(devicePixelRatio());
|
||||
m_image.fill(colorTable[(m_backgroundColorIndex) % (sizeof(colorTable) / sizeof(colorTable[0]))].rgba());
|
||||
|
||||
QPainter p(&m_image);
|
||||
p.drawImage(0, 0, old);
|
||||
}
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
void Window::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
switch (event->key()) {
|
||||
case Qt::Key_Backspace:
|
||||
m_text.chop(1);
|
||||
break;
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
m_text.append('\n');
|
||||
break;
|
||||
default:
|
||||
m_text.append(event->text());
|
||||
break;
|
||||
}
|
||||
scheduleRender();
|
||||
}
|
||||
|
||||
void Window::scheduleRender()
|
||||
{
|
||||
if (!m_renderTimer)
|
||||
m_renderTimer = startTimer(1);
|
||||
}
|
||||
|
||||
void Window::timerEvent(QTimerEvent *)
|
||||
{
|
||||
render();
|
||||
killTimer(m_renderTimer);
|
||||
m_renderTimer = 0;
|
||||
}
|
||||
|
||||
void Window::render()
|
||||
{
|
||||
QRect rect(QPoint(), geometry().size());
|
||||
|
||||
m_backingStore->resize(rect.size());
|
||||
|
||||
m_backingStore->beginPaint(rect);
|
||||
|
||||
QPaintDevice *device = m_backingStore->paintDevice();
|
||||
|
||||
QPainter p(device);
|
||||
p.drawImage(0, 0, m_image);
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(32);
|
||||
|
||||
p.setFont(font);
|
||||
p.drawText(rect, 0, m_text);
|
||||
|
||||
// draw grid:
|
||||
int gridSpace = 80;
|
||||
|
||||
QPen pen;
|
||||
pen.setCosmetic(true);
|
||||
pen.setWidth(1);
|
||||
p.setPen(pen);
|
||||
|
||||
|
||||
for (int y = 0; y < geometry().height() + gridSpace; y+= gridSpace) {
|
||||
int offset = scrollOffset.y() % gridSpace;
|
||||
//int color = ((y + offset) %255);// + scrollOffset.y()) % 255);
|
||||
p.drawLine(0, y + offset, geometry().width(), y + offset);
|
||||
//p.setBrush(QColor(color,0, 0));
|
||||
//p.fillRect(0, y + offset, geometry().width(), gridSpace,QColor(color,0, 0));
|
||||
}
|
||||
|
||||
|
||||
for (int x = 0; x < geometry().width() + gridSpace; x+= gridSpace) {
|
||||
p.drawLine(x + scrollOffset.x() % gridSpace, 0, x + scrollOffset.x() % gridSpace, geometry().height());
|
||||
}
|
||||
|
||||
m_backingStore->endPaint();
|
||||
m_backingStore->flush(rect);
|
||||
}
|
||||
|
||||
|
38
tests/manual/cocoa/wheelevent/window.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QWindow>
|
||||
#include <QImage>
|
||||
|
||||
class Window : public QWindow
|
||||
{
|
||||
public:
|
||||
Window(QWindow *parent = nullptr);
|
||||
Window(QScreen *screen);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
void mouseMoveEvent(QMouseEvent *);
|
||||
void mouseReleaseEvent(QMouseEvent *);
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
|
||||
void keyPressEvent(QKeyEvent *);
|
||||
|
||||
void exposeEvent(QExposeEvent *);
|
||||
void resizeEvent(QResizeEvent *);
|
||||
|
||||
void timerEvent(QTimerEvent *);
|
||||
|
||||
private:
|
||||
void render();
|
||||
void scheduleRender();
|
||||
void initialize();
|
||||
|
||||
QString m_text;
|
||||
QImage m_image;
|
||||
QPoint m_lastPos;
|
||||
int m_backgroundColorIndex;
|
||||
QBackingStore *m_backingStore;
|
||||
int m_renderTimer;
|
||||
QPoint scrollOffset;
|
||||
};
|
46
tests/manual/corelib/tools/qhash/main.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QDebug>
|
||||
#include <QHash>
|
||||
|
||||
void testEraseNoError()
|
||||
{
|
||||
QHash<int, int> a;
|
||||
|
||||
a.insert(100, 100);
|
||||
a.insert(101, 200);
|
||||
a.insert(5, 50);
|
||||
a.insertMulti(5, 60);
|
||||
a.insertMulti(5, 70);
|
||||
a.insertMulti(5, 80);
|
||||
|
||||
QHash<int, int>::iterator i = a.begin();
|
||||
while (i.key() != 5)
|
||||
++i;
|
||||
++i;
|
||||
a.erase(i);
|
||||
|
||||
qDebug() << "Erase - got no errors on iterator check";
|
||||
}
|
||||
|
||||
void testErase()
|
||||
{
|
||||
QHash<int, int> a, b;
|
||||
a.insert(5, 50);
|
||||
a.insert(6, 60);
|
||||
a.insert(7, 70);
|
||||
b = a;
|
||||
a.erase(a.begin());
|
||||
b.erase(b.end() - 1);
|
||||
qDebug() << "Erase - Executing line with error now.";
|
||||
a.erase(b.begin());
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
testEraseNoError();
|
||||
testErase();
|
||||
return 0;
|
||||
}
|
1
tests/manual/corelib/tools/qhash/main.pro
Normal file
@ -0,0 +1 @@
|
||||
SOURCES = main.cpp
|
33
tests/manual/corelib/tools/qlist/main.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QDebug>
|
||||
#include <QList>
|
||||
|
||||
void testErase()
|
||||
{
|
||||
QList<int> a, b;
|
||||
a.append(5);
|
||||
a.append(6);
|
||||
a.append(7);
|
||||
b = a;
|
||||
a.erase(a.begin());
|
||||
qDebug() << "erase - Executing line with error now.";
|
||||
// a.erase(a.end());
|
||||
a.erase(b.begin());
|
||||
}
|
||||
void testInsert()
|
||||
{
|
||||
QList<int> a, b;
|
||||
a.insert(a.begin(), 1);
|
||||
a.insert(a.begin(), 2);
|
||||
a.insert(a.end(), 3);
|
||||
b = a;
|
||||
qDebug() << "insert - Executing line with error now.";
|
||||
a.insert(b.begin(), 4);
|
||||
}
|
||||
int main()
|
||||
{
|
||||
// testErase();
|
||||
testInsert();
|
||||
return 0;
|
||||
}
|
1
tests/manual/corelib/tools/qlist/main.pro
Normal file
@ -0,0 +1 @@
|
||||
SOURCES = main.cpp
|
73
tests/manual/corelib/tools/qmap/main.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
//#define Q_NO_DEBUGMAP_PARENT_TEST
|
||||
// Comment in line above to skip the parent test.
|
||||
#include <QtCore/QMap>
|
||||
#include <QDebug>
|
||||
|
||||
void noBugErase()
|
||||
{
|
||||
QMap<int, int> a, b;
|
||||
a[10] = 11;
|
||||
a[11] = 12;
|
||||
b = a;
|
||||
b.erase(b.begin());
|
||||
}
|
||||
|
||||
void noBugInsertWithHints()
|
||||
{
|
||||
QMap<int, int> a;
|
||||
QMap<int, int> b;
|
||||
for (int u = 100; u < 10000; u += 20)
|
||||
a.insert(u, u);
|
||||
b = a;
|
||||
QMap<int, int>::const_iterator b_ite(b.begin()); // b.begin() ensures correct detach()
|
||||
++b_ite;
|
||||
b.insert(b_ite, 501, 501);
|
||||
b.insert(b_ite, 115, 115);
|
||||
QMap<int, int> c;
|
||||
c = b;
|
||||
c.setSharable(false);
|
||||
}
|
||||
|
||||
void testInsertWithHintCorruption()
|
||||
{
|
||||
qDebug() << "Starting testInsertWithHintCorruption";
|
||||
|
||||
QMap<int, int> a;
|
||||
QMap<int, int> b;
|
||||
for (int u = 100; u < 10000; u += 20)
|
||||
a.insert(u, u);
|
||||
b = a;
|
||||
QMap<int, int>::const_iterator b_ite = b.constBegin();
|
||||
++b_ite;
|
||||
b.insert(b_ite, 501, 501);
|
||||
b.insert(b_ite, 115, 115); // insert with wrong hint.
|
||||
QMap<int, int> c;
|
||||
c = b;
|
||||
c.setSharable(false);
|
||||
qDebug() << "End of testInsertWithHintCorruption - failed silently";
|
||||
}
|
||||
|
||||
void testEraseCorruption()
|
||||
{
|
||||
qDebug() << "Starting testEraseCorruption";
|
||||
|
||||
QMap<int, int> a, b;
|
||||
a[10] = 11;
|
||||
a[11] = 12;
|
||||
b = a;
|
||||
b.erase(a.begin());
|
||||
qDebug() << "End of testEraseCorruption - failed silently";
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
noBugErase();
|
||||
noBugInsertWithHints();
|
||||
|
||||
// testEraseCorruption();
|
||||
testInsertWithHintCorruption();
|
||||
return 0;
|
||||
}
|
2
tests/manual/corelib/tools/qmap/qmaptest.pro
Normal file
@ -0,0 +1,2 @@
|
||||
TEMPLATE = app
|
||||
SOURCES = main.cpp
|
24
tests/manual/corelib/tools/qset/main.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSet>
|
||||
|
||||
void testErase()
|
||||
{
|
||||
QSet<int> a, b;
|
||||
a.insert(5);
|
||||
a.insert(6);
|
||||
a.insert(7);
|
||||
b = a;
|
||||
a.erase(a.begin());
|
||||
b.erase(b.end() - 1);
|
||||
qDebug() << "erase - no errors until now";
|
||||
a.erase(b.begin());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
testErase();
|
||||
return 0;
|
||||
}
|
1
tests/manual/corelib/tools/qset/main.pro
Normal file
@ -0,0 +1 @@
|
||||
SOURCES = main.cpp
|
37
tests/manual/corelib/tools/qvarlengtharray/main.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QDebug>
|
||||
#include <QVarLengthArray>
|
||||
|
||||
void testErase()
|
||||
{
|
||||
QVarLengthArray<int> a, b;
|
||||
a.append(5);
|
||||
a.append(6);
|
||||
a.append(7);
|
||||
b = a;
|
||||
a.erase(a.begin());
|
||||
a.erase(a.end() - 1);
|
||||
qDebug() << "erase - no errors until now";
|
||||
// a.erase(a.end());
|
||||
a.erase(b.begin());
|
||||
}
|
||||
|
||||
void testInsert()
|
||||
{
|
||||
QVarLengthArray<int> a, b;
|
||||
a.insert(a.begin(), 1);
|
||||
a.insert(a.begin(), 2);
|
||||
a.insert(a.end(), 3);
|
||||
b = a;
|
||||
qDebug() << "insert - no errors until now";
|
||||
a.insert(b.begin(), 1, 4);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// testErase();
|
||||
testInsert();
|
||||
return 0;
|
||||
}
|
1
tests/manual/corelib/tools/qvarlengtharray/main.pro
Normal file
@ -0,0 +1 @@
|
||||
SOURCES=main.cpp
|
37
tests/manual/corelib/tools/qvector/main.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QDebug>
|
||||
#include <QVector>
|
||||
|
||||
void testErase()
|
||||
{
|
||||
QVector<int> a, b;
|
||||
a.append(5);
|
||||
a.append(6);
|
||||
a.append(7);
|
||||
b = a;
|
||||
a.erase(a.begin());
|
||||
a.erase(a.end() - 1);
|
||||
qDebug() << "erase - no errors until now";
|
||||
// a.erase(a.end());
|
||||
a.erase(b.begin());
|
||||
}
|
||||
|
||||
void testInsert()
|
||||
{
|
||||
QVector<int> a, b;
|
||||
a.insert(a.begin(), 1, 1);
|
||||
a.insert(a.begin(), 1, 2);
|
||||
a.insert(a.begin(), 1, 3);
|
||||
b = a;
|
||||
qDebug() << "insert - no errors until now";
|
||||
a.insert(b.begin(), 1, 4);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
testErase();
|
||||
// testInsert();
|
||||
return 0;
|
||||
}
|
1
tests/manual/corelib/tools/qvector/main.pro
Normal file
@ -0,0 +1 @@
|
||||
SOURCES = main.cpp
|
61
tests/manual/diaglib/README.txt
Normal file
@ -0,0 +1,61 @@
|
||||
This is a collection of functions and classes helpful for diagnosing bugs
|
||||
in Qt 4 and Qt 5. It can be included in the application's .pro file by
|
||||
adding:
|
||||
|
||||
include([path to Qt sources]/tests/manual/diaglib/diaglib.pri)
|
||||
|
||||
For Qt 4, the environment variable QTDIR may be used:
|
||||
include($$(QTDIR)/tests/manual/diaglib/diaglib.pri)
|
||||
|
||||
The .pri file adds the define QT_DIAG_LIB, so, diagnostic
|
||||
code can be enlosed within #ifdef to work without it as well.
|
||||
|
||||
All functions and classes are in the QtDiag namespace.
|
||||
|
||||
function dumpText() (textdump.h)
|
||||
Returns a string containing the input text split up in characters
|
||||
listing category, script, direction etc.
|
||||
Useful for analyzing non-Latin text.
|
||||
|
||||
function dumpTextAsCode() (textdump.h)
|
||||
Returns a string containing a code snippet creating a QString
|
||||
by appending the unicode value of character of the input.
|
||||
This is useful for constructing non-Latin strings with purely ASCII
|
||||
source code.
|
||||
|
||||
class EventFilter (eventfilter.h):
|
||||
An event filter that logs Qt events to qDebug() depending on
|
||||
configured categories (for example mouse, keyboard, etc).
|
||||
|
||||
class DebugProxyStyle (debugproxystyle.h)
|
||||
A proxy style that wraps around an existing style and outputs
|
||||
the parameters and return values of its function calls, useful
|
||||
for debugging QStyle.
|
||||
|
||||
class LogWidget (logwidget.h)
|
||||
A Log Widget inheriting QPlainTextEdit with convenience functions
|
||||
to install as a message handler.
|
||||
|
||||
class LogFunctionGuard
|
||||
A guard class for use with LogWidget logging messages when a function
|
||||
is entered/left (indenting the log messages).
|
||||
Can be instantiated using:
|
||||
LogFunctionGuard guard(__FUNCTION__) or
|
||||
LogFunctionGuard guard(Q_FUNC_INFO)
|
||||
|
||||
function glInfo() (glinfo.h):
|
||||
Returns a string describing the Open GL configuration (obtained
|
||||
by querying GL_VENDOR and GL_RENDERER). Available only
|
||||
when the QT qmake variable contains opengl.
|
||||
|
||||
functions dumpNativeWindows(), dumpNativeQtTopLevels():
|
||||
These functions du,p out the hierarchy of native Windows. Currently
|
||||
implemented for Windows only.
|
||||
|
||||
function dumpAllWidgets() (qwidgetdump.h):
|
||||
Dumps the hierarchy of QWidgets including information about flags,
|
||||
visibility, geometry, etc.
|
||||
|
||||
function dumpAllWindows() (qwindowdump.h):
|
||||
Dumps the hierarchy of QWindows including information about flags,
|
||||
visibility, geometry, etc.
|
144
tests/manual/diaglib/debugproxystyle.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "debugproxystyle.h"
|
||||
#include "eventfilter.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QWidget>
|
||||
#include <QStyleOption>
|
||||
#include <QApplication>
|
||||
|
||||
QDebug operator<<(QDebug debug, const QStyleOption *option)
|
||||
{
|
||||
QDebugStateSaver saver(debug);
|
||||
debug.noquote();
|
||||
debug.nospace();
|
||||
if (!option) {
|
||||
debug << "QStyleOption(0)";
|
||||
return debug;
|
||||
}
|
||||
if (const QStyleOptionViewItem *ivo = qstyleoption_cast<const QStyleOptionViewItem *>(option)) {
|
||||
debug << "QStyleOptionViewItem(";
|
||||
debug << ivo->index;
|
||||
if (const int textSize = ivo->text.size())
|
||||
debug << ", \"" << (textSize < 20 ? ivo->text : ivo->text.left(20) + QLatin1String("...")) << '"';
|
||||
debug << ", ";
|
||||
} else {
|
||||
debug << "QStyleOption(";
|
||||
}
|
||||
debug << "rect=" << option->rect.width() << 'x' << option->rect.height() << Qt::forcesign
|
||||
<< option->rect.x() << option->rect.y() << Qt::noforcesign;
|
||||
if (option->state != QStyle::State_None)
|
||||
debug << ", state=" << option->state;
|
||||
if (option->styleObject && !option->styleObject->isWidgetType())
|
||||
debug << ", styleObject=" << QtDiag::formatQObject(option->styleObject);
|
||||
debug << ')';
|
||||
return debug;
|
||||
}
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
DebugProxyStyle::DebugProxyStyle(QStyle *style) : QProxyStyle(style)
|
||||
{
|
||||
const qreal devicePixelRatio = qApp->devicePixelRatio();
|
||||
qDebug() << __FUNCTION__ << QT_VERSION_STR
|
||||
<< QGuiApplication::platformName()
|
||||
<< style->objectName() << "devicePixelRatio=" << devicePixelRatio;
|
||||
}
|
||||
|
||||
void DebugProxyStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
qDebug() << __FUNCTION__ << "element=" << element << option << QtDiag::formatQObject(widget);
|
||||
QProxyStyle::drawPrimitive( element, option, painter, widget);
|
||||
}
|
||||
|
||||
void DebugProxyStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
qDebug() << __FUNCTION__ << "element=" << element << option << QtDiag::formatQObject(widget);
|
||||
QProxyStyle::drawControl(element, option, painter, widget);
|
||||
}
|
||||
|
||||
void DebugProxyStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
qDebug() << __FUNCTION__ << "control=" << control << option << QtDiag::formatQObject(widget);
|
||||
QProxyStyle::drawComplexControl(control, option, painter, widget);
|
||||
}
|
||||
|
||||
void DebugProxyStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const
|
||||
{
|
||||
qDebug() << __FUNCTION__ << rect << "alignment=" << alignment << pixmap;
|
||||
QProxyStyle::drawItemPixmap(painter, rect, alignment, pixmap);
|
||||
}
|
||||
|
||||
QSize DebugProxyStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const
|
||||
{
|
||||
const QSize result = QProxyStyle::sizeFromContents(type, option, size, widget);
|
||||
qDebug() << __FUNCTION__ << size << "type=" << type << option
|
||||
<< QtDiag::formatQObject(widget) << "returns" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
QRect DebugProxyStyle::subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget) const
|
||||
{
|
||||
const QRect result = QProxyStyle::subElementRect(element, option, widget);
|
||||
qDebug() << __FUNCTION__ << "element=" << element << option
|
||||
<< QtDiag::formatQObject(widget) << "returns" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
QRect DebugProxyStyle::subControlRect(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QStyle::SubControl sc, const QWidget *widget) const
|
||||
{
|
||||
const QRect result = QProxyStyle::subControlRect(cc, opt, sc, widget);
|
||||
qDebug() << __FUNCTION__ << "cc=" << cc << "sc=" << sc << opt
|
||||
<< QtDiag::formatQObject(widget) << "returns" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
QRect DebugProxyStyle::itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const
|
||||
{
|
||||
const QRect result = QProxyStyle::itemTextRect(fm, r, flags, enabled, text);
|
||||
qDebug() << __FUNCTION__ << r << "flags=" << flags << "enabled=" << enabled
|
||||
<< text << "returns" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
QRect DebugProxyStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
|
||||
{
|
||||
const QRect result = QProxyStyle::itemPixmapRect(r, flags, pixmap);
|
||||
qDebug() << __FUNCTION__ << r << "flags=" << flags << pixmap << "returns" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
int DebugProxyStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
|
||||
QStyleHintReturn *returnData) const
|
||||
{
|
||||
const int result = QProxyStyle::styleHint(hint, option, widget, returnData);
|
||||
qDebug() << __FUNCTION__ << hint << option << QtDiag::formatQObject(widget) << "returnData="
|
||||
<< returnData << "returns" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
int DebugProxyStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
|
||||
{
|
||||
const int result = QProxyStyle::pixelMetric(metric, option, widget);
|
||||
qDebug() << __FUNCTION__ << "metric=" << metric << option
|
||||
<< QtDiag::formatQObject(widget) << "returns" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
QPixmap DebugProxyStyle::standardPixmap(QStyle::StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const
|
||||
{
|
||||
const QPixmap result = QProxyStyle::standardPixmap(standardPixmap, opt, widget);
|
||||
qDebug() << __FUNCTION__ << "standardPixmap=" << standardPixmap << opt << "returns" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
QPixmap DebugProxyStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
|
||||
{
|
||||
const QPixmap result = QProxyStyle::generatedIconPixmap(iconMode, pixmap, opt);
|
||||
qDebug() << __FUNCTION__ << "iconMode=" << iconMode << pixmap << opt << "returns" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace QtDiag
|
34
tests/manual/diaglib/debugproxystyle.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef DEBUGPROXYSTYLE_H
|
||||
#define DEBUGPROXYSTYLE_H
|
||||
|
||||
#include <QProxyStyle>
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
class DebugProxyStyle : public QProxyStyle {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DebugProxyStyle(QStyle *style);
|
||||
|
||||
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override;
|
||||
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override;
|
||||
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override;
|
||||
void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const override;
|
||||
QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override;
|
||||
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override;
|
||||
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override;
|
||||
QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const override;
|
||||
QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const override;
|
||||
int styleHint(StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override;
|
||||
int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override;
|
||||
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = nullptr) const override;
|
||||
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override;
|
||||
};
|
||||
|
||||
} // namespace QtDiag
|
||||
|
||||
#endif // DEBUGPROXYSTYLE_H
|
44
tests/manual/diaglib/diaglib.pri
Normal file
@ -0,0 +1,44 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
SOURCES += \
|
||||
$$PWD/textdump.cpp \
|
||||
$$PWD/eventfilter.cpp \
|
||||
$$PWD/qwindowdump.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/textdump.h \
|
||||
$$PWD/eventfilter.h \
|
||||
$$PWD/qwindowdump.h \
|
||||
$$PWD/nativewindowdump.h
|
||||
|
||||
win32: {
|
||||
SOURCES += $$PWD/nativewindowdump_win.cpp
|
||||
LIBS += -luser32
|
||||
} else {
|
||||
SOURCES += $$PWD/nativewindowdump.cpp
|
||||
}
|
||||
|
||||
QT += gui-private core-private
|
||||
contains(QT, widgets) {
|
||||
HEADERS += \
|
||||
$$PWD/qwidgetdump.h \
|
||||
$$PWD/debugproxystyle.h \
|
||||
$$PWD/logwidget.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qwidgetdump.cpp \
|
||||
$$PWD/debugproxystyle.cpp \
|
||||
$$PWD/logwidget.cpp
|
||||
QT += widgets-private
|
||||
}
|
||||
|
||||
contains(QT, opengl) {
|
||||
HEADERS += \
|
||||
$$PWD/glinfo.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/glinfo.cpp
|
||||
|
||||
QT += opengl openglwidgets
|
||||
}
|
||||
|
||||
DEFINES += QT_DIAG_LIB
|
200
tests/manual/diaglib/eventfilter.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "eventfilter.h"
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
#if defined(QT_WIDGETS_LIB)
|
||||
# define HAVE_APPLICATION
|
||||
#endif
|
||||
#if defined(QT_GUI_LIB)
|
||||
# define HAVE_GUI_APPLICATION
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_APPLICATION
|
||||
# include <QApplication>
|
||||
# include <QWidget>
|
||||
#endif
|
||||
#ifdef HAVE_GUI_APPLICATION
|
||||
# include <QtGui/QGuiApplication>
|
||||
# include <QtGui/QWindow>
|
||||
#endif
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
EventFilter::EventFilter(EventCategories eventCategories, QObject *p)
|
||||
: QObject(p)
|
||||
{
|
||||
init(eventCategories);
|
||||
}
|
||||
|
||||
EventFilter::EventFilter(QObject *p)
|
||||
: QObject(p)
|
||||
{
|
||||
init(EventCategories(0xFFFFFFF));
|
||||
}
|
||||
|
||||
void EventFilter::init(EventCategories eventCategories)
|
||||
{
|
||||
m_objectTypes = OtherType | QWidgetType | QWindowType;
|
||||
|
||||
if (eventCategories & MouseEvents) {
|
||||
m_eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease
|
||||
<< QEvent::MouseButtonDblClick << QEvent::NonClientAreaMouseButtonPress
|
||||
<< QEvent::NonClientAreaMouseButtonRelease
|
||||
<< QEvent::NonClientAreaMouseButtonDblClick
|
||||
<< QEvent::Wheel << QEvent::Enter << QEvent::Leave;
|
||||
}
|
||||
if (eventCategories & MouseMoveEvents)
|
||||
m_eventTypes << QEvent::MouseMove << QEvent::NonClientAreaMouseMove;
|
||||
if (eventCategories & TouchEvents) {
|
||||
m_eventTypes << QEvent::TouchBegin << QEvent::TouchUpdate << QEvent::TouchEnd;
|
||||
m_eventTypes << QEvent::TouchCancel;
|
||||
}
|
||||
if (eventCategories & TabletEvents) {
|
||||
m_eventTypes << QEvent::TabletEnterProximity << QEvent::TabletLeaveProximity
|
||||
<< QEvent::TabletMove << QEvent::TabletPress << QEvent::TabletRelease;
|
||||
}
|
||||
if (eventCategories & DragAndDropEvents) {
|
||||
m_eventTypes << QEvent::DragEnter << QEvent::DragMove << QEvent::DragLeave
|
||||
<< QEvent::Drop << QEvent::DragResponse;
|
||||
}
|
||||
if (eventCategories & KeyEvents) {
|
||||
m_eventTypes << QEvent::KeyPress << QEvent::KeyRelease << QEvent::ShortcutOverride
|
||||
<< QEvent::Shortcut;
|
||||
}
|
||||
if (eventCategories & FocusEvents) {
|
||||
m_eventTypes
|
||||
<< QEvent::FocusAboutToChange
|
||||
<< QEvent::FocusIn << QEvent::FocusOut;
|
||||
}
|
||||
if (eventCategories & GeometryEvents)
|
||||
m_eventTypes << QEvent::Move << QEvent::Resize;
|
||||
if (eventCategories & PaintEvents) {
|
||||
m_eventTypes << QEvent::UpdateRequest << QEvent::Paint
|
||||
<< QEvent::Show << QEvent::Hide;
|
||||
m_eventTypes << QEvent::Expose;
|
||||
}
|
||||
if (eventCategories & StateChangeEvents) {
|
||||
m_eventTypes
|
||||
<< QEvent::WindowStateChange
|
||||
<< QEvent::WindowBlocked << QEvent::WindowUnblocked
|
||||
<< QEvent::ApplicationStateChange
|
||||
<< QEvent::ApplicationActivate << QEvent::ApplicationDeactivate;
|
||||
}
|
||||
if (eventCategories & TimerEvents)
|
||||
m_eventTypes << QEvent::Timer << QEvent::ZeroTimerEvent;
|
||||
if (eventCategories & ObjectEvents) {
|
||||
m_eventTypes << QEvent::ChildAdded << QEvent::ChildPolished
|
||||
<< QEvent::ChildRemoved << QEvent::Create << QEvent::Destroy;
|
||||
}
|
||||
if (eventCategories & InputMethodEvents) {
|
||||
m_eventTypes << QEvent::InputMethod;
|
||||
m_eventTypes << QEvent::InputMethodQuery;
|
||||
}
|
||||
#ifndef QT_NO_GESTURES
|
||||
if (eventCategories & GestureEvents) {
|
||||
m_eventTypes << QEvent::Gesture << QEvent::GestureOverride
|
||||
<< QEvent::NativeGesture;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool matchesType(const QObject *o, EventFilter::ObjectTypes types)
|
||||
{
|
||||
if (o->isWidgetType())
|
||||
return types & EventFilter::QWidgetType;
|
||||
if (o->isWindowType())
|
||||
return types & EventFilter::QWindowType;
|
||||
return types & EventFilter::OtherType;
|
||||
}
|
||||
|
||||
void EventFilter::formatObject(const QObject *o, QDebug debug)
|
||||
{
|
||||
if (o) {
|
||||
debug << o->metaObject()->className();
|
||||
const QString on = o->objectName();
|
||||
if (!on.isEmpty())
|
||||
debug << '/' << on;
|
||||
} else {
|
||||
debug << "null";
|
||||
}
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug d, const formatQObject &fo)
|
||||
{
|
||||
EventFilter::formatObject(fo.m_object, d);
|
||||
return d;
|
||||
}
|
||||
|
||||
static void formatApplicationState(QDebug debug)
|
||||
{
|
||||
#if defined(HAVE_APPLICATION)
|
||||
if (const QWidget *mw = QApplication::activeModalWidget())
|
||||
debug << "\n QApplication::activeModalWidget = " << formatQObject(mw);
|
||||
if (const QWidget *pw = QApplication::activePopupWidget())
|
||||
debug << "\n QApplication::activePopupWidget = " << formatQObject(pw);
|
||||
debug << "\n QApplication::activeWindow = " << formatQObject(QApplication::activeWindow());
|
||||
#endif // HAVE_APPLICATION
|
||||
#if defined(HAVE_GUI_APPLICATION)
|
||||
if (const QWindow *mw = QGuiApplication::modalWindow()) {
|
||||
debug << "\n QGuiApplication::modalWindow = " << formatQObject(mw);
|
||||
}
|
||||
const QObject *focusObject = QGuiApplication::focusObject();
|
||||
const QObject *focusWindow = QGuiApplication::focusWindow();
|
||||
debug << "\n QGuiApplication::focusObject = " << formatQObject(focusObject);
|
||||
if (focusWindow && focusWindow != focusObject)
|
||||
debug << "\n QGuiApplication::focusWindow = " << formatQObject(focusWindow);
|
||||
#endif // HAVE_GUI_APPLICATION
|
||||
}
|
||||
|
||||
#ifdef HAVE_APPLICATION
|
||||
static void formatMouseState(QObject *o, QDebug debug)
|
||||
{
|
||||
if (o->isWidgetType()) {
|
||||
auto w = static_cast<const QWidget *>(o);
|
||||
if (QWidget::mouseGrabber() == w)
|
||||
debug << " [grabbed]";
|
||||
if (w->hasMouseTracking())
|
||||
debug << " [tracking]";
|
||||
}
|
||||
}
|
||||
#endif // HAVE_APPLICATION
|
||||
|
||||
bool EventFilter::eventFilter(QObject *o, QEvent *e)
|
||||
{
|
||||
static int n = 0;
|
||||
if (matchesType(o, m_objectTypes) && m_eventTypes.contains(e->type())) {
|
||||
QDebug debug = qDebug().nospace();
|
||||
debug << '#' << n++ << ' ';
|
||||
formatObject(o, debug);
|
||||
debug << ' ' << e;
|
||||
switch (e->type()) {
|
||||
case QEvent::FocusAboutToChange:
|
||||
case QEvent::FocusIn:
|
||||
formatApplicationState(debug);
|
||||
break;
|
||||
#ifdef HAVE_APPLICATION
|
||||
case QEvent::MouseButtonDblClick:
|
||||
case QEvent::MouseButtonPress:
|
||||
case QEvent::MouseButtonRelease:
|
||||
case QEvent::MouseMove:
|
||||
case QEvent::NonClientAreaMouseButtonDblClick:
|
||||
case QEvent::NonClientAreaMouseButtonPress:
|
||||
case QEvent::NonClientAreaMouseButtonRelease:
|
||||
case QEvent::NonClientAreaMouseMove:
|
||||
case QEvent::Enter:
|
||||
case QEvent::Leave:
|
||||
formatMouseState(o, debug);
|
||||
break;
|
||||
#endif // HAVE_APPLICATION
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace QtDiag
|
77
tests/manual/diaglib/eventfilter.h
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef _EVENTFILTER_
|
||||
#define _EVENTFILTER_
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QList>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QDebug)
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
// Event filter that can for example be installed on QApplication
|
||||
// to log relevant events.
|
||||
|
||||
class EventFilter : public QObject {
|
||||
public:
|
||||
enum EventCategory {
|
||||
MouseEvents = 0x00001,
|
||||
MouseMoveEvents = 0x00002,
|
||||
TouchEvents = 0x00004,
|
||||
TabletEvents = 0x00008,
|
||||
DragAndDropEvents = 0x00010,
|
||||
KeyEvents = 0x00020,
|
||||
FocusEvents = 0x00040,
|
||||
GeometryEvents = 0x00080,
|
||||
PaintEvents = 0x00100,
|
||||
StateChangeEvents = 0x00200,
|
||||
InputMethodEvents = 0x00400,
|
||||
TimerEvents = 0x00800,
|
||||
ObjectEvents = 0x01000,
|
||||
GestureEvents = 0x02000,
|
||||
AllEvents = 0xFFFFF
|
||||
};
|
||||
Q_DECLARE_FLAGS(EventCategories, EventCategory)
|
||||
|
||||
enum ObjectType {
|
||||
QWindowType = 0x1,
|
||||
QWidgetType = 0x2,
|
||||
OtherType = 0x4
|
||||
};
|
||||
Q_DECLARE_FLAGS(ObjectTypes, ObjectType)
|
||||
|
||||
explicit EventFilter(EventCategories eventCategories, QObject *p = nullptr);
|
||||
explicit EventFilter(QObject *p = nullptr);
|
||||
|
||||
bool eventFilter(QObject *, QEvent *) override;
|
||||
|
||||
ObjectTypes objectTypes() const { return m_objectTypes; }
|
||||
void setObjectTypes(ObjectTypes objectTypes) { m_objectTypes = objectTypes; }
|
||||
|
||||
static void formatObject(const QObject *o, QDebug debug);
|
||||
|
||||
private:
|
||||
void init(EventCategories eventCategories);
|
||||
|
||||
QList<QEvent::Type> m_eventTypes;
|
||||
ObjectTypes m_objectTypes;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(EventFilter::EventCategories)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(EventFilter::ObjectTypes)
|
||||
|
||||
struct formatQObject
|
||||
{
|
||||
explicit formatQObject(const QObject *o) : m_object(o) {}
|
||||
|
||||
const QObject *m_object;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug d, const formatQObject &fo);
|
||||
|
||||
} // namespace QtDiag
|
||||
|
||||
#endif
|
47
tests/manual/diaglib/glinfo.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "glinfo.h"
|
||||
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QtOpenGLWidgets/QOpenGLWidget>
|
||||
#include <QtOpenGL/QOpenGLWindow>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <QtGui/QOpenGLFunctions>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
static QString getGlString(const QOpenGLContext *ctx, GLenum name)
|
||||
{
|
||||
if (const GLubyte *p = ctx->functions()->glGetString(name))
|
||||
return QString::fromLatin1(reinterpret_cast<const char *>(p));
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QString glInfo(const QOpenGLContext *ctx)
|
||||
{
|
||||
return getGlString(ctx, GL_VENDOR)
|
||||
+ QLatin1Char('\n')
|
||||
+ getGlString(ctx, GL_RENDERER);
|
||||
}
|
||||
|
||||
QString glInfo(const QObject *o)
|
||||
{
|
||||
if (o->isWindowType()) {
|
||||
if (const QOpenGLWindow *oglw = qobject_cast<const QOpenGLWindow *>(o))
|
||||
return glInfo(oglw->context());
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (o->isWidgetType()) {
|
||||
if (const QOpenGLWidget *g = qobject_cast<const QOpenGLWidget *>(o))
|
||||
return glInfo(g->context());
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
} // namespace QtDiag
|
18
tests/manual/diaglib/glinfo.h
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef _GLINFO_
|
||||
#define _GLINFO_
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QObject)
|
||||
QT_FORWARD_DECLARE_CLASS(QString)
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
QString glInfo(const QObject *o);
|
||||
|
||||
} // namespace QtDiag
|
||||
|
||||
#endif
|
107
tests/manual/diaglib/logwidget.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "logwidget.h"
|
||||
#include <QApplication>
|
||||
#include <QStyle>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QLibraryInfo>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/qlogging.h>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
LogWidget *LogWidget::m_instance = nullptr;
|
||||
bool LogWidget::m_lineNumberingEnabled = true;
|
||||
bool LogWidget::m_showMessageType = true;
|
||||
int LogWidget::m_indent = 0;
|
||||
|
||||
LogWidget::LogWidget(QWidget *parent)
|
||||
: QPlainTextEdit(parent)
|
||||
{
|
||||
LogWidget::m_instance = this;
|
||||
setReadOnly(true);
|
||||
}
|
||||
|
||||
LogWidget::~LogWidget()
|
||||
{
|
||||
LogWidget::m_instance = nullptr;
|
||||
}
|
||||
|
||||
QString LogWidget::startupMessage()
|
||||
{
|
||||
QString result;
|
||||
result += QLatin1String(QLibraryInfo::build());
|
||||
|
||||
const QCoreApplication *coreApp = QCoreApplication::instance();
|
||||
if (qobject_cast<const QGuiApplication *>(coreApp)) {
|
||||
result += QLatin1Char(' ');
|
||||
result += QGuiApplication::platformName();
|
||||
}
|
||||
if (qobject_cast<const QApplication *>(coreApp)) {
|
||||
result += QLatin1Char(' ');
|
||||
result += QApplication::style()->objectName();
|
||||
}
|
||||
if (coreApp) {
|
||||
QStringList arguments = QCoreApplication::arguments();
|
||||
arguments.pop_front();
|
||||
if (!arguments.isEmpty()) {
|
||||
result += QLatin1Char('\n');
|
||||
result += arguments.join(QLatin1String(" "));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static const QList<QString> &messageTypes()
|
||||
{
|
||||
static QList<QString> result;
|
||||
if (result.isEmpty()) {
|
||||
result << QLatin1String("debug") << QLatin1String("warn")
|
||||
<< QLatin1String("critical") << QLatin1String("fatal")
|
||||
<< QLatin1String("info");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void messageHandler(QtMsgType type, const QString &text)
|
||||
{
|
||||
static int n = 0;
|
||||
QString message;
|
||||
if (LogWidget::lineNumberingEnabled())
|
||||
message.append(QString::fromLatin1("%1 ").arg(n, 4, 10, QLatin1Char('0')));
|
||||
if (LogWidget::showMessageType()) {
|
||||
message.append(messageTypes().at(type));
|
||||
message.append(QLatin1Char(' '));
|
||||
}
|
||||
for (int i = 0, ie = LogWidget::indent(); i < ie; ++i)
|
||||
message.append(QLatin1Char(' '));
|
||||
message.append(text);
|
||||
if (LogWidget *logWindow = LogWidget::instance())
|
||||
logWindow->appendText(message);
|
||||
#ifdef Q_OS_WIN
|
||||
std::wcerr << reinterpret_cast<const wchar_t *>(message.utf16()) << L'\n';
|
||||
#else
|
||||
std::cerr << qPrintable(message) << '\n';
|
||||
#endif
|
||||
n++;
|
||||
}
|
||||
|
||||
static void qtMessageHandler(QtMsgType type, const QMessageLogContext &, const QString &text)
|
||||
{ messageHandler(type, text); }
|
||||
|
||||
void LogWidget::install()
|
||||
{
|
||||
qInstallMessageHandler(qtMessageHandler);
|
||||
qInfo("%s", qPrintable(LogWidget::startupMessage()));
|
||||
}
|
||||
|
||||
void LogWidget::uninstall() { qInstallMessageHandler(nullptr); }
|
||||
|
||||
void LogWidget::appendText(const QString &message)
|
||||
{
|
||||
appendPlainText(message);
|
||||
ensureCursorVisible();
|
||||
}
|
64
tests/manual/diaglib/logwidget.h
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef LOGWIDGET_H
|
||||
#define LOGWIDGET_H
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
// Instantiate as follows: LogFunctionGuard guard(Q_FUNC_INFO)
|
||||
class LogFunctionGuard {
|
||||
Q_DISABLE_COPY(LogFunctionGuard)
|
||||
public:
|
||||
explicit LogFunctionGuard(const char *name);
|
||||
~LogFunctionGuard();
|
||||
|
||||
private:
|
||||
const char *m_name;
|
||||
};
|
||||
|
||||
class LogWidget : public QPlainTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LogWidget(QWidget *parent = nullptr);
|
||||
~LogWidget();
|
||||
|
||||
static LogWidget *instance() { return m_instance; }
|
||||
|
||||
static QString startupMessage();
|
||||
static void install();
|
||||
static void uninstall();
|
||||
|
||||
static int indent() { return m_indent; }
|
||||
static void setIndent(int i) { m_indent = i; }
|
||||
|
||||
static bool lineNumberingEnabled() { return m_lineNumberingEnabled; }
|
||||
static void setLineNumberingEnabled(bool l) { m_lineNumberingEnabled = l; }
|
||||
|
||||
static bool showMessageType() { return m_showMessageType; }
|
||||
static void setShowMessageType(bool s) { m_showMessageType = s; }
|
||||
|
||||
public slots:
|
||||
void appendText(const QString &);
|
||||
|
||||
private:
|
||||
static int m_indent;
|
||||
static bool m_lineNumberingEnabled;
|
||||
static bool m_showMessageType;
|
||||
static LogWidget *m_instance;
|
||||
};
|
||||
|
||||
inline LogFunctionGuard::LogFunctionGuard(const char *name) : m_name(name)
|
||||
{
|
||||
qDebug(">%s", m_name);
|
||||
LogWidget::setIndent(LogWidget::indent() + 2);
|
||||
}
|
||||
|
||||
inline LogFunctionGuard::~LogFunctionGuard()
|
||||
{
|
||||
LogWidget::setIndent(LogWidget::indent() - 2);
|
||||
qDebug("<%s", m_name);
|
||||
}
|
||||
|
||||
#endif // LOGWIDGET_H
|
26
tests/manual/diaglib/nativewindowdump.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "nativewindowdump.h"
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
void dumpNativeWindows(WId wid)
|
||||
{
|
||||
QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface();
|
||||
QString result;
|
||||
QMetaObject::invokeMethod(ni, "dumpNativeWindows", Qt::DirectConnection,
|
||||
Q_RETURN_ARG(QString, result),
|
||||
Q_ARG(WId, wid));
|
||||
qDebug().noquote() << result;
|
||||
}
|
||||
|
||||
void dumpNativeQtTopLevels()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace QtDiag
|
16
tests/manual/diaglib/nativewindowdump.h
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef _NATIVEWINDOWDUMP_
|
||||
#define _NATIVEWINDOWDUMP_
|
||||
|
||||
#include <QtGui/qwindowdefs.h>
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
void dumpNativeWindows(WId root = 0);
|
||||
void dumpNativeQtTopLevels();
|
||||
|
||||
} // namespace QtDiag
|
||||
|
||||
#endif
|
274
tests/manual/diaglib/nativewindowdump_win.cpp
Normal file
@ -0,0 +1,274 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "nativewindowdump.h"
|
||||
#include "qwindowdump.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QRect>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
#include <QtCore/qt_windows.h>
|
||||
|
||||
#ifndef WS_EX_NOREDIRECTIONBITMAP
|
||||
# define WS_EX_NOREDIRECTIONBITMAP 0x00200000L
|
||||
#endif
|
||||
|
||||
using namespace Qt;
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
struct DumpContext {
|
||||
DumpContext() : indentation(0), parent(0) {}
|
||||
|
||||
int indentation;
|
||||
HWND parent;
|
||||
QSharedPointer<QTextStream> stream;
|
||||
};
|
||||
|
||||
#define debugWinStyle(str, style, styleConstant) \
|
||||
if (style & styleConstant) \
|
||||
str << ' ' << #styleConstant;
|
||||
|
||||
static QTextStream &operator<<(QTextStream &str, const QPoint &p)
|
||||
{
|
||||
str << p.x() << ", " << p.y();
|
||||
return str;
|
||||
}
|
||||
|
||||
static QTextStream &operator<<(QTextStream &str, const QSize &s)
|
||||
{
|
||||
str << s.width() << 'x' << s.height();
|
||||
return str;
|
||||
}
|
||||
|
||||
static QTextStream &operator<<(QTextStream &str, const QRect &rect)
|
||||
{
|
||||
str << rect.size() << Qt::forcesign << rect.x() << rect.y() << Qt::noforcesign;
|
||||
return str;
|
||||
}
|
||||
|
||||
static inline QSize qsizeFromRECT(const RECT &rect)
|
||||
{
|
||||
return QSize(rect.right -rect.left, rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
static inline QRect qrectFromRECT(const RECT &rect)
|
||||
{
|
||||
return QRect(QPoint(rect.left, rect.top), qsizeFromRECT(rect));
|
||||
}
|
||||
|
||||
static QRect getFrameGeometry(HWND hwnd)
|
||||
{
|
||||
RECT rect;
|
||||
return GetWindowRect(hwnd, &rect) ? qrectFromRECT(rect) : QRect();
|
||||
}
|
||||
|
||||
static QPoint getClientAreaScreenPos(HWND hwnd)
|
||||
{
|
||||
POINT clientPos{0, 0};
|
||||
return ClientToScreen(hwnd, &clientPos) ? QPoint(clientPos.x, clientPos.y) : QPoint();
|
||||
}
|
||||
|
||||
static QRect getClientAreaGeometry(HWND hwnd)
|
||||
{
|
||||
RECT clientRect;
|
||||
return GetClientRect(hwnd, &clientRect)
|
||||
? QRect(getClientAreaScreenPos(hwnd), qsizeFromRECT(clientRect)) : QRect();
|
||||
}
|
||||
|
||||
static bool isTopLevel(HWND hwnd)
|
||||
{
|
||||
auto parent = GetParent(hwnd);
|
||||
return !parent || parent == GetDesktopWindow();
|
||||
}
|
||||
|
||||
static void formatNativeWindow(HWND hwnd, QTextStream &str)
|
||||
{
|
||||
str << Qt::hex << Qt::showbase << quintptr(hwnd) << Qt::noshowbase << Qt::dec;
|
||||
|
||||
const bool topLevel = isTopLevel(hwnd);
|
||||
if (topLevel)
|
||||
str << " [top]";
|
||||
const auto frameGeometry = getFrameGeometry(hwnd);
|
||||
const auto clientGeometry = getClientAreaGeometry(hwnd);
|
||||
str << ' ' << frameGeometry;
|
||||
if (!topLevel)
|
||||
str << " local: " << (clientGeometry.topLeft() - getClientAreaScreenPos(GetParent(hwnd)));
|
||||
if (clientGeometry != frameGeometry) {
|
||||
str << " client: " << clientGeometry << " frame: "
|
||||
<< (clientGeometry.topLeft() - frameGeometry.topLeft());
|
||||
}
|
||||
|
||||
if (IsWindowVisible(hwnd))
|
||||
str << " [visible]";
|
||||
|
||||
wchar_t buf[512];
|
||||
if (GetWindowText(hwnd, buf, sizeof(buf)/sizeof(buf[0])) && buf[0])
|
||||
str << " title=\"" << QString::fromWCharArray(buf) << "\"/";
|
||||
else
|
||||
str << ' ';
|
||||
if (GetClassName(hwnd, buf, sizeof(buf)/sizeof(buf[0])))
|
||||
str << '"' << QString::fromWCharArray(buf) << '"';
|
||||
|
||||
str << Qt::hex << Qt::showbase;
|
||||
if (const LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE)) {
|
||||
str << " style=" << style;
|
||||
debugWinStyle(str, style, WS_OVERLAPPED)
|
||||
debugWinStyle(str, style, WS_POPUP)
|
||||
debugWinStyle(str, style, WS_MINIMIZE)
|
||||
debugWinStyle(str, style, WS_CHILD)
|
||||
debugWinStyle(str, style, WS_VISIBLE)
|
||||
debugWinStyle(str, style, WS_DISABLED)
|
||||
debugWinStyle(str, style, WS_CLIPSIBLINGS)
|
||||
debugWinStyle(str, style, WS_CLIPCHILDREN)
|
||||
debugWinStyle(str, style, WS_MAXIMIZE)
|
||||
debugWinStyle(str, style, WS_CAPTION)
|
||||
debugWinStyle(str, style, WS_BORDER)
|
||||
debugWinStyle(str, style, WS_DLGFRAME)
|
||||
debugWinStyle(str, style, WS_VSCROLL)
|
||||
debugWinStyle(str, style, WS_HSCROLL)
|
||||
debugWinStyle(str, style, WS_SYSMENU)
|
||||
debugWinStyle(str, style, WS_THICKFRAME)
|
||||
debugWinStyle(str, style, WS_GROUP)
|
||||
debugWinStyle(str, style, WS_TABSTOP)
|
||||
debugWinStyle(str, style, WS_MINIMIZEBOX)
|
||||
debugWinStyle(str, style, WS_MAXIMIZEBOX)
|
||||
}
|
||||
if (const LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE)) {
|
||||
str << " exStyle=" << exStyle;
|
||||
debugWinStyle(str, exStyle, WS_EX_DLGMODALFRAME)
|
||||
debugWinStyle(str, exStyle, WS_EX_NOPARENTNOTIFY)
|
||||
debugWinStyle(str, exStyle, WS_EX_TOPMOST)
|
||||
debugWinStyle(str, exStyle, WS_EX_ACCEPTFILES)
|
||||
debugWinStyle(str, exStyle, WS_EX_TRANSPARENT)
|
||||
debugWinStyle(str, exStyle, WS_EX_MDICHILD)
|
||||
debugWinStyle(str, exStyle, WS_EX_TOOLWINDOW)
|
||||
debugWinStyle(str, exStyle, WS_EX_WINDOWEDGE)
|
||||
debugWinStyle(str, exStyle, WS_EX_CLIENTEDGE)
|
||||
debugWinStyle(str, exStyle, WS_EX_CONTEXTHELP)
|
||||
debugWinStyle(str, exStyle, WS_EX_RIGHT)
|
||||
debugWinStyle(str, exStyle, WS_EX_LEFT)
|
||||
debugWinStyle(str, exStyle, WS_EX_RTLREADING)
|
||||
debugWinStyle(str, exStyle, WS_EX_LTRREADING)
|
||||
debugWinStyle(str, exStyle, WS_EX_LEFTSCROLLBAR)
|
||||
debugWinStyle(str, exStyle, WS_EX_RIGHTSCROLLBAR)
|
||||
debugWinStyle(str, exStyle, WS_EX_CONTROLPARENT)
|
||||
debugWinStyle(str, exStyle, WS_EX_STATICEDGE)
|
||||
debugWinStyle(str, exStyle, WS_EX_APPWINDOW)
|
||||
debugWinStyle(str, exStyle, WS_EX_LAYERED)
|
||||
debugWinStyle(str, exStyle, WS_EX_NOINHERITLAYOUT)
|
||||
debugWinStyle(str, exStyle, WS_EX_NOREDIRECTIONBITMAP)
|
||||
debugWinStyle(str, exStyle, WS_EX_LAYOUTRTL)
|
||||
debugWinStyle(str, exStyle, WS_EX_COMPOSITED)
|
||||
debugWinStyle(str, exStyle, WS_EX_NOACTIVATE)
|
||||
}
|
||||
|
||||
if (const ULONG_PTR classStyle = GetClassLongPtr(hwnd, GCL_STYLE)) {
|
||||
str << " classStyle=" << classStyle;
|
||||
debugWinStyle(str, classStyle, CS_BYTEALIGNCLIENT)
|
||||
debugWinStyle(str, classStyle, CS_BYTEALIGNWINDOW)
|
||||
debugWinStyle(str, classStyle, CS_CLASSDC)
|
||||
debugWinStyle(str, classStyle, CS_DBLCLKS)
|
||||
debugWinStyle(str, classStyle, CS_DROPSHADOW)
|
||||
debugWinStyle(str, classStyle, CS_GLOBALCLASS)
|
||||
debugWinStyle(str, classStyle, CS_HREDRAW)
|
||||
debugWinStyle(str, classStyle, CS_NOCLOSE)
|
||||
debugWinStyle(str, classStyle, CS_OWNDC)
|
||||
debugWinStyle(str, classStyle, CS_PARENTDC)
|
||||
debugWinStyle(str, classStyle, CS_SAVEBITS)
|
||||
debugWinStyle(str, classStyle, CS_VREDRAW)
|
||||
}
|
||||
|
||||
if (const ULONG_PTR wndProc = GetClassLongPtr(hwnd, GCLP_WNDPROC))
|
||||
str << " wndProc=" << wndProc;
|
||||
|
||||
str << Qt::noshowbase << Qt::dec;
|
||||
|
||||
if (GetWindowModuleFileName(hwnd, buf, sizeof(buf)/sizeof(buf[0])))
|
||||
str << " module=\"" << QString::fromWCharArray(buf) << '"';
|
||||
|
||||
str << '\n';
|
||||
}
|
||||
|
||||
static void dumpNativeWindowRecursion(HWND hwnd, DumpContext *dc);
|
||||
|
||||
BOOL CALLBACK dumpWindowEnumChildProc(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
DumpContext *dumpContext = reinterpret_cast<DumpContext *>(lParam);
|
||||
// EnumChildWindows enumerates grand children as well, skip these to
|
||||
// get the hierarchical formatting right.
|
||||
if (GetAncestor(hwnd, GA_PARENT) == dumpContext->parent)
|
||||
dumpNativeWindowRecursion(hwnd, dumpContext);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void dumpNativeWindowRecursion(HWND hwnd, DumpContext *dc)
|
||||
{
|
||||
indentStream(*dc->stream, dc->indentation);
|
||||
formatNativeWindow(hwnd, *dc->stream);
|
||||
DumpContext nextLevel = *dc;
|
||||
nextLevel.indentation += 2;
|
||||
nextLevel.parent = hwnd;
|
||||
EnumChildWindows(hwnd, dumpWindowEnumChildProc, reinterpret_cast<LPARAM>(&nextLevel));
|
||||
}
|
||||
|
||||
/* recurse by Z order, same result */
|
||||
static void dumpNativeWindowRecursionByZ(HWND hwnd, DumpContext *dc)
|
||||
{
|
||||
indentStream(*dc->stream, dc->indentation);
|
||||
formatNativeWindow(hwnd, *dc->stream);
|
||||
if (const HWND topChild = GetTopWindow(hwnd)) {
|
||||
DumpContext nextLevel = *dc;
|
||||
nextLevel.indentation += 2;
|
||||
for (HWND child = topChild; child ; child = GetNextWindow(child, GW_HWNDNEXT))
|
||||
dumpNativeWindowRecursionByZ(child, &nextLevel);
|
||||
}
|
||||
}
|
||||
|
||||
typedef QList<WId> WIdVector;
|
||||
|
||||
static void dumpNativeWindows(const WIdVector& wins)
|
||||
{
|
||||
DumpContext dc;
|
||||
QString s;
|
||||
dc.stream = QSharedPointer<QTextStream>(new QTextStream(&s));
|
||||
for (WId win : wins)
|
||||
dumpNativeWindowRecursion(reinterpret_cast<HWND>(win), &dc);
|
||||
qDebug().noquote() << s;
|
||||
}
|
||||
|
||||
void dumpNativeWindows(WId rootIn)
|
||||
{
|
||||
const WId root = rootIn ? rootIn : reinterpret_cast<WId>(GetDesktopWindow());
|
||||
dumpNativeWindows(WIdVector(1, root));
|
||||
}
|
||||
|
||||
BOOL CALLBACK findQtTopLevelEnumChildProc(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
WIdVector *v = reinterpret_cast<WIdVector *>(lParam);
|
||||
wchar_t buf[512];
|
||||
if (GetClassName(hwnd, buf, sizeof(buf)/sizeof(buf[0]))) {
|
||||
if (wcsstr(buf, L"Qt"))
|
||||
v->append(reinterpret_cast<WId>(hwnd));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static WIdVector findQtTopLevels()
|
||||
{
|
||||
WIdVector result;
|
||||
EnumChildWindows(GetDesktopWindow(),
|
||||
findQtTopLevelEnumChildProc,
|
||||
reinterpret_cast<LPARAM>(&result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void dumpNativeQtTopLevels()
|
||||
{
|
||||
dumpNativeWindows(findQtTopLevels());
|
||||
}
|
||||
|
||||
} // namespace QtDiag
|
132
tests/manual/diaglib/qwidgetdump.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qwidgetdump.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QWidget>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QWindow>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
static const char *qtWidgetClasses[] = {
|
||||
"QAbstractItemView", "QAbstractScrollArea", "QAbstractSlider", "QAbstractSpinBox",
|
||||
"QCalendarWidget", "QCheckBox", "QColorDialog", "QColumnView", "QComboBox",
|
||||
"QCommandLinkButton", "QDateEdit", "QDateTimeEdit", "QDial",
|
||||
"QDialog", "QDialogButtonBox", "QDockWidget", "QDoubleSpinBox", "QErrorMessage",
|
||||
"QFileDialog", "QFontComboBox", "QFontDialog", "QFrame", "QGraphicsView",
|
||||
"QGroupBox", "QHeaderView", "QInputDialog", "QLCDNumber", "QLabel", "QLineEdit",
|
||||
"QListView", "QListWidget", "QMainWindow", "QMdiArea", "QMdiSubWindow", "QMenu",
|
||||
"QMenuBar", "QMessageBox", "QOpenGLWidget", "QPlainTextEdit", "QProgressBar",
|
||||
"QProgressDialog", "QPushButton", "QRadioButton", "QRubberBand", "QScrollArea",
|
||||
"QScrollBar", "QSlider", "QSpinBox", "QSplashScreen", "QSplitter",
|
||||
"QStackedWidget", "QStatusBar", "QTabBar", "QTabWidget", "QTableView",
|
||||
"QTableWidget", "QTextBrowser", "QTextEdit", "QTimeEdit", "QToolBar",
|
||||
"QToolBox", "QToolButton", "QTreeView", "QTreeWidget", "QWidget",
|
||||
"QWizard", "QWizardPage"
|
||||
};
|
||||
|
||||
static bool isQtWidget(const char *className)
|
||||
{
|
||||
for (auto qtWidgetClass : qtWidgetClasses) {
|
||||
if (qstrcmp(className, qtWidgetClass) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void formatWidgetClass(QTextStream &str, const QWidget *w)
|
||||
{
|
||||
const QMetaObject *mo = w->metaObject();
|
||||
str << mo->className();
|
||||
while (!isQtWidget(mo->className())) {
|
||||
mo = mo->superClass();
|
||||
str << ':' << mo->className();
|
||||
}
|
||||
const QString on = w->objectName();
|
||||
if (!on.isEmpty())
|
||||
str << "/\"" << on << '"';
|
||||
}
|
||||
|
||||
static void dumpWidgetRecursion(QTextStream &str, const QWidget *w,
|
||||
FormatWindowOptions options, int depth = 0)
|
||||
{
|
||||
indentStream(str, 2 * depth);
|
||||
formatWidgetClass(str, w);
|
||||
str << ' ' << (w->isVisible() ? "[visible] " : "[hidden] ");
|
||||
if (const WId nativeWinId = w->internalWinId())
|
||||
str << "[native: " << Qt::hex << Qt::showbase << nativeWinId << Qt::dec << Qt::noshowbase
|
||||
<< "] ";
|
||||
if (w->isWindow())
|
||||
str << "[top] ";
|
||||
str << (w->testAttribute(Qt::WA_Mapped) ? "[mapped] " : "[not mapped] ");
|
||||
if (w->testAttribute(Qt::WA_DontCreateNativeAncestors))
|
||||
str << "[NoNativeAncestors] ";
|
||||
if (const int states = w->windowState())
|
||||
str << "windowState=" << Qt::hex << Qt::showbase << states << Qt::dec << Qt::noshowbase
|
||||
<< ' ';
|
||||
formatRect(str, w->geometry());
|
||||
if (w->isWindow()) {
|
||||
str << ' ' << w->logicalDpiX() << "DPI";
|
||||
const qreal dpr = w->devicePixelRatio();
|
||||
if (!qFuzzyCompare(dpr, qreal(1)))
|
||||
str << " dpr=" << dpr;
|
||||
const QRect normalGeometry = w->normalGeometry();
|
||||
if (normalGeometry.isValid() && !normalGeometry.isEmpty() && normalGeometry != w->geometry()) {
|
||||
str << " normal=";
|
||||
formatRect(str, w->normalGeometry());
|
||||
}
|
||||
}
|
||||
if (!(options & DontPrintWindowFlags)) {
|
||||
str << ' ';
|
||||
formatWindowFlags(str, w->windowFlags());
|
||||
}
|
||||
if (options & PrintSizeConstraints) {
|
||||
str << ' ';
|
||||
const QSize minimumSize = w->minimumSize();
|
||||
if (minimumSize.width() > 0 || minimumSize.height() > 0)
|
||||
str << "minimumSize=" << minimumSize.width() << 'x' << minimumSize.height() << ' ';
|
||||
const QSize sizeHint = w->sizeHint();
|
||||
const QSize minimumSizeHint = w->minimumSizeHint();
|
||||
if (minimumSizeHint.isValid() && !(sizeHint.isValid() && minimumSizeHint == sizeHint))
|
||||
str << "minimumSizeHint=" << minimumSizeHint.width() << 'x' << minimumSizeHint.height() << ' ';
|
||||
if (sizeHint.isValid())
|
||||
str << "sizeHint=" << sizeHint.width() << 'x' << sizeHint.height() << ' ';
|
||||
const QSize maximumSize = w->maximumSize();
|
||||
if (maximumSize.width() < QWIDGETSIZE_MAX || maximumSize.height() < QWIDGETSIZE_MAX)
|
||||
str << "maximumSize=" << maximumSize.width() << 'x' << maximumSize.height() << ' ';
|
||||
}
|
||||
str << '\n';
|
||||
if (const QWindow *win = w->windowHandle()) {
|
||||
indentStream(str, 2 * (1 + depth));
|
||||
formatWindow(str, win, options);
|
||||
str << '\n';
|
||||
}
|
||||
for (const QObject *co : w->children()) {
|
||||
if (co->isWidgetType())
|
||||
dumpWidgetRecursion(str, static_cast<const QWidget *>(co), options, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void dumpAllWidgets(FormatWindowOptions options, const QWidget *root)
|
||||
{
|
||||
QString d;
|
||||
QTextStream str(&d);
|
||||
str << "### QWidgets:\n";
|
||||
QWidgetList topLevels;
|
||||
if (root)
|
||||
topLevels.append(const_cast<QWidget *>(root));
|
||||
else
|
||||
topLevels = QApplication::topLevelWidgets();
|
||||
for (QWidget *tw : std::as_const(topLevels))
|
||||
dumpWidgetRecursion(str, tw, options);
|
||||
for (const QString &line : d.split(QLatin1Char('\n')))
|
||||
qDebug().noquote() << line;
|
||||
}
|
||||
|
||||
} // namespace QtDiag
|
17
tests/manual/diaglib/qwidgetdump.h
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef _WIDGETDUMP_
|
||||
#define _WIDGETDUMP_
|
||||
|
||||
#include "qwindowdump.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QWidget)
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
void dumpAllWidgets(FormatWindowOptions options = {}, const QWidget *root = nullptr);
|
||||
|
||||
} // namespace QtDiag
|
||||
|
||||
#endif
|
146
tests/manual/diaglib/qwindowdump.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qwindowdump.h"
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtCore/QRect>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
#include <qpa/qplatformwindow.h>
|
||||
#include <private/qwindow_p.h>
|
||||
#include <private/qhighdpiscaling_p.h>
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
void indentStream(QTextStream &s, int indent)
|
||||
{
|
||||
for (int i = 0; i < indent; ++i)
|
||||
s << ' ';
|
||||
}
|
||||
|
||||
void formatObject(QTextStream &str, const QObject *o)
|
||||
{
|
||||
str << o->metaObject()->className();
|
||||
const QString on = o->objectName();
|
||||
if (!on.isEmpty())
|
||||
str << "/\"" << on << '"';
|
||||
}
|
||||
|
||||
void formatRect(QTextStream &str, const QRect &geom)
|
||||
{
|
||||
str << geom.width() << 'x' << geom.height() << Qt::forcesign
|
||||
<< geom.x() << geom.y() << Qt::noforcesign;
|
||||
}
|
||||
|
||||
#define debugType(s, type, typeConstant) \
|
||||
if ((type & typeConstant) == typeConstant) \
|
||||
s << ' ' << #typeConstant;
|
||||
|
||||
#define debugFlag(s, flags, flagConstant) \
|
||||
if (flags & flagConstant) \
|
||||
s << ' ' << #flagConstant;
|
||||
|
||||
void formatWindowFlags(QTextStream &str, Qt::WindowFlags flags)
|
||||
{
|
||||
str << Qt::showbase << Qt::hex << unsigned(flags) << Qt::dec << Qt::noshowbase;
|
||||
const Qt::WindowFlags windowType = flags & Qt::WindowType_Mask;
|
||||
debugFlag(str, flags, Qt::Window)
|
||||
debugType(str, windowType, Qt::Dialog)
|
||||
debugType(str, windowType, Qt::Sheet)
|
||||
debugType(str, windowType, Qt::Drawer)
|
||||
debugType(str, windowType, Qt::Popup)
|
||||
debugType(str, windowType, Qt::Tool)
|
||||
debugType(str, windowType, Qt::ToolTip)
|
||||
debugType(str, windowType, Qt::SplashScreen)
|
||||
debugType(str, windowType, Qt::Desktop)
|
||||
debugType(str, windowType, Qt::SubWindow)
|
||||
debugType(str, windowType, Qt::ForeignWindow)
|
||||
debugType(str, windowType, Qt::CoverWindow)
|
||||
debugFlag(str, flags, Qt::MSWindowsFixedSizeDialogHint)
|
||||
debugFlag(str, flags, Qt::MSWindowsOwnDC)
|
||||
debugFlag(str, flags, Qt::X11BypassWindowManagerHint)
|
||||
debugFlag(str, flags, Qt::FramelessWindowHint)
|
||||
debugFlag(str, flags, Qt::WindowTitleHint)
|
||||
debugFlag(str, flags, Qt::WindowSystemMenuHint)
|
||||
debugFlag(str, flags, Qt::WindowMinimizeButtonHint)
|
||||
debugFlag(str, flags, Qt::WindowMaximizeButtonHint)
|
||||
debugFlag(str, flags, Qt::WindowContextHelpButtonHint)
|
||||
debugFlag(str, flags, Qt::WindowShadeButtonHint)
|
||||
debugFlag(str, flags, Qt::WindowStaysOnTopHint)
|
||||
debugFlag(str, flags, Qt::CustomizeWindowHint)
|
||||
debugFlag(str, flags, Qt::WindowTransparentForInput)
|
||||
debugFlag(str, flags, Qt::WindowOverridesSystemGestures)
|
||||
debugFlag(str, flags, Qt::WindowDoesNotAcceptFocus)
|
||||
debugFlag(str, flags, Qt::NoDropShadowWindowHint)
|
||||
debugFlag(str, flags, Qt::WindowFullscreenButtonHint)
|
||||
debugFlag(str, flags, Qt::WindowStaysOnBottomHint)
|
||||
debugFlag(str, flags, Qt::MacWindowToolBarButtonHint)
|
||||
debugFlag(str, flags, Qt::BypassGraphicsProxyWidget)
|
||||
}
|
||||
|
||||
void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions options)
|
||||
{
|
||||
const QPlatformWindow *pw = w->handle();
|
||||
formatObject(str, w);
|
||||
str << ' ' << (w->isVisible() ? "[visible] " : "[hidden] ");
|
||||
if (const WId nativeWinId = pw ? pw->winId() : WId(0))
|
||||
str << "[native: " << Qt::hex << Qt::showbase << nativeWinId << Qt::dec << Qt::noshowbase
|
||||
<< "] ";
|
||||
if (w->isTopLevel())
|
||||
str << "[top] ";
|
||||
if (w->isExposed())
|
||||
str << "[exposed] ";
|
||||
if (w->surfaceClass() == QWindow::Offscreen)
|
||||
str << "[offscreen] ";
|
||||
str << "surface=" << w->surfaceType() << ' ';
|
||||
if (const Qt::WindowState state = w->windowState())
|
||||
str << "windowState=" << state << ' ';
|
||||
formatRect(str, w->geometry());
|
||||
if (w->isTopLevel()) {
|
||||
str << " \"" << w->screen()->name() << "\" ";
|
||||
if (QHighDpiScaling::isActive())
|
||||
str << "factor=" << QHighDpiScaling::factor(w) << " dpr=" << w->devicePixelRatio();
|
||||
}
|
||||
if (!(options & DontPrintWindowFlags)) {
|
||||
str << ' ';
|
||||
formatWindowFlags(str, w->flags());
|
||||
}
|
||||
if (options & PrintSizeConstraints) {
|
||||
str << ' ';
|
||||
const QSize minimumSize = w->minimumSize();
|
||||
if (minimumSize.width() > 0 || minimumSize.height() > 0)
|
||||
str << "minimumSize=" << minimumSize.width() << 'x' << minimumSize.height() << ' ';
|
||||
const QSize maximumSize = w->maximumSize();
|
||||
if (maximumSize.width() < QWINDOWSIZE_MAX || maximumSize.height() < QWINDOWSIZE_MAX)
|
||||
str << "maximumSize=" << maximumSize.width() << 'x' << maximumSize.height() << ' ';
|
||||
}
|
||||
str << '\n';
|
||||
}
|
||||
|
||||
static void dumpWindowRecursion(QTextStream &str, const QWindow *w,
|
||||
FormatWindowOptions options = {}, int depth = 0)
|
||||
{
|
||||
indentStream(str, 2 * depth);
|
||||
formatWindow(str, w, options);
|
||||
for (const QObject *co : w->children()) {
|
||||
if (co->isWindowType())
|
||||
dumpWindowRecursion(str, static_cast<const QWindow *>(co), options, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void dumpAllWindows(FormatWindowOptions options)
|
||||
{
|
||||
QString d;
|
||||
QTextStream str(&d);
|
||||
str << "### QWindows:\n";
|
||||
for (QWindow *w : QGuiApplication::topLevelWindows())
|
||||
dumpWindowRecursion(str, w, options);
|
||||
qDebug().noquote() << d;
|
||||
}
|
||||
|
||||
} // namespace QtDiag
|
34
tests/manual/diaglib/qwindowdump.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef _WINDOWDUMP_
|
||||
#define _WINDOWDUMP_
|
||||
|
||||
#include <QtCore/qnamespace.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QRect)
|
||||
QT_FORWARD_DECLARE_CLASS(QObject)
|
||||
QT_FORWARD_DECLARE_CLASS(QWindow)
|
||||
QT_FORWARD_DECLARE_CLASS(QTextStream)
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
enum FormatWindowOption {
|
||||
DontPrintWindowFlags = 0x001,
|
||||
PrintSizeConstraints = 0x002
|
||||
};
|
||||
|
||||
Q_DECLARE_FLAGS(FormatWindowOptions, FormatWindowOption)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(FormatWindowOptions)
|
||||
|
||||
void indentStream(QTextStream &s, int indent);
|
||||
void formatObject(QTextStream &str, const QObject *o);
|
||||
void formatRect(QTextStream &str, const QRect &geom);
|
||||
void formatWindowFlags(QTextStream &str, Qt::WindowFlags flags);
|
||||
|
||||
void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions options = {});
|
||||
void dumpAllWindows(FormatWindowOptions options = {});
|
||||
|
||||
} // namespace QtDiag
|
||||
|
||||
#endif
|
430
tests/manual/diaglib/textdump.cpp
Normal file
@ -0,0 +1,430 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "textdump.h"
|
||||
|
||||
#include <QTextStream>
|
||||
#include <QString>
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
struct EnumLookup {
|
||||
int value;
|
||||
const char *description;
|
||||
};
|
||||
|
||||
static const EnumLookup specialCharactersEnumLookup[] =
|
||||
{
|
||||
{QChar::Null, "Null"},
|
||||
{QChar::Tabulation, "Tabulation"},
|
||||
{QChar::LineFeed, "LineFeed"},
|
||||
{QChar::FormFeed, "FormFeed"},
|
||||
{QChar::CarriageReturn, "CarriageReturn"},
|
||||
{QChar::Space, "Space"},
|
||||
{QChar::Nbsp, "Nbsp"},
|
||||
{QChar::SoftHyphen, "SoftHyphen"},
|
||||
{QChar::ReplacementCharacter, "ReplacementCharacter"},
|
||||
{QChar::ObjectReplacementCharacter, "ObjectReplacementCharacter"},
|
||||
{QChar::ByteOrderMark, "ByteOrderMark"},
|
||||
{QChar::ByteOrderSwapped, "ByteOrderSwapped"},
|
||||
{QChar::ParagraphSeparator, "ParagraphSeparator"},
|
||||
{QChar::LineSeparator, "LineSeparator"},
|
||||
{QChar::LastValidCodePoint, "LastValidCodePoint"}
|
||||
};
|
||||
|
||||
static const EnumLookup categoryEnumLookup[] =
|
||||
{
|
||||
{QChar::Mark_NonSpacing, "Mark_NonSpacing"},
|
||||
{QChar::Mark_SpacingCombining, "Mark_SpacingCombining"},
|
||||
{QChar::Mark_Enclosing, "Mark_Enclosing"},
|
||||
|
||||
{QChar::Number_DecimalDigit, "Number_DecimalDigit"},
|
||||
{QChar::Number_Letter, "Number_Letter"},
|
||||
{QChar::Number_Other, "Number_Other"},
|
||||
|
||||
{QChar::Separator_Space, "Separator_Space"},
|
||||
{QChar::Separator_Line, "Separator_Line"},
|
||||
{QChar::Separator_Paragraph, "Separator_Paragraph"},
|
||||
|
||||
{QChar::Other_Control, "Other_Control"},
|
||||
{QChar::Other_Format, "Other_Format"},
|
||||
{QChar::Other_Surrogate, "Other_Surrogate"},
|
||||
{QChar::Other_PrivateUse, "Other_PrivateUse"},
|
||||
{QChar::Other_NotAssigned, "Other_NotAssigned"},
|
||||
|
||||
{QChar::Letter_Uppercase, "Letter_Uppercase"},
|
||||
{QChar::Letter_Lowercase, "Letter_Lowercase"},
|
||||
{QChar::Letter_Titlecase, "Letter_Titlecase"},
|
||||
{QChar::Letter_Modifier, "Letter_Modifier"},
|
||||
{QChar::Letter_Other, "Letter_Other"},
|
||||
|
||||
{QChar::Punctuation_Connector, "Punctuation_Connector"},
|
||||
{QChar::Punctuation_Dash, "Punctuation_Dash"},
|
||||
{QChar::Punctuation_Open, "Punctuation_Open"},
|
||||
{QChar::Punctuation_Close, "Punctuation_Close"},
|
||||
{QChar::Punctuation_InitialQuote, "Punctuation_InitialQuote"},
|
||||
{QChar::Punctuation_FinalQuote, "Punctuation_FinalQuote"},
|
||||
{QChar::Punctuation_Other, "Punctuation_Other"},
|
||||
|
||||
{QChar::Symbol_Math, "Symbol_Math"},
|
||||
{QChar::Symbol_Currency, "Symbol_Currency"},
|
||||
{QChar::Symbol_Modifier, "Symbol_Modifier"},
|
||||
{QChar::Symbol_Other, "Symbol_Other"},
|
||||
};
|
||||
|
||||
static const EnumLookup scriptEnumLookup[] =
|
||||
{
|
||||
{QChar::Script_Unknown, "Script_Unknown"},
|
||||
{QChar::Script_Inherited, "Script_Inherited"},
|
||||
{QChar::Script_Common, "Script_Common"},
|
||||
|
||||
{QChar::Script_Latin, "Script_Latin"},
|
||||
{QChar::Script_Greek, "Script_Greek"},
|
||||
{QChar::Script_Cyrillic, "Script_Cyrillic"},
|
||||
{QChar::Script_Armenian, "Script_Armenian"},
|
||||
{QChar::Script_Hebrew, "Script_Hebrew"},
|
||||
{QChar::Script_Arabic, "Script_Arabic"},
|
||||
{QChar::Script_Syriac, "Script_Syriac"},
|
||||
{QChar::Script_Thaana, "Script_Thaana"},
|
||||
{QChar::Script_Devanagari, "Script_Devanagari"},
|
||||
{QChar::Script_Bengali, "Script_Bengali"},
|
||||
{QChar::Script_Gurmukhi, "Script_Gurmukhi"},
|
||||
{QChar::Script_Gujarati, "Script_Gujarati"},
|
||||
{QChar::Script_Oriya, "Script_Oriya"},
|
||||
{QChar::Script_Tamil, "Script_Tamil"},
|
||||
{QChar::Script_Telugu, "Script_Telugu"},
|
||||
{QChar::Script_Kannada, "Script_Kannada"},
|
||||
{QChar::Script_Malayalam, "Script_Malayalam"},
|
||||
{QChar::Script_Sinhala, "Script_Sinhala"},
|
||||
{QChar::Script_Thai, "Script_Thai"},
|
||||
{QChar::Script_Lao, "Script_Lao"},
|
||||
{QChar::Script_Tibetan, "Script_Tibetan"},
|
||||
{QChar::Script_Myanmar, "Script_Myanmar"},
|
||||
{QChar::Script_Georgian, "Script_Georgian"},
|
||||
{QChar::Script_Hangul, "Script_Hangul"},
|
||||
{QChar::Script_Ethiopic, "Script_Ethiopic"},
|
||||
{QChar::Script_Cherokee, "Script_Cherokee"},
|
||||
{QChar::Script_CanadianAboriginal, "Script_CanadianAboriginal"},
|
||||
{QChar::Script_Ogham, "Script_Ogham"},
|
||||
{QChar::Script_Runic, "Script_Runic"},
|
||||
{QChar::Script_Khmer, "Script_Khmer"},
|
||||
{QChar::Script_Mongolian, "Script_Mongolian"},
|
||||
{QChar::Script_Hiragana, "Script_Hiragana"},
|
||||
{QChar::Script_Katakana, "Script_Katakana"},
|
||||
{QChar::Script_Bopomofo, "Script_Bopomofo"},
|
||||
{QChar::Script_Han, "Script_Han"},
|
||||
{QChar::Script_Yi, "Script_Yi"},
|
||||
{QChar::Script_OldItalic, "Script_OldItalic"},
|
||||
{QChar::Script_Gothic, "Script_Gothic"},
|
||||
{QChar::Script_Deseret, "Script_Deseret"},
|
||||
{QChar::Script_Tagalog, "Script_Tagalog"},
|
||||
{QChar::Script_Hanunoo, "Script_Hanunoo"},
|
||||
{QChar::Script_Buhid, "Script_Buhid"},
|
||||
{QChar::Script_Tagbanwa, "Script_Tagbanwa"},
|
||||
{QChar::Script_Coptic, "Script_Coptic"},
|
||||
|
||||
{QChar::Script_Limbu, "Script_Limbu"},
|
||||
{QChar::Script_TaiLe, "Script_TaiLe"},
|
||||
{QChar::Script_LinearB, "Script_LinearB"},
|
||||
{QChar::Script_Ugaritic, "Script_Ugaritic"},
|
||||
{QChar::Script_Shavian, "Script_Shavian"},
|
||||
{QChar::Script_Osmanya, "Script_Osmanya"},
|
||||
{QChar::Script_Cypriot, "Script_Cypriot"},
|
||||
{QChar::Script_Braille, "Script_Braille"},
|
||||
|
||||
{QChar::Script_Buginese, "Script_Buginese"},
|
||||
{QChar::Script_NewTaiLue, "Script_NewTaiLue"},
|
||||
{QChar::Script_Glagolitic, "Script_Glagolitic"},
|
||||
{QChar::Script_Tifinagh, "Script_Tifinagh"},
|
||||
{QChar::Script_SylotiNagri, "Script_SylotiNagri"},
|
||||
{QChar::Script_OldPersian, "Script_OldPersian"},
|
||||
{QChar::Script_Kharoshthi, "Script_Kharoshthi"},
|
||||
|
||||
{QChar::Script_Balinese, "Script_Balinese"},
|
||||
{QChar::Script_Cuneiform, "Script_Cuneiform"},
|
||||
{QChar::Script_Phoenician, "Script_Phoenician"},
|
||||
{QChar::Script_PhagsPa, "Script_PhagsPa"},
|
||||
{QChar::Script_Nko, "Script_Nko"},
|
||||
|
||||
{QChar::Script_Sundanese, "Script_Sundanese"},
|
||||
{QChar::Script_Lepcha, "Script_Lepcha"},
|
||||
{QChar::Script_OlChiki, "Script_OlChiki"},
|
||||
{QChar::Script_Vai, "Script_Vai"},
|
||||
{QChar::Script_Saurashtra, "Script_Saurashtra"},
|
||||
{QChar::Script_KayahLi, "Script_KayahLi"},
|
||||
{QChar::Script_Rejang, "Script_Rejang"},
|
||||
{QChar::Script_Lycian, "Script_Lycian"},
|
||||
{QChar::Script_Carian, "Script_Carian"},
|
||||
{QChar::Script_Lydian, "Script_Lydian"},
|
||||
{QChar::Script_Cham, "Script_Cham"},
|
||||
|
||||
{QChar::Script_TaiTham, "Script_TaiTham"},
|
||||
{QChar::Script_TaiViet, "Script_TaiViet"},
|
||||
{QChar::Script_Avestan, "Script_Avestan"},
|
||||
{QChar::Script_EgyptianHieroglyphs, "Script_EgyptianHieroglyphs"},
|
||||
{QChar::Script_Samaritan, "Script_Samaritan"},
|
||||
{QChar::Script_Lisu, "Script_Lisu"},
|
||||
{QChar::Script_Bamum, "Script_Bamum"},
|
||||
{QChar::Script_Javanese, "Script_Javanese"},
|
||||
{QChar::Script_MeeteiMayek, "Script_MeeteiMayek"},
|
||||
{QChar::Script_ImperialAramaic, "Script_ImperialAramaic"},
|
||||
{QChar::Script_OldSouthArabian, "Script_OldSouthArabian"},
|
||||
{QChar::Script_InscriptionalParthian, "Script_InscriptionalParthian"},
|
||||
{QChar::Script_InscriptionalPahlavi, "Script_InscriptionalPahlavi"},
|
||||
{QChar::Script_OldTurkic, "Script_OldTurkic"},
|
||||
{QChar::Script_Kaithi, "Script_Kaithi"},
|
||||
|
||||
{QChar::Script_Batak, "Script_Batak"},
|
||||
{QChar::Script_Brahmi, "Script_Brahmi"},
|
||||
{QChar::Script_Mandaic, "Script_Mandaic"},
|
||||
|
||||
{QChar::Script_Chakma, "Script_Chakma"},
|
||||
{QChar::Script_MeroiticCursive, "Script_MeroiticCursive"},
|
||||
{QChar::Script_MeroiticHieroglyphs, "Script_MeroiticHieroglyphs"},
|
||||
{QChar::Script_Miao, "Script_Miao"},
|
||||
{QChar::Script_Sharada, "Script_Sharada"},
|
||||
{QChar::Script_SoraSompeng, "Script_SoraSompeng"},
|
||||
{QChar::Script_Takri, "Script_Takri"},
|
||||
|
||||
{QChar::Script_CaucasianAlbanian, "Script_CaucasianAlbanian"},
|
||||
{QChar::Script_BassaVah, "Script_BassaVah"},
|
||||
{QChar::Script_Duployan, "Script_Duployan"},
|
||||
{QChar::Script_Elbasan, "Script_Elbasan"},
|
||||
{QChar::Script_Grantha, "Script_Grantha"},
|
||||
{QChar::Script_PahawhHmong, "Script_PahawhHmong"},
|
||||
{QChar::Script_Khojki, "Script_Khojki"},
|
||||
{QChar::Script_LinearA, "Script_LinearA"},
|
||||
{QChar::Script_Mahajani, "Script_Mahajani"},
|
||||
{QChar::Script_Manichaean, "Script_Manichaean"},
|
||||
{QChar::Script_MendeKikakui, "Script_MendeKikakui"},
|
||||
{QChar::Script_Modi, "Script_Modi"},
|
||||
{QChar::Script_Mro, "Script_Mro"},
|
||||
{QChar::Script_OldNorthArabian, "Script_OldNorthArabian"},
|
||||
{QChar::Script_Nabataean, "Script_Nabataean"},
|
||||
{QChar::Script_Palmyrene, "Script_Palmyrene"},
|
||||
{QChar::Script_PauCinHau, "Script_PauCinHau"},
|
||||
{QChar::Script_OldPermic, "Script_OldPermic"},
|
||||
{QChar::Script_PsalterPahlavi, "Script_PsalterPahlavi"},
|
||||
{QChar::Script_Siddham, "Script_Siddham"},
|
||||
{QChar::Script_Khudawadi, "Script_Khudawadi"},
|
||||
{QChar::Script_Tirhuta, "Script_Tirhuta"},
|
||||
{QChar::Script_WarangCiti, "Script_WarangCiti"},
|
||||
|
||||
{QChar::Script_Ahom, "Script_Ahom"},
|
||||
{QChar::Script_AnatolianHieroglyphs, "Script_AnatolianHieroglyphs"},
|
||||
{QChar::Script_Hatran, "Script_Hatran"},
|
||||
{QChar::Script_Multani, "Script_Multani"},
|
||||
{QChar::Script_OldHungarian, "Script_OldHungarian"},
|
||||
{QChar::Script_SignWriting, "Script_SignWriting"},
|
||||
};
|
||||
|
||||
static const EnumLookup directionEnumLookup[] =
|
||||
{
|
||||
{QChar::DirL, "DirL"},
|
||||
{QChar::DirR, "DirR"},
|
||||
{QChar::DirEN, "DirEN"},
|
||||
{QChar::DirES, "DirES"},
|
||||
{QChar::DirET, "DirET"},
|
||||
{QChar::DirAN, "DirAN"},
|
||||
{QChar::DirCS, "DirCS"},
|
||||
{QChar::DirB, "DirB"},
|
||||
{QChar::DirS, "DirS"},
|
||||
{QChar::DirWS, "DirWS"},
|
||||
{QChar::DirON, "DirON"},
|
||||
{QChar::DirLRE, "DirLRE"},
|
||||
{QChar::DirLRO, "DirLRO"},
|
||||
{QChar::DirAL, "DirAL"},
|
||||
{QChar::DirRLE, "DirRLE"},
|
||||
{QChar::DirRLO, "DirRLO"},
|
||||
{QChar::DirPDF, "DirPDF"},
|
||||
{QChar::DirNSM, "DirNSM"},
|
||||
{QChar::DirBN, "DirBN"},
|
||||
{QChar::DirLRI, "DirLRI"},
|
||||
{QChar::DirRLI, "DirRLI"},
|
||||
{QChar::DirFSI, "DirFSI"},
|
||||
{QChar::DirPDI, "DirPDI"},
|
||||
};
|
||||
|
||||
static const EnumLookup decompositionEnumLookup[] =
|
||||
{
|
||||
{QChar::NoDecomposition, "NoDecomposition"},
|
||||
{QChar::Canonical, "Canonical"},
|
||||
{QChar::Font, "Font"},
|
||||
{QChar::NoBreak, "NoBreak"},
|
||||
{QChar::Initial, "Initial"},
|
||||
{QChar::Medial, "Medial"},
|
||||
{QChar::Final, "Final"},
|
||||
{QChar::Isolated, "Isolated"},
|
||||
{QChar::Circle, "Circle"},
|
||||
{QChar::Super, "Super"},
|
||||
{QChar::Sub, "Sub"},
|
||||
{QChar::Vertical, "Vertical"},
|
||||
{QChar::Wide, "Wide"},
|
||||
{QChar::Narrow, "Narrow"},
|
||||
{QChar::Small, "Small"},
|
||||
{QChar::Square, "Square"},
|
||||
{QChar::Compat, "Compat"},
|
||||
{QChar::Fraction, "Fraction"},
|
||||
};
|
||||
|
||||
static const EnumLookup joiningTypeEnumLookup[] =
|
||||
{
|
||||
{QChar::Joining_None, "Joining_None"},
|
||||
{QChar::Joining_Causing, "Joining_Causing"},
|
||||
{QChar::Joining_Dual, "Joining_Dual"},
|
||||
{QChar::Joining_Right, "Joining_Right"},
|
||||
{QChar::Joining_Left, "Joining_Left"},
|
||||
{QChar::Joining_Transparent, "Joining_Transparent"}
|
||||
};
|
||||
|
||||
static const EnumLookup combiningClassEnumLookup[] =
|
||||
{
|
||||
{QChar::Combining_BelowLeftAttached, "Combining_BelowLeftAttached"},
|
||||
{QChar::Combining_BelowAttached, "Combining_BelowAttached"},
|
||||
{QChar::Combining_BelowRightAttached, "Combining_BelowRightAttached"},
|
||||
{QChar::Combining_LeftAttached, "Combining_LeftAttached"},
|
||||
{QChar::Combining_RightAttached, "Combining_RightAttached"},
|
||||
{QChar::Combining_AboveLeftAttached, "Combining_AboveLeftAttached"},
|
||||
{QChar::Combining_AboveAttached, "Combining_AboveAttached"},
|
||||
{QChar::Combining_AboveRightAttached, "Combining_AboveRightAttached"},
|
||||
|
||||
{QChar::Combining_BelowLeft, "Combining_BelowLeft"},
|
||||
{QChar::Combining_Below, "Combining_Below"},
|
||||
{QChar::Combining_BelowRight, "Combining_BelowRight"},
|
||||
{QChar::Combining_Left, "Combining_Left"},
|
||||
{QChar::Combining_Right, "Combining_Right"},
|
||||
{QChar::Combining_AboveLeft, "Combining_AboveLeft"},
|
||||
{QChar::Combining_Above, "Combining_Above"},
|
||||
{QChar::Combining_AboveRight, "Combining_AboveRight"},
|
||||
|
||||
{QChar::Combining_DoubleBelow, "Combining_DoubleBelow"},
|
||||
{QChar::Combining_DoubleAbove, "Combining_DoubleAbove"},
|
||||
{QChar::Combining_IotaSubscript, "Combining_IotaSubscript"},
|
||||
};
|
||||
|
||||
static const EnumLookup unicodeVersionEnumLookup[] =
|
||||
{
|
||||
{QChar::Unicode_Unassigned, "Unicode_Unassigned"},
|
||||
{QChar::Unicode_1_1, "Unicode_1_1"},
|
||||
{QChar::Unicode_2_0, "Unicode_2_0"},
|
||||
{QChar::Unicode_2_1_2, "Unicode_2_1_2"},
|
||||
{QChar::Unicode_3_0, "Unicode_3_0"},
|
||||
{QChar::Unicode_3_1, "Unicode_3_1"},
|
||||
{QChar::Unicode_3_2, "Unicode_3_2"},
|
||||
{QChar::Unicode_4_0, "Unicode_4_0"},
|
||||
{QChar::Unicode_4_1, "Unicode_4_1"},
|
||||
{QChar::Unicode_5_0, "Unicode_5_0"},
|
||||
{QChar::Unicode_5_1, "Unicode_5_1"},
|
||||
{QChar::Unicode_5_2, "Unicode_5_2"},
|
||||
{QChar::Unicode_6_0, "Unicode_6_0"},
|
||||
{QChar::Unicode_6_1, "Unicode_6_1"},
|
||||
{QChar::Unicode_6_2, "Unicode_6_2"},
|
||||
{QChar::Unicode_6_3, "Unicode_6_3"},
|
||||
{QChar::Unicode_7_0, "Unicode_7_0"},
|
||||
{QChar::Unicode_8_0, "Unicode_8_0"},
|
||||
};
|
||||
|
||||
static const EnumLookup *enumLookup(int v, const EnumLookup *array, size_t size)
|
||||
{
|
||||
const EnumLookup *end = array + size;
|
||||
for (const EnumLookup *p = array; p < end; ++p) {
|
||||
if (p->value == v)
|
||||
return p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static const char *enumName(int v, const EnumLookup *array, size_t size)
|
||||
{
|
||||
const EnumLookup *e = enumLookup(v, array, size);
|
||||
return e ? e->description : "<unknown>";
|
||||
}
|
||||
|
||||
// Context struct storing the parameters of the last character, only the parameters
|
||||
// that change will be output.
|
||||
struct FormattingContext
|
||||
{
|
||||
int category = -1;
|
||||
int direction = -1;
|
||||
int joiningType = -1;
|
||||
int decompositionTag = -1;
|
||||
int script = -1;
|
||||
int unicodeVersion = -1;
|
||||
};
|
||||
|
||||
static void formatCharacter(QTextStream &str, const QChar &qc, FormattingContext &context)
|
||||
{
|
||||
const ushort unicode = qc.unicode();
|
||||
str << "U+" << qSetFieldWidth(4) << qSetPadChar('0') << Qt::uppercasedigits << Qt::hex
|
||||
<< unicode << Qt::dec << qSetFieldWidth(0) << ' ';
|
||||
|
||||
const EnumLookup *specialChar = enumLookup(unicode, specialCharactersEnumLookup, sizeof(specialCharactersEnumLookup) / sizeof(EnumLookup));
|
||||
if (specialChar)
|
||||
str << specialChar->description;
|
||||
else
|
||||
str << "'" << qc << '\'';
|
||||
|
||||
const int category = qc.category();
|
||||
if (category != context.category) {
|
||||
str << " category="
|
||||
<< enumName(category, categoryEnumLookup, sizeof(categoryEnumLookup) / sizeof(EnumLookup));
|
||||
context.category = category;
|
||||
}
|
||||
const int script = qc.script();
|
||||
if (script != context.script) {
|
||||
str << " script="
|
||||
<< enumName(script, scriptEnumLookup, sizeof(scriptEnumLookup) / sizeof(EnumLookup))
|
||||
<< '(' << script << ')';
|
||||
context.script = script;
|
||||
}
|
||||
const int direction = qc.direction();
|
||||
if (direction != context.direction) {
|
||||
str << " direction="
|
||||
<< enumName(direction, directionEnumLookup, sizeof(directionEnumLookup) / sizeof(EnumLookup));
|
||||
context.direction = direction;
|
||||
}
|
||||
const int joiningType = qc.joiningType();
|
||||
if (joiningType != context.joiningType) {
|
||||
str << " joiningType="
|
||||
<< enumName(joiningType, joiningTypeEnumLookup, sizeof(joiningTypeEnumLookup) / sizeof(EnumLookup));
|
||||
context.joiningType = joiningType;
|
||||
}
|
||||
const int decompositionTag = qc.decompositionTag();
|
||||
if (decompositionTag != context.decompositionTag) {
|
||||
str << " decomposition="
|
||||
<< enumName(decompositionTag, decompositionEnumLookup, sizeof(decompositionEnumLookup) / sizeof(EnumLookup));
|
||||
context.decompositionTag = decompositionTag;
|
||||
}
|
||||
const int unicodeVersion = qc.unicodeVersion();
|
||||
if (unicodeVersion != context.unicodeVersion) {
|
||||
str << " version="
|
||||
<< enumName(unicodeVersion, unicodeVersionEnumLookup, sizeof(unicodeVersionEnumLookup) / sizeof(EnumLookup));
|
||||
context.unicodeVersion = unicodeVersion;
|
||||
}
|
||||
}
|
||||
|
||||
QString dumpText(const QString &text)
|
||||
{
|
||||
QString result;
|
||||
QTextStream str(&result);
|
||||
FormattingContext context;
|
||||
for (int i = 0; i < text.size(); ++i) {
|
||||
str << '#' << (i + 1) << ' ';
|
||||
formatCharacter(str, text.at(i), context);
|
||||
str << '\n';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString dumpTextAsCode(const QString &text)
|
||||
{
|
||||
QString result;
|
||||
QTextStream str(&result);
|
||||
str << " QString result;\n" << Qt::hex << Qt::showbase;
|
||||
for (QChar c : text)
|
||||
str << " result += QChar(" << c.unicode() << ");\n";
|
||||
str << '\n';
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace QtDiag
|
18
tests/manual/diaglib/textdump.h
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef TEXTDUMP_H
|
||||
#define TEXTDUMP_H
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QString)
|
||||
|
||||
namespace QtDiag {
|
||||
|
||||
QString dumpText(const QString &text);
|
||||
QString dumpTextAsCode(const QString &text);
|
||||
|
||||
} // namespace QtDiag
|
||||
|
||||
#endif // TEXTDUMP_H
|
36
tests/manual/dialogs/CMakeLists.txt
Normal file
@ -0,0 +1,36 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## dialogs Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(dialogs
|
||||
GUI
|
||||
SOURCES
|
||||
colordialogpanel.cpp colordialogpanel.h
|
||||
filedialogpanel.cpp filedialogpanel.h
|
||||
fontdialogpanel.cpp fontdialogpanel.h
|
||||
main.cpp
|
||||
messageboxpanel.cpp messageboxpanel.h
|
||||
utils.cpp utils.h
|
||||
wizardpanel.cpp wizardpanel.h
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(dialogs CONDITION TARGET Qt::PrintSupport
|
||||
LIBRARIES
|
||||
Qt::PrintSupport
|
||||
)
|
||||
|
||||
qt_internal_extend_target(dialogs CONDITION NOT (QT_FEATURE_printer EQUAL FALSE)
|
||||
SOURCES
|
||||
printdialogpanel.cpp printdialogpanel.h printdialogpanel.ui
|
||||
ENABLE_AUTOGEN_TOOLS
|
||||
uic
|
||||
)
|
236
tests/manual/dialogs/colordialogpanel.cpp
Normal file
@ -0,0 +1,236 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "colordialogpanel.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QGroupBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QComboBox>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
|
||||
// SVG color keyword names provided by the World Wide Web Consortium
|
||||
static inline QStringList svgColorNames()
|
||||
{
|
||||
return QStringList()
|
||||
<< "aliceblue" << "antiquewhite" << "aqua" << "aquamarine" << "azure" << "beige" << "bisque"
|
||||
<< "black" << "blanchedalmond" << "blue" << "blueviolet" << "brown" << "burlywood" << "cadetblue"
|
||||
<< "chartreuse" << "chocolate" << "coral" << "cornflowerblue" << "cornsilk" << "crimson" << "cyan"
|
||||
<< "darkblue" << "darkcyan" << "darkgoldenrod" << "darkgray" << "darkgreen" << "darkgrey"
|
||||
<< "darkkhaki" << "darkmagenta" << "darkolivegreen" << "darkorange" << "darkorchid" << "darkred"
|
||||
<< "darksalmon" << "darkseagreen" << "darkslateblue" << "darkslategray" << "darkslategrey"
|
||||
<< "darkturquoise" << "darkviolet" << "deeppink" << "deepskyblue" << "dimgray" << "dimgrey"
|
||||
<< "dodgerblue" << "firebrick" << "floralwhite" << "forestgreen" << "fuchsia" << "gainsboro"
|
||||
<< "ghostwhite" << "gold" << "goldenrod" << "gray" << "grey" << "green" << "greenyellow"
|
||||
<< "honeydew" << "hotpink" << "indianred" << "indigo" << "ivory" << "khaki" << "lavender"
|
||||
<< "lavenderblush" << "lawngreen" << "lemonchiffon" << "lightblue" << "lightcoral" << "lightcyan"
|
||||
<< "lightgoldenrodyellow" << "lightgray" << "lightgreen" << "lightgrey" << "lightpink"
|
||||
<< "lightsalmon" << "lightseagreen" << "lightskyblue" << "lightslategray" << "lightslategrey"
|
||||
<< "lightsteelblue" << "lightyellow" << "lime" << "limegreen" << "linen" << "magenta"
|
||||
<< "maroon" << "mediumaquamarine" << "mediumblue" << "mediumorchid" << "mediumpurple"
|
||||
<< "mediumseagreen" << "mediumslateblue" << "mediumspringgreen" << "mediumturquoise"
|
||||
<< "mediumvioletred" << "midnightblue" << "mintcream" << "mistyrose" << "moccasin"
|
||||
<< "navajowhite" << "navy" << "oldlace" << "olive" << "olivedrab" << "orange" << "orangered"
|
||||
<< "orchid" << "palegoldenrod" << "palegreen" << "paleturquoise" << "palevioletred"
|
||||
<< "papayawhip" << "peachpuff" << "peru" << "pink" << "plum" << "powderblue" << "purple" << "red"
|
||||
<< "rosybrown" << "royalblue" << "saddlebrown" << "salmon" << "sandybrown" << "seagreen"
|
||||
<< "seashell" << "sienna" << "silver" << "skyblue" << "slateblue" << "slategray" << "slategrey"
|
||||
<< "snow" << "springgreen" << "steelblue" << "tan" << "teal" << "thistle" << "tomato"
|
||||
<< "turquoise" << "violet" << "wheat" << "white" << "whitesmoke" << "yellow" << "yellowgreen";
|
||||
}
|
||||
|
||||
class ColorProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
ColorProxyModel(QObject *parent = nullptr) : QSortFilterProxyModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
|
||||
{
|
||||
if (role == Qt::DisplayRole) {
|
||||
QString name = data(index, Qt::EditRole).toString();
|
||||
return tr("%1 (%2)").arg(name, QColor(name).name());
|
||||
}
|
||||
if (role == Qt::DecorationRole)
|
||||
return QColor(data(index, Qt::EditRole).toString());
|
||||
return QSortFilterProxyModel::data(index, role);
|
||||
}
|
||||
};
|
||||
|
||||
ColorDialogPanel::ColorDialogPanel(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_colorComboBox(new QComboBox)
|
||||
, m_showAlphaChannel(new QCheckBox(tr("Show alpha channel")))
|
||||
, m_noButtons(new QCheckBox(tr("Don't display OK/Cancel buttons")))
|
||||
, m_dontUseNativeDialog(new QCheckBox(tr("Don't use native dialog")))
|
||||
{
|
||||
// Options
|
||||
QGroupBox *optionsGroupBox = new QGroupBox(tr("Options"), this);
|
||||
QVBoxLayout *optionsLayout = new QVBoxLayout(optionsGroupBox);
|
||||
optionsLayout->addWidget(m_showAlphaChannel);
|
||||
optionsLayout->addWidget(m_noButtons);
|
||||
optionsLayout->addWidget(m_dontUseNativeDialog);
|
||||
|
||||
// Color
|
||||
QGroupBox *colorGroupBox = new QGroupBox(tr("Color"), this);
|
||||
QVBoxLayout *colorLayout = new QVBoxLayout(colorGroupBox);
|
||||
colorLayout->addWidget(m_colorComboBox);
|
||||
m_colorComboBox->addItems(svgColorNames());
|
||||
m_colorComboBox->setEditable(true);
|
||||
|
||||
QAbstractItemModel *sourceModel = m_colorComboBox->model();
|
||||
ColorProxyModel* proxyModel = new ColorProxyModel(m_colorComboBox);
|
||||
proxyModel->setSourceModel(sourceModel);
|
||||
sourceModel->setParent(proxyModel);
|
||||
m_colorComboBox->setModel(proxyModel);
|
||||
|
||||
// Buttons
|
||||
QGroupBox *buttonsGroupBox = new QGroupBox(tr("Show"));
|
||||
QVBoxLayout *buttonsLayout = new QVBoxLayout(buttonsGroupBox);
|
||||
addButton(tr("Exec modal"), buttonsLayout, this, SLOT(execModal()));
|
||||
addButton(tr("Show application modal"), buttonsLayout,
|
||||
[this]() { showModal(Qt::ApplicationModal); });
|
||||
addButton(tr("Show window modal"), buttonsLayout, [this]() { showModal(Qt::WindowModal); });
|
||||
m_deleteModalDialogButton =
|
||||
addButton(tr("Delete modal"), buttonsLayout, this, SLOT(deleteModalDialog()));
|
||||
addButton(tr("Show non-modal"), buttonsLayout, this, SLOT(showNonModal()));
|
||||
m_deleteNonModalDialogButton =
|
||||
addButton(tr("Delete non-modal"), buttonsLayout, this, SLOT(deleteNonModalDialog()));
|
||||
addButton(tr("Restore defaults"), buttonsLayout, this, SLOT(restoreDefaults()));
|
||||
buttonsLayout->addStretch();
|
||||
|
||||
// Main layout
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
QVBoxLayout *leftLayout = new QVBoxLayout;
|
||||
leftLayout->addWidget(optionsGroupBox);
|
||||
leftLayout->addWidget(colorGroupBox);
|
||||
leftLayout->addStretch();
|
||||
mainLayout->addLayout(leftLayout);
|
||||
mainLayout->addWidget(buttonsGroupBox);
|
||||
|
||||
enableDeleteModalDialogButton();
|
||||
enableDeleteNonModalDialogButton();
|
||||
restoreDefaults();
|
||||
}
|
||||
|
||||
void ColorDialogPanel::execModal()
|
||||
{
|
||||
QColorDialog dialog(this);
|
||||
applySettings(&dialog);
|
||||
connect(&dialog, SIGNAL(accepted()), this, SLOT(accepted()));
|
||||
connect(&dialog, SIGNAL(rejected()), this, SLOT(rejected()));
|
||||
connect(&dialog, SIGNAL(currentColorChanged(const QColor&)), this, SLOT(currentColorChanged(const QColor&)));
|
||||
dialog.setWindowTitle(tr("Modal Color Dialog Qt %1").arg(QLatin1String(QT_VERSION_STR)));
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void ColorDialogPanel::showModal(Qt::WindowModality modality)
|
||||
{
|
||||
if (m_modalDialog.isNull()) {
|
||||
static int n = 0;
|
||||
m_modalDialog = new QColorDialog(this);
|
||||
m_modalDialog->setModal(true);
|
||||
connect(m_modalDialog.data(), SIGNAL(accepted()), this, SLOT(accepted()));
|
||||
connect(m_modalDialog.data(), SIGNAL(rejected()), this, SLOT(rejected()));
|
||||
connect(m_modalDialog.data(), SIGNAL(currentColorChanged(const QColor&)), this, SLOT(currentColorChanged(const QColor&)));
|
||||
m_modalDialog->setWindowTitle(tr("Modal Color Dialog #%1 Qt %2")
|
||||
.arg(++n)
|
||||
.arg(QLatin1String(QT_VERSION_STR)));
|
||||
enableDeleteModalDialogButton();
|
||||
}
|
||||
m_modalDialog->setWindowModality(modality);
|
||||
applySettings(m_modalDialog);
|
||||
m_modalDialog->show();
|
||||
}
|
||||
|
||||
void ColorDialogPanel::showNonModal()
|
||||
{
|
||||
if (m_nonModalDialog.isNull()) {
|
||||
static int n = 0;
|
||||
m_nonModalDialog = new QColorDialog(this);
|
||||
connect(m_nonModalDialog.data(), SIGNAL(accepted()), this, SLOT(accepted()));
|
||||
connect(m_nonModalDialog.data(), SIGNAL(rejected()), this, SLOT(rejected()));
|
||||
connect(m_nonModalDialog.data(), SIGNAL(currentColorChanged(const QColor&)), this, SLOT(currentColorChanged(const QColor&)));
|
||||
m_nonModalDialog->setWindowTitle(tr("Non-Modal Color Dialog #%1 Qt %2")
|
||||
.arg(++n)
|
||||
.arg(QLatin1String(QT_VERSION_STR)));
|
||||
enableDeleteNonModalDialogButton();
|
||||
}
|
||||
applySettings(m_nonModalDialog);
|
||||
m_nonModalDialog->show();
|
||||
}
|
||||
|
||||
void ColorDialogPanel::deleteNonModalDialog()
|
||||
{
|
||||
if (!m_nonModalDialog.isNull())
|
||||
delete m_nonModalDialog;
|
||||
enableDeleteNonModalDialogButton();
|
||||
}
|
||||
|
||||
void ColorDialogPanel::deleteModalDialog()
|
||||
{
|
||||
if (!m_modalDialog.isNull())
|
||||
delete m_modalDialog;
|
||||
enableDeleteModalDialogButton();
|
||||
}
|
||||
|
||||
void ColorDialogPanel::accepted()
|
||||
{
|
||||
const QColorDialog *d = qobject_cast<const QColorDialog *>(sender());
|
||||
Q_ASSERT(d);
|
||||
m_result.clear();
|
||||
qDebug() << "Current color: " << d->currentColor()
|
||||
<< "Selected color: " << d->selectedColor();
|
||||
QDebug(&m_result).nospace()
|
||||
<< "Current color: " << d->currentColor()
|
||||
<< "\nSelected color: " << d->selectedColor();
|
||||
QTimer::singleShot(0, this, SLOT(showAcceptedResult())); // Avoid problems with the closing (modal) dialog as parent.
|
||||
}
|
||||
|
||||
void ColorDialogPanel::rejected()
|
||||
{
|
||||
qDebug() << "rejected";
|
||||
}
|
||||
|
||||
void ColorDialogPanel::currentColorChanged(const QColor &color)
|
||||
{
|
||||
qDebug() << color;
|
||||
}
|
||||
|
||||
void ColorDialogPanel::showAcceptedResult()
|
||||
{
|
||||
QMessageBox::information(this, tr("Color Dialog Accepted"), m_result, QMessageBox::Ok);
|
||||
}
|
||||
|
||||
void ColorDialogPanel::restoreDefaults()
|
||||
{
|
||||
QColorDialog d;
|
||||
m_showAlphaChannel->setChecked(d.testOption(QColorDialog::ShowAlphaChannel));
|
||||
m_noButtons->setChecked(d.testOption(QColorDialog::NoButtons));
|
||||
m_dontUseNativeDialog->setChecked(d.testOption(QColorDialog::DontUseNativeDialog));
|
||||
}
|
||||
|
||||
void ColorDialogPanel::enableDeleteNonModalDialogButton()
|
||||
{
|
||||
m_deleteNonModalDialogButton->setEnabled(!m_nonModalDialog.isNull());
|
||||
}
|
||||
|
||||
void ColorDialogPanel::enableDeleteModalDialogButton()
|
||||
{
|
||||
m_deleteModalDialogButton->setEnabled(!m_modalDialog.isNull());
|
||||
}
|
||||
|
||||
void ColorDialogPanel::applySettings(QColorDialog *d) const
|
||||
{
|
||||
d->setOption(QColorDialog::ShowAlphaChannel, m_showAlphaChannel->isChecked());
|
||||
d->setOption(QColorDialog::NoButtons, m_noButtons->isChecked());
|
||||
d->setOption(QColorDialog::DontUseNativeDialog, m_dontUseNativeDialog->isChecked());
|
||||
d->setCurrentColor(QColor(m_colorComboBox->itemData(m_colorComboBox->currentIndex(), Qt::EditRole).toString()));
|
||||
}
|
52
tests/manual/dialogs/colordialogpanel.h
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef COLORDIALOGPANEL_H
|
||||
#define COLORDIALOGPANEL_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <QColorDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
class QCheckBox;
|
||||
class QPushButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class ColorDialogPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ColorDialogPanel(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void execModal();
|
||||
void showModal(Qt::WindowModality modality);
|
||||
void showNonModal();
|
||||
void deleteNonModalDialog();
|
||||
void deleteModalDialog();
|
||||
void accepted();
|
||||
void rejected();
|
||||
void currentColorChanged(const QColor & color);
|
||||
void showAcceptedResult();
|
||||
void restoreDefaults();
|
||||
|
||||
private slots:
|
||||
void enableDeleteNonModalDialogButton();
|
||||
void enableDeleteModalDialogButton();
|
||||
|
||||
private:
|
||||
void applySettings(QColorDialog *d) const;
|
||||
|
||||
QComboBox *m_colorComboBox;
|
||||
QCheckBox *m_showAlphaChannel;
|
||||
QCheckBox *m_noButtons;
|
||||
QCheckBox *m_dontUseNativeDialog;
|
||||
QPushButton *m_deleteNonModalDialogButton;
|
||||
QPushButton *m_deleteModalDialogButton;
|
||||
QString m_result;
|
||||
QPointer<QColorDialog> m_modalDialog;
|
||||
QPointer<QColorDialog> m_nonModalDialog;
|
||||
};
|
||||
|
||||
#endif // COLORDIALOGPANEL_H
|
16
tests/manual/dialogs/dialogs.pro
Normal file
@ -0,0 +1,16 @@
|
||||
QT += core gui widgets
|
||||
qtHaveModule(printsupport): QT += printsupport
|
||||
|
||||
TARGET = dialogs
|
||||
TEMPLATE = app
|
||||
|
||||
SOURCES += main.cpp filedialogpanel.cpp colordialogpanel.cpp fontdialogpanel.cpp \
|
||||
wizardpanel.cpp messageboxpanel.cpp utils.cpp
|
||||
HEADERS += filedialogpanel.h colordialogpanel.h fontdialogpanel.h \
|
||||
wizardpanel.h messageboxpanel.h utils.h
|
||||
|
||||
!contains(DEFINES, QT_NO_PRINTER) {
|
||||
SOURCES += printdialogpanel.cpp
|
||||
HEADERS += printdialogpanel.h
|
||||
FORMS += printdialogpanel.ui
|
||||
}
|
481
tests/manual/dialogs/filedialogpanel.cpp
Normal file
@ -0,0 +1,481 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "filedialogpanel.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QFormLayout>
|
||||
#include <QSpacerItem>
|
||||
#include <QGroupBox>
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
#include <QLineEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QApplication>
|
||||
#include <QUrl>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
|
||||
const FlagData acceptModeComboData[] =
|
||||
{
|
||||
{"AcceptOpen", QFileDialog::AcceptOpen },
|
||||
{"AcceptSave", QFileDialog::AcceptSave }
|
||||
};
|
||||
|
||||
const FlagData viewModeComboData[] =
|
||||
{
|
||||
{"Detail", QFileDialog::Detail},
|
||||
{"List", QFileDialog::List}
|
||||
};
|
||||
|
||||
const FlagData fileModeComboData[] =
|
||||
{
|
||||
{"AnyFile", QFileDialog::AnyFile},
|
||||
{"ExistingFile", QFileDialog::ExistingFile},
|
||||
{"ExistingFiles", QFileDialog::ExistingFiles},
|
||||
{"Directory", QFileDialog::Directory}
|
||||
};
|
||||
|
||||
// A line edit for editing the label fields of the dialog, keeping track of whether it has
|
||||
// been modified by the user to avoid applying Qt's default texts to native dialogs.
|
||||
|
||||
class LabelLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LabelLineEdit(QFileDialog::DialogLabel label, QWidget *parent = nullptr) : QLineEdit(parent), m_label(label), m_dirty(false)
|
||||
{
|
||||
connect(this, SIGNAL(textEdited(QString)), this, SLOT(setDirty()));
|
||||
}
|
||||
|
||||
void restoreDefault(const QFileDialog *d)
|
||||
{
|
||||
setText(d->labelText(m_label));
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
void apply(QFileDialog *d) const
|
||||
{
|
||||
if (m_dirty)
|
||||
d->setLabelText(m_label, text());
|
||||
}
|
||||
|
||||
private slots:
|
||||
void setDirty() { m_dirty = true; }
|
||||
|
||||
private:
|
||||
const QFileDialog::DialogLabel m_label;
|
||||
bool m_dirty;
|
||||
};
|
||||
|
||||
FileDialogPanel::FileDialogPanel(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_showDirsOnly(new QCheckBox(tr("Show dirs only")))
|
||||
, m_readOnly(new QCheckBox(tr("Read only")))
|
||||
, m_confirmOverWrite(new QCheckBox(tr("Confirm overwrite")))
|
||||
, m_nameFilterDetailsVisible(new QCheckBox(tr("Name filter details visible")))
|
||||
, m_resolveSymLinks(new QCheckBox(tr("Resolve symlinks")))
|
||||
, m_native(new QCheckBox(tr("Use native dialog")))
|
||||
, m_customDirIcons(new QCheckBox(tr("Don't use custom directory icons")))
|
||||
, m_acceptMode(createCombo(this, acceptModeComboData, sizeof(acceptModeComboData)/sizeof(FlagData)))
|
||||
, m_fileMode(createCombo(this, fileModeComboData, sizeof(fileModeComboData)/sizeof(FlagData)))
|
||||
, m_viewMode(createCombo(this, viewModeComboData, sizeof(viewModeComboData)/sizeof(FlagData)))
|
||||
, m_allowedSchemes(new QLineEdit(this))
|
||||
, m_defaultSuffix(new QLineEdit(this))
|
||||
, m_directory(new QLineEdit(this))
|
||||
, m_selectedFileName(new QLineEdit(this))
|
||||
, m_useMimeTypeFilters(new QCheckBox(this))
|
||||
, m_nameFilters(new QPlainTextEdit)
|
||||
, m_selectedNameFilter(new QLineEdit(this))
|
||||
, m_deleteNonModalDialogButton(0)
|
||||
, m_deleteModalDialogButton(0)
|
||||
{
|
||||
// Options
|
||||
QGroupBox *optionsGroupBox = new QGroupBox(tr("Options"));
|
||||
QFormLayout *optionsLayout = new QFormLayout(optionsGroupBox);
|
||||
optionsLayout->addRow(tr("AcceptMode:"), m_acceptMode);
|
||||
optionsLayout->addRow(tr("FileMode:"), m_fileMode);
|
||||
optionsLayout->addRow(tr("ViewMode:"), m_viewMode);
|
||||
optionsLayout->addRow(tr("Allowed Schemes:"), m_allowedSchemes);
|
||||
optionsLayout->addRow(m_showDirsOnly);
|
||||
optionsLayout->addRow(m_native);
|
||||
optionsLayout->addRow(m_confirmOverWrite);
|
||||
optionsLayout->addRow(m_nameFilterDetailsVisible);
|
||||
optionsLayout->addRow(m_resolveSymLinks);
|
||||
optionsLayout->addRow(m_readOnly);
|
||||
optionsLayout->addRow(m_customDirIcons);
|
||||
|
||||
// Files
|
||||
QGroupBox *filesGroupBox = new QGroupBox(tr("Files / Filters"));
|
||||
filesLayout = new QFormLayout(filesGroupBox);
|
||||
filesLayout->addRow(tr("Default Suffix:"), m_defaultSuffix);
|
||||
filesLayout->addRow(tr("Directory:"), m_directory);
|
||||
filesLayout->addRow(tr("Selected file:"), m_selectedFileName);
|
||||
filesLayout->addRow(tr("Use mime type filters:"), m_useMimeTypeFilters);
|
||||
m_nameFilters->setMaximumHeight(80);
|
||||
filesLayout->addRow(tr("Name filters:"), m_nameFilters);
|
||||
filesLayout->addRow(tr("Selected name filter:"), m_selectedNameFilter);
|
||||
|
||||
// Optional labels
|
||||
QGroupBox *labelsGroupBox = new QGroupBox(tr("Labels"));
|
||||
QFormLayout *labelsLayout = new QFormLayout(labelsGroupBox);
|
||||
m_labelLineEdits.push_back(new LabelLineEdit(QFileDialog::LookIn, this));
|
||||
labelsLayout->addRow(tr("Look in label:"), m_labelLineEdits.back());
|
||||
m_labelLineEdits.push_back(new LabelLineEdit(QFileDialog::FileName, this));
|
||||
labelsLayout->addRow(tr("File name label:"), m_labelLineEdits.back());
|
||||
m_labelLineEdits.push_back(new LabelLineEdit(QFileDialog::FileType, this));
|
||||
labelsLayout->addRow(tr("File type label:"), m_labelLineEdits.back());
|
||||
m_labelLineEdits.push_back(new LabelLineEdit(QFileDialog::Accept, this));
|
||||
labelsLayout->addRow(tr("Accept label:"), m_labelLineEdits.back());
|
||||
m_labelLineEdits.push_back(new LabelLineEdit(QFileDialog::Reject, this));
|
||||
labelsLayout->addRow(tr("Reject label:"), m_labelLineEdits.back());
|
||||
|
||||
// Buttons
|
||||
QGroupBox *buttonsGroupBox = new QGroupBox(tr("Show"));
|
||||
QGridLayout *buttonLayout = new QGridLayout(buttonsGroupBox);
|
||||
int row = 0;
|
||||
int column = 0;
|
||||
addButton(tr("Exec modal"), buttonLayout, row, column, this, SLOT(execModal()));
|
||||
addButton(tr("Show application modal"), buttonLayout, row, column,
|
||||
[this]() { showModal(Qt::ApplicationModal); });
|
||||
addButton(tr("Show window modal"), buttonLayout, row, column,
|
||||
[this]() { showModal(Qt::WindowModal); });
|
||||
m_deleteModalDialogButton = addButton(tr("Delete modal"), buttonLayout, row, column, this,
|
||||
SLOT(deleteModalDialog()));
|
||||
addButton(tr("Show non-modal"), buttonLayout, row, column, this, SLOT(showNonModal()));
|
||||
m_deleteNonModalDialogButton =
|
||||
addButton(tr("Delete non-modal"), buttonLayout, row, column, this, SLOT(deleteNonModalDialog()));
|
||||
row = 0;
|
||||
column++;
|
||||
addButton(tr("getOpenFileName"), buttonLayout, row, column, this, SLOT(getOpenFileName()));
|
||||
addButton(tr("getOpenFileUrl"), buttonLayout, row, column, this, SLOT(getOpenFileUrl()));
|
||||
addButton(tr("getOpenFileNames"), buttonLayout, row, column, this, SLOT(getOpenFileNames()));
|
||||
addButton(tr("getOpenFileUrls"), buttonLayout, row, column, this, SLOT(getOpenFileUrls()));
|
||||
addButton(tr("getSaveFileName"), buttonLayout, row, column, this, SLOT(getSaveFileName()));
|
||||
addButton(tr("getSaveFileUrl"), buttonLayout, row, column, this, SLOT(getSaveFileUrl()));
|
||||
addButton(tr("getExistingDirectory"), buttonLayout, row, column, this, SLOT(getExistingDirectory()));
|
||||
addButton(tr("getExistingDirectoryUrl"), buttonLayout, row, column, this, SLOT(getExistingDirectoryUrl()));
|
||||
addButton(tr("Restore defaults"), buttonLayout, row, column, this, SLOT(restoreDefaults()));
|
||||
|
||||
// Main layout
|
||||
QGridLayout *gridLayout = new QGridLayout(this);
|
||||
gridLayout->addWidget(optionsGroupBox, 0, 0);
|
||||
gridLayout->addWidget(filesGroupBox, 0, 1);
|
||||
gridLayout->addWidget(labelsGroupBox, 1, 0);
|
||||
gridLayout->addWidget(buttonsGroupBox, 1, 1);
|
||||
|
||||
connect(m_useMimeTypeFilters, SIGNAL(toggled(bool)), this, SLOT(useMimeTypeFilters(bool)));
|
||||
|
||||
enableDeleteModalDialogButton();
|
||||
enableDeleteNonModalDialogButton();
|
||||
restoreDefaults();
|
||||
}
|
||||
|
||||
void FileDialogPanel::execModal()
|
||||
{
|
||||
QFileDialog dialog(this);
|
||||
applySettings(&dialog);
|
||||
connect(&dialog, SIGNAL(accepted()), this, SLOT(accepted()));
|
||||
dialog.setWindowTitle(tr("Modal File Dialog Qt %1").arg(QLatin1String(QT_VERSION_STR)));
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void FileDialogPanel::showModal(Qt::WindowModality modality)
|
||||
{
|
||||
if (m_modalDialog.isNull()) {
|
||||
static int n = 0;
|
||||
m_modalDialog = new QFileDialog(this);
|
||||
m_modalDialog->setModal(true);
|
||||
connect(m_modalDialog.data(), SIGNAL(accepted()), this, SLOT(accepted()));
|
||||
m_modalDialog->setWindowTitle(tr("Modal File Dialog #%1 Qt %2")
|
||||
.arg(++n)
|
||||
.arg(QLatin1String(QT_VERSION_STR)));
|
||||
enableDeleteModalDialogButton();
|
||||
}
|
||||
m_modalDialog->setWindowModality(modality);
|
||||
applySettings(m_modalDialog);
|
||||
m_modalDialog->show();
|
||||
}
|
||||
|
||||
void FileDialogPanel::showNonModal()
|
||||
{
|
||||
if (m_nonModalDialog.isNull()) {
|
||||
static int n = 0;
|
||||
m_nonModalDialog = new QFileDialog(this);
|
||||
connect(m_nonModalDialog.data(), SIGNAL(accepted()), this, SLOT(accepted()));
|
||||
m_nonModalDialog->setWindowTitle(tr("Non-Modal File Dialog #%1 Qt %2")
|
||||
.arg(++n)
|
||||
.arg(QLatin1String(QT_VERSION_STR)));
|
||||
enableDeleteNonModalDialogButton();
|
||||
}
|
||||
applySettings(m_nonModalDialog);
|
||||
m_nonModalDialog->show();
|
||||
}
|
||||
|
||||
void FileDialogPanel::deleteNonModalDialog()
|
||||
{
|
||||
if (!m_nonModalDialog.isNull())
|
||||
delete m_nonModalDialog;
|
||||
enableDeleteNonModalDialogButton();
|
||||
}
|
||||
|
||||
void FileDialogPanel::deleteModalDialog()
|
||||
{
|
||||
if (!m_modalDialog.isNull())
|
||||
delete m_modalDialog;
|
||||
enableDeleteModalDialogButton();
|
||||
}
|
||||
|
||||
void FileDialogPanel::enableDeleteNonModalDialogButton()
|
||||
{
|
||||
m_deleteNonModalDialogButton->setEnabled(!m_nonModalDialog.isNull());
|
||||
}
|
||||
|
||||
void FileDialogPanel::enableDeleteModalDialogButton()
|
||||
{
|
||||
m_deleteModalDialogButton->setEnabled(!m_modalDialog.isNull());
|
||||
}
|
||||
|
||||
|
||||
QString FileDialogPanel::filterString() const
|
||||
{
|
||||
return m_nameFilters->toPlainText().trimmed().replace(QLatin1String("\n"), QLatin1String(";;"));
|
||||
}
|
||||
|
||||
QUrl FileDialogPanel::currentDirectoryUrl() const
|
||||
{
|
||||
return QUrl::fromUserInput(m_directory->text().trimmed());
|
||||
}
|
||||
|
||||
QFileDialog::Options FileDialogPanel::options() const
|
||||
{
|
||||
QFileDialog::Options result;
|
||||
if (m_showDirsOnly->isChecked())
|
||||
result |= QFileDialog::ShowDirsOnly;
|
||||
if (!m_nameFilterDetailsVisible->isChecked())
|
||||
result |= QFileDialog::HideNameFilterDetails;
|
||||
if (!m_resolveSymLinks->isChecked())
|
||||
result |= QFileDialog::DontResolveSymlinks;
|
||||
if (m_readOnly->isChecked())
|
||||
result |= QFileDialog::ReadOnly;
|
||||
if (!m_confirmOverWrite->isChecked())
|
||||
result |= QFileDialog::DontConfirmOverwrite;
|
||||
if (!m_native->isChecked())
|
||||
result |= QFileDialog::DontUseNativeDialog;
|
||||
if (m_customDirIcons->isChecked())
|
||||
result |= QFileDialog::DontUseCustomDirectoryIcons;
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList FileDialogPanel::allowedSchemes() const
|
||||
{
|
||||
return m_allowedSchemes->text().simplified().split(' ', Qt::SkipEmptyParts);
|
||||
}
|
||||
|
||||
void FileDialogPanel::getOpenFileNames()
|
||||
{
|
||||
QString selectedFilter = m_selectedNameFilter->text().trimmed();
|
||||
const QStringList files =
|
||||
QFileDialog::getOpenFileNames(this, tr("getOpenFileNames Qt %1").arg(QLatin1String(QT_VERSION_STR)),
|
||||
m_directory->text(), filterString(), &selectedFilter, options());
|
||||
if (!files.isEmpty()) {
|
||||
QString result;
|
||||
QDebug(&result).nospace()
|
||||
<< "Files: " << files
|
||||
<< "\nName filter: " << selectedFilter;
|
||||
QMessageBox::information(this, tr("getOpenFileNames"), result, QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
void FileDialogPanel::getOpenFileUrls()
|
||||
{
|
||||
QString selectedFilter = m_selectedNameFilter->text().trimmed();
|
||||
const QList<QUrl> files =
|
||||
QFileDialog::getOpenFileUrls(this, tr("getOpenFileNames Qt %1").arg(QLatin1String(QT_VERSION_STR)),
|
||||
currentDirectoryUrl(), filterString(), &selectedFilter, options(),
|
||||
allowedSchemes());
|
||||
if (!files.isEmpty()) {
|
||||
QString result;
|
||||
QDebug(&result).nospace()
|
||||
<< "Files: " << QUrl::toStringList(files)
|
||||
<< "\nName filter: " << selectedFilter;
|
||||
QMessageBox::information(this, tr("getOpenFileNames"), result, QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
void FileDialogPanel::getOpenFileName()
|
||||
{
|
||||
QString selectedFilter = m_selectedNameFilter->text().trimmed();
|
||||
const QString file =
|
||||
QFileDialog::getOpenFileName(this, tr("getOpenFileName Qt %1").arg(QLatin1String(QT_VERSION_STR)),
|
||||
m_directory->text(), filterString(), &selectedFilter, options());
|
||||
if (!file.isEmpty()) {
|
||||
QString result;
|
||||
QDebug(&result).nospace()
|
||||
<< "File: " << file
|
||||
<< "\nName filter: " << selectedFilter;
|
||||
QMessageBox::information(this, tr("getOpenFileName"), result, QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
void FileDialogPanel::getOpenFileUrl()
|
||||
{
|
||||
QString selectedFilter = m_selectedNameFilter->text().trimmed();
|
||||
const QUrl file =
|
||||
QFileDialog::getOpenFileUrl(this, tr("getOpenFileUrl Qt %1").arg(QLatin1String(QT_VERSION_STR)),
|
||||
currentDirectoryUrl(), filterString(), &selectedFilter, options(),
|
||||
allowedSchemes());
|
||||
if (file.isValid()) {
|
||||
QString result;
|
||||
QDebug(&result).nospace()
|
||||
<< "File: " << file.toString()
|
||||
<< "\nName filter: " << selectedFilter;
|
||||
QMessageBox::information(this, tr("getOpenFileName"), result, QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
void FileDialogPanel::getSaveFileName()
|
||||
{
|
||||
QString selectedFilter = m_selectedNameFilter->text().trimmed();
|
||||
const QString file =
|
||||
QFileDialog::getSaveFileName(this, tr("getSaveFileName Qt %1").arg(QLatin1String(QT_VERSION_STR)),
|
||||
m_directory->text(), filterString(), &selectedFilter, options());
|
||||
if (!file.isEmpty()) {
|
||||
QString result;
|
||||
QDebug(&result).nospace()
|
||||
<< "File: " << file
|
||||
<< "\nName filter: " << selectedFilter;
|
||||
QMessageBox::information(this, tr("getSaveFileNames"), result, QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
void FileDialogPanel::getSaveFileUrl()
|
||||
{
|
||||
QString selectedFilter = m_selectedNameFilter->text().trimmed();
|
||||
const QUrl file =
|
||||
QFileDialog::getSaveFileUrl(this, tr("getSaveFileName Qt %1").arg(QLatin1String(QT_VERSION_STR)),
|
||||
currentDirectoryUrl(), filterString(), &selectedFilter, options(),
|
||||
allowedSchemes());
|
||||
if (file.isValid()) {
|
||||
QString result;
|
||||
QDebug(&result).nospace()
|
||||
<< "File: " << file.toString()
|
||||
<< "\nName filter: " << selectedFilter;
|
||||
QMessageBox::information(this, tr("getSaveFileNames"), result, QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
void FileDialogPanel::getExistingDirectory()
|
||||
{
|
||||
const QString dir =
|
||||
QFileDialog::getExistingDirectory(this, tr("getExistingDirectory Qt %1").arg(QLatin1String(QT_VERSION_STR)),
|
||||
m_directory->text(), options() | QFileDialog::ShowDirsOnly);
|
||||
if (!dir.isEmpty())
|
||||
QMessageBox::information(this, tr("getExistingDirectory"), QLatin1String("Directory: ") + dir, QMessageBox::Ok);
|
||||
}
|
||||
|
||||
void FileDialogPanel::getExistingDirectoryUrl()
|
||||
{
|
||||
const QUrl dir =
|
||||
QFileDialog::getExistingDirectoryUrl(this, tr("getExistingDirectory Qt %1").arg(QLatin1String(QT_VERSION_STR)),
|
||||
currentDirectoryUrl(), options() | QFileDialog::ShowDirsOnly,
|
||||
allowedSchemes());
|
||||
if (!dir.isEmpty())
|
||||
QMessageBox::information(this, tr("getExistingDirectory"), QLatin1String("Directory: ") + dir.toString(), QMessageBox::Ok);
|
||||
}
|
||||
|
||||
void FileDialogPanel::restoreDefaults()
|
||||
{
|
||||
QFileDialog d;
|
||||
setComboBoxValue(m_acceptMode, d.acceptMode());
|
||||
setComboBoxValue(m_fileMode, d.fileMode());
|
||||
setComboBoxValue(m_viewMode, d.viewMode());
|
||||
m_showDirsOnly->setChecked(d.testOption(QFileDialog::ShowDirsOnly));
|
||||
m_allowedSchemes->setText(QString());
|
||||
m_confirmOverWrite->setChecked(!d.testOption(QFileDialog::DontConfirmOverwrite));
|
||||
m_nameFilterDetailsVisible->setChecked(!d.testOption(QFileDialog::HideNameFilterDetails));
|
||||
m_resolveSymLinks->setChecked(!d.testOption(QFileDialog::DontResolveSymlinks));
|
||||
m_readOnly->setChecked(d.testOption(QFileDialog::ReadOnly));
|
||||
m_native->setChecked(true);
|
||||
m_customDirIcons->setChecked(d.testOption(QFileDialog::DontUseCustomDirectoryIcons));
|
||||
m_directory->setText(QDir::homePath());
|
||||
m_defaultSuffix->setText(QLatin1String("txt"));
|
||||
m_useMimeTypeFilters->setChecked(false);
|
||||
useMimeTypeFilters(false);
|
||||
m_selectedFileName->setText(QString());
|
||||
m_selectedNameFilter->setText(QString());
|
||||
foreach (LabelLineEdit *l, m_labelLineEdits)
|
||||
l->restoreDefault(&d);
|
||||
}
|
||||
|
||||
void FileDialogPanel::applySettings(QFileDialog *d) const
|
||||
{
|
||||
d->setAcceptMode(comboBoxValue<QFileDialog::AcceptMode>(m_acceptMode));
|
||||
d->setViewMode(comboBoxValue<QFileDialog::ViewMode>(m_viewMode));
|
||||
d->setFileMode(comboBoxValue<QFileDialog::FileMode>(m_fileMode));
|
||||
d->setOptions(options());
|
||||
d->setDefaultSuffix(m_defaultSuffix->text().trimmed());
|
||||
const QString directory = m_directory->text().trimmed();
|
||||
if (!directory.isEmpty())
|
||||
d->setDirectory(directory);
|
||||
const QString file = m_selectedFileName->text().trimmed();
|
||||
if (!file.isEmpty())
|
||||
d->selectFile(file);
|
||||
const QString filter = m_selectedNameFilter->text().trimmed();
|
||||
const QStringList filters = m_nameFilters->toPlainText().trimmed().split(QLatin1Char('\n'), Qt::SkipEmptyParts);
|
||||
if (!m_useMimeTypeFilters->isChecked()) {
|
||||
d->setNameFilters(filters);
|
||||
if (!filter.isEmpty())
|
||||
d->selectNameFilter(filter);
|
||||
} else {
|
||||
d->setMimeTypeFilters(filters);
|
||||
if (!filter.isEmpty())
|
||||
d->selectMimeTypeFilter(filter);
|
||||
}
|
||||
foreach (LabelLineEdit *l, m_labelLineEdits)
|
||||
l->apply(d);
|
||||
}
|
||||
|
||||
void FileDialogPanel::useMimeTypeFilters(bool b)
|
||||
{
|
||||
QWidget *textEdit = filesLayout->labelForField(m_nameFilters);
|
||||
if (QLabel *label = qobject_cast<QLabel *>(textEdit))
|
||||
label->setText(b ? tr("Mime type filters:") : tr("Name filters:"));
|
||||
QWidget *w = filesLayout->labelForField(m_selectedNameFilter);
|
||||
if (QLabel *label = qobject_cast<QLabel *>(w))
|
||||
label->setText(b ? tr("Selected mime type filter:") : tr("Selected name filter:"));
|
||||
|
||||
if (b)
|
||||
m_nameFilters->setPlainText(QLatin1String("image/jpeg\nimage/png\ntext/plain\napplication/octet-stream"));
|
||||
else
|
||||
m_nameFilters->setPlainText(QLatin1String("Any files (*)\nImage files (*.png *.xpm *.jpg)\nText files (*.txt)"));
|
||||
}
|
||||
|
||||
void FileDialogPanel::accepted()
|
||||
{
|
||||
const QFileDialog *d = qobject_cast<const QFileDialog *>(sender());
|
||||
Q_ASSERT(d);
|
||||
m_result.clear();
|
||||
QDebug(&m_result).nospace()
|
||||
<< "URLs: " << d->selectedUrls() << '\n'
|
||||
<< "Files: " << d->selectedFiles()
|
||||
<< "\nDirectory: "
|
||||
<< d->directoryUrl() << ", "
|
||||
<< d->directory().absolutePath()
|
||||
<< "\nName filter: " << d->selectedNameFilter();
|
||||
QTimer::singleShot(0, this, SLOT(showAcceptedResult())); // Avoid problems with the closing (modal) dialog as parent.
|
||||
}
|
||||
|
||||
void FileDialogPanel::showAcceptedResult()
|
||||
{
|
||||
QMessageBox::information(this, tr("File Dialog Accepted"), m_result, QMessageBox::Ok);
|
||||
}
|
||||
|
||||
#include "filedialogpanel.moc"
|
83
tests/manual/dialogs/filedialogpanel.h
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef FILEDIALOGPANEL_H
|
||||
#define FILEDIALOGPANEL_H
|
||||
|
||||
#include <QGroupBox>
|
||||
#include <QFileDialog>
|
||||
#include <QPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QLineEdit;
|
||||
class QPlainTextEdit;
|
||||
class QFormLayout;
|
||||
QT_END_NAMESPACE
|
||||
class LabelLineEdit;
|
||||
|
||||
class FileDialogPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FileDialogPanel(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void execModal();
|
||||
void showModal(Qt::WindowModality modality);
|
||||
void showNonModal();
|
||||
void deleteNonModalDialog();
|
||||
void deleteModalDialog();
|
||||
void getOpenFileNames();
|
||||
void getOpenFileUrls();
|
||||
void getOpenFileName();
|
||||
void getOpenFileUrl();
|
||||
void getSaveFileName();
|
||||
void getSaveFileUrl();
|
||||
void getExistingDirectory();
|
||||
void getExistingDirectoryUrl();
|
||||
void accepted();
|
||||
void showAcceptedResult();
|
||||
void restoreDefaults();
|
||||
|
||||
private slots:
|
||||
void enableDeleteNonModalDialogButton();
|
||||
void enableDeleteModalDialogButton();
|
||||
void useMimeTypeFilters(bool);
|
||||
|
||||
private:
|
||||
QUrl currentDirectoryUrl() const;
|
||||
QString filterString() const;
|
||||
QFileDialog::Options options() const;
|
||||
QStringList allowedSchemes() const;
|
||||
void applySettings(QFileDialog *d) const;
|
||||
|
||||
QFormLayout *filesLayout;
|
||||
QCheckBox *m_showDirsOnly;
|
||||
QCheckBox *m_readOnly;
|
||||
QCheckBox *m_confirmOverWrite;
|
||||
QCheckBox *m_nameFilterDetailsVisible;
|
||||
QCheckBox *m_resolveSymLinks;
|
||||
QCheckBox *m_native;
|
||||
QCheckBox *m_customDirIcons;
|
||||
QComboBox *m_acceptMode;
|
||||
QComboBox *m_fileMode;
|
||||
QComboBox *m_viewMode;
|
||||
QLineEdit *m_allowedSchemes;
|
||||
QLineEdit *m_defaultSuffix;
|
||||
QLineEdit *m_directory;
|
||||
QLineEdit *m_selectedFileName;
|
||||
QList<LabelLineEdit *> m_labelLineEdits;
|
||||
QCheckBox *m_useMimeTypeFilters;
|
||||
QPlainTextEdit *m_nameFilters;
|
||||
QLineEdit *m_selectedNameFilter;
|
||||
QPushButton *m_deleteNonModalDialogButton;
|
||||
QPushButton *m_deleteModalDialogButton;
|
||||
QString m_result;
|
||||
QPointer<QFileDialog> m_modalDialog;
|
||||
QPointer<QFileDialog> m_nonModalDialog;
|
||||
};
|
||||
|
||||
#endif // FILEDIALOGPANEL_H
|
177
tests/manual/dialogs/fontdialogpanel.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "fontdialogpanel.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QGroupBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QFontComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
|
||||
FontDialogPanel::FontDialogPanel(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_fontFamilyBox(new QFontComboBox)
|
||||
, m_fontSizeBox(new QDoubleSpinBox)
|
||||
, m_noButtons(new QCheckBox(tr("Don't display OK/Cancel buttons")))
|
||||
, m_dontUseNativeDialog(new QCheckBox(tr("Don't use native dialog")))
|
||||
, m_scalableFilter(new QCheckBox(tr("Filter scalable fonts")))
|
||||
, m_nonScalableFilter(new QCheckBox(tr("Filter non scalable fonts")))
|
||||
, m_monospacedFilter(new QCheckBox(tr("Filter monospaced fonts")))
|
||||
, m_proportionalFilter(new QCheckBox(tr("Filter proportional fonts")))
|
||||
{
|
||||
// Options
|
||||
QGroupBox *optionsGroupBox = new QGroupBox(tr("Options"), this);
|
||||
QVBoxLayout *optionsLayout = new QVBoxLayout(optionsGroupBox);
|
||||
optionsLayout->addWidget(m_noButtons);
|
||||
optionsLayout->addWidget(m_dontUseNativeDialog);
|
||||
optionsLayout->addWidget(m_scalableFilter);
|
||||
optionsLayout->addWidget(m_nonScalableFilter);
|
||||
optionsLayout->addWidget(m_monospacedFilter);
|
||||
optionsLayout->addWidget(m_proportionalFilter);
|
||||
|
||||
// Font
|
||||
QGroupBox *fontGroupBox = new QGroupBox(tr("Font"), this);
|
||||
QHBoxLayout *fontLayout = new QHBoxLayout(fontGroupBox);
|
||||
fontLayout->addWidget(m_fontFamilyBox);
|
||||
fontLayout->addWidget(m_fontSizeBox);
|
||||
m_fontSizeBox->setValue(QFont().pointSizeF());
|
||||
|
||||
// Buttons
|
||||
QGroupBox *buttonsGroupBox = new QGroupBox(tr("Show"));
|
||||
QVBoxLayout *buttonsLayout = new QVBoxLayout(buttonsGroupBox);
|
||||
addButton(tr("Exec modal"), buttonsLayout, this, SLOT(execModal()));
|
||||
addButton(tr("Show application modal"), buttonsLayout,
|
||||
[this]() { showModal(Qt::ApplicationModal); });
|
||||
addButton(tr("Show window modal"), buttonsLayout, [this]() { showModal(Qt::WindowModal); });
|
||||
m_deleteModalDialogButton =
|
||||
addButton(tr("Delete modal"), buttonsLayout, this, SLOT(deleteModalDialog()));
|
||||
addButton(tr("Show non-modal"), buttonsLayout, this, SLOT(showNonModal()));
|
||||
m_deleteNonModalDialogButton =
|
||||
addButton(tr("Delete non-modal"), buttonsLayout, this, SLOT(deleteNonModalDialog()));
|
||||
addButton(tr("Restore defaults"), buttonsLayout, this, SLOT(restoreDefaults()));
|
||||
buttonsLayout->addStretch();
|
||||
|
||||
// Main layout
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
QVBoxLayout *leftLayout = new QVBoxLayout;
|
||||
leftLayout->addWidget(optionsGroupBox);
|
||||
leftLayout->addWidget(fontGroupBox);
|
||||
leftLayout->addStretch();
|
||||
mainLayout->addLayout(leftLayout);
|
||||
mainLayout->addWidget(buttonsGroupBox);
|
||||
|
||||
enableDeleteModalDialogButton();
|
||||
enableDeleteNonModalDialogButton();
|
||||
restoreDefaults();
|
||||
}
|
||||
|
||||
void FontDialogPanel::execModal()
|
||||
{
|
||||
QFontDialog dialog(this);
|
||||
applySettings(&dialog);
|
||||
connect(&dialog, SIGNAL(accepted()), this, SLOT(accepted()));
|
||||
dialog.setWindowTitle(tr("Modal Font Dialog Qt %1").arg(QLatin1String(QT_VERSION_STR)));
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void FontDialogPanel::showModal(Qt::WindowModality modality)
|
||||
{
|
||||
if (m_modalDialog.isNull()) {
|
||||
static int n = 0;
|
||||
m_modalDialog = new QFontDialog(this);
|
||||
m_modalDialog->setModal(true);
|
||||
connect(m_modalDialog.data(), SIGNAL(accepted()), this, SLOT(accepted()));
|
||||
m_modalDialog->setWindowTitle(tr("Modal Font Dialog #%1 Qt %2")
|
||||
.arg(++n)
|
||||
.arg(QLatin1String(QT_VERSION_STR)));
|
||||
enableDeleteModalDialogButton();
|
||||
}
|
||||
m_modalDialog->setWindowModality(modality);
|
||||
applySettings(m_modalDialog);
|
||||
m_modalDialog->show();
|
||||
}
|
||||
|
||||
void FontDialogPanel::showNonModal()
|
||||
{
|
||||
if (m_nonModalDialog.isNull()) {
|
||||
static int n = 0;
|
||||
m_nonModalDialog = new QFontDialog(this);
|
||||
connect(m_nonModalDialog.data(), SIGNAL(accepted()), this, SLOT(accepted()));
|
||||
m_nonModalDialog->setWindowTitle(tr("Non-Modal Font Dialog #%1 Qt %2")
|
||||
.arg(++n)
|
||||
.arg(QLatin1String(QT_VERSION_STR)));
|
||||
enableDeleteNonModalDialogButton();
|
||||
}
|
||||
applySettings(m_nonModalDialog);
|
||||
m_nonModalDialog->show();
|
||||
}
|
||||
|
||||
void FontDialogPanel::deleteNonModalDialog()
|
||||
{
|
||||
if (!m_nonModalDialog.isNull())
|
||||
delete m_nonModalDialog;
|
||||
enableDeleteNonModalDialogButton();
|
||||
}
|
||||
|
||||
void FontDialogPanel::deleteModalDialog()
|
||||
{
|
||||
if (!m_modalDialog.isNull())
|
||||
delete m_modalDialog;
|
||||
enableDeleteModalDialogButton();
|
||||
}
|
||||
|
||||
void FontDialogPanel::accepted()
|
||||
{
|
||||
const QFontDialog *d = qobject_cast<const QFontDialog *>(sender());
|
||||
Q_ASSERT(d);
|
||||
m_result.clear();
|
||||
QDebug(&m_result).nospace()
|
||||
<< "Current font: " << d->currentFont()
|
||||
<< "\nSelected font: " << d->selectedFont();
|
||||
QTimer::singleShot(0, this, SLOT(showAcceptedResult())); // Avoid problems with the closing (modal) dialog as parent.
|
||||
}
|
||||
|
||||
void FontDialogPanel::showAcceptedResult()
|
||||
{
|
||||
QMessageBox::information(this, tr("Color Dialog Accepted"), m_result, QMessageBox::Ok);
|
||||
}
|
||||
|
||||
void FontDialogPanel::restoreDefaults()
|
||||
{
|
||||
QFontDialog d;
|
||||
m_noButtons->setChecked(d.testOption(QFontDialog::NoButtons));
|
||||
m_dontUseNativeDialog->setChecked(d.testOption(QFontDialog::DontUseNativeDialog));
|
||||
m_fontFamilyBox->setCurrentFont(QFont());
|
||||
m_fontSizeBox->setValue(QFont().pointSizeF());
|
||||
}
|
||||
|
||||
void FontDialogPanel::enableDeleteNonModalDialogButton()
|
||||
{
|
||||
m_deleteNonModalDialogButton->setEnabled(!m_nonModalDialog.isNull());
|
||||
}
|
||||
|
||||
void FontDialogPanel::enableDeleteModalDialogButton()
|
||||
{
|
||||
m_deleteModalDialogButton->setEnabled(!m_modalDialog.isNull());
|
||||
}
|
||||
|
||||
void FontDialogPanel::applySettings(QFontDialog *d) const
|
||||
{
|
||||
d->setOption(QFontDialog::NoButtons, m_noButtons->isChecked());
|
||||
d->setOption(QFontDialog::DontUseNativeDialog, m_dontUseNativeDialog->isChecked());
|
||||
d->setOption(QFontDialog::ScalableFonts, m_scalableFilter->isChecked());
|
||||
d->setOption(QFontDialog::NonScalableFonts, m_nonScalableFilter->isChecked());
|
||||
d->setOption(QFontDialog::MonospacedFonts, m_monospacedFilter->isChecked());
|
||||
d->setOption(QFontDialog::ProportionalFonts, m_proportionalFilter->isChecked());
|
||||
|
||||
QFont font = m_fontFamilyBox->currentFont();
|
||||
font.setPointSizeF(m_fontSizeBox->value());
|
||||
d->setCurrentFont(font);
|
||||
}
|
55
tests/manual/dialogs/fontdialogpanel.h
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef FONTDIALOGPANEL_H
|
||||
#define FONTDIALOGPANEL_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <QFontDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QCheckBox;
|
||||
class QPushButton;
|
||||
class QFontComboBox;
|
||||
class QDoubleSpinBox;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class FontDialogPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FontDialogPanel(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void execModal();
|
||||
void showModal(Qt::WindowModality modality);
|
||||
void showNonModal();
|
||||
void deleteNonModalDialog();
|
||||
void deleteModalDialog();
|
||||
void accepted();
|
||||
void showAcceptedResult();
|
||||
void restoreDefaults();
|
||||
|
||||
private slots:
|
||||
void enableDeleteNonModalDialogButton();
|
||||
void enableDeleteModalDialogButton();
|
||||
|
||||
private:
|
||||
void applySettings(QFontDialog *d) const;
|
||||
|
||||
QFontComboBox *m_fontFamilyBox;
|
||||
QDoubleSpinBox *m_fontSizeBox;
|
||||
QCheckBox *m_noButtons;
|
||||
QCheckBox *m_dontUseNativeDialog;
|
||||
QCheckBox *m_scalableFilter;
|
||||
QCheckBox *m_nonScalableFilter;
|
||||
QCheckBox *m_monospacedFilter;
|
||||
QCheckBox *m_proportionalFilter;
|
||||
QPushButton *m_deleteNonModalDialogButton;
|
||||
QPushButton *m_deleteModalDialogButton;
|
||||
QString m_result;
|
||||
QPointer<QFontDialog> m_modalDialog;
|
||||
QPointer<QFontDialog> m_nonModalDialog;
|
||||
};
|
||||
|
||||
#endif // FONTDIALOGPANEL_H
|
114
tests/manual/dialogs/main.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "filedialogpanel.h"
|
||||
#include "colordialogpanel.h"
|
||||
#include "fontdialogpanel.h"
|
||||
#include "printdialogpanel.h"
|
||||
#include "wizardpanel.h"
|
||||
#include "messageboxpanel.h"
|
||||
|
||||
#include <QLibraryInfo>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QMainWindow>
|
||||
#include <QApplication>
|
||||
#include <QMenuBar>
|
||||
#include <QTabWidget>
|
||||
#include <QFormLayout>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QKeySequence>
|
||||
|
||||
static bool optNoPrinter = false;
|
||||
|
||||
// Test for dialogs, allowing to play with all dialog options for implementing native dialogs.
|
||||
// Compiles with Qt 4.8 and Qt 5.
|
||||
|
||||
class AboutDialog : public QDialog
|
||||
{
|
||||
public:
|
||||
explicit AboutDialog(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
QFormLayout *mainLayout = new QFormLayout(this);
|
||||
mainLayout->addRow(new QLabel(QLibraryInfo::build()));
|
||||
mainLayout->addRow("Style:", new QLabel(qApp->style()->objectName()));
|
||||
mainLayout->addRow("DPR:", new QLabel(QString::number(qApp->devicePixelRatio())));
|
||||
const QString resolution = QString::number(logicalDpiX()) + QLatin1Char(',')
|
||||
+ QString::number(logicalDpiY()) + QLatin1String("dpi");
|
||||
mainLayout->addRow("Resolution:", new QLabel(resolution));
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal);
|
||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
mainLayout->addRow(buttonBox);
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void aboutDialog();
|
||||
};
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
{
|
||||
setWindowTitle(tr("Dialogs Qt %1").arg(QLatin1String(QT_VERSION_STR)));
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
|
||||
QAction *quitAction = fileMenu->addAction(tr("Quit"));
|
||||
quitAction->setShortcut(QKeySequence(QKeySequence::Quit));
|
||||
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
|
||||
QAction *action = editMenu->addAction(tr("Cut"));
|
||||
action->setShortcut(QKeySequence(QKeySequence::Cut));
|
||||
action = editMenu->addAction(tr("Copy"));
|
||||
action->setShortcut(QKeySequence(QKeySequence::Copy));
|
||||
action = editMenu->addAction(tr("Paste"));
|
||||
action->setShortcut(QKeySequence(QKeySequence::Paste));
|
||||
action = editMenu->addAction(tr("Select All"));
|
||||
action->setShortcut(QKeySequence(QKeySequence::SelectAll));
|
||||
QMenu *aboutMenu = menuBar()->addMenu(tr("&About"));
|
||||
QAction *aboutAction = aboutMenu->addAction(tr("About..."), this, SLOT(aboutDialog()));
|
||||
aboutAction->setShortcut(Qt::Key_F1);
|
||||
QTabWidget *tabWidget = new QTabWidget;
|
||||
tabWidget->addTab(new FileDialogPanel, tr("QFileDialog"));
|
||||
tabWidget->addTab(new ColorDialogPanel, tr("QColorDialog"));
|
||||
tabWidget->addTab(new FontDialogPanel, tr("QFontDialog"));
|
||||
tabWidget->addTab(new WizardPanel, tr("QWizard"));
|
||||
tabWidget->addTab(new MessageBoxPanel, tr("QMessageBox"));
|
||||
#ifndef QT_NO_PRINTER
|
||||
if (!optNoPrinter)
|
||||
tabWidget->addTab(new PrintDialogPanel, tr("QPrintDialog"));
|
||||
#endif
|
||||
setCentralWidget(tabWidget);
|
||||
}
|
||||
|
||||
void MainWindow::aboutDialog()
|
||||
{
|
||||
AboutDialog dialog(this);
|
||||
dialog.setWindowTitle(tr("About Dialogs"));
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
for (int a = 1; a < argc; ++a) {
|
||||
if (!qstrcmp(argv[a], "-n")) {
|
||||
qDebug("AA_DontUseNativeDialogs");
|
||||
QCoreApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
|
||||
} else if (!qstrcmp(argv[a], "-p")) {
|
||||
optNoPrinter = true; // Avoid startup slowdown by printer code
|
||||
}
|
||||
}
|
||||
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.move(500, 200);
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
163
tests/manual/dialogs/messageboxpanel.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
// Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "messageboxpanel.h"
|
||||
|
||||
#include <QGroupBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QDebug>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QCheckBox>
|
||||
#include <QRegularExpressionValidator>
|
||||
#include <QRegularExpression>
|
||||
|
||||
MessageBoxPanel::MessageBoxPanel(QWidget *parent) : QWidget(parent)
|
||||
,m_iconComboBox(new QComboBox)
|
||||
,m_textInMsgBox(new QLineEdit)
|
||||
,m_informativeText(new QLineEdit)
|
||||
,m_detailedtext(new QLineEdit)
|
||||
,m_buttonsMask(new QLineEdit)
|
||||
,m_btnExec(new QPushButton)
|
||||
,m_btnShowApply(new QPushButton)
|
||||
,m_resultLabel(new QLabel)
|
||||
,m_chkReallocMsgBox(new QCheckBox(QString::fromLatin1("Reallocate Message Box")))
|
||||
,m_checkboxText(new QLineEdit)
|
||||
,m_checkBoxResult(new QLabel)
|
||||
,m_msgbox(new QMessageBox)
|
||||
{
|
||||
// --- Options ---
|
||||
QGroupBox *optionsGroupBox = new QGroupBox(tr("Options"), this);
|
||||
QVBoxLayout *optionsLayout = new QVBoxLayout(optionsGroupBox);
|
||||
|
||||
// text
|
||||
optionsLayout->addWidget(new QLabel(QString::fromLatin1("Message box text")));
|
||||
m_textInMsgBox->setText(QString::fromLatin1("This is a simple test with a text that is not long"));
|
||||
optionsLayout->addWidget(m_textInMsgBox);
|
||||
|
||||
// informative text
|
||||
optionsLayout->addWidget(new QLabel(QString::fromLatin1("Informative Text")));
|
||||
optionsLayout->addWidget(m_informativeText);
|
||||
|
||||
// detailed text
|
||||
optionsLayout->addWidget(new QLabel(QString::fromLatin1("detailed Text")));
|
||||
optionsLayout->addWidget(m_detailedtext);
|
||||
|
||||
// icon
|
||||
QStringList items;
|
||||
items << "NoIcon" << "Information" << "Warning" << "Critical" << "Question";
|
||||
m_iconComboBox->addItems(items);
|
||||
optionsLayout->addWidget(new QLabel(QString::fromLatin1("Message box icon")));
|
||||
optionsLayout->addWidget(m_iconComboBox);
|
||||
|
||||
// buttons mask
|
||||
optionsLayout->addWidget(new QLabel(QString::fromLatin1("Message box button mask (in hex)")));
|
||||
m_validator = new QRegularExpressionValidator(QRegularExpression("0[xX]?[0-9a-fA-F]+"), this);
|
||||
m_buttonsMask->setMaxLength(10);
|
||||
m_buttonsMask->setValidator(m_validator);
|
||||
m_buttonsMask->setText(QString::fromLatin1("0x00300400"));
|
||||
optionsLayout->addWidget(m_buttonsMask);
|
||||
|
||||
// check box check
|
||||
optionsLayout->addWidget(new QLabel(QString::fromLatin1("Checkbox text ("" => no chkbox)")));
|
||||
optionsLayout->addWidget(m_checkboxText);
|
||||
|
||||
// reallocate
|
||||
optionsLayout->addWidget(m_chkReallocMsgBox);
|
||||
optionsLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding));
|
||||
|
||||
// Exec/Show
|
||||
QGroupBox *execGroupBox = new QGroupBox(tr("Exec"));
|
||||
QVBoxLayout *execLayout = new QVBoxLayout(execGroupBox);
|
||||
m_btnExec->setText(QString::fromLatin1("Exec message box"));
|
||||
connect(m_btnExec, SIGNAL(clicked()), this, SLOT(doExec()));
|
||||
execLayout->addWidget(m_btnExec);
|
||||
|
||||
m_btnShowApply->setText(QString::fromLatin1("Show / apply"));
|
||||
connect(m_btnShowApply, SIGNAL(clicked()), this, SLOT(doShowApply()));
|
||||
execLayout->addWidget(m_btnShowApply);
|
||||
|
||||
// result label
|
||||
execLayout->addWidget(m_resultLabel);
|
||||
execLayout->addWidget(m_checkBoxResult);
|
||||
|
||||
execLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding));
|
||||
execGroupBox->setLayout(execLayout);
|
||||
|
||||
// Main layout
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout();
|
||||
mainLayout->addWidget(optionsGroupBox);
|
||||
mainLayout->addWidget(execGroupBox);
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
void MessageBoxPanel::setupMessageBox(QMessageBox &box)
|
||||
{
|
||||
m_resultLabel->setText(QString());
|
||||
m_checkBoxResult->setText(QString());
|
||||
box.setText(m_textInMsgBox->text());
|
||||
box.setInformativeText(m_informativeText->text());
|
||||
box.setDetailedText(m_detailedtext->text());
|
||||
|
||||
QString btnHexText = m_buttonsMask->text();
|
||||
btnHexText = btnHexText.replace(QString::fromLatin1("0x"), QString(), Qt::CaseInsensitive);
|
||||
bool ok;
|
||||
QMessageBox::StandardButtons btns = (QMessageBox::StandardButtons) btnHexText.toUInt(&ok, 16);
|
||||
box.setStandardButtons((QMessageBox::StandardButtons) btns);
|
||||
if (box.standardButtons() == QMessageBox::StandardButtons())
|
||||
box.setStandardButtons(QMessageBox::Ok); // just to have something.
|
||||
|
||||
box.setCheckBox(0);
|
||||
if (m_checkboxText->text().length() > 0)
|
||||
box.setCheckBox(new QCheckBox(m_checkboxText->text()));
|
||||
|
||||
box.setIcon((QMessageBox::Icon) m_iconComboBox->currentIndex());
|
||||
}
|
||||
|
||||
MessageBoxPanel::~MessageBoxPanel()
|
||||
{
|
||||
if (m_msgbox)
|
||||
m_msgbox->deleteLater();
|
||||
}
|
||||
|
||||
void MessageBoxPanel::doExec()
|
||||
{
|
||||
if (!m_msgbox || m_chkReallocMsgBox->isChecked()) {
|
||||
if (m_msgbox)
|
||||
m_msgbox->deleteLater();
|
||||
m_msgbox = new QMessageBox;
|
||||
}
|
||||
setupMessageBox(*m_msgbox);
|
||||
m_msgbox->setWindowModality(Qt::NonModal);
|
||||
|
||||
int res = m_msgbox->exec();
|
||||
QString sres;
|
||||
sres.setNum(res, 16);
|
||||
m_resultLabel->setText(QString::fromLatin1("Return value (hex): %1").arg(sres));
|
||||
if (m_msgbox->checkBox()) {
|
||||
if (m_msgbox->checkBox()->isChecked())
|
||||
m_checkBoxResult->setText(QString::fromLatin1("Checkbox was checked"));
|
||||
else
|
||||
m_checkBoxResult->setText(QString::fromLatin1("Checkbox was not checked"));
|
||||
}
|
||||
}
|
||||
|
||||
void MessageBoxPanel::doShowApply()
|
||||
{
|
||||
if (!m_msgbox || m_chkReallocMsgBox->isChecked()) {
|
||||
if (m_msgbox)
|
||||
m_msgbox->deleteLater();
|
||||
m_msgbox = new QMessageBox;
|
||||
}
|
||||
setupMessageBox(*m_msgbox);
|
||||
if (!m_msgbox->isVisible()) {
|
||||
m_msgbox->setWindowModality(Qt::NonModal);
|
||||
m_msgbox->show();
|
||||
}
|
||||
}
|
49
tests/manual/dialogs/messageboxpanel.h
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright (C) 2013 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef MESSAGEBOXPANEL_H
|
||||
#define MESSAGEBOXPANEL_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QCheckBox>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
class QCheckBox;
|
||||
class QPushButton;
|
||||
class QLineEdit;
|
||||
class QValidator;
|
||||
class QLabel;
|
||||
class QMessageBox;
|
||||
class QCheckBox;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MessageBoxPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MessageBoxPanel(QWidget *parent = nullptr);
|
||||
~MessageBoxPanel();
|
||||
|
||||
public slots:
|
||||
void doExec();
|
||||
void doShowApply();
|
||||
|
||||
private:
|
||||
QComboBox *m_iconComboBox;
|
||||
QLineEdit *m_textInMsgBox;
|
||||
QLineEdit *m_informativeText;
|
||||
QLineEdit *m_detailedtext;
|
||||
QLineEdit *m_buttonsMask;
|
||||
QPushButton *m_btnExec;
|
||||
QPushButton *m_btnShowApply;
|
||||
QValidator *m_validator;
|
||||
QLabel *m_resultLabel;
|
||||
QCheckBox *m_chkReallocMsgBox;
|
||||
QLineEdit *m_checkboxText;
|
||||
QLabel *m_checkBoxResult;
|
||||
QMessageBox *m_msgbox;
|
||||
void setupMessageBox(QMessageBox &box);
|
||||
};
|
||||
|
||||
#endif
|
582
tests/manual/dialogs/printdialogpanel.cpp
Normal file
@ -0,0 +1,582 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef QT_NO_PRINTER
|
||||
|
||||
#include "printdialogpanel.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QPrinter>
|
||||
#include <QPrinterInfo>
|
||||
#include <QPrintDialog>
|
||||
#include <QPrintPreviewDialog>
|
||||
#include <QPageSetupDialog>
|
||||
#include <QApplication>
|
||||
#include <QGroupBox>
|
||||
#include <QCheckBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QGridLayout>
|
||||
#include <QFormLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QPainter>
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QTextStream>
|
||||
#include <QDir>
|
||||
#include <QScreen>
|
||||
|
||||
const FlagData printerModeComboData[] =
|
||||
{
|
||||
{"ScreenResolution", QPrinter::ScreenResolution},
|
||||
{"PrinterResolution", QPrinter::PrinterResolution},
|
||||
{"HighResolution", QPrinter::HighResolution}
|
||||
};
|
||||
|
||||
|
||||
const FlagData printRangeComboData[] =
|
||||
{
|
||||
{"AllPages", QPrinter::AllPages},
|
||||
{"Selection", QPrinter::Selection},
|
||||
{"PageRange", QPrinter::PageRange},
|
||||
{"CurrentPage", QPrinter::CurrentPage}
|
||||
};
|
||||
|
||||
const FlagData pageOrderComboData[] =
|
||||
{
|
||||
{"FirstPageFirst", QPrinter::FirstPageFirst},
|
||||
{"LastPageFirst", QPrinter::LastPageFirst},
|
||||
};
|
||||
|
||||
const FlagData duplexModeComboData[] =
|
||||
{
|
||||
{"DuplexNone", QPrinter::DuplexNone},
|
||||
{"DuplexAuto", QPrinter::DuplexAuto},
|
||||
{"DuplexLongSide", QPrinter::DuplexLongSide},
|
||||
{"DuplexShortSide", QPrinter::DuplexShortSide},
|
||||
};
|
||||
|
||||
const FlagData paperSourceComboData[] =
|
||||
{
|
||||
{"OnlyOne", QPrinter::OnlyOne},
|
||||
{"Lower", QPrinter::Lower},
|
||||
{"Middle", QPrinter::Middle},
|
||||
{"Manual", QPrinter::Manual},
|
||||
{"Envelope", QPrinter::Envelope},
|
||||
{"EnvelopeManual", QPrinter::EnvelopeManual},
|
||||
{"Auto", QPrinter::Auto},
|
||||
{"Tractor", QPrinter::Tractor},
|
||||
{"SmallFormat", QPrinter::SmallFormat},
|
||||
{"LargeFormat", QPrinter::LargeFormat},
|
||||
{"LargeCapacity", QPrinter::LargeCapacity},
|
||||
{"Cassette", QPrinter::Cassette},
|
||||
{"FormSource", QPrinter::FormSource},
|
||||
{"DuplexLongSide", QPrinter::DuplexLongSide},
|
||||
{"DuplexShortSide", QPrinter::DuplexShortSide},
|
||||
};
|
||||
|
||||
const FlagData colorModeComboData[] =
|
||||
{
|
||||
{"GrayScale", QPrinter::GrayScale},
|
||||
{"Color", QPrinter::Color},
|
||||
};
|
||||
|
||||
const FlagData unitsComboData[] =
|
||||
{
|
||||
{"Millimeter", QPageLayout::Millimeter},
|
||||
{"Inch", QPageLayout::Inch},
|
||||
{"Point", QPageLayout::Point},
|
||||
{"Pica", QPageLayout::Pica},
|
||||
{"Didot", QPageLayout::Didot},
|
||||
{"Cicero", QPageLayout::Cicero},
|
||||
};
|
||||
|
||||
const FlagData orientationComboData[] =
|
||||
{
|
||||
{"Portrait", QPageLayout::Portrait},
|
||||
{"Landscape", QPageLayout::Landscape},
|
||||
};
|
||||
|
||||
const FlagData layoutModeComboData[] =
|
||||
{
|
||||
{"StandardMode", QPageLayout::StandardMode},
|
||||
{"FullPageMode", QPageLayout::FullPageMode},
|
||||
};
|
||||
|
||||
const FlagData printDialogOptions[] =
|
||||
{
|
||||
{"PrintToFile", QPrintDialog::PrintToFile},
|
||||
{"PrintSelection", QPrintDialog::PrintSelection},
|
||||
{"PrintPageRange", QPrintDialog::PrintPageRange},
|
||||
{"PrintShowPageSize", QPrintDialog::PrintShowPageSize},
|
||||
{"PrintCollateCopies", QPrintDialog::PrintCollateCopies},
|
||||
{"PrintCurrentPage", QPrintDialog::PrintCurrentPage}
|
||||
};
|
||||
|
||||
QTextStream &operator<<(QTextStream &s, const QSizeF &size)
|
||||
{
|
||||
s << size.width() << 'x' << size.height();
|
||||
return s;
|
||||
}
|
||||
|
||||
QTextStream &operator<<(QTextStream &s, const QRectF &rect)
|
||||
{
|
||||
s << rect.width() << 'x' << rect.height() << Qt::forcesign << rect.x() << rect.y()
|
||||
<< Qt::noforcesign;
|
||||
return s;
|
||||
}
|
||||
|
||||
QTextStream &operator<<(QTextStream &s, const QPrinter &printer)
|
||||
{
|
||||
const auto pageLayout = printer.pageLayout();
|
||||
const auto pageSize = pageLayout.pageSize();
|
||||
s << '"' << printer.printerName() << "\"\nPaper #" << pageSize.id()
|
||||
<< " \"" << pageSize.name() << '"'
|
||||
<< (pageLayout.orientation() == QPageLayout::Portrait ? ", Portrait" : ", Landscape");
|
||||
if (printer.fullPage())
|
||||
s << ", full page";
|
||||
s << "\nPaper size: "
|
||||
<< pageSize.sizePoints() << "pt "
|
||||
<< pageSize.size(QPageSize::Millimeter) << "mm "
|
||||
<< "\n " << pageSize.sizePixels(printer.resolution()) << " device pt "
|
||||
<< pageSize.size(QPageSize::Inch) << "inch "
|
||||
<< "\n " << pageSize.size(QPageSize::Millimeter) << "mm"
|
||||
<< "\nLogical resolution : " << printer.logicalDpiX() << ',' << printer.logicalDpiY() << "DPI"
|
||||
<< "\nPhysical resolution: " << printer.physicalDpiX() << ',' << printer.physicalDpiY() << "DPI"
|
||||
<< "\nPaperRect: " << printer.paperRect(QPrinter::Point) << "pt "
|
||||
<< printer.paperRect(QPrinter::Millimeter) << "mm "
|
||||
<< "\n " << printer.paperRect(QPrinter::DevicePixel) << "device pt"
|
||||
<< "\nPageRect: " << printer.pageRect(QPrinter::Point) << "pt "
|
||||
<< printer.pageRect(QPrinter::Millimeter) << "mm "
|
||||
<< "\n " << printer.pageRect(QPrinter::DevicePixel) << "device pt";
|
||||
return s;
|
||||
}
|
||||
|
||||
// Print a page with a rectangular frame, vertical / horizontal rulers in cm and printer info.
|
||||
|
||||
static void drawHorizCmRuler(QPainter &painter, int x1, int x2, int y)
|
||||
{
|
||||
painter.drawLine(x1, y, x2, y);
|
||||
const int dpI = painter.device()->logicalDpiX();
|
||||
const int dpCm = qRound(double(dpI) / 2.54);
|
||||
const int h = dpCm / 2;
|
||||
const QFontMetrics fm(painter.font());
|
||||
for (int cm = 0, x = x1; x < x2; x += dpCm, ++cm) {
|
||||
painter.drawLine(x, y, x, y - h);
|
||||
if (cm) {
|
||||
const QString n = QString::number(cm);
|
||||
const QRect br = fm.boundingRect(n);
|
||||
painter.drawText(x - br.width() / 2, y - h - 10, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void drawVertCmRuler(QPainter &painter, int x, int y1, int y2)
|
||||
{
|
||||
painter.drawLine(x, y1, x, y2);
|
||||
const int dpI = painter.device()->logicalDpiY();
|
||||
const int dpCm = qRound(double(dpI) / 2.54);
|
||||
const int h = dpCm / 2;
|
||||
const QFontMetrics fm(painter.font());
|
||||
for (int cm = 0, y = y1; y < y2; y += dpCm, ++cm) {
|
||||
painter.drawLine(x, y, x + h, y);
|
||||
if (cm) {
|
||||
const QString n = QString::number(cm);
|
||||
const QRect br = fm.boundingRect(n);
|
||||
painter.drawText(x + h + 10, y + br.height() / 2, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool print(QPrinter *printer, QString *errorMessage)
|
||||
{
|
||||
QPainter painter;
|
||||
|
||||
if (!printer->isValid()) {
|
||||
*errorMessage = QLatin1String("Invalid printer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (printer->printerState() != QPrinter::Idle) {
|
||||
*errorMessage = QLatin1String("Printer not idle (state ")
|
||||
+ QString::number(printer->printerState())
|
||||
+ QLatin1String(").");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!painter.begin(printer)) {
|
||||
*errorMessage = QLatin1String("QPainter::begin() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const QRectF pageF = printer->pageRect(QPrinter::DevicePixel);
|
||||
|
||||
QFont font = painter.font();
|
||||
font.setFamily("Courier");
|
||||
font.setPointSize(10);
|
||||
|
||||
// Format message.
|
||||
const int charHeight = QFontMetrics(font).boundingRect('X').height();
|
||||
QString msg;
|
||||
QTextStream str(&msg);
|
||||
str << "Qt "<< QT_VERSION_STR;
|
||||
str << ' ' << QGuiApplication::platformName();
|
||||
str << ' ' << QDateTime::currentDateTime().toString()
|
||||
<< "\nFont: " << font.family() << ' ' << font.pointSize() << '\n'
|
||||
<< *printer;
|
||||
|
||||
if (!painter.device()->logicalDpiY() || !painter.device()->logicalDpiX()) {
|
||||
*errorMessage = QLatin1String("Bailing out due to invalid DPI.");
|
||||
return false;
|
||||
}
|
||||
|
||||
painter.drawRect(pageF);
|
||||
|
||||
drawHorizCmRuler(painter, pageF.x(), pageF.right(), pageF.height() /2);
|
||||
drawVertCmRuler(painter, pageF.x() + pageF.width() / 2, pageF.top(), pageF.bottom());
|
||||
|
||||
painter.setFont(font);
|
||||
QPointF textPoint = pageF.topLeft() + QPoint(10, charHeight + 10);
|
||||
foreach (const QString &line, msg.split('\n')) {
|
||||
painter.drawText(textPoint, line);
|
||||
textPoint.ry() += (15 * charHeight) / 10;
|
||||
}
|
||||
|
||||
if (!painter.end()) {
|
||||
*errorMessage = QLatin1String("QPainter::end() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool print(QPrinter *printer, QWidget *dialogParent)
|
||||
{
|
||||
QString errorMessage;
|
||||
const bool result = print(printer, &errorMessage);
|
||||
if (!result)
|
||||
QMessageBox::warning(dialogParent, QLatin1String("Printing Failed"), errorMessage);
|
||||
return result;
|
||||
}
|
||||
|
||||
class PrintPreviewDialog : public QPrintPreviewDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PrintPreviewDialog(QPrinter *printer, QWidget *parent = nullptr) : QPrintPreviewDialog(printer, parent)
|
||||
{
|
||||
connect(this, SIGNAL(paintRequested(QPrinter*)), this, SLOT(slotPaintRequested(QPrinter*)));
|
||||
}
|
||||
|
||||
public slots:
|
||||
void slotPaintRequested(QPrinter *p) { print(p, this); }
|
||||
};
|
||||
|
||||
PrintDialogPanel::PrintDialogPanel(QWidget *parent)
|
||||
: QWidget(parent), m_blockSignals(true)
|
||||
{
|
||||
m_panel.setupUi(this);
|
||||
|
||||
// Setup the Create box
|
||||
populateCombo(m_panel.m_printerModeCombo, printerModeComboData, sizeof(printerModeComboData)/sizeof(FlagData));
|
||||
connect(m_panel.m_createButton, SIGNAL(clicked()), this, SLOT(createPrinter()));
|
||||
connect(m_panel.m_deleteButton, SIGNAL(clicked()), this, SLOT(deletePrinter()));
|
||||
|
||||
// Setup the Page Layout box
|
||||
populateCombo(m_panel.m_unitsCombo, unitsComboData, sizeof(unitsComboData)/sizeof(FlagData));
|
||||
connect(m_panel.m_unitsCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(unitsChanged()));
|
||||
for (int i = QPageSize::A4; i < QPageSize::LastPageSize; ++i) {
|
||||
QPageSize::PageSizeId id = QPageSize::PageSizeId(i);
|
||||
m_panel.m_pageSizeCombo->addItem(QPageSize::name(id), QVariant(id));
|
||||
}
|
||||
connect(m_panel.m_pageSizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(pageSizeChanged()));
|
||||
connect(m_panel.m_pageWidth, SIGNAL(valueChanged(double)), this, SLOT(pageDimensionsChanged()));
|
||||
connect(m_panel.m_pageHeight, SIGNAL(valueChanged(double)), this, SLOT(pageDimensionsChanged()));
|
||||
populateCombo(m_panel.m_orientationCombo, orientationComboData, sizeof(orientationComboData)/sizeof(FlagData));
|
||||
connect(m_panel.m_orientationCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(orientationChanged()));
|
||||
connect(m_panel.m_leftMargin, SIGNAL(valueChanged(double)), this, SLOT(marginsChanged()));
|
||||
connect(m_panel.m_topMargin, SIGNAL(valueChanged(double)), this, SLOT(marginsChanged()));
|
||||
connect(m_panel.m_rightMargin, SIGNAL(valueChanged(double)), this, SLOT(marginsChanged()));
|
||||
connect(m_panel.m_bottomMargin, SIGNAL(valueChanged(double)), this, SLOT(marginsChanged()));
|
||||
populateCombo(m_panel.m_layoutModeCombo, layoutModeComboData, sizeof(layoutModeComboData)/sizeof(FlagData));
|
||||
connect(m_panel.m_layoutModeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(layoutModeChanged()));
|
||||
|
||||
// Setup the Print Job box
|
||||
m_panel.m_printerCombo->addItem(tr("Print to PDF"), QVariant("PdfFormat"));
|
||||
foreach (const QString &name, QPrinterInfo::availablePrinterNames())
|
||||
m_panel.m_printerCombo->addItem(name, QVariant(name));
|
||||
connect(m_panel.m_printerCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(printerChanged()));
|
||||
populateCombo(m_panel.m_printRangeCombo, printRangeComboData, sizeof(printRangeComboData)/sizeof(FlagData));
|
||||
populateCombo(m_panel.m_pageOrderCombo, pageOrderComboData, sizeof(pageOrderComboData)/sizeof(FlagData));
|
||||
populateCombo(m_panel.m_duplexModeCombo, duplexModeComboData, sizeof(duplexModeComboData)/sizeof(FlagData));
|
||||
populateCombo(m_panel.m_paperSourceCombo, paperSourceComboData, sizeof(paperSourceComboData)/sizeof(FlagData));
|
||||
populateCombo(m_panel.m_colorModeCombo, colorModeComboData, sizeof(colorModeComboData)/sizeof(FlagData));
|
||||
|
||||
// Setup the Dialogs box
|
||||
m_panel.m_dialogOptionsGroupBox->populateOptions(printDialogOptions, sizeof(printDialogOptions) / sizeof(FlagData));
|
||||
QPrintDialog dialog;
|
||||
m_panel.m_dialogOptionsGroupBox->setValue(dialog.options());
|
||||
connect(m_panel.m_printButton, SIGNAL(clicked()), this, SLOT(showPrintDialog()));
|
||||
connect(m_panel.m_printPreviewButton, SIGNAL(clicked()), this, SLOT(showPreviewDialog()));
|
||||
connect(m_panel.m_pageSetupButton, SIGNAL(clicked()), this, SLOT(showPageSetupDialog()));
|
||||
connect(m_panel.m_directPrintButton, SIGNAL(clicked()), this, SLOT(directPrint()));
|
||||
|
||||
enablePanels();
|
||||
m_blockSignals = false;
|
||||
}
|
||||
|
||||
PrintDialogPanel::~PrintDialogPanel()
|
||||
{
|
||||
}
|
||||
|
||||
void PrintDialogPanel::enablePanels()
|
||||
{
|
||||
const bool exists = !m_printer.isNull();
|
||||
m_panel.m_createButton->setEnabled(!exists);
|
||||
m_panel.m_printerModeCombo->setEnabled(!exists);
|
||||
m_panel.m_deleteButton->setEnabled(exists);
|
||||
m_panel.m_pageLayoutGroupBox->setEnabled(exists);
|
||||
m_panel.m_printJobGroupBox->setEnabled(exists);
|
||||
m_panel.m_dialogsGroupBox->setEnabled(exists);
|
||||
}
|
||||
|
||||
void PrintDialogPanel::createPrinter()
|
||||
{
|
||||
const QPrinter::PrinterMode mode = comboBoxValue<QPrinter::PrinterMode>(m_panel.m_printerModeCombo);
|
||||
m_printer.reset(new QPrinter(mode)); // Can set only once.
|
||||
retrieveSettings(m_printer.data());
|
||||
enablePanels();
|
||||
}
|
||||
|
||||
void PrintDialogPanel::deletePrinter()
|
||||
{
|
||||
m_printer.reset();
|
||||
enablePanels();
|
||||
}
|
||||
|
||||
QSizeF PrintDialogPanel::customPageSize() const
|
||||
{
|
||||
return QSizeF(m_panel.m_pageWidth->value(), m_panel.m_pageHeight->value());
|
||||
}
|
||||
|
||||
// Apply the settings to the QPrinter
|
||||
void PrintDialogPanel::applySettings(QPrinter *printer) const
|
||||
{
|
||||
const int currentIndex = m_panel.m_printerCombo->currentIndex();
|
||||
QString printerName = m_panel.m_printerCombo->itemData(currentIndex).toString();
|
||||
if (printerName == QLatin1String("PdfFormat"))
|
||||
printer->setOutputFileName(m_panel.m_fileName->text());
|
||||
else
|
||||
printer->setPrinterName(printerName);
|
||||
printer->setPrintRange(comboBoxValue<QPrinter::PrintRange>(m_panel.m_printRangeCombo));
|
||||
printer->setFromTo(m_panel.m_fromPage->value(), m_panel.m_toPage->value());
|
||||
printer->setPageOrder(comboBoxValue<QPrinter::PageOrder>(m_panel.m_pageOrderCombo));
|
||||
printer->setCopyCount(m_panel.m_copyCount->value());
|
||||
printer->setCollateCopies(m_panel.m_collateCopies->isChecked());
|
||||
printer->setDuplex(comboBoxValue<QPrinter::DuplexMode>(m_panel.m_duplexModeCombo));
|
||||
printer->setPaperSource(comboBoxValue<QPrinter::PaperSource>(m_panel.m_paperSourceCombo));
|
||||
printer->setColorMode(comboBoxValue<QPrinter::ColorMode>(m_panel.m_colorModeCombo));
|
||||
printer->setResolution(m_panel.m_resolution->value());
|
||||
|
||||
printer->setPageLayout(m_pageLayout);
|
||||
}
|
||||
|
||||
// Retrieve the settings from the QPrinter
|
||||
void PrintDialogPanel::retrieveSettings(const QPrinter *printer)
|
||||
{
|
||||
if (printer->outputFormat() == QPrinter::NativeFormat) {
|
||||
m_panel.m_printerCombo->setCurrentIndex(m_panel.m_printerCombo->findData(QVariant(printer->printerName())));
|
||||
m_panel.m_fileName->setEnabled(false);
|
||||
} else {
|
||||
m_panel.m_printerCombo->setCurrentIndex(m_panel.m_printerCombo->findData(QVariant(QLatin1String("PdfFormat"))));
|
||||
m_panel.m_fileName->setEnabled(true);
|
||||
}
|
||||
m_panel.m_fileName->setText(printer->outputFileName());
|
||||
setComboBoxValue(m_panel.m_printRangeCombo, printer->printRange());
|
||||
m_panel.m_fromPage->setValue(printer->fromPage());
|
||||
m_panel.m_toPage->setValue(printer->toPage());
|
||||
setComboBoxValue(m_panel.m_pageOrderCombo, printer->pageOrder());
|
||||
m_panel.m_copyCount->setValue(printer->copyCount());
|
||||
m_panel.m_collateCopies->setChecked(printer->collateCopies());
|
||||
setComboBoxValue(m_panel.m_duplexModeCombo, printer->duplex());
|
||||
setComboBoxValue(m_panel.m_paperSourceCombo, printer->paperSource());
|
||||
setComboBoxValue(m_panel.m_colorModeCombo, printer->colorMode());
|
||||
m_panel.m_resolution->setValue(printer->resolution());
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QString availPaperSources;
|
||||
foreach (QPrinter::PaperSource ps, printer->supportedPaperSources())
|
||||
availPaperSources += QString::number(int(ps)) + QLatin1Char(' ');
|
||||
m_panel.availPaperSourceLabel->setText(availPaperSources);
|
||||
#else
|
||||
m_panel.availPaperSourceLabel->setText(QLatin1String("N/A"));
|
||||
#endif
|
||||
|
||||
m_pageLayout = printer->pageLayout();
|
||||
updatePageLayoutWidgets();
|
||||
}
|
||||
|
||||
void PrintDialogPanel::updatePageLayoutWidgets()
|
||||
{
|
||||
m_blockSignals = true;
|
||||
setComboBoxValue(m_panel.m_unitsCombo, m_pageLayout.units());
|
||||
setComboBoxValue(m_panel.m_pageSizeCombo, m_pageLayout.pageSize().id());
|
||||
QSizeF sizef = m_pageLayout.pageSize().size(QPageSize::Unit(m_pageLayout.units()));
|
||||
bool custom = (m_pageLayout.pageSize().id() == QPageSize::Custom);
|
||||
setComboBoxValue(m_panel.m_orientationCombo, m_pageLayout.orientation());
|
||||
m_panel.m_leftMargin->setValue(m_pageLayout.margins().left());
|
||||
m_panel.m_topMargin->setValue(m_pageLayout.margins().top());
|
||||
m_panel.m_rightMargin->setValue(m_pageLayout.margins().right());
|
||||
m_panel.m_bottomMargin->setValue(m_pageLayout.margins().bottom());
|
||||
setComboBoxValue(m_panel.m_layoutModeCombo, m_pageLayout.mode());
|
||||
QRectF rectf = m_pageLayout.paintRect();
|
||||
|
||||
m_panel.m_pageWidth->setValue(sizef.width());
|
||||
m_panel.m_pageHeight->setValue(sizef.height());
|
||||
m_panel.m_pageWidth->setEnabled(custom);
|
||||
m_panel.m_pageHeight->setEnabled(custom);
|
||||
m_panel.m_rectX->setValue(rectf.x());
|
||||
m_panel.m_rectY->setValue(rectf.y());
|
||||
m_panel.m_rectWidth->setValue(rectf.width());
|
||||
m_panel.m_rectHeight->setValue(rectf.height());
|
||||
QString suffix;
|
||||
switch (comboBoxValue<QPageLayout::Unit>(m_panel.m_unitsCombo)) {
|
||||
case QPageLayout::Millimeter:
|
||||
suffix = tr(" mm");
|
||||
break;
|
||||
case QPageLayout::Point:
|
||||
suffix = tr(" pt");
|
||||
break;
|
||||
case QPageLayout::Inch:
|
||||
suffix = tr(" in");
|
||||
break;
|
||||
case QPageLayout::Pica:
|
||||
suffix = tr(" pc");
|
||||
break;
|
||||
case QPageLayout::Didot:
|
||||
suffix = tr(" DD");
|
||||
break;
|
||||
case QPageLayout::Cicero:
|
||||
suffix = tr(" CC");
|
||||
break;
|
||||
}
|
||||
m_panel.m_pageWidth->setSuffix(suffix);
|
||||
m_panel.m_pageHeight->setSuffix(suffix);
|
||||
m_panel.m_leftMargin->setSuffix(suffix);
|
||||
m_panel.m_topMargin->setSuffix(suffix);
|
||||
m_panel.m_rightMargin->setSuffix(suffix);
|
||||
m_panel.m_bottomMargin->setSuffix(suffix);
|
||||
m_panel.m_rectX->setSuffix(suffix);
|
||||
m_panel.m_rectY->setSuffix(suffix);
|
||||
m_panel.m_rectWidth->setSuffix(suffix);
|
||||
m_panel.m_rectHeight->setSuffix(suffix);
|
||||
m_blockSignals = false;
|
||||
}
|
||||
|
||||
void PrintDialogPanel::unitsChanged()
|
||||
{
|
||||
if (m_blockSignals)
|
||||
return;
|
||||
m_pageLayout.setUnits(comboBoxValue<QPageLayout::Unit>(m_panel.m_unitsCombo));
|
||||
updatePageLayoutWidgets();
|
||||
}
|
||||
|
||||
void PrintDialogPanel::pageSizeChanged()
|
||||
{
|
||||
if (m_blockSignals)
|
||||
return;
|
||||
const QPageSize::PageSizeId pageSizeId = comboBoxValue<QPageSize::PageSizeId>(m_panel.m_pageSizeCombo);
|
||||
QPageSize pageSize;
|
||||
if (pageSizeId == QPageSize::Custom)
|
||||
pageSize = QPageSize(QSizeF(200, 200), QPageSize::Unit(m_pageLayout.units()));
|
||||
else
|
||||
pageSize = QPageSize(pageSizeId);
|
||||
m_pageLayout.setPageSize(pageSize);
|
||||
updatePageLayoutWidgets();
|
||||
}
|
||||
|
||||
void PrintDialogPanel::pageDimensionsChanged()
|
||||
{
|
||||
if (m_blockSignals)
|
||||
return;
|
||||
m_pageLayout.setPageSize(QPageSize(customPageSize(), QPageSize::Unit(m_pageLayout.units())));
|
||||
updatePageLayoutWidgets();
|
||||
}
|
||||
|
||||
void PrintDialogPanel::orientationChanged()
|
||||
{
|
||||
if (m_blockSignals)
|
||||
return;
|
||||
m_pageLayout.setOrientation(comboBoxValue<QPageLayout::Orientation>(m_panel.m_orientationCombo));
|
||||
updatePageLayoutWidgets();
|
||||
}
|
||||
|
||||
void PrintDialogPanel::marginsChanged()
|
||||
{
|
||||
if (m_blockSignals)
|
||||
return;
|
||||
m_pageLayout.setMargins(QMarginsF(m_panel.m_leftMargin->value(), m_panel.m_topMargin->value(),
|
||||
m_panel.m_rightMargin->value(), m_panel.m_bottomMargin->value()));
|
||||
updatePageLayoutWidgets();
|
||||
}
|
||||
|
||||
void PrintDialogPanel::layoutModeChanged()
|
||||
{
|
||||
if (m_blockSignals)
|
||||
return;
|
||||
m_pageLayout.setMode(comboBoxValue<QPageLayout::Mode>(m_panel.m_layoutModeCombo));
|
||||
updatePageLayoutWidgets();
|
||||
}
|
||||
|
||||
void PrintDialogPanel::printerChanged()
|
||||
{
|
||||
const int currentIndex = m_panel.m_printerCombo->currentIndex();
|
||||
const bool isPdf = (m_panel.m_printerCombo->itemData(currentIndex).toString() == QLatin1String("PdfFormat"));
|
||||
m_panel.m_fileName->setEnabled(isPdf);
|
||||
if (isPdf && m_panel.m_fileName->text().isEmpty())
|
||||
m_panel.m_fileName->setText(QDir::homePath() + QDir::separator() + QLatin1String("print.pdf"));
|
||||
}
|
||||
|
||||
void PrintDialogPanel::showPrintDialog()
|
||||
{
|
||||
applySettings(m_printer.data());
|
||||
QPrintDialog dialog(m_printer.data(), this);
|
||||
dialog.setOptions(m_panel.m_dialogOptionsGroupBox->value<QPrintDialog::PrintDialogOptions>());
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
retrieveSettings(m_printer.data());
|
||||
print(m_printer.data(), this);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintDialogPanel::showPreviewDialog()
|
||||
{
|
||||
applySettings(m_printer.data());
|
||||
PrintPreviewDialog dialog(m_printer.data(), this);
|
||||
const QSize availableSize = screen()->availableSize();
|
||||
dialog.resize(availableSize * 4/ 5);
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
retrieveSettings(m_printer.data());
|
||||
}
|
||||
|
||||
void PrintDialogPanel::showPageSetupDialog()
|
||||
{
|
||||
applySettings(m_printer.data());
|
||||
QPageSetupDialog dialog(m_printer.data(), this);
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
retrieveSettings(m_printer.data());
|
||||
}
|
||||
|
||||
void PrintDialogPanel::directPrint()
|
||||
{
|
||||
applySettings(m_printer.data());
|
||||
print(m_printer.data(), this);
|
||||
retrieveSettings(m_printer.data());
|
||||
}
|
||||
|
||||
#include "moc_printdialogpanel.cpp"
|
||||
#include "printdialogpanel.moc"
|
||||
|
||||
#endif // !QT_NO_PRINTER
|
63
tests/manual/dialogs/printdialogpanel.h
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef PRINTDIALOGPANEL_H
|
||||
#define PRINTDIALOGPANEL_H
|
||||
|
||||
#ifndef QT_NO_PRINTER
|
||||
|
||||
#include "ui_printdialogpanel.h"
|
||||
|
||||
#include <QPageLayout>
|
||||
#include <QPrinter>
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QPrinter;
|
||||
class QComboBox;
|
||||
class QGroupBox;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class PageSizeControl;
|
||||
class OptionsControl;
|
||||
|
||||
class PrintDialogPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PrintDialogPanel(QWidget *parent = nullptr);
|
||||
~PrintDialogPanel();
|
||||
|
||||
private slots:
|
||||
void createPrinter();
|
||||
void deletePrinter();
|
||||
void showPrintDialog();
|
||||
void showPreviewDialog();
|
||||
void showPageSetupDialog();
|
||||
void directPrint();
|
||||
void unitsChanged();
|
||||
void pageSizeChanged();
|
||||
void pageDimensionsChanged();
|
||||
void orientationChanged();
|
||||
void marginsChanged();
|
||||
void layoutModeChanged();
|
||||
void printerChanged();
|
||||
|
||||
private:
|
||||
QSizeF customPageSize() const;
|
||||
void applySettings(QPrinter *printer) const;
|
||||
void retrieveSettings(const QPrinter *printer);
|
||||
void updatePageLayoutWidgets();
|
||||
void enablePanels();
|
||||
|
||||
bool m_blockSignals;
|
||||
Ui::PrintDialogPanel m_panel;
|
||||
|
||||
QPageLayout m_pageLayout;
|
||||
QScopedPointer<QPrinter> m_printer;
|
||||
};
|
||||
|
||||
#endif // !QT_NO_PRINTER
|
||||
#endif // PRINTDIALOGPANEL_H
|
694
tests/manual/dialogs/printdialogpanel.ui
Normal file
@ -0,0 +1,694 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PrintDialogPanel</class>
|
||||
<widget class="QWidget" name="PrintDialogPanel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>650</width>
|
||||
<height>707</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_createGroupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Create</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Printer Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="m_printerModeCombo"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_createButton">
|
||||
<property name="text">
|
||||
<string>Create</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_deleteButton">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_pageLayoutGroupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Page Layout</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Units:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="m_unitsCombo"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Page Size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="m_pageSizeCombo"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_pageWidth">
|
||||
<property name="suffix">
|
||||
<string> mm</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>x</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_pageHeight">
|
||||
<property name="suffix">
|
||||
<string> mm</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Orientation:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="m_orientationCombo"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Margins:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_leftMargin">
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>l</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_rightMargin">
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>t</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_topMargin">
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>r</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_bottomMargin">
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>b</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Layout Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="m_layoutModeCombo"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Paint Rect:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_rectX">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::NoButtons</enum>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> mm</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>x</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_rectY">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::NoButtons</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>y</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_rectWidth">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::NoButtons</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>w</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_rectHeight">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::NoButtons</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>h</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_printJobGroupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Print Job</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>Printer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="m_printerCombo"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>File Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="m_fileName"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Print Range:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="m_printRangeCombo"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="text">
|
||||
<string>Page Range:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="m_fromPage">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="text">
|
||||
<string>to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="m_toPage">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>Copies:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="m_copyCount">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_collateCopies">
|
||||
<property name="text">
|
||||
<string>Collate Copies</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="text">
|
||||
<string>Duplex Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="m_duplexModeCombo"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_27">
|
||||
<property name="text">
|
||||
<string>Paper Source:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QComboBox" name="m_paperSourceCombo"/>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_23">
|
||||
<property name="text">
|
||||
<string>Color Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QComboBox" name="m_colorModeCombo"/>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_28">
|
||||
<property name="text">
|
||||
<string>Resolution:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="m_resolution">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="text">
|
||||
<string>Page Order:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="m_pageOrderCombo"/>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="availPaperSourceDescLabel">
|
||||
<property name="text">
|
||||
<string>Available Paper Sources:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="availPaperSourceLabel"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_dialogsGroupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Dialogs</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="OptionsControl" name="m_dialogOptionsGroupBox">
|
||||
<property name="title">
|
||||
<string>Options</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_printButton">
|
||||
<property name="text">
|
||||
<string>Print...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_printPreviewButton">
|
||||
<property name="text">
|
||||
<string>Preview...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_pageSetupButton">
|
||||
<property name="text">
|
||||
<string>Page Setup...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_directPrintButton">
|
||||
<property name="text">
|
||||
<string>Direct Print</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>OptionsControl</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header>utils.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
105
tests/manual/dialogs/utils.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QGridLayout>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
QComboBox *createCombo(QWidget *parent, const FlagData *d, size_t size)
|
||||
{
|
||||
QComboBox *c = new QComboBox(parent);
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c->addItem(QLatin1String(d[i].description), QVariant(d[i].value));
|
||||
return c;
|
||||
}
|
||||
|
||||
void populateCombo(QComboBox *combo, const FlagData *d, size_t size)
|
||||
{
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
combo->addItem(QLatin1String(d[i].description), QVariant(d[i].value));
|
||||
}
|
||||
|
||||
void setComboBoxValue(QComboBox *c, int v)
|
||||
{
|
||||
c->setCurrentIndex(c->findData(QVariant(v)));
|
||||
}
|
||||
|
||||
OptionsControl::OptionsControl(QWidget *parent)
|
||||
: QGroupBox(parent)
|
||||
{
|
||||
setLayout(new QVBoxLayout(this));
|
||||
}
|
||||
|
||||
OptionsControl::OptionsControl(const QString &title, const FlagData *data, size_t count, QWidget *parent)
|
||||
: QGroupBox(title, parent)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
QCheckBox *box = new QCheckBox(QString::fromLatin1(data[i].description));
|
||||
m_checkBoxes.push_back(CheckBoxFlagPair(box, data[i].value));
|
||||
layout->addWidget(box);
|
||||
}
|
||||
}
|
||||
|
||||
void OptionsControl::populateOptions(const FlagData *data, size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
QCheckBox *box = new QCheckBox(QString::fromLatin1(data[i].description));
|
||||
m_checkBoxes.push_back(CheckBoxFlagPair(box, data[i].value));
|
||||
layout()->addWidget(box);
|
||||
}
|
||||
}
|
||||
|
||||
void OptionsControl::setValue(int flags)
|
||||
{
|
||||
foreach (const CheckBoxFlagPair &cf, m_checkBoxes)
|
||||
cf.first->setChecked(cf.second & flags);
|
||||
}
|
||||
|
||||
int OptionsControl::intValue() const
|
||||
{
|
||||
int result = 0;
|
||||
foreach (const CheckBoxFlagPair &cf, m_checkBoxes) {
|
||||
if (cf.first->isChecked())
|
||||
result |= cf.second;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QPushButton *addButton(const QString &description, QGridLayout *layout, int &row, int column,
|
||||
QObject *receiver, const char *slotFunc)
|
||||
{
|
||||
QPushButton *button = new QPushButton(description);
|
||||
QObject::connect(button, SIGNAL(clicked()), receiver, slotFunc);
|
||||
layout->addWidget(button, row++, column);
|
||||
return button;
|
||||
}
|
||||
|
||||
QPushButton *addButton(const QString &description, QGridLayout *layout, int &row, int column,
|
||||
std::function<void()> fn)
|
||||
{
|
||||
QPushButton *button = new QPushButton(description);
|
||||
QObject::connect(button, &QPushButton::clicked, fn);
|
||||
layout->addWidget(button, row++, column);
|
||||
return button;
|
||||
}
|
||||
|
||||
QPushButton *addButton(const QString &description, QVBoxLayout *layout, QObject *receiver,
|
||||
const char *slotFunc)
|
||||
{
|
||||
QPushButton *button = new QPushButton(description);
|
||||
QObject::connect(button, SIGNAL(clicked()), receiver, slotFunc);
|
||||
layout->addWidget(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
QPushButton *addButton(const QString &description, QVBoxLayout *layout, std::function<void()> fn)
|
||||
{
|
||||
QPushButton *button = new QPushButton(description);
|
||||
QObject::connect(button, &QPushButton::clicked, fn);
|
||||
layout->addWidget(button);
|
||||
return button;
|
||||
}
|
70
tests/manual/dialogs/utils.h
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QGroupBox>
|
||||
#include <QVariant>
|
||||
#include <QPair>
|
||||
#include <QList>
|
||||
|
||||
#include <functional>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QCheckBox)
|
||||
QT_FORWARD_DECLARE_CLASS(QGridLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||
|
||||
// Associate enum/flag value with a description.
|
||||
struct FlagData
|
||||
{
|
||||
const char *description;
|
||||
int value;
|
||||
};
|
||||
|
||||
// Helpers for creating combo boxes representing enumeration values from flag data.
|
||||
QComboBox *createCombo(QWidget *parent, const FlagData *d, size_t size);
|
||||
void populateCombo(QComboBox *combo, const FlagData *d, size_t size);
|
||||
|
||||
template <class Enum>
|
||||
Enum comboBoxValue(const QComboBox *c)
|
||||
{
|
||||
return static_cast<Enum>(c->itemData(c->currentIndex()).toInt());
|
||||
}
|
||||
|
||||
void setComboBoxValue(QComboBox *c, int v);
|
||||
|
||||
// A group box with check boxes for option flags.
|
||||
class OptionsControl : public QGroupBox {
|
||||
public:
|
||||
OptionsControl(QWidget *parent);
|
||||
explicit OptionsControl(const QString &title, const FlagData *data, size_t count, QWidget *parent);
|
||||
|
||||
void populateOptions(const FlagData *data, size_t count);
|
||||
|
||||
void setValue(int flags);
|
||||
template <class Enum>
|
||||
Enum value() const { return static_cast<Enum>(intValue()); }
|
||||
|
||||
private:
|
||||
typedef QPair<QCheckBox *, int> CheckBoxFlagPair;
|
||||
|
||||
int intValue() const;
|
||||
|
||||
QList<CheckBoxFlagPair> m_checkBoxes;
|
||||
};
|
||||
|
||||
QPushButton *addButton(const QString &description, QGridLayout *layout, int &row, int column,
|
||||
QObject *receiver, const char *slotFunc);
|
||||
|
||||
QPushButton *addButton(const QString &description, QGridLayout *layout, int &row, int column,
|
||||
std::function<void()> fn);
|
||||
|
||||
QPushButton *addButton(const QString &description, QVBoxLayout *layout, QObject *receiver,
|
||||
const char *slotFunc);
|
||||
|
||||
QPushButton *addButton(const QString &description, QVBoxLayout *layout, std::function<void()> fn);
|
||||
|
||||
#endif // UTILS_H
|
339
tests/manual/dialogs/wizardpanel.cpp
Normal file
@ -0,0 +1,339 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "wizardpanel.h"
|
||||
|
||||
#include <QWizard>
|
||||
#include <QWizardPage>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QRadioButton>
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
#include <QButtonGroup>
|
||||
#include <QSpacerItem>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QStyle>
|
||||
#include <QIcon>
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QHash>
|
||||
|
||||
static QIcon coloredIcon(const Qt::GlobalColor color)
|
||||
{
|
||||
QImage image(QSize(24, 24), QImage::Format_RGB32);
|
||||
image.fill(color);
|
||||
return QIcon(QPixmap::fromImage(image));
|
||||
}
|
||||
|
||||
static QPixmap pixmapWithText(const QString &text, const QColor color)
|
||||
{
|
||||
QFont font;
|
||||
QFontMetrics metric(font);
|
||||
QRect rectangle = metric.boundingRect(text);
|
||||
rectangle.setBottomRight(rectangle.bottomRight() + QPoint(20, 20));
|
||||
QImage image(rectangle.size(), QImage::Format_RGB32);
|
||||
image.fill(color);
|
||||
QPainter painter(&image);
|
||||
painter.setFont(font);
|
||||
painter.drawText(rectangle, Qt::AlignHCenter | Qt::AlignVCenter, text);
|
||||
return QPixmap::fromImage(image);
|
||||
}
|
||||
|
||||
// A radio-group control for QWizard::WizardStyle.
|
||||
class WizardStyleControl : public QGroupBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WizardStyleControl(QWidget *parent = nullptr);
|
||||
|
||||
void setWizardStyle(int style);
|
||||
QWizard::WizardStyle wizardStyle() const;
|
||||
|
||||
signals:
|
||||
void wizardStyleChanged(int);
|
||||
|
||||
private:
|
||||
QButtonGroup *m_group;
|
||||
};
|
||||
|
||||
WizardStyleControl::WizardStyleControl(QWidget *parent)
|
||||
: QGroupBox(tr("Style"), parent)
|
||||
, m_group(new QButtonGroup(this))
|
||||
{
|
||||
m_group->setExclusive(true);
|
||||
connect(m_group, &QButtonGroup::idClicked, this, &WizardStyleControl::wizardStyleChanged);
|
||||
QVBoxLayout *vLayout = new QVBoxLayout(this);
|
||||
QRadioButton *radioButton = new QRadioButton(tr("None/OS Default"), this);
|
||||
m_group->addButton(radioButton, QWizard::NStyles);
|
||||
vLayout->addWidget(radioButton);
|
||||
radioButton = new QRadioButton(tr("ClassicStyle"), this);
|
||||
m_group->addButton(radioButton, QWizard::ClassicStyle);
|
||||
vLayout->addWidget(radioButton);
|
||||
radioButton = new QRadioButton(tr("ModernStyle"), this);
|
||||
m_group->addButton(radioButton, QWizard::ModernStyle);
|
||||
vLayout->addWidget(radioButton);
|
||||
radioButton = new QRadioButton(tr("MacStyle"), this);
|
||||
m_group->addButton(radioButton, QWizard::MacStyle);
|
||||
vLayout->addWidget(radioButton);
|
||||
radioButton = new QRadioButton(tr("AeroStyle"), this);
|
||||
m_group->addButton(radioButton, QWizard::AeroStyle);
|
||||
vLayout->addWidget(radioButton);
|
||||
vLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
|
||||
|
||||
setWizardStyle(style()->styleHint(QStyle::SH_WizardStyle));
|
||||
}
|
||||
|
||||
QWizard::WizardStyle WizardStyleControl::wizardStyle() const
|
||||
{
|
||||
return static_cast<QWizard::WizardStyle>(m_group->checkedId());
|
||||
}
|
||||
|
||||
void WizardStyleControl::setWizardStyle(int wizardStyle)
|
||||
{
|
||||
if (wizardStyle < 0 || wizardStyle > QWizard::NStyles)
|
||||
wizardStyle = QWizard::NStyles;
|
||||
QAbstractButton *button = m_group->button(wizardStyle);
|
||||
Q_ASSERT(button);
|
||||
const bool blocked = m_group->blockSignals(true);
|
||||
button->setChecked(true);
|
||||
m_group->blockSignals(blocked);
|
||||
}
|
||||
|
||||
// A control with checkboxes for QWizard::WizardOption.
|
||||
class WizardOptionsControl : public QGroupBox
|
||||
{
|
||||
public:
|
||||
explicit WizardOptionsControl(QWidget *parent = nullptr);
|
||||
|
||||
QWizard::WizardOption wizardOptions() const;
|
||||
void setWizardOptions(int options);
|
||||
|
||||
private:
|
||||
typedef QHash<int, QCheckBox *> CheckBoxHash;
|
||||
|
||||
void addCheckBox(QVBoxLayout *layout, int flag, const QString &title);
|
||||
|
||||
CheckBoxHash m_checkBoxes;
|
||||
};
|
||||
|
||||
WizardOptionsControl::WizardOptionsControl(QWidget *parent)
|
||||
: QGroupBox(tr("Options"), parent)
|
||||
{
|
||||
QVBoxLayout *vLayout = new QVBoxLayout(this);
|
||||
addCheckBox(vLayout, QWizard::IndependentPages, QLatin1String("IndependentPages"));
|
||||
addCheckBox(vLayout, QWizard::IgnoreSubTitles, QLatin1String("IgnoreSubTitles"));
|
||||
addCheckBox(vLayout, QWizard::ExtendedWatermarkPixmap, QLatin1String("ExtendedWatermarkPixmap"));
|
||||
addCheckBox(vLayout, QWizard::NoDefaultButton, QLatin1String("NoDefaultButton"));
|
||||
addCheckBox(vLayout, QWizard::NoBackButtonOnStartPage, QLatin1String("NoBackButtonOnStartPage"));
|
||||
addCheckBox(vLayout, QWizard::NoBackButtonOnLastPage, QLatin1String("NoBackButtonOnLastPage"));
|
||||
addCheckBox(vLayout, QWizard::DisabledBackButtonOnLastPage, QLatin1String("DisabledBackButtonOnLastPage"));
|
||||
addCheckBox(vLayout, QWizard::HaveNextButtonOnLastPage, QLatin1String("HaveNextButtonOnLastPage"));
|
||||
addCheckBox(vLayout, QWizard::HaveFinishButtonOnEarlyPages, QLatin1String("HaveFinishButtonOnEarlyPages"));
|
||||
addCheckBox(vLayout, QWizard::NoCancelButton, QLatin1String("NoCancelButton"));
|
||||
addCheckBox(vLayout, QWizard::CancelButtonOnLeft, QLatin1String("CancelButtonOnLeft"));
|
||||
addCheckBox(vLayout, QWizard::HaveHelpButton, QLatin1String("HaveHelpButton"));
|
||||
addCheckBox(vLayout, QWizard::HelpButtonOnRight, QLatin1String("HelpButtonOnRight"));
|
||||
addCheckBox(vLayout, QWizard::HaveCustomButton1, QLatin1String("HaveCustomButton1"));
|
||||
addCheckBox(vLayout, QWizard::HaveCustomButton2, QLatin1String("HaveCustomButton2"));
|
||||
addCheckBox(vLayout, QWizard::HaveCustomButton3, QLatin1String("HaveCustomButton3"));
|
||||
vLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
|
||||
}
|
||||
|
||||
void WizardOptionsControl::addCheckBox(QVBoxLayout *layout, int flag, const QString &title)
|
||||
{
|
||||
QCheckBox *checkBox = new QCheckBox(title, this);
|
||||
layout->addWidget(checkBox);
|
||||
m_checkBoxes.insert(flag, checkBox);
|
||||
}
|
||||
|
||||
QWizard::WizardOption WizardOptionsControl::wizardOptions() const
|
||||
{
|
||||
int result = 0;
|
||||
typedef CheckBoxHash::const_iterator ConstIterator;
|
||||
const ConstIterator cend = m_checkBoxes.constEnd();
|
||||
for (ConstIterator it = m_checkBoxes.constBegin(); it != cend; ++it)
|
||||
if (it.value()->isChecked())
|
||||
result |= it.key();
|
||||
return static_cast<QWizard::WizardOption>(result);
|
||||
}
|
||||
|
||||
void WizardOptionsControl::setWizardOptions(int options)
|
||||
{
|
||||
typedef CheckBoxHash::iterator Iterator;
|
||||
const Iterator end = m_checkBoxes.end();
|
||||
for (Iterator it = m_checkBoxes.begin(); it != end; ++it)
|
||||
it.value()->setChecked(options & it.key());
|
||||
}
|
||||
|
||||
// A test wizard with a slot to change its style.
|
||||
class Wizard : public QWizard {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Wizard(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
|
||||
|
||||
public slots:
|
||||
void changeWizardStyle(int newStyle);
|
||||
};
|
||||
|
||||
void Wizard::changeWizardStyle(int newStyle)
|
||||
{
|
||||
if (newStyle >= 0 && newStyle < int(QWizard::NStyles))
|
||||
setWizardStyle(static_cast<QWizard::WizardStyle>(newStyle));
|
||||
}
|
||||
|
||||
// A test wizard page with a WizardStyleControl.
|
||||
class WizardPage : public QWizardPage
|
||||
{
|
||||
public:
|
||||
explicit WizardPage(const QString &title, QWidget *parent = nullptr);
|
||||
|
||||
void initializePage();
|
||||
|
||||
private:
|
||||
WizardStyleControl *m_styleControl;
|
||||
bool m_firstTimeShown;
|
||||
};
|
||||
|
||||
WizardPage::WizardPage(const QString &title, QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
, m_styleControl(new WizardStyleControl(this))
|
||||
, m_firstTimeShown(true)
|
||||
{
|
||||
setTitle(title);
|
||||
setSubTitle(title + QLatin1String(" SubTitle"));
|
||||
QVBoxLayout *vLayout = new QVBoxLayout(this);
|
||||
vLayout->addWidget(m_styleControl);
|
||||
}
|
||||
|
||||
void WizardPage::initializePage()
|
||||
{
|
||||
m_styleControl->setWizardStyle(wizard()->wizardStyle());
|
||||
if (m_firstTimeShown) {
|
||||
m_firstTimeShown = false;
|
||||
connect(m_styleControl, SIGNAL(wizardStyleChanged(int)),
|
||||
wizard(), SLOT(changeWizardStyle(int)));
|
||||
}
|
||||
}
|
||||
|
||||
Wizard::Wizard(QWidget *parent, Qt::WindowFlags flags)
|
||||
: QWizard(parent, flags)
|
||||
{
|
||||
setWindowIcon(coloredIcon(Qt::red));
|
||||
setWindowTitle(QLatin1String("Wizard ") + QLatin1String(QT_VERSION_STR));
|
||||
addPage(new WizardPage(tr("Page 1"), this));
|
||||
addPage(new WizardPage(tr("Page 2"), this));
|
||||
addPage(new WizardPage(tr("Page 3"), this));
|
||||
}
|
||||
|
||||
// A dialog using a Wizard as child widget (emulating Qt Designer).
|
||||
class WizardEmbeddingDialog : public QDialog {
|
||||
public:
|
||||
explicit WizardEmbeddingDialog(QWidget *parent = nullptr);
|
||||
|
||||
Wizard *wizard() const { return m_wizard; }
|
||||
|
||||
private:
|
||||
Wizard *m_wizard;
|
||||
};
|
||||
|
||||
WizardEmbeddingDialog::WizardEmbeddingDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_wizard(new Wizard)
|
||||
{
|
||||
setWindowTitle(QString::fromLatin1("Dialog Embedding QWizard %1").arg(QT_VERSION_STR));
|
||||
QGridLayout *gridLayout = new QGridLayout(this);
|
||||
gridLayout->addWidget(new QLabel(tr("Above wizard")), 0, 0, 1, 3);
|
||||
gridLayout->addWidget(new QLabel(tr("Left of wizard")), 1, 0);
|
||||
m_wizard->setObjectName(QLatin1String("EmbeddedWizard"));
|
||||
m_wizard->setParent(this, Qt::Widget);
|
||||
gridLayout->addWidget(m_wizard, 1, 1);
|
||||
gridLayout->addWidget(new QLabel(tr("Right of wizard")), 1, 2);
|
||||
gridLayout->addWidget(new QLabel(tr("Below wizard")), 2, 0, 1, 3);
|
||||
}
|
||||
|
||||
WizardPanel::WizardPanel(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_styleControl(new WizardStyleControl(this))
|
||||
, m_optionsControl(new WizardOptionsControl(this))
|
||||
{
|
||||
{
|
||||
QWizard wizard;
|
||||
m_optionsControl->setWizardOptions(wizard.options());
|
||||
m_styleControl->setWizardStyle(wizard.wizardStyle());
|
||||
}
|
||||
|
||||
QGridLayout *gridLayout = new QGridLayout(this);
|
||||
gridLayout->addWidget(m_optionsControl, 0, 0, 2, 1);
|
||||
gridLayout->addWidget(m_styleControl, 0, 1);
|
||||
QGroupBox *buttonGroupBox = new QGroupBox(this);
|
||||
QVBoxLayout *vLayout = new QVBoxLayout(buttonGroupBox);
|
||||
QPushButton *button = new QPushButton(tr("Exec modal"), this);
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(execModal()));
|
||||
vLayout->addWidget(button);
|
||||
button = new QPushButton(tr("Show application modal"), this);
|
||||
connect(button, &QPushButton::clicked, [this]() { showModal(Qt::ApplicationModal); });
|
||||
vLayout->addWidget(button);
|
||||
button = new QPushButton(tr("Show window modal"), this);
|
||||
connect(button, &QPushButton::clicked, [this]() { showModal(Qt::WindowModal); });
|
||||
vLayout->addWidget(button);
|
||||
button = new QPushButton(tr("Show non-modal"), this);
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(showNonModal()));
|
||||
vLayout->addWidget(button);
|
||||
button = new QPushButton(tr("Show embedded"), this);
|
||||
button->setToolTip(tr("Test QWizard's behavior when used as a widget child."));
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(showEmbedded()));
|
||||
vLayout->addWidget(button);
|
||||
vLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
|
||||
gridLayout->addWidget(buttonGroupBox, 1, 1);
|
||||
}
|
||||
|
||||
void WizardPanel::execModal()
|
||||
{
|
||||
Wizard wizard(this);
|
||||
applyParameters(&wizard);
|
||||
wizard.exec();
|
||||
}
|
||||
|
||||
void WizardPanel::showModal(Qt::WindowModality modality)
|
||||
{
|
||||
Wizard *wizard = new Wizard(this);
|
||||
applyParameters(wizard);
|
||||
wizard->setModal(true);
|
||||
wizard->setAttribute(Qt::WA_DeleteOnClose);
|
||||
wizard->setWindowModality(modality);
|
||||
wizard->show();
|
||||
}
|
||||
|
||||
void WizardPanel::showNonModal()
|
||||
{
|
||||
Wizard *wizard = new Wizard(this);
|
||||
applyParameters(wizard);
|
||||
wizard->setModal(false);
|
||||
wizard->setAttribute(Qt::WA_DeleteOnClose);
|
||||
wizard->show();
|
||||
}
|
||||
|
||||
void WizardPanel::showEmbedded()
|
||||
{
|
||||
WizardEmbeddingDialog *dialog = new WizardEmbeddingDialog(this);
|
||||
applyParameters(dialog->wizard());
|
||||
dialog->setModal(false);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
void WizardPanel::applyParameters(QWizard *wizard) const
|
||||
{
|
||||
wizard->setWizardStyle(m_styleControl->wizardStyle());
|
||||
wizard->setOptions(m_optionsControl->wizardOptions());
|
||||
wizard->setPixmap(QWizard::WatermarkPixmap, pixmapWithText(QLatin1String("Watermark"), QColor(Qt::blue).lighter()));
|
||||
wizard->setPixmap(QWizard::LogoPixmap, pixmapWithText(QLatin1String("Logo"), Qt::green));
|
||||
wizard->setPixmap(QWizard::BannerPixmap, pixmapWithText(QLatin1String("Banner"), Qt::green));
|
||||
wizard->setPixmap(QWizard::BackgroundPixmap, pixmapWithText(QLatin1String("Background"), QColor(Qt::red).lighter()));
|
||||
}
|
||||
|
||||
#include "wizardpanel.moc"
|
34
tests/manual/dialogs/wizardpanel.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef WIZARDPANEL_H
|
||||
#define WIZARDPANEL_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class WizardStyleControl;
|
||||
class WizardOptionsControl;
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QWizard;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class WizardPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WizardPanel(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void execModal();
|
||||
void showModal(Qt::WindowModality modality);
|
||||
void showNonModal();
|
||||
void showEmbedded();
|
||||
|
||||
private:
|
||||
void applyParameters(QWizard *wizard) const;
|
||||
|
||||
WizardStyleControl *m_styleControl;
|
||||
WizardOptionsControl *m_optionsControl;
|
||||
};
|
||||
|
||||
#endif // WIZARDPANEL_H
|
56
tests/manual/embeddedintoforeignwindow/CMakeLists.txt
Normal file
@ -0,0 +1,56 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## embeddedintoforeignwindow Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(embeddedintoforeignwindow
|
||||
SOURCES
|
||||
../diaglib/eventfilter.cpp ../diaglib/eventfilter.h
|
||||
../diaglib/nativewindowdump.h
|
||||
../diaglib/qwindowdump.cpp ../diaglib/qwindowdump.h
|
||||
../diaglib/textdump.cpp ../diaglib/textdump.h
|
||||
itemwindow.cpp itemwindow.h
|
||||
main.cpp
|
||||
DEFINES
|
||||
QT_DIAG_LIB
|
||||
INCLUDE_DIRECTORIES
|
||||
../diaglib
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(embeddedintoforeignwindow CONDITION WIN32
|
||||
SOURCES
|
||||
../diaglib/nativewindowdump_win.cpp
|
||||
LIBRARIES
|
||||
user32
|
||||
)
|
||||
|
||||
qt_internal_extend_target(embeddedintoforeignwindow CONDITION UNIX
|
||||
SOURCES
|
||||
../diaglib/nativewindowdump.cpp
|
||||
)
|
||||
|
||||
qt_internal_extend_target(embeddedintoforeignwindow CONDITION QT_FEATURE_widgets
|
||||
SOURCES
|
||||
../diaglib/debugproxystyle.cpp ../diaglib/debugproxystyle.h
|
||||
../diaglib/logwidget.cpp ../diaglib/logwidget.h
|
||||
../diaglib/qwidgetdump.cpp ../diaglib/qwidgetdump.h
|
||||
LIBRARIES
|
||||
Qt::WidgetsPrivate
|
||||
)
|
||||
|
||||
qt_internal_extend_target(embeddedintoforeignwindow CONDITION QT_FEATURE_opengl
|
||||
SOURCES
|
||||
../diaglib/glinfo.cpp ../diaglib/glinfo.h
|
||||
LIBRARIES
|
||||
Qt::OpenGL
|
||||
Qt::OpenGLWidgets
|
||||
)
|
@ -0,0 +1,6 @@
|
||||
TEMPLATE = app
|
||||
QT += gui-private
|
||||
CONFIG += cmdline c++11
|
||||
SOURCES += main.cpp itemwindow.cpp
|
||||
HEADERS += itemwindow.h
|
||||
include(../diaglib/diaglib.pri)
|