diff options
Diffstat (limited to 'examples')
113 files changed, 2317 insertions, 1631 deletions
diff --git a/examples/opengl/hellogl2/mainwindow.cpp b/examples/opengl/hellogl2/mainwindow.cpp index 104cf24b37..b938300349 100644 --- a/examples/opengl/hellogl2/mainwindow.cpp +++ b/examples/opengl/hellogl2/mainwindow.cpp @@ -51,7 +51,7 @@ MainWindow::MainWindow() QAction *addNew = new QAction(menuWindow); addNew->setText(tr("Add new")); menuWindow->addAction(addNew); - connect(addNew, SIGNAL(triggered()), this, SLOT(onAddNew())); + connect(addNew, &QAction::triggered, this, &MainWindow::onAddNew); setMenuBar(menuBar); onAddNew(); diff --git a/examples/opengl/hellogl2/window.cpp b/examples/opengl/hellogl2/window.cpp index e60de3b05b..11a5ae68a9 100644 --- a/examples/opengl/hellogl2/window.cpp +++ b/examples/opengl/hellogl2/window.cpp @@ -59,12 +59,12 @@ Window::Window(MainWindow *mw) ySlider = createSlider(); zSlider = createSlider(); - connect(xSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setXRotation(int))); - connect(glWidget, SIGNAL(xRotationChanged(int)), xSlider, SLOT(setValue(int))); - connect(ySlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setYRotation(int))); - connect(glWidget, SIGNAL(yRotationChanged(int)), ySlider, SLOT(setValue(int))); - connect(zSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setZRotation(int))); - connect(glWidget, SIGNAL(zRotationChanged(int)), zSlider, SLOT(setValue(int))); + connect(xSlider, &QSlider::valueChanged, glWidget, &GLWidget::setXRotation); + connect(glWidget, &GLWidget::xRotationChanged, xSlider, &QSlider::setValue); + connect(ySlider, &QSlider::valueChanged, glWidget, &GLWidget::setYRotation); + connect(glWidget, &GLWidget::yRotationChanged, ySlider, &QSlider::setValue); + connect(zSlider, &QSlider::valueChanged, glWidget, &GLWidget::setZRotation); + connect(glWidget, &GLWidget::zRotationChanged, zSlider, &QSlider::setValue); QVBoxLayout *mainLayout = new QVBoxLayout; QHBoxLayout *container = new QHBoxLayout; @@ -77,7 +77,7 @@ Window::Window(MainWindow *mw) w->setLayout(container); mainLayout->addWidget(w); dockBtn = new QPushButton(tr("Undock"), this); - connect(dockBtn, SIGNAL(clicked()), this, SLOT(dockUndock())); + connect(dockBtn, &QPushButton::clicked, this, &Window::dockUndock); mainLayout->addWidget(dockBtn); setLayout(mainLayout); diff --git a/examples/opengl/hellogles3/glwindow.cpp b/examples/opengl/hellogles3/glwindow.cpp new file mode 100644 index 0000000000..ad654b854c --- /dev/null +++ b/examples/opengl/hellogles3/glwindow.cpp @@ -0,0 +1,281 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "glwindow.h" +#include <QImage> +#include <QOpenGLTexture> +#include <QOpenGLShaderProgram> +#include <QOpenGLBuffer> +#include <QOpenGLContext> +#include <QOpenGLVertexArrayObject> +#include <QOpenGLExtraFunctions> +#include <QPropertyAnimation> +#include <QPauseAnimation> +#include <QSequentialAnimationGroup> +#include <QTimer> + +GLWindow::GLWindow() + : m_texture(0), + m_program(0), + m_vbo(0), + m_vao(0), + m_target(0, 0, -1), + m_uniformsDirty(true), + m_r(0), + m_r2(0) +{ + m_world.setToIdentity(); + m_world.translate(0, 0, -1); + m_world.rotate(180, 1, 0, 0); + + QSequentialAnimationGroup *animGroup = new QSequentialAnimationGroup(this); + animGroup->setLoopCount(-1); + QPropertyAnimation *zAnim0 = new QPropertyAnimation(this, QByteArrayLiteral("z")); + zAnim0->setStartValue(1.5f); + zAnim0->setEndValue(10.0f); + zAnim0->setDuration(2000); + animGroup->addAnimation(zAnim0); + QPropertyAnimation *zAnim1 = new QPropertyAnimation(this, QByteArrayLiteral("z")); + zAnim1->setStartValue(10.0f); + zAnim1->setEndValue(50.0f); + zAnim1->setDuration(4000); + zAnim1->setEasingCurve(QEasingCurve::OutElastic); + animGroup->addAnimation(zAnim1); + QPropertyAnimation *zAnim2 = new QPropertyAnimation(this, QByteArrayLiteral("z")); + zAnim2->setStartValue(50.0f); + zAnim2->setEndValue(1.5f); + zAnim2->setDuration(2000); + animGroup->addAnimation(zAnim2); + animGroup->start(); + + QPropertyAnimation* rAnim = new QPropertyAnimation(this, QByteArrayLiteral("r")); + rAnim->setStartValue(0.0f); + rAnim->setEndValue(360.0f); + rAnim->setDuration(2000); + rAnim->setLoopCount(-1); + rAnim->start(); + + QTimer::singleShot(4000, this, SLOT(startSecondStage())); +} + +GLWindow::~GLWindow() +{ + makeCurrent(); + delete m_texture; + delete m_program; + delete m_vbo; + delete m_vao; +} + +void GLWindow::startSecondStage() +{ + QPropertyAnimation* r2Anim = new QPropertyAnimation(this, QByteArrayLiteral("r2")); + r2Anim->setStartValue(0.0f); + r2Anim->setEndValue(360.0f); + r2Anim->setDuration(20000); + r2Anim->setLoopCount(-1); + r2Anim->start(); +} + +void GLWindow::setZ(float v) +{ + m_eye.setZ(v); + m_uniformsDirty = true; + update(); +} + +void GLWindow::setR(float v) +{ + m_r = v; + m_uniformsDirty = true; + update(); +} + +void GLWindow::setR2(float v) +{ + m_r2 = v; + m_uniformsDirty = true; + update(); +} + +static const char *vertexShaderSource = + "layout(location = 0) in vec4 vertex;\n" + "layout(location = 1) in vec3 normal;\n" + "out vec3 vert;\n" + "out vec3 vertNormal;\n" + "out vec3 color;\n" + "uniform mat4 projMatrix;\n" + "uniform mat4 camMatrix;\n" + "uniform mat4 worldMatrix;\n" + "uniform mat4 myMatrix;\n" + "uniform sampler2D sampler;\n" + "void main() {\n" + " ivec2 pos = ivec2(gl_InstanceID % 32, gl_InstanceID / 32);\n" + " vec2 t = vec2(float(-16 + pos.x) * 0.8, float(-18 + pos.y) * 0.6);\n" + " float val = 2.0 * length(texelFetch(sampler, pos, 0).rgb);\n" + " mat4 wm = myMatrix * mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, t.x, t.y, val, 1) * worldMatrix;\n" + " color = texelFetch(sampler, pos, 0).rgb * vec3(0.4, 1.0, 0.0);\n" + " vert = vec3(wm * vertex);\n" + " vertNormal = mat3(transpose(inverse(wm))) * normal;\n" + " gl_Position = projMatrix * camMatrix * wm * vertex;\n" + "}\n"; + +static const char *fragmentShaderSource = + "in highp vec3 vert;\n" + "in highp vec3 vertNormal;\n" + "in highp vec3 color;\n" + "out highp vec4 fragColor;\n" + "uniform highp vec3 lightPos;\n" + "void main() {\n" + " highp vec3 L = normalize(lightPos - vert);\n" + " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n" + " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n" + " fragColor = vec4(col, 1.0);\n" + "}\n"; + +QByteArray versionedShaderCode(const char *src) +{ + QByteArray versionedSrc; + + if (QOpenGLContext::currentContext()->isOpenGLES()) + versionedSrc.append(QByteArrayLiteral("#version 300 es\n")); + else + versionedSrc.append(QByteArrayLiteral("#version 330\n")); + + versionedSrc.append(src); + return versionedSrc; +} + +void GLWindow::initializeGL() +{ + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + + if (m_texture) { + delete m_texture; + m_texture = 0; + } + QImage img(":/qtlogo.png"); + Q_ASSERT(!img.isNull()); + m_texture = new QOpenGLTexture(img.scaled(32, 36).mirrored()); + + if (m_program) { + delete m_program; + m_program = 0; + } + m_program = new QOpenGLShaderProgram; + // Prepend the correct version directive to the sources. The rest is the + // same, thanks to the common GLSL syntax. + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, versionedShaderCode(vertexShaderSource)); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, versionedShaderCode(fragmentShaderSource)); + m_program->link(); + + m_projMatrixLoc = m_program->uniformLocation("projMatrix"); + m_camMatrixLoc = m_program->uniformLocation("camMatrix"); + m_worldMatrixLoc = m_program->uniformLocation("worldMatrix"); + m_myMatrixLoc = m_program->uniformLocation("myMatrix"); + m_lightPosLoc = m_program->uniformLocation("lightPos"); + + // Create a VAO. Not strictly required for ES 3, but it is for plain OpenGL. + if (m_vao) { + delete m_vao; + m_vao = 0; + } + m_vao = new QOpenGLVertexArrayObject; + if (m_vao->create()) + m_vao->bind(); + + if (m_vbo) { + delete m_vbo; + m_vbo = 0; + } + m_program->bind(); + m_vbo = new QOpenGLBuffer; + m_vbo->create(); + m_vbo->bind(); + m_vbo->allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat)); + f->glEnableVertexAttribArray(0); + f->glEnableVertexAttribArray(1); + f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0); + f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat))); + m_vbo->release(); + + f->glEnable(GL_DEPTH_TEST); + f->glEnable(GL_CULL_FACE); +} + +void GLWindow::resizeGL(int w, int h) +{ + m_proj.setToIdentity(); + m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f); + m_uniformsDirty = true; +} + +void GLWindow::paintGL() +{ + // Now use QOpenGLExtraFunctions instead of QOpenGLFunctions as we want to + // do more than what GL(ES) 2.0 offers. + QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions(); + + f->glClearColor(0, 0, 0, 1); + f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + m_program->bind(); + m_texture->bind(); + + if (m_uniformsDirty) { + m_uniformsDirty = false; + QMatrix4x4 camera; + camera.lookAt(m_eye, m_eye + m_target, QVector3D(0, 1, 0)); + m_program->setUniformValue(m_projMatrixLoc, m_proj); + m_program->setUniformValue(m_camMatrixLoc, camera); + QMatrix4x4 wm = m_world; + wm.rotate(m_r, 1, 1, 0); + m_program->setUniformValue(m_worldMatrixLoc, wm); + QMatrix4x4 mm; + mm.setToIdentity(); + mm.rotate(-m_r2, 1, 0, 0); + m_program->setUniformValue(m_myMatrixLoc, mm); + m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70)); + } + + // Now call a function introduced in OpenGL 3.1 / OpenGL ES 3.0. We + // requested a 3.3 or ES 3.0 context, so we know this will work. + f->glDrawArraysInstanced(GL_TRIANGLES, 0, m_logo.vertexCount(), 32 * 36); +} diff --git a/examples/widgets/mainwindows/recentfiles/mainwindow.h b/examples/opengl/hellogles3/glwindow.h index 95252ca525..fe5d5383e9 100644 --- a/examples/widgets/mainwindows/recentfiles/mainwindow.h +++ b/examples/opengl/hellogles3/glwindow.h @@ -38,59 +38,61 @@ ** ****************************************************************************/ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H +#ifndef GLWIDGET_H +#define GLWIDGET_H -#include <QList> -#include <QMainWindow> +#include <QOpenGLWindow> +#include <QMatrix4x4> +#include <QVector3D> +#include "../hellogl2/logo.h" -QT_BEGIN_NAMESPACE -class QAction; -class QMenu; -class QTextEdit; -QT_END_NAMESPACE +class QOpenGLTexture; +class QOpenGLShaderProgram; +class QOpenGLBuffer; +class QOpenGLVertexArrayObject; -class MainWindow : public QMainWindow +class GLWindow : public QOpenGLWindow { Q_OBJECT + Q_PROPERTY(float z READ z WRITE setZ) + Q_PROPERTY(float r READ r WRITE setR) + Q_PROPERTY(float r2 READ r2 WRITE setR2) public: - MainWindow(); + GLWindow(); + ~GLWindow(); -private slots: - void newFile(); - void open(); - void save(); - void saveAs(); - void openRecentFile(); - void about(); - -private: - void createActions(); - void createMenus(); - void loadFile(const QString &fileName); - void saveFile(const QString &fileName); - void setCurrentFile(const QString &fileName); - void updateRecentFileActions(); - QString strippedName(const QString &fullFileName); + void initializeGL(); + void resizeGL(int w, int h); + void paintGL(); - QString curFile; + float z() const { return m_eye.z(); } + void setZ(float v); - QTextEdit *textEdit; - QMenu *fileMenu; - QMenu *recentFilesMenu; - QMenu *helpMenu; - QAction *newAct; - QAction *openAct; - QAction *saveAct; - QAction *saveAsAct; - QAction *exitAct; - QAction *aboutAct; - QAction *aboutQtAct; - QAction *separatorAct; - - enum { MaxRecentFiles = 5 }; - QAction *recentFileActs[MaxRecentFiles]; + float r() const { return m_r; } + void setR(float v); + float r2() const { return m_r2; } + void setR2(float v); +private slots: + void startSecondStage(); +private: + QOpenGLTexture *m_texture; + QOpenGLShaderProgram *m_program; + QOpenGLBuffer *m_vbo; + QOpenGLVertexArrayObject *m_vao; + Logo m_logo; + int m_projMatrixLoc; + int m_camMatrixLoc; + int m_worldMatrixLoc; + int m_myMatrixLoc; + int m_lightPosLoc; + QMatrix4x4 m_proj; + QMatrix4x4 m_world; + QVector3D m_eye; + QVector3D m_target; + bool m_uniformsDirty; + float m_r; + float m_r2; }; #endif diff --git a/examples/opengl/hellogles3/hellogles3.pro b/examples/opengl/hellogles3/hellogles3.pro new file mode 100644 index 0000000000..e0d4c25ca6 --- /dev/null +++ b/examples/opengl/hellogles3/hellogles3.pro @@ -0,0 +1,11 @@ +HEADERS = $$PWD/glwindow.h \ + $$PWD/../hellogl2/logo.h + +SOURCES = $$PWD/glwindow.cpp \ + $$PWD/main.cpp \ + $$PWD/../hellogl2/logo.cpp + +RESOURCES += hellogles3.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/hellogles3 +INSTALLS += target diff --git a/examples/opengl/hellogles3/hellogles3.qrc b/examples/opengl/hellogles3/hellogles3.qrc new file mode 100644 index 0000000000..f3a0978084 --- /dev/null +++ b/examples/opengl/hellogles3/hellogles3.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource> + <file>qtlogo.png</file> + </qresource> +</RCC> diff --git a/examples/opengl/hellogles3/main.cpp b/examples/opengl/hellogles3/main.cpp new file mode 100644 index 0000000000..f0de28bdc4 --- /dev/null +++ b/examples/opengl/hellogles3/main.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QSurfaceFormat> +#include <QOpenGLContext> + +#include "glwindow.h" + +// This example demonstrates easy, cross-platform usage of OpenGL ES 3.0 functions via +// QOpenGLExtraFunctions in an application that works identically on desktop platforms +// with OpenGL 3.3 and mobile/embedded devices with OpenGL ES 3.0. + +// The code is always the same, with the exception of two places: (1) the OpenGL context +// creation has to have a sufficiently high version number for the features that are in +// use, and (2) the shader code's version directive is different. + +int main(int argc, char *argv[]) +{ + QSurfaceFormat fmt; + fmt.setDepthBufferSize(24); + + // Request OpenGL 3.3 compatibility or OpenGL ES 3.0. + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + qDebug("Requesting 3.3 compatibility context"); + fmt.setVersion(3, 3); + fmt.setProfile(QSurfaceFormat::CompatibilityProfile); + } else { + qDebug("Requesting 3.0 context"); + fmt.setVersion(3, 0); + } + + QSurfaceFormat::setDefaultFormat(fmt); + + QGuiApplication app(argc, argv); + + GLWindow glWindow; + glWindow.showMaximized(); + + return app.exec(); +} diff --git a/examples/opengl/hellogles3/qtlogo.png b/examples/opengl/hellogles3/qtlogo.png Binary files differnew file mode 100644 index 0000000000..868fcea860 --- /dev/null +++ b/examples/opengl/hellogles3/qtlogo.png diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro index cf5329c55d..ed8134743b 100644 --- a/examples/opengl/opengl.pro +++ b/examples/opengl/opengl.pro @@ -13,5 +13,6 @@ qtHaveModule(widgets) { !wince: SUBDIRS += \ qopenglwidget \ cube \ - textures + textures \ + hellogles3 } diff --git a/examples/qtconcurrent/map/main.cpp b/examples/qtconcurrent/map/main.cpp index 75b1da4e6f..eaa7c911cb 100644 --- a/examples/qtconcurrent/map/main.cpp +++ b/examples/qtconcurrent/map/main.cpp @@ -64,7 +64,7 @@ int main(int argc, char *argv[]) // Use QtConcurrentBlocking::mapped to apply the scale function to all the // images in the list. - QList<QImage> thumbnails = QtConcurrent::blockingMapped<QList<QImage> >(images, scale); + QList<QImage> thumbnails = QtConcurrent::blockingMapped(images, scale); return 0; } diff --git a/examples/sql/books/books.pro b/examples/sql/books/books.pro index 94f8104414..c64766c29f 100644 --- a/examples/sql/books/books.pro +++ b/examples/sql/books/books.pro @@ -16,5 +16,5 @@ wince { CONFIG(debug, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*d4.dll CONFIG(release, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*[^d]4.dll sqlPlugins.path = sqldrivers - DEPLOYMENT += sqlPlugins + INSTALLS += sqlPlugins } diff --git a/examples/webkit/webkit-guide/js/anim_accord.js b/examples/webkit/webkit-guide/js/anim_accord.js index cc95b7f7c9..cc95b7f7c9 100755..100644 --- a/examples/webkit/webkit-guide/js/anim_accord.js +++ b/examples/webkit/webkit-guide/js/anim_accord.js diff --git a/examples/webkit/webkit-guide/js/anim_gallery.js b/examples/webkit/webkit-guide/js/anim_gallery.js index 050f113bb4..050f113bb4 100755..100644 --- a/examples/webkit/webkit-guide/js/anim_gallery.js +++ b/examples/webkit/webkit-guide/js/anim_gallery.js diff --git a/examples/webkit/webkit-guide/js/anim_panel.js b/examples/webkit/webkit-guide/js/anim_panel.js index e6cc5e6d8f..e6cc5e6d8f 100755..100644 --- a/examples/webkit/webkit-guide/js/anim_panel.js +++ b/examples/webkit/webkit-guide/js/anim_panel.js diff --git a/examples/webkit/webkit-guide/js/anim_skew.js b/examples/webkit/webkit-guide/js/anim_skew.js index 8b1300fd1f..8b1300fd1f 100755..100644 --- a/examples/webkit/webkit-guide/js/anim_skew.js +++ b/examples/webkit/webkit-guide/js/anim_skew.js diff --git a/examples/webkit/webkit-guide/js/css3_backgrounds.js b/examples/webkit/webkit-guide/js/css3_backgrounds.js index 29004c7b53..29004c7b53 100755..100644 --- a/examples/webkit/webkit-guide/js/css3_backgrounds.js +++ b/examples/webkit/webkit-guide/js/css3_backgrounds.js diff --git a/examples/webkit/webkit-guide/js/css3_border-img.js b/examples/webkit/webkit-guide/js/css3_border-img.js index a8bfd9132d..a8bfd9132d 100755..100644 --- a/examples/webkit/webkit-guide/js/css3_border-img.js +++ b/examples/webkit/webkit-guide/js/css3_border-img.js diff --git a/examples/webkit/webkit-guide/js/css3_grad-radial.js b/examples/webkit/webkit-guide/js/css3_grad-radial.js index f194ddaa6c..f194ddaa6c 100755..100644 --- a/examples/webkit/webkit-guide/js/css3_grad-radial.js +++ b/examples/webkit/webkit-guide/js/css3_grad-radial.js diff --git a/examples/webkit/webkit-guide/js/css3_mask-grad.js b/examples/webkit/webkit-guide/js/css3_mask-grad.js index 911212dcf4..911212dcf4 100755..100644 --- a/examples/webkit/webkit-guide/js/css3_mask-grad.js +++ b/examples/webkit/webkit-guide/js/css3_mask-grad.js diff --git a/examples/webkit/webkit-guide/js/css3_mask-img.js b/examples/webkit/webkit-guide/js/css3_mask-img.js index a8bfd9132d..a8bfd9132d 100755..100644 --- a/examples/webkit/webkit-guide/js/css3_mask-img.js +++ b/examples/webkit/webkit-guide/js/css3_mask-img.js diff --git a/examples/webkit/webkit-guide/js/css3_text-overflow.js b/examples/webkit/webkit-guide/js/css3_text-overflow.js index 58af80d6d1..58af80d6d1 100755..100644 --- a/examples/webkit/webkit-guide/js/css3_text-overflow.js +++ b/examples/webkit/webkit-guide/js/css3_text-overflow.js diff --git a/examples/webkit/webkit-guide/js/form_tapper.js b/examples/webkit/webkit-guide/js/form_tapper.js index d4d87a2c1a..d4d87a2c1a 100755..100644 --- a/examples/webkit/webkit-guide/js/form_tapper.js +++ b/examples/webkit/webkit-guide/js/form_tapper.js diff --git a/examples/webkit/webkit-guide/js/mob_condjs.js b/examples/webkit/webkit-guide/js/mob_condjs.js index 32bf550d20..32bf550d20 100755..100644 --- a/examples/webkit/webkit-guide/js/mob_condjs.js +++ b/examples/webkit/webkit-guide/js/mob_condjs.js diff --git a/examples/webkit/webkit-guide/js/mobile.js b/examples/webkit/webkit-guide/js/mobile.js index 51c94d4080..51c94d4080 100755..100644 --- a/examples/webkit/webkit-guide/js/mobile.js +++ b/examples/webkit/webkit-guide/js/mobile.js diff --git a/examples/webkit/webkit-guide/js/storage.js b/examples/webkit/webkit-guide/js/storage.js index b5a374f39d..b5a374f39d 100755..100644 --- a/examples/webkit/webkit-guide/js/storage.js +++ b/examples/webkit/webkit-guide/js/storage.js diff --git a/examples/widgets/dialogs/classwizard/classwizard.cpp b/examples/widgets/dialogs/classwizard/classwizard.cpp index 0f1a2a0869..c913d7b592 100644 --- a/examples/widgets/dialogs/classwizard/classwizard.cpp +++ b/examples/widgets/dialogs/classwizard/classwizard.cpp @@ -252,8 +252,8 @@ ClassInfoPage::ClassInfoPage(QWidget *parent) defaultCtorRadioButton->setChecked(true); - connect(defaultCtorRadioButton, SIGNAL(toggled(bool)), - copyCtorCheckBox, SLOT(setEnabled(bool))); + connect(defaultCtorRadioButton, &QAbstractButton::toggled, + copyCtorCheckBox, &QWidget::setEnabled); //! [11] //! [12] registerField("className*", classNameLineEdit); @@ -311,14 +311,14 @@ CodeStylePage::CodeStylePage(QWidget *parent) baseIncludeLineEdit = new QLineEdit; baseIncludeLabel->setBuddy(baseIncludeLineEdit); - connect(protectCheckBox, SIGNAL(toggled(bool)), - macroNameLabel, SLOT(setEnabled(bool))); - connect(protectCheckBox, SIGNAL(toggled(bool)), - macroNameLineEdit, SLOT(setEnabled(bool))); - connect(includeBaseCheckBox, SIGNAL(toggled(bool)), - baseIncludeLabel, SLOT(setEnabled(bool))); - connect(includeBaseCheckBox, SIGNAL(toggled(bool)), - baseIncludeLineEdit, SLOT(setEnabled(bool))); + connect(protectCheckBox, &QAbstractButton::toggled, + macroNameLabel, &QWidget::setEnabled); + connect(protectCheckBox, &QAbstractButton::toggled, + macroNameLineEdit, &QWidget::setEnabled); + connect(includeBaseCheckBox, &QAbstractButton::toggled, + baseIncludeLabel, &QWidget::setEnabled); + connect(includeBaseCheckBox, &QAbstractButton::toggled, + baseIncludeLineEdit, &QWidget::setEnabled); registerField("comment", commentCheckBox); registerField("protect", protectCheckBox); diff --git a/examples/widgets/dialogs/configdialog/configdialog.cpp b/examples/widgets/dialogs/configdialog/configdialog.cpp index 8e68940227..c4565a6407 100644 --- a/examples/widgets/dialogs/configdialog/configdialog.cpp +++ b/examples/widgets/dialogs/configdialog/configdialog.cpp @@ -62,7 +62,7 @@ ConfigDialog::ConfigDialog() createIcons(); contentsWidget->setCurrentRow(0); - connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); + connect(closeButton, &QAbstractButton::clicked, this, &QWidget::close); QHBoxLayout *horizontalLayout = new QHBoxLayout; horizontalLayout->addWidget(contentsWidget); @@ -102,9 +102,7 @@ void ConfigDialog::createIcons() queryButton->setTextAlignment(Qt::AlignHCenter); queryButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - connect(contentsWidget, - SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), - this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*))); + connect(contentsWidget, &QListWidget::currentItemChanged, this, &ConfigDialog::changePage); } void ConfigDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) diff --git a/examples/widgets/dialogs/extension/finddialog.cpp b/examples/widgets/dialogs/extension/finddialog.cpp index 19eab195cb..895b0cf2ce 100644 --- a/examples/widgets/dialogs/extension/finddialog.cpp +++ b/examples/widgets/dialogs/extension/finddialog.cpp @@ -78,7 +78,7 @@ FindDialog::FindDialog(QWidget *parent) buttonBox->addButton(findButton, QDialogButtonBox::ActionRole); buttonBox->addButton(moreButton, QDialogButtonBox::ActionRole); - connect(moreButton, SIGNAL(toggled(bool)), extension, SLOT(setVisible(bool))); + connect(moreButton, &QAbstractButton::toggled, extension, &QWidget::setVisible); QVBoxLayout *extensionLayout = new QVBoxLayout; extensionLayout->setMargin(0); diff --git a/examples/widgets/dialogs/findfiles/window.cpp b/examples/widgets/dialogs/findfiles/window.cpp index 86c34a6352..780c398ad5 100644 --- a/examples/widgets/dialogs/findfiles/window.cpp +++ b/examples/widgets/dialogs/findfiles/window.cpp @@ -46,8 +46,10 @@ Window::Window(QWidget *parent) : QWidget(parent) { - browseButton = createButton(tr("&Browse..."), SLOT(browse())); - findButton = createButton(tr("&Find"), SLOT(find())); + browseButton = new QPushButton(tr("&Browse..."), this); + connect(browseButton, &QAbstractButton::clicked, this, &Window::browse); + findButton = new QPushButton(tr("&Find"), this); + connect(findButton, &QAbstractButton::clicked, this, &Window::find); fileComboBox = createComboBox(tr("*")); textComboBox = createComboBox(); @@ -195,15 +197,6 @@ void Window::showFiles(const QStringList &files) } //! [8] -//! [9] -QPushButton *Window::createButton(const QString &text, const char *member) -{ - QPushButton *button = new QPushButton(text); - connect(button, SIGNAL(clicked()), this, member); - return button; -} -//! [9] - //! [10] QComboBox *Window::createComboBox(const QString &text) { @@ -228,8 +221,8 @@ void Window::createFilesTable() filesTable->verticalHeader()->hide(); filesTable->setShowGrid(false); - connect(filesTable, SIGNAL(cellActivated(int,int)), - this, SLOT(openFileOfItem(int,int))); + connect(filesTable, &QTableWidget::cellActivated, + this, &Window::openFileOfItem); } //! [11] diff --git a/examples/widgets/dialogs/findfiles/window.h b/examples/widgets/dialogs/findfiles/window.h index 281c932e2f..89dd87b83b 100644 --- a/examples/widgets/dialogs/findfiles/window.h +++ b/examples/widgets/dialogs/findfiles/window.h @@ -68,7 +68,6 @@ private slots: private: QStringList findFiles(const QStringList &files, const QString &text); void showFiles(const QStringList &files); - QPushButton *createButton(const QString &text, const char *member); QComboBox *createComboBox(const QString &text = QString()); void createFilesTable(); diff --git a/examples/widgets/dialogs/licensewizard/licensewizard.cpp b/examples/widgets/dialogs/licensewizard/licensewizard.cpp index ace2e1229a..0f11f3ab7b 100644 --- a/examples/widgets/dialogs/licensewizard/licensewizard.cpp +++ b/examples/widgets/dialogs/licensewizard/licensewizard.cpp @@ -70,7 +70,7 @@ LicenseWizard::LicenseWizard(QWidget *parent) setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png")); //! [7] - connect(this, SIGNAL(helpRequested()), this, SLOT(showHelp())); + connect(this, &QWizard::helpRequested, this, &LicenseWizard::showHelp); //! [7] setWindowTitle(tr("License Wizard")); @@ -339,13 +339,13 @@ void ConclusionPage::setVisible(bool visible) //! [29] wizard()->setButtonText(QWizard::CustomButton1, tr("&Print")); wizard()->setOption(QWizard::HaveCustomButton1, true); - connect(wizard(), SIGNAL(customButtonClicked(int)), - this, SLOT(printButtonClicked())); + connect(wizard(), &QWizard::customButtonClicked, + this, &ConclusionPage::printButtonClicked); //! [29] } else { wizard()->setOption(QWizard::HaveCustomButton1, false); - disconnect(wizard(), SIGNAL(customButtonClicked(int)), - this, SLOT(printButtonClicked())); + disconnect(wizard(), &QWizard::customButtonClicked, + this, &ConclusionPage::printButtonClicked); } } //! [28] diff --git a/examples/widgets/dialogs/sipdialog/dialog.cpp b/examples/widgets/dialogs/sipdialog/dialog.cpp index f57cd094ae..48859ec5ff 100644 --- a/examples/widgets/dialogs/sipdialog/dialog.cpp +++ b/examples/widgets/dialogs/sipdialog/dialog.cpp @@ -89,10 +89,9 @@ Dialog::Dialog() //! [Dialog constructor part4] //! [Dialog constructor part5] - connect(button, SIGNAL(clicked()), - qApp, SLOT(closeAllWindows())); - connect(QApplication::desktop(), SIGNAL(workAreaResized(int)), - this, SLOT(desktopResized(int))); + connect(button, &QAbstractButton::clicked, qApp, &QApplication::closeAllWindows); + connect(QApplication::desktop(), &QDesktopWidget::workAreaResized, + this, &Dialog::desktopResized); } //! [Dialog constructor part5] diff --git a/examples/widgets/dialogs/standarddialogs/dialog.cpp b/examples/widgets/dialogs/standarddialogs/dialog.cpp index 0a1532616c..560ca77f31 100644 --- a/examples/widgets/dialogs/standarddialogs/dialog.cpp +++ b/examples/widgets/dialogs/standarddialogs/dialog.cpp @@ -180,27 +180,27 @@ Dialog::Dialog(QWidget *parent) QPushButton *errorButton = new QPushButton(tr("QErrorMessage::showM&essage()")); - connect(integerButton, SIGNAL(clicked()), this, SLOT(setInteger())); - connect(doubleButton, SIGNAL(clicked()), this, SLOT(setDouble())); - connect(itemButton, SIGNAL(clicked()), this, SLOT(setItem())); - connect(textButton, SIGNAL(clicked()), this, SLOT(setText())); - connect(multiLineTextButton, SIGNAL(clicked()), this, SLOT(setMultiLineText())); - connect(colorButton, SIGNAL(clicked()), this, SLOT(setColor())); - connect(fontButton, SIGNAL(clicked()), this, SLOT(setFont())); - connect(directoryButton, SIGNAL(clicked()), - this, SLOT(setExistingDirectory())); - connect(openFileNameButton, SIGNAL(clicked()), - this, SLOT(setOpenFileName())); - connect(openFileNamesButton, SIGNAL(clicked()), - this, SLOT(setOpenFileNames())); - connect(saveFileNameButton, SIGNAL(clicked()), - this, SLOT(setSaveFileName())); - connect(criticalButton, SIGNAL(clicked()), this, SLOT(criticalMessage())); - connect(informationButton, SIGNAL(clicked()), - this, SLOT(informationMessage())); - connect(questionButton, SIGNAL(clicked()), this, SLOT(questionMessage())); - connect(warningButton, SIGNAL(clicked()), this, SLOT(warningMessage())); - connect(errorButton, SIGNAL(clicked()), this, SLOT(errorMessage())); + connect(integerButton, &QAbstractButton::clicked, this, &Dialog::setInteger); + connect(doubleButton, &QAbstractButton::clicked, this, &Dialog::setDouble); + connect(itemButton, &QAbstractButton::clicked, this, &Dialog::setItem); + connect(textButton, &QAbstractButton::clicked, this, &Dialog::setText); + connect(multiLineTextButton, &QAbstractButton::clicked, this, &Dialog::setMultiLineText); + connect(colorButton, &QAbstractButton::clicked, this, &Dialog::setColor); + connect(fontButton, &QAbstractButton::clicked, this, &Dialog::setFont); + connect(directoryButton, &QAbstractButton::clicked, + this, &Dialog::setExistingDirectory); + connect(openFileNameButton, &QAbstractButton::clicked, + this, &Dialog::setOpenFileName); + connect(openFileNamesButton, &QAbstractButton::clicked, + this, &Dialog::setOpenFileNames); + connect(saveFileNameButton, &QAbstractButton::clicked, + this, &Dialog::setSaveFileName); + connect(criticalButton, &QAbstractButton::clicked, this, &Dialog::criticalMessage); + connect(informationButton, &QAbstractButton::clicked, + this, &Dialog::informationMessage); + connect(questionButton, &QAbstractButton::clicked, this, &Dialog::questionMessage); + connect(warningButton, &QAbstractButton::clicked, this, &Dialog::warningMessage); + connect(errorButton, &QAbstractButton::clicked, this, &Dialog::errorMessage); QWidget *page = new QWidget; QGridLayout *layout = new QGridLayout(page); diff --git a/examples/widgets/dialogs/tabdialog/tabdialog.cpp b/examples/widgets/dialogs/tabdialog/tabdialog.cpp index ec1a6efbc8..75a7b85e3b 100644 --- a/examples/widgets/dialogs/tabdialog/tabdialog.cpp +++ b/examples/widgets/dialogs/tabdialog/tabdialog.cpp @@ -59,8 +59,8 @@ TabDialog::TabDialog(const QString &fileName, QWidget *parent) //! [1] //! [3] | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); //! [2] //! [3] //! [4] diff --git a/examples/widgets/doc/images/regularexpression-example.png b/examples/widgets/doc/images/regularexpression-example.png Binary files differnew file mode 100644 index 0000000000..d426d8514a --- /dev/null +++ b/examples/widgets/doc/images/regularexpression-example.png diff --git a/examples/widgets/doc/src/application.qdoc b/examples/widgets/doc/src/application.qdoc index ac32c592fc..cd284ecba0 100644 --- a/examples/widgets/doc/src/application.qdoc +++ b/examples/widgets/doc/src/application.qdoc @@ -50,11 +50,10 @@ To keep the example simple, recently opened files aren't shown in the \uicontrol{File} menu, even though this feature is desired in 90% - of applications. The \l{mainwindows/recentfiles}{Recent Files} - example shows how to implement this. Furthermore, this example - can only load one file at a time. The \l{mainwindows/sdi}{SDI} - and \l{mainwindows/mdi}{MDI} examples shows how to lift these - restrictions. + of applications. Furthermore, this example can only load one file at a + time. The \l{mainwindows/sdi}{SDI} and \l{mainwindows/mdi}{MDI} examples + show how to lift these restrictions and how to implement recently opened files + handling. \section1 MainWindow Class Definition @@ -96,8 +95,7 @@ the widget that occupies the central area of the main window, between the toolbars and the status bar. - Then we call \c createActions(), \c createMenus(), \c - createToolBars(), and \c createStatusBar(), four private + Then we call \c createActions() and \c createStatusBar(), two private functions that set up the user interface. After that, we call \c readSettings() to restore the user's preferences. @@ -184,7 +182,8 @@ \snippet mainwindows/application/mainwindow.cpp 22 The \c createActions() private function, which is called from the - \c MainWindow constructor, creates \l{QAction}s. The code is very + \c MainWindow constructor, creates \l{QAction}s and populates + the menus and two toolbars. The code is very repetitive, so we show only the actions corresponding to \uicontrol{File|New}, \uicontrol{File|Open}, and \uicontrol{Help|About Qt}. @@ -198,13 +197,27 @@ a "What's This?" text, and more. It emits a \l{QAction::triggered()}{triggered()} signal whenever the user invokes the action (e.g., by clicking the associated menu item or - toolbar button). We connect this signal to a slot that performs - the actual action. + toolbar button). + + Instances of QAction can be created by passing a parent QObject or + by using one of the convenience functions of QMenu, QMenuBar or QToolBar. + We create the actions that are in a menu as well as in a toolbar + parented on the window to prevent ownership issues. For actions + that are only in the menu, we use the convenience function + QMenu::addAction(), which allows us to pass text, icon and the + target object and its slot member function. + + Creating toolbars is very similar to creating menus. The same + actions that we put in the menus can be reused in the toolbars. + After creating the action, we add it to the toolbar using + QToolBar::addAction(). The code above contains one more idiom that must be explained. For some of the actions, we specify an icon as a QIcon to the - QAction constructor. The QIcon constructor takes the file name - of an image that it tries to load. Here, the file name starts + QAction constructor. We use QIcon::fromTheme() to obtain + the correct standard icon from the underlying window system. + If that fails due to the platform not supporting it, we + pass a file name as fallback. Here, the file name starts with \c{:}. Such file names aren't ordinary file names, but rather path in the executable's stored resources. We'll come back to this when we review the \c application.qrc file that's part of @@ -219,30 +232,12 @@ the QAction::setEnabled() slot, ensuring that the actions are disabled when the text editor has no selection. - \snippet mainwindows/application/mainwindow.cpp 25 - \snippet mainwindows/application/mainwindow.cpp 27 - - Creating actions isn't sufficient to make them available to the - user; we must also add them to the menu system. This is what \c - createMenus() does. We create a \uicontrol{File}, an \uicontrol{Edit}, and - a \uicontrol{Help} menu. QMainWindow::menuBar() lets us access the - window's menu bar widget. We don't have to worry about creating - the menu bar ourselves; the first time we call this function, the - QMenuBar is created. - Just before we create the \uicontrol{Help} menu, we call QMenuBar::addSeparator(). This has no effect for most widget styles (e.g., Windows and OS X styles), but for some styles this makes sure that \uicontrol{Help} is pushed to the right side of the menu bar. - Let's now review the toolbars: - - \snippet mainwindows/application/mainwindow.cpp 30 - - Creating toolbars is very similar to creating menus. The same - actions that we put in the menus can be reused in the toolbars. - \snippet mainwindows/application/mainwindow.cpp 32 \snippet mainwindows/application/mainwindow.cpp 33 @@ -265,15 +260,15 @@ company and the name of the product. This ensures that the settings for different applications are kept separately. - We use QSettings::value() to extract the value of the "pos" and - "size" settings. The second argument to QSettings::value() is + We use QSettings::value() to extract the value of the geometry setting. + The second argument to QSettings::value() is optional and specifies a default value for the setting if there exists none. This value is used the first time the application is run. - When restoring the position and size of a window, it's important - to call QWidget::resize() before QWidget::move(). The reason why - is given in the \l{Window Geometry} overview. + We use QWidget::saveGeometry() and Widget::restoreGeometry() to + save the position. They use an opaque QByteArray to store + screen number, geometry and window state. \snippet mainwindows/application/mainwindow.cpp 37 \snippet mainwindows/application/mainwindow.cpp 39 @@ -297,9 +292,9 @@ QMessageBox::Escape flag. The \c maybeSave() function returns \c true in all cases, except - when the user clicks \uicontrol{Cancel}. The caller must check the - return value and stop whatever it was doing if the return value - is \c false. + when the user clicks \uicontrol{Cancel} or saving the file fails. + The caller must check the return value and stop whatever it was + doing if the return value is \c false. \snippet mainwindows/application/mainwindow.cpp 42 \snippet mainwindows/application/mainwindow.cpp 43 @@ -361,6 +356,10 @@ \snippet mainwindows/application/main.cpp 0 + The main function uses QCommandLineParser to check whether some file + argument was passed to the application and loads it via + MainWindow::loadFile(). + \section1 The Resource File As you will probably recall, for some of the actions, we diff --git a/examples/widgets/doc/src/findfiles.qdoc b/examples/widgets/doc/src/findfiles.qdoc index 0a4fb8268d..dd06ed8bb4 100644 --- a/examples/widgets/doc/src/findfiles.qdoc +++ b/examples/widgets/doc/src/findfiles.qdoc @@ -200,13 +200,6 @@ We also update the total number of files found. - \snippet dialogs/findfiles/window.cpp 9 - - The private \c createButton() function is called from the - constructor. We create a QPushButton with the provided text, - connect it to the provided slot, and return a pointer to the - button. - \snippet dialogs/findfiles/window.cpp 10 The private \c createComboBox() function is also called from the diff --git a/examples/widgets/doc/src/recentfiles.qdoc b/examples/widgets/doc/src/regularexpression.qdoc index b58c9a1f76..804867fb58 100644 --- a/examples/widgets/doc/src/recentfiles.qdoc +++ b/examples/widgets/doc/src/regularexpression.qdoc @@ -26,12 +26,23 @@ ****************************************************************************/ /*! - \example mainwindows/recentfiles - \title Recent Files Example - \ingroup examples-mainwindow + \example tools/regularexpression + \title QRegularExpression Example + \ingroup examples-widgets-tools - \brief The Recent Files example shows how a standard File menu can be extended to show - the most recent files loaded by a main window application. + \brief The QRegularExpression example shows how regular expressions in Qt are + applied to text by providing an environment in which new regular expressions can be + created and tested on custom text strings. - \image recentfiles-example.png + The example makes usage of the QRegularExpression class, which has been + introduced in Qt 5.0. QRegularExpression implements Perl-compatible regular + expressions, supporting a number of advanced matching features, such as + case insensitive matching, multiline matching, Unicode properties selectors + and partial/incremental matching. + + QRegularExpression is a big improvement over QRegExp in terms of features + and performance and should be used in all new code. + + \image regularexpression-example.png */ + diff --git a/examples/widgets/doc/src/tablet.qdoc b/examples/widgets/doc/src/tablet.qdoc index 1ab2917b7e..bc03d46332 100644 --- a/examples/widgets/doc/src/tablet.qdoc +++ b/examples/widgets/doc/src/tablet.qdoc @@ -259,24 +259,18 @@ \snippet widgets/tablet/tabletcanvas.cpp 5 - In this function we draw on the pixmap based on the movement of the - device. If the device used on the tablet is a stylus we want to draw a - line between the positions of the stylus recorded in \c polyLine. We - also assume that this is a reasonable handling of any unknown device, - but update the statusbar with a warning so that the user can see that - for his tablet he might have to implement special handling. - If it is an airbrush we want to draw a circle of points with a - point density based on the tangential pressure, which is the position - of the finger wheel on the airbrush. We use the Qt::BrushStyle to - draw the points as it has styles that draw points with different - density; we select the style based on the tangential pressure in - \c brushPattern(). + In this function we draw on the pixmap based on the movement of the device. + If the device used on the tablet is a stylus, we want to draw a line from + the last-known position to the current position. We also assume that this + is a reasonable handling of any unknown device, but update the status bar + with a warning. If it is an airbrush, we want to draw a circle filled with + a soft gradient, whose density can depend on various event parameters. + By default it depends on the tangential pressure, which is the position of + the finger wheel on the airbrush. If it is a rotation stylus, we simulate + a felt marker by drawing trapezoidal strokes. \snippet widgets/tablet/tabletcanvas.cpp 6 - We return a brush style with a point density that increases with - the tangential pressure. - In \c updateBrush() we set the pen and brush used for drawing to match \c alphaChannelType, \c lineWidthType, \c colorSaturationType, and \c myColor. We will examine the code to diff --git a/examples/widgets/draganddrop/puzzle/puzzle.pro b/examples/widgets/draganddrop/puzzle/puzzle.pro index 67fff21a26..404b75187d 100644 --- a/examples/widgets/draganddrop/puzzle/puzzle.pro +++ b/examples/widgets/draganddrop/puzzle/puzzle.pro @@ -18,5 +18,5 @@ INSTALLS += target wince { addFile.files = example.jpg addFile.path = . - DEPLOYMENT += addFile + INSTALLS += addFile } diff --git a/examples/widgets/itemviews/addressbook/adddialog.cpp b/examples/widgets/itemviews/addressbook/adddialog.cpp index de5c7eaf87..d153381b56 100644 --- a/examples/widgets/itemviews/addressbook/adddialog.cpp +++ b/examples/widgets/itemviews/addressbook/adddialog.cpp @@ -72,8 +72,8 @@ AddDialog::AddDialog(QWidget *parent) mainLayout->addLayout(gLayout); setLayout(mainLayout); - connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + connect(okButton, &QAbstractButton::clicked, this, &QDialog::accept); + connect(cancelButton, &QAbstractButton::clicked, this, &QDialog::reject); setWindowTitle(tr("Add a Contact")); } diff --git a/examples/widgets/itemviews/addressbook/addresswidget.cpp b/examples/widgets/itemviews/addressbook/addresswidget.cpp index 20589a9417..792d626a4e 100644 --- a/examples/widgets/itemviews/addressbook/addresswidget.cpp +++ b/examples/widgets/itemviews/addressbook/addresswidget.cpp @@ -49,8 +49,8 @@ AddressWidget::AddressWidget(QWidget *parent) { table = new TableModel(this); newAddressTab = new NewAddressTab(this); - connect(newAddressTab, SIGNAL(sendDetails(QString, QString)), - this, SLOT(addEntry(QString, QString))); + connect(newAddressTab, &NewAddressTab::sendDetails, + this, &AddressWidget::addEntry); addTab(newAddressTab, "Address Book"); @@ -59,7 +59,7 @@ AddressWidget::AddressWidget(QWidget *parent) //! [0] //! [2] -void AddressWidget::addEntry() +void AddressWidget::showAddEntryDialog() { AddDialog aDialog; @@ -182,8 +182,8 @@ void AddressWidget::setupTabs() tableView->setSortingEnabled(true); connect(tableView->selectionModel(), - SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - this, SIGNAL(selectionChanged(QItemSelection))); + &QItemSelectionModel::selectionChanged, + this, &AddressWidget::selectionChanged); addTab(tableView, str); } diff --git a/examples/widgets/itemviews/addressbook/addresswidget.h b/examples/widgets/itemviews/addressbook/addresswidget.h index b990c47911..a2fc4bc03b 100644 --- a/examples/widgets/itemviews/addressbook/addresswidget.h +++ b/examples/widgets/itemviews/addressbook/addresswidget.h @@ -63,7 +63,7 @@ public: void writeToFile(const QString &fileName); public slots: - void addEntry(); + void showAddEntryDialog(); void addEntry(QString name, QString address); void editEntry(); void removeEntry(); diff --git a/examples/widgets/itemviews/addressbook/mainwindow.cpp b/examples/widgets/itemviews/addressbook/mainwindow.cpp index f729f43604..94b38ea2f6 100644 --- a/examples/widgets/itemviews/addressbook/mainwindow.cpp +++ b/examples/widgets/itemviews/addressbook/mainwindow.cpp @@ -61,40 +61,40 @@ void MainWindow::createMenus() openAct = new QAction(tr("&Open..."), this); fileMenu->addAction(openAct); - connect(openAct, SIGNAL(triggered()), this, SLOT(openFile())); + connect(openAct, &QAction::triggered, this, &MainWindow::openFile); //! [1a] saveAct = new QAction(tr("&Save As..."), this); fileMenu->addAction(saveAct); - connect(saveAct, SIGNAL(triggered()), this, SLOT(saveFile())); + connect(saveAct, &QAction::triggered, this, &MainWindow::saveFile); fileMenu->addSeparator(); exitAct = new QAction(tr("E&xit"), this); fileMenu->addAction(exitAct); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); + connect(exitAct, &QAction::triggered, this, &QWidget::close); toolMenu = menuBar()->addMenu(tr("&Tools")); addAct = new QAction(tr("&Add Entry..."), this); toolMenu->addAction(addAct); - connect(addAct, SIGNAL(triggered()), addressWidget, SLOT(addEntry())); + connect(addAct, &QAction::triggered, addressWidget, &AddressWidget::showAddEntryDialog); //! [1b] editAct = new QAction(tr("&Edit Entry..."), this); editAct->setEnabled(false); toolMenu->addAction(editAct); - connect(editAct, SIGNAL(triggered()), addressWidget, SLOT(editEntry())); + connect(editAct, &QAction::triggered, addressWidget, &AddressWidget::editEntry); toolMenu->addSeparator(); removeAct = new QAction(tr("&Remove Entry"), this); removeAct->setEnabled(false); toolMenu->addAction(removeAct); - connect(removeAct, SIGNAL(triggered()), addressWidget, SLOT(removeEntry())); + connect(removeAct, &QAction::triggered, addressWidget, &AddressWidget::removeEntry); - connect(addressWidget, SIGNAL(selectionChanged(QItemSelection)), - this, SLOT(updateActions(QItemSelection))); + connect(addressWidget, &AddressWidget::selectionChanged, + this, &MainWindow::updateActions); } //! [1b] diff --git a/examples/widgets/itemviews/addressbook/newaddresstab.cpp b/examples/widgets/itemviews/addressbook/newaddresstab.cpp index 012a19991c..af66636995 100644 --- a/examples/widgets/itemviews/addressbook/newaddresstab.cpp +++ b/examples/widgets/itemviews/addressbook/newaddresstab.cpp @@ -53,7 +53,7 @@ NewAddressTab::NewAddressTab(QWidget *parent) addButton = new QPushButton(tr("Add")); - connect(addButton, SIGNAL(clicked()), this, SLOT(addEntry())); + connect(addButton, &QAbstractButton::clicked, this, &NewAddressTab::addEntry); mainLayout = new QVBoxLayout; mainLayout->addWidget(descriptionLabel); diff --git a/examples/widgets/itemviews/basicsortfiltermodel/window.cpp b/examples/widgets/itemviews/basicsortfiltermodel/window.cpp index b518460230..0f5a434bcc 100644 --- a/examples/widgets/itemviews/basicsortfiltermodel/window.cpp +++ b/examples/widgets/itemviews/basicsortfiltermodel/window.cpp @@ -77,16 +77,18 @@ Window::Window() filterColumnLabel = new QLabel(tr("Filter &column:")); filterColumnLabel->setBuddy(filterColumnComboBox); - connect(filterPatternLineEdit, SIGNAL(textChanged(QString)), - this, SLOT(filterRegExpChanged())); - connect(filterSyntaxComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(filterRegExpChanged())); - connect(filterColumnComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(filterColumnChanged())); - connect(filterCaseSensitivityCheckBox, SIGNAL(toggled(bool)), - this, SLOT(filterRegExpChanged())); - connect(sortCaseSensitivityCheckBox, SIGNAL(toggled(bool)), - this, SLOT(sortChanged())); + connect(filterPatternLineEdit, &QLineEdit::textChanged, + this, &Window::filterRegExpChanged); + + typedef void (QComboBox::*QComboIntSignal)(int); + connect(filterSyntaxComboBox, static_cast<QComboIntSignal>(&QComboBox::currentIndexChanged), + this, &Window::filterRegExpChanged); + connect(filterColumnComboBox, static_cast<QComboIntSignal>(&QComboBox::currentIndexChanged), + this, &Window::filterColumnChanged); + connect(filterCaseSensitivityCheckBox, &QAbstractButton::toggled, + this, &Window::filterRegExpChanged); + connect(sortCaseSensitivityCheckBox, &QAbstractButton::toggled, + this, &Window::sortChanged); sourceGroupBox = new QGroupBox(tr("Original Model")); proxyGroupBox = new QGroupBox(tr("Sorted/Filtered Model")); diff --git a/examples/widgets/itemviews/chart/mainwindow.cpp b/examples/widgets/itemviews/chart/mainwindow.cpp index 646b8a293a..9a3b372233 100644 --- a/examples/widgets/itemviews/chart/mainwindow.cpp +++ b/examples/widgets/itemviews/chart/mainwindow.cpp @@ -56,14 +56,14 @@ MainWindow::MainWindow() setupModel(); setupViews(); - connect(openAction, SIGNAL(triggered()), this, SLOT(openFile())); - connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile())); - connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(openAction, &QAction::triggered, this, &MainWindow::openFile); + connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); + connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); menuBar()->addMenu(fileMenu); statusBar(); - openFile(":/Charts/qtdata.cht"); + loadFile(":/Charts/qtdata.cht"); setWindowTitle(tr("Chart")); resize(870, 550); @@ -99,17 +99,16 @@ void MainWindow::setupViews() setCentralWidget(splitter); } -void MainWindow::openFile(const QString &path) +void MainWindow::openFile() { - QString fileName; - if (path.isNull()) - fileName = QFileDialog::getOpenFileName(this, tr("Choose a data file"), "", "*.cht"); - else - fileName = path; - - if (fileName.isEmpty()) - return; + const QString fileName = + QFileDialog::getOpenFileName(this, tr("Choose a data file"), "", "*.cht"); + if (!fileName.isEmpty()) + loadFile(fileName); +} +void MainWindow::loadFile(const QString &fileName) +{ QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) return; diff --git a/examples/widgets/itemviews/chart/mainwindow.h b/examples/widgets/itemviews/chart/mainwindow.h index 2fc47bb75b..523ad70441 100644 --- a/examples/widgets/itemviews/chart/mainwindow.h +++ b/examples/widgets/itemviews/chart/mainwindow.h @@ -57,12 +57,13 @@ public: MainWindow(); private slots: - void openFile(const QString &path = QString()); + void openFile(); void saveFile(); private: void setupModel(); void setupViews(); + void loadFile(const QString &path); QAbstractItemModel *model; QAbstractItemView *pieChart; diff --git a/examples/widgets/itemviews/combowidgetmapper/window.cpp b/examples/widgets/itemviews/combowidgetmapper/window.cpp index d135ffb33f..3a6f649856 100644 --- a/examples/widgets/itemviews/combowidgetmapper/window.cpp +++ b/examples/widgets/itemviews/combowidgetmapper/window.cpp @@ -72,12 +72,12 @@ Window::Window(QWidget *parent) //! [Set up the mapper] //! [Set up connections and layouts] - connect(previousButton, SIGNAL(clicked()), - mapper, SLOT(toPrevious())); - connect(nextButton, SIGNAL(clicked()), - mapper, SLOT(toNext())); - connect(mapper, SIGNAL(currentIndexChanged(int)), - this, SLOT(updateButtons(int))); + connect(previousButton, &QAbstractButton::clicked, + mapper, &QDataWidgetMapper::toPrevious); + connect(nextButton, &QAbstractButton::clicked, + mapper, &QDataWidgetMapper::toNext); + connect(mapper, &QDataWidgetMapper::currentIndexChanged, + this, &Window::updateButtons); QGridLayout *layout = new QGridLayout(); layout->addWidget(nameLabel, 0, 0, 1, 1); diff --git a/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp b/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp index 6b5896f3c1..12019e606a 100644 --- a/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp +++ b/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp @@ -55,12 +55,12 @@ FilterWidget::FilterWidget(QWidget *parent) , m_patternGroup(new QActionGroup(this)) { setClearButtonEnabled(true); - connect(this, SIGNAL(textChanged(QString)), this, SIGNAL(filterChanged())); + connect(this, &QLineEdit::textChanged, this, &FilterWidget::filterChanged); QMenu *menu = new QMenu(this); m_caseSensitivityAction = menu->addAction(tr("Case Sensitive")); m_caseSensitivityAction->setCheckable(true); - connect(m_caseSensitivityAction, SIGNAL(toggled(bool)), this, SIGNAL(filterChanged())); + connect(m_caseSensitivityAction, &QAction::toggled, this, &FilterWidget::filterChanged); menu->addSeparator(); m_patternGroup->setExclusive(true); @@ -77,7 +77,7 @@ FilterWidget::FilterWidget(QWidget *parent) patternAction->setCheckable(true); patternAction->setData(QVariant(int(QRegExp::Wildcard))); m_patternGroup->addAction(patternAction); - connect(m_patternGroup, SIGNAL(triggered(QAction*)), this, SIGNAL(filterChanged())); + connect(m_patternGroup, &QActionGroup::triggered, this, &FilterWidget::filterChanged); const QIcon icon = QIcon(QPixmap(":/images/find.png")); QToolButton *optionsButton = new QToolButton; diff --git a/examples/widgets/itemviews/customsortfiltermodel/window.cpp b/examples/widgets/itemviews/customsortfiltermodel/window.cpp index 8653df2a61..ff07dfe79c 100644 --- a/examples/widgets/itemviews/customsortfiltermodel/window.cpp +++ b/examples/widgets/itemviews/customsortfiltermodel/window.cpp @@ -66,7 +66,7 @@ Window::Window() //! [3] filterWidget = new FilterWidget; filterWidget->setText("Grace|Sports"); - connect(filterWidget, SIGNAL(filterChanged()), this, SLOT(textFilterChanged())); + connect(filterWidget, &FilterWidget::filterChanged, this, &Window::textFilterChanged); filterPatternLabel = new QLabel(tr("&Filter pattern:")); filterPatternLabel->setBuddy(filterWidget); @@ -81,13 +81,13 @@ Window::Window() toLabel = new QLabel(tr("&To:")); toLabel->setBuddy(toDateEdit); - connect(filterWidget, SIGNAL(textChanged(QString)), - this, SLOT(textFilterChanged())); - connect(fromDateEdit, SIGNAL(dateChanged(QDate)), - this, SLOT(dateFilterChanged())); - connect(toDateEdit, SIGNAL(dateChanged(QDate)), + connect(filterWidget, &QLineEdit::textChanged, + this, &Window::textFilterChanged); + connect(fromDateEdit, &QDateTimeEdit::dateChanged, + this, &Window::dateFilterChanged); + connect(toDateEdit, &QDateTimeEdit::dateChanged, //! [3] //! [4] - this, SLOT(dateFilterChanged())); + this, &Window::dateFilterChanged); //! [4] //! [5] diff --git a/examples/widgets/itemviews/editabletreemodel/mainwindow.cpp b/examples/widgets/itemviews/editabletreemodel/mainwindow.cpp index c7abe59c77..f138e27095 100644 --- a/examples/widgets/itemviews/editabletreemodel/mainwindow.cpp +++ b/examples/widgets/itemviews/editabletreemodel/mainwindow.cpp @@ -60,19 +60,17 @@ MainWindow::MainWindow(QWidget *parent) for (int column = 0; column < model->columnCount(); ++column) view->resizeColumnToContents(column); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit); - connect(view->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection &, - const QItemSelection &)), - this, SLOT(updateActions())); + connect(view->selectionModel(), &QItemSelectionModel::selectionChanged, + this, &MainWindow::updateActions); - connect(actionsMenu, SIGNAL(aboutToShow()), this, SLOT(updateActions())); - connect(insertRowAction, SIGNAL(triggered()), this, SLOT(insertRow())); - connect(insertColumnAction, SIGNAL(triggered()), this, SLOT(insertColumn())); - connect(removeRowAction, SIGNAL(triggered()), this, SLOT(removeRow())); - connect(removeColumnAction, SIGNAL(triggered()), this, SLOT(removeColumn())); - connect(insertChildAction, SIGNAL(triggered()), this, SLOT(insertChild())); + connect(actionsMenu, &QMenu::aboutToShow, this, &MainWindow::updateActions); + connect(insertRowAction, &QAction::triggered, this, &MainWindow::insertRow); + connect(insertColumnAction, &QAction::triggered, this, &MainWindow::insertColumn); + connect(removeRowAction, &QAction::triggered, this, &MainWindow::removeRow); + connect(removeColumnAction, &QAction::triggered, this, &MainWindow::removeColumn); + connect(insertChildAction, &QAction::triggered, this, &MainWindow::insertChild); updateActions(); } @@ -102,13 +100,13 @@ void MainWindow::insertChild() updateActions(); } -bool MainWindow::insertColumn(const QModelIndex &parent) +bool MainWindow::insertColumn() { QAbstractItemModel *model = view->model(); int column = view->selectionModel()->currentIndex().column(); // Insert a column in the parent item. - bool changed = model->insertColumn(column + 1, parent); + bool changed = model->insertColumn(column + 1); if (changed) model->setHeaderData(column + 1, Qt::Horizontal, QVariant("[No header]"), Qt::EditRole); @@ -133,15 +131,15 @@ void MainWindow::insertRow() } } -bool MainWindow::removeColumn(const QModelIndex &parent) +bool MainWindow::removeColumn() { QAbstractItemModel *model = view->model(); int column = view->selectionModel()->currentIndex().column(); // Insert columns in each child of the parent item. - bool changed = model->removeColumn(column, parent); + bool changed = model->removeColumn(column); - if (!parent.isValid() && changed) + if (changed) updateActions(); return changed; diff --git a/examples/widgets/itemviews/editabletreemodel/mainwindow.h b/examples/widgets/itemviews/editabletreemodel/mainwindow.h index 4626ecbc2a..4c164f88c1 100644 --- a/examples/widgets/itemviews/editabletreemodel/mainwindow.h +++ b/examples/widgets/itemviews/editabletreemodel/mainwindow.h @@ -58,9 +58,9 @@ public slots: private slots: void insertChild(); - bool insertColumn(const QModelIndex &parent = QModelIndex()); + bool insertColumn(); void insertRow(); - bool removeColumn(const QModelIndex &parent = QModelIndex()); + bool removeColumn(); void removeRow(); }; diff --git a/examples/widgets/itemviews/fetchmore/window.cpp b/examples/widgets/itemviews/fetchmore/window.cpp index eefa09622d..aa4e0adc90 100644 --- a/examples/widgets/itemviews/fetchmore/window.cpp +++ b/examples/widgets/itemviews/fetchmore/window.cpp @@ -59,12 +59,12 @@ Window::Window(QWidget *parent) logViewer = new QTextBrowser; logViewer->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); - connect(lineEdit, SIGNAL(textChanged(QString)), - model, SLOT(setDirPath(QString))); - connect(lineEdit, SIGNAL(textChanged(QString)), - logViewer, SLOT(clear())); - connect(model, SIGNAL(numberPopulated(int)), - this, SLOT(updateLog(int))); + connect(lineEdit, &QLineEdit::textChanged, + model, &FileListModel::setDirPath); + connect(lineEdit, &QLineEdit::textChanged, + logViewer, &QTextEdit::clear); + connect(model, &FileListModel::numberPopulated, + this, &Window::updateLog); QGridLayout *layout = new QGridLayout; layout->addWidget(label, 0, 0); diff --git a/examples/widgets/itemviews/frozencolumn/freezetablewidget.cpp b/examples/widgets/itemviews/frozencolumn/freezetablewidget.cpp index 254786b16e..c2233abcc2 100644 --- a/examples/widgets/itemviews/frozencolumn/freezetablewidget.cpp +++ b/examples/widgets/itemviews/frozencolumn/freezetablewidget.cpp @@ -52,15 +52,15 @@ FreezeTableWidget::FreezeTableWidget(QAbstractItemModel * model) init(); //connect the headers and scrollbars of both tableviews together - connect(horizontalHeader(),SIGNAL(sectionResized(int,int,int)), this, - SLOT(updateSectionWidth(int,int,int))); - connect(verticalHeader(),SIGNAL(sectionResized(int,int,int)), this, - SLOT(updateSectionHeight(int,int,int))); - - connect(frozenTableView->verticalScrollBar(), SIGNAL(valueChanged(int)), - verticalScrollBar(), SLOT(setValue(int))); - connect(verticalScrollBar(), SIGNAL(valueChanged(int)), - frozenTableView->verticalScrollBar(), SLOT(setValue(int))); + connect(horizontalHeader(),&QHeaderView::sectionResized, this, + &FreezeTableWidget::updateSectionWidth); + connect(verticalHeader(),&QHeaderView::sectionResized, this, + &FreezeTableWidget::updateSectionHeight); + + connect(frozenTableView->verticalScrollBar(), &QAbstractSlider::valueChanged, + verticalScrollBar(), &QAbstractSlider::setValue); + connect(verticalScrollBar(), &QAbstractSlider::valueChanged, + frozenTableView->verticalScrollBar(), &QAbstractSlider::setValue); } diff --git a/examples/widgets/itemviews/pixelator/mainwindow.cpp b/examples/widgets/itemviews/pixelator/mainwindow.cpp index a05880225b..bab130a2b2 100644 --- a/examples/widgets/itemviews/pixelator/mainwindow.cpp +++ b/examples/widgets/itemviews/pixelator/mainwindow.cpp @@ -98,15 +98,16 @@ MainWindow::MainWindow() menuBar()->addSeparator(); menuBar()->addMenu(helpMenu); - connect(openAction, SIGNAL(triggered()), this, SLOT(chooseImage())); - connect(printAction, SIGNAL(triggered()), this, SLOT(printImage())); - connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(aboutAction, SIGNAL(triggered()), this, SLOT(showAboutBox())); + connect(openAction, &QAction::triggered, this, &MainWindow::chooseImage); + connect(printAction, &QAction::triggered, this, &MainWindow::printImage); + connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); + connect(aboutAction, &QAction::triggered, this, &MainWindow::showAboutBox); //! [4] - connect(pixelSizeSpinBox, SIGNAL(valueChanged(int)), - delegate, SLOT(setPixelSize(int))); - connect(pixelSizeSpinBox, SIGNAL(valueChanged(int)), - this, SLOT(updateView())); + typedef void (QSpinBox::*QSpinBoxIntSignal)(int); + connect(pixelSizeSpinBox, static_cast<QSpinBoxIntSignal>(&QSpinBox::valueChanged), + delegate, &PixelDelegate::setPixelSize); + connect(pixelSizeSpinBox, static_cast<QSpinBoxIntSignal>(&QSpinBox::valueChanged), + this, &MainWindow::updateView); //! [4] QHBoxLayout *controlsLayout = new QHBoxLayout; diff --git a/examples/widgets/itemviews/puzzle/main.cpp b/examples/widgets/itemviews/puzzle/main.cpp index 866c6f0d8b..a7980489a8 100644 --- a/examples/widgets/itemviews/puzzle/main.cpp +++ b/examples/widgets/itemviews/puzzle/main.cpp @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); MainWindow window; - window.openImage(":/images/example.jpg"); + window.loadImage(":/images/example.jpg"); window.show(); return app.exec(); } diff --git a/examples/widgets/itemviews/puzzle/mainwindow.cpp b/examples/widgets/itemviews/puzzle/mainwindow.cpp index 2e2a1d0ab5..5cd9a7f0df 100644 --- a/examples/widgets/itemviews/puzzle/mainwindow.cpp +++ b/examples/widgets/itemviews/puzzle/mainwindow.cpp @@ -57,26 +57,27 @@ MainWindow::MainWindow(QWidget *parent) setWindowTitle(tr("Puzzle")); } -void MainWindow::openImage(const QString &path) +void MainWindow::openImage() { - QString fileName = path; - - if (fileName.isNull()) { - fileName = QFileDialog::getOpenFileName(this, - tr("Open Image"), "", tr("Image Files (*.png *.jpg *.bmp)")); - } + const QString fileName = + QFileDialog::getOpenFileName(this, + tr("Open Image"), QString(), + tr("Image Files (*.png *.jpg *.bmp)")); + if (!fileName.isEmpty()) + loadImage(fileName); +} - if (!fileName.isEmpty()) { - QPixmap newImage; - if (!newImage.load(fileName)) { - QMessageBox::warning(this, tr("Open Image"), - tr("The image file could not be loaded."), - QMessageBox::Cancel); - return; - } - puzzleImage = newImage; - setupPuzzle(); +void MainWindow::loadImage(const QString &fileName) +{ + QPixmap newImage; + if (!newImage.load(fileName)) { + QMessageBox::warning(this, tr("Open Image"), + tr("The image file could not be loaded."), + QMessageBox::Cancel); + return; } + puzzleImage = newImage; + setupPuzzle(); } void MainWindow::setCompleted() @@ -116,9 +117,9 @@ void MainWindow::setupMenus() QAction *restartAction = gameMenu->addAction(tr("&Restart")); - connect(openAction, SIGNAL(triggered()), this, SLOT(openImage())); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(restartAction, SIGNAL(triggered()), this, SLOT(setupPuzzle())); + connect(openAction, &QAction::triggered, this, &MainWindow::openImage); + connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit); + connect(restartAction, &QAction::triggered, this, &MainWindow::setupPuzzle); } void MainWindow::setupWidgets() @@ -141,8 +142,8 @@ void MainWindow::setupWidgets() PiecesModel *model = new PiecesModel(puzzleWidget->pieceSize(), this); piecesList->setModel(model); - connect(puzzleWidget, SIGNAL(puzzleCompleted()), - this, SLOT(setCompleted()), Qt::QueuedConnection); + connect(puzzleWidget, &PuzzleWidget::puzzleCompleted, + this, &MainWindow::setCompleted, Qt::QueuedConnection); frameLayout->addWidget(piecesList); frameLayout->addWidget(puzzleWidget); diff --git a/examples/widgets/itemviews/puzzle/mainwindow.h b/examples/widgets/itemviews/puzzle/mainwindow.h index 86daf0af2d..440dd46377 100644 --- a/examples/widgets/itemviews/puzzle/mainwindow.h +++ b/examples/widgets/itemviews/puzzle/mainwindow.h @@ -58,7 +58,8 @@ public: MainWindow(QWidget *parent = 0); public slots: - void openImage(const QString &path = QString()); + void openImage(); + void loadImage(const QString &path); void setupPuzzle(); private slots: diff --git a/examples/widgets/itemviews/simpledommodel/mainwindow.cpp b/examples/widgets/itemviews/simpledommodel/mainwindow.cpp index 4dc87dac1a..c11fb40a0e 100644 --- a/examples/widgets/itemviews/simpledommodel/mainwindow.cpp +++ b/examples/widgets/itemviews/simpledommodel/mainwindow.cpp @@ -49,8 +49,8 @@ MainWindow::MainWindow() : QMainWindow(), model(0) { fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(tr("&Open..."), this, SLOT(openFile()), QKeySequence::Open); - fileMenu->addAction(tr("E&xit"), this, SLOT(close()), QKeySequence::Quit); + fileMenu->addAction(tr("&Open..."), this, &MainWindow::openFile, QKeySequence::Open); + fileMenu->addAction(tr("E&xit"), this, &QWidget::close, QKeySequence::Quit); model = new DomModel(QDomDocument(), this); view = new QTreeView(this); diff --git a/examples/widgets/itemviews/simplewidgetmapper/window.cpp b/examples/widgets/itemviews/simplewidgetmapper/window.cpp index 9df004430b..0d99acc603 100644 --- a/examples/widgets/itemviews/simplewidgetmapper/window.cpp +++ b/examples/widgets/itemviews/simplewidgetmapper/window.cpp @@ -69,9 +69,9 @@ Window::Window(QWidget *parent) mapper->addMapping(addressEdit, 1); mapper->addMapping(ageSpinBox, 2); - connect(previousButton, SIGNAL(clicked()), mapper, SLOT(toPrevious())); - connect(nextButton, SIGNAL(clicked()), mapper, SLOT(toNext())); - connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(updateButtons(int))); + connect(previousButton, &QAbstractButton::clicked, mapper, &QDataWidgetMapper::toPrevious); + connect(nextButton, &QAbstractButton::clicked, mapper, &QDataWidgetMapper::toNext); + connect(mapper, &QDataWidgetMapper::currentIndexChanged, this, &Window::updateButtons); //! [Set up the mapper] //! [Set up the layout] diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp index 02e635b87a..41b51c1071 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp +++ b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp @@ -73,17 +73,17 @@ SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent) setCentralWidget(table); statusBar(); - connect(table, SIGNAL(currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)), - this, SLOT(updateStatus(QTableWidgetItem*))); - connect(table, SIGNAL(currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)), - this, SLOT(updateColor(QTableWidgetItem*))); - connect(table, SIGNAL(currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)), - this, SLOT(updateLineEdit(QTableWidgetItem*))); - connect(table, SIGNAL(itemChanged(QTableWidgetItem*)), - this, SLOT(updateStatus(QTableWidgetItem*))); - connect(formulaInput, SIGNAL(returnPressed()), this, SLOT(returnPressed())); - connect(table, SIGNAL(itemChanged(QTableWidgetItem*)), - this, SLOT(updateLineEdit(QTableWidgetItem*))); + connect(table, &QTableWidget::currentItemChanged, + this, &SpreadSheet::updateStatus); + connect(table, &QTableWidget::currentItemChanged, + this, &SpreadSheet::updateColor); + connect(table, &QTableWidget::currentItemChanged, + this, &SpreadSheet::updateLineEdit); + connect(table, &QTableWidget::itemChanged, + this, &SpreadSheet::updateStatus); + connect(formulaInput, &QLineEdit::returnPressed, this, &SpreadSheet::returnPressed); + connect(table, &QTableWidget::itemChanged, + this, &SpreadSheet::updateLineEdit); setWindowTitle(tr("Spreadsheet")); } @@ -91,43 +91,43 @@ SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent) void SpreadSheet::createActions() { cell_sumAction = new QAction(tr("Sum"), this); - connect(cell_sumAction, SIGNAL(triggered()), this, SLOT(actionSum())); + connect(cell_sumAction, &QAction::triggered, this, &SpreadSheet::actionSum); cell_addAction = new QAction(tr("&Add"), this); cell_addAction->setShortcut(Qt::CTRL | Qt::Key_Plus); - connect(cell_addAction, SIGNAL(triggered()), this, SLOT(actionAdd())); + connect(cell_addAction, &QAction::triggered, this, &SpreadSheet::actionAdd); cell_subAction = new QAction(tr("&Subtract"), this); cell_subAction->setShortcut(Qt::CTRL | Qt::Key_Minus); - connect(cell_subAction, SIGNAL(triggered()), this, SLOT(actionSubtract())); + connect(cell_subAction, &QAction::triggered, this, &SpreadSheet::actionSubtract); cell_mulAction = new QAction(tr("&Multiply"), this); cell_mulAction->setShortcut(Qt::CTRL | Qt::Key_multiply); - connect(cell_mulAction, SIGNAL(triggered()), this, SLOT(actionMultiply())); + connect(cell_mulAction, &QAction::triggered, this, &SpreadSheet::actionMultiply); cell_divAction = new QAction(tr("&Divide"), this); cell_divAction->setShortcut(Qt::CTRL | Qt::Key_division); - connect(cell_divAction, SIGNAL(triggered()), this, SLOT(actionDivide())); + connect(cell_divAction, &QAction::triggered, this, &SpreadSheet::actionDivide); fontAction = new QAction(tr("Font..."), this); fontAction->setShortcut(Qt::CTRL | Qt::Key_F); - connect(fontAction, SIGNAL(triggered()), this, SLOT(selectFont())); + connect(fontAction, &QAction::triggered, this, &SpreadSheet::selectFont); colorAction = new QAction(QPixmap(16, 16), tr("Background &Color..."), this); - connect(colorAction, SIGNAL(triggered()), this, SLOT(selectColor())); + connect(colorAction, &QAction::triggered, this, &SpreadSheet::selectColor); clearAction = new QAction(tr("Clear"), this); clearAction->setShortcut(Qt::Key_Delete); - connect(clearAction, SIGNAL(triggered()), this, SLOT(clear())); + connect(clearAction, &QAction::triggered, this, &SpreadSheet::clear); aboutSpreadSheet = new QAction(tr("About Spreadsheet"), this); - connect(aboutSpreadSheet, SIGNAL(triggered()), this, SLOT(showAbout())); + connect(aboutSpreadSheet, &QAction::triggered, this, &SpreadSheet::showAbout); exitAction = new QAction(tr("E&xit"), this); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit); printAction = new QAction(tr("&Print"), this); - connect(printAction, SIGNAL(triggered()), this, SLOT(print())); + connect(printAction, &QAction::triggered, this, &SpreadSheet::print); firstSeparator = new QAction(this); firstSeparator->setSeparator(true); @@ -309,11 +309,11 @@ bool SpreadSheet::runInputDialog(const QString &title, outColInput.setCurrentIndex(outCol); QPushButton cancelButton(tr("Cancel"), &addDialog); - connect(&cancelButton, SIGNAL(clicked()), &addDialog, SLOT(reject())); + connect(&cancelButton, &QAbstractButton::clicked, &addDialog, &QDialog::reject); QPushButton okButton(tr("OK"), &addDialog); okButton.setDefault(true); - connect(&okButton, SIGNAL(clicked()), &addDialog, SLOT(accept())); + connect(&okButton, &QAbstractButton::clicked, &addDialog, &QDialog::accept); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addStretch(1); @@ -625,7 +625,7 @@ void SpreadSheet::print() QPrintPreviewDialog dlg(&printer); PrintView view; view.setModel(table->model()); - connect(&dlg, SIGNAL(paintRequested(QPrinter*)), &view, SLOT(print(QPrinter*))); + connect(&dlg, &QPrintPreviewDialog::paintRequested, &view, &PrintView::print); dlg.exec(); #endif } diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp index d056e3f8e4..a7404fe159 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp +++ b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp @@ -63,7 +63,7 @@ QWidget *SpreadSheetDelegate::createEditor(QWidget *parent, QCompleter *autoComplete = new QCompleter(allStrings); editor->setCompleter(autoComplete); - connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); + connect(editor, &QLineEdit::editingFinished, this, &SpreadSheetDelegate::commitAndCloseEditor); return editor; } diff --git a/examples/widgets/itemviews/stardelegate/stardelegate.cpp b/examples/widgets/itemviews/stardelegate/stardelegate.cpp index 48f6eb543b..a9e8f71699 100644 --- a/examples/widgets/itemviews/stardelegate/stardelegate.cpp +++ b/examples/widgets/itemviews/stardelegate/stardelegate.cpp @@ -83,8 +83,8 @@ QWidget *StarDelegate::createEditor(QWidget *parent, { if (index.data().canConvert<StarRating>()) { StarEditor *editor = new StarEditor(parent); - connect(editor, SIGNAL(editingFinished()), - this, SLOT(commitAndCloseEditor())); + connect(editor, &StarEditor::editingFinished, + this, &StarDelegate::commitAndCloseEditor); return editor; } else { return QStyledItemDelegate::createEditor(parent, option, index); diff --git a/examples/widgets/mainwindows/application/main.cpp b/examples/widgets/mainwindows/application/main.cpp index 41913db07e..73c1cf57d3 100644 --- a/examples/widgets/mainwindows/application/main.cpp +++ b/examples/widgets/mainwindows/application/main.cpp @@ -40,6 +40,8 @@ //! [0] #include <QApplication> +#include <QCommandLineParser> +#include <QCommandLineOption> #include "mainwindow.h" @@ -48,9 +50,19 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(application); QApplication app(argc, argv); - app.setOrganizationName("QtProject"); - app.setApplicationName("Application Example"); + QCoreApplication::setOrganizationName("QtProject"); + QCoreApplication::setApplicationName("Application Example"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::applicationName()); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("file", "The file to open."); + parser.process(app); + MainWindow mainWin; + if (!parser.positionalArguments().isEmpty()) + mainWin.loadFile(parser.positionalArguments().first()); mainWin.show(); return app.exec(); } diff --git a/examples/widgets/mainwindows/application/mainwindow.cpp b/examples/widgets/mainwindows/application/mainwindow.cpp index d3f9c7645e..7a93a0cd22 100644 --- a/examples/widgets/mainwindows/application/mainwindow.cpp +++ b/examples/widgets/mainwindows/application/mainwindow.cpp @@ -46,22 +46,20 @@ //! [1] MainWindow::MainWindow() + : textEdit(new QPlainTextEdit) //! [1] //! [2] { - textEdit = new QPlainTextEdit; setCentralWidget(textEdit); createActions(); - createMenus(); - createToolBars(); createStatusBar(); readSettings(); - connect(textEdit->document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(textEdit->document(), &QTextDocument::contentsChanged, + this, &MainWindow::documentWasModified); - setCurrentFile(""); + setCurrentFile(QString()); setUnifiedTitleAndToolBarOnMac(true); } //! [2] @@ -85,7 +83,7 @@ void MainWindow::newFile() { if (maybeSave()) { textEdit->clear(); - setCurrentFile(""); + setCurrentFile(QString()); } } //! [6] @@ -121,13 +119,9 @@ bool MainWindow::saveAs() QFileDialog dialog(this); dialog.setWindowModality(Qt::WindowModal); dialog.setAcceptMode(QFileDialog::AcceptSave); - QStringList files; - if (dialog.exec()) - files = dialog.selectedFiles(); - else + if (dialog.exec() != QDialog::Accepted) return false; - - return saveFile(files.at(0)); + return saveFile(dialog.selectedFiles().first()); } //! [12] @@ -154,121 +148,103 @@ void MainWindow::documentWasModified() void MainWindow::createActions() //! [17] //! [18] { - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); + + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newAct = new QAction(newIcon, tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); //! [19] - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); //! [18] //! [19] - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); - saveAsAct = new QAction(tr("Save &As..."), this); + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + QAction *saveAsAct = fileMenu->addAction(saveAsIcon, tr("Save &As..."), this, &MainWindow::saveAs); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); //! [20] - exitAct = new QAction(tr("E&xit"), this); + + fileMenu->addSeparator(); + + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close); exitAct->setShortcuts(QKeySequence::Quit); //! [20] exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); //! [21] - cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); +//! + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this); //! [21] cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut())); + connect(cutAct, &QAction::triggered, textEdit, &QPlainTextEdit::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); - copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + QAction *copyAct = new QAction(copyIcon, tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy())); + connect(copyAct, &QAction::triggered, textEdit, &QPlainTextEdit::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); - pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + QAction *pasteAct = new QAction(pasteIcon, tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste())); + connect(pasteAct, &QAction::triggered, textEdit, &QPlainTextEdit::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); + + menuBar()->addSeparator(); - aboutAct = new QAction(tr("&About"), this); + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); //! [22] - aboutQtAct = new QAction(tr("About &Qt"), this); + + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); //! [22] //! [23] cutAct->setEnabled(false); //! [23] //! [24] copyAct->setEnabled(false); - connect(textEdit, SIGNAL(copyAvailable(bool)), - cutAct, SLOT(setEnabled(bool))); - connect(textEdit, SIGNAL(copyAvailable(bool)), - copyAct, SLOT(setEnabled(bool))); + connect(textEdit, &QPlainTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(textEdit, &QPlainTextEdit::copyAvailable, copyAct, &QAction::setEnabled); } //! [24] -//! [25] //! [26] -void MainWindow::createMenus() -//! [25] //! [27] -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); -//! [28] - fileMenu->addAction(openAct); -//! [28] - fileMenu->addAction(saveAct); -//! [26] - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(exitAct); - - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} -//! [27] - -//! [29] //! [30] -void MainWindow::createToolBars() -{ - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); -//! [29] //! [31] - fileToolBar->addAction(openAct); -//! [31] - fileToolBar->addAction(saveAct); - - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); -} -//! [30] - //! [32] void MainWindow::createStatusBar() //! [32] //! [33] @@ -281,11 +257,16 @@ void MainWindow::createStatusBar() void MainWindow::readSettings() //! [34] //! [36] { - QSettings settings("QtProject", "Application Example"); - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); - resize(size); - move(pos); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } } //! [35] //! [36] @@ -293,9 +274,8 @@ void MainWindow::readSettings() void MainWindow::writeSettings() //! [37] //! [39] { - QSettings settings("QtProject", "Application Example"); - settings.setValue("pos", pos()); - settings.setValue("size", size()); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); } //! [38] //! [39] @@ -303,16 +283,20 @@ void MainWindow::writeSettings() bool MainWindow::maybeSave() //! [40] //! [41] { - if (textEdit->document()->isModified()) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("Application"), - tr("The document has been modified.\n" - "Do you want to save your changes?"), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; + if (!textEdit->document()->isModified()) + return true; + const QMessageBox::StandardButton ret + = QMessageBox::warning(this, tr("Application"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; } return true; } @@ -326,8 +310,7 @@ void MainWindow::loadFile(const QString &fileName) if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("Application"), tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } @@ -353,8 +336,8 @@ bool MainWindow::saveFile(const QString &fileName) if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("Application"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), + file.errorString())); return false; } diff --git a/examples/widgets/mainwindows/application/mainwindow.h b/examples/widgets/mainwindows/application/mainwindow.h index cb791abf00..08b4aa17f5 100644 --- a/examples/widgets/mainwindows/application/mainwindow.h +++ b/examples/widgets/mainwindows/application/mainwindow.h @@ -57,6 +57,8 @@ class MainWindow : public QMainWindow public: MainWindow(); + void loadFile(const QString &fileName); + protected: void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; @@ -70,35 +72,16 @@ private slots: private: void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); bool maybeSave(); - void loadFile(const QString &fileName); bool saveFile(const QString &fileName); void setCurrentFile(const QString &fileName); QString strippedName(const QString &fullFileName); QPlainTextEdit *textEdit; QString curFile; - - QMenu *fileMenu; - QMenu *editMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; - QAction *newAct; - QAction *openAct; - QAction *saveAct; - QAction *saveAsAct; - QAction *exitAct; - QAction *cutAct; - QAction *copyAct; - QAction *pasteAct; - QAction *aboutAct; - QAction *aboutQtAct; }; //! [0] diff --git a/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp b/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp index 20c2bd1c70..c0472b537c 100644 --- a/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp +++ b/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp @@ -49,13 +49,11 @@ //! [1] MainWindow::MainWindow() + : textEdit(new QTextEdit) { - textEdit = new QTextEdit; setCentralWidget(textEdit); createActions(); - createMenus(); - createToolBars(); createStatusBar(); createDockWindows(); @@ -135,17 +133,17 @@ void MainWindow::print() //! [4] void MainWindow::save() { + QMimeDatabase mimeDatabase; QString fileName = QFileDialog::getSaveFileName(this, tr("Choose a file name"), ".", - tr("HTML (*.html *.htm)")); + mimeDatabase.mimeTypeForName("text/html").filterString()); if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("Dock Widgets"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } @@ -222,71 +220,60 @@ void MainWindow::about() void MainWindow::createActions() { - newLetterAct = new QAction(QIcon(":/images/new.png"), tr("&New Letter"), - this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newLetterAct = new QAction(newIcon, tr("&New Letter"), this); newLetterAct->setShortcuts(QKeySequence::New); newLetterAct->setStatusTip(tr("Create a new form letter")); - connect(newLetterAct, SIGNAL(triggered()), this, SLOT(newLetter())); + connect(newLetterAct, &QAction::triggered, this, &MainWindow::newLetter); + fileMenu->addAction(newLetterAct); + fileToolBar->addAction(newLetterAct); - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save..."), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save..."), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the current form letter")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); - printAct = new QAction(QIcon(":/images/print.png"), tr("&Print..."), this); + const QIcon printIcon = QIcon::fromTheme("document-print", QIcon(":/images/print.png")); + QAction *printAct = new QAction(printIcon, tr("&Print..."), this); printAct->setShortcuts(QKeySequence::Print); printAct->setStatusTip(tr("Print the current form letter")); - connect(printAct, SIGNAL(triggered()), this, SLOT(print())); + connect(printAct, &QAction::triggered, this, &MainWindow::print); + fileMenu->addAction(printAct); + fileToolBar->addAction(printAct); - undoAct = new QAction(QIcon(":/images/undo.png"), tr("&Undo"), this); - undoAct->setShortcuts(QKeySequence::Undo); - undoAct->setStatusTip(tr("Undo the last editing action")); - connect(undoAct, SIGNAL(triggered()), this, SLOT(undo())); + fileMenu->addSeparator(); - quitAct = new QAction(tr("&Quit"), this); + QAction *quitAct = fileMenu->addAction(tr("&Quit"), this, &QWidget::close); quitAct->setShortcuts(QKeySequence::Quit); quitAct->setStatusTip(tr("Quit the application")); - connect(quitAct, SIGNAL(triggered()), this, SLOT(close())); - - aboutAct = new QAction(tr("&About"), this); - aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newLetterAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(printAct); - fileMenu->addSeparator(); - fileMenu->addAction(quitAct); - editMenu = menuBar()->addMenu(tr("&Edit")); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + const QIcon undoIcon = QIcon::fromTheme("edit-undo", QIcon(":/images/undo.png")); + QAction *undoAct = new QAction(undoIcon, tr("&Undo"), this); + undoAct->setShortcuts(QKeySequence::Undo); + undoAct->setStatusTip(tr("Undo the last editing action")); + connect(undoAct, &QAction::triggered, this, &MainWindow::undo); editMenu->addAction(undoAct); + editToolBar->addAction(undoAct); viewMenu = menuBar()->addMenu(tr("&View")); menuBar()->addSeparator(); - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); -void MainWindow::createToolBars() -{ - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newLetterAct); - fileToolBar->addAction(saveAct); - fileToolBar->addAction(printAct); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); + aboutAct->setStatusTip(tr("Show the application's About box")); - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(undoAct); + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); + aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); } //! [8] @@ -337,9 +324,9 @@ void MainWindow::createDockWindows() addDockWidget(Qt::RightDockWidgetArea, dock); viewMenu->addAction(dock->toggleViewAction()); - connect(customerList, SIGNAL(currentTextChanged(QString)), - this, SLOT(insertCustomer(QString))); - connect(paragraphsList, SIGNAL(currentTextChanged(QString)), - this, SLOT(addParagraph(QString))); + connect(customerList, &QListWidget::currentTextChanged, + this, &MainWindow::insertCustomer); + connect(paragraphsList, &QListWidget::currentTextChanged, + this, &MainWindow::addParagraph); } //! [9] diff --git a/examples/widgets/mainwindows/dockwidgets/mainwindow.h b/examples/widgets/mainwindows/dockwidgets/mainwindow.h index 2fb161a20b..c244febf9a 100644 --- a/examples/widgets/mainwindows/dockwidgets/mainwindow.h +++ b/examples/widgets/mainwindows/dockwidgets/mainwindow.h @@ -69,8 +69,6 @@ private slots: private: void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void createDockWindows(); @@ -78,19 +76,7 @@ private: QListWidget *customerList; QListWidget *paragraphsList; - QMenu *fileMenu; - QMenu *editMenu; QMenu *viewMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; - QAction *newLetterAct; - QAction *saveAct; - QAction *printAct; - QAction *undoAct; - QAction *aboutAct; - QAction *aboutQtAct; - QAction *quitAct; }; //! [0] diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp index 408f6c4b0f..d746bbe8d3 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp @@ -42,6 +42,7 @@ #include <QImage> #include <QColor> #include <QDialog> +#include <QDialogButtonBox> #include <QGridLayout> #include <QSpinBox> #include <QLabel> @@ -57,15 +58,15 @@ QColor bgColorForName(const QString &name) { if (name == "Black") return QColor("#D8D8D8"); - else if (name == "White") + if (name == "White") return QColor("#F1F1F1"); - else if (name == "Red") + if (name == "Red") return QColor("#F1D8D8"); - else if (name == "Green") + if (name == "Green") return QColor("#D8E4D8"); - else if (name == "Blue") + if (name == "Blue") return QColor("#D8D8F1"); - else if (name == "Yellow") + if (name == "Yellow") return QColor("#F1F0D8"); return QColor(name).light(110); } @@ -74,15 +75,15 @@ QColor fgColorForName(const QString &name) { if (name == "Black") return QColor("#6C6C6C"); - else if (name == "White") + if (name == "White") return QColor("#F8F8F8"); - else if (name == "Red") + if (name == "Red") return QColor("#F86C6C"); - else if (name == "Green") + if (name == "Green") return QColor("#6CB26C"); - else if (name == "Blue") + if (name == "Blue") return QColor("#6C6CF8"); - else if (name == "Yellow") + if (name == "Yellow") return QColor("#F8F76C"); return QColor(name); } @@ -91,10 +92,10 @@ class ColorDock : public QFrame { Q_OBJECT public: - ColorDock(const QString &c, QWidget *parent); + explicit ColorDock(const QString &c, QWidget *parent); - virtual QSize sizeHint() const Q_DECL_OVERRIDE; - virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + QSize sizeHint() const Q_DECL_OVERRIDE { return szHint; } + QSize minimumSizeHint() const Q_DECL_OVERRIDE { return minSzHint; } void setCustomSizeHint(const QSize &size); @@ -103,28 +104,22 @@ public slots: protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; - QString color; - QSize szHint, minSzHint; + +private: + const QString color; + QSize szHint; + QSize minSzHint; }; ColorDock::ColorDock(const QString &c, QWidget *parent) - : QFrame(parent) , color(c) + : QFrame(parent) + , color(c) + , szHint(-1, -1) + , minSzHint(125, 75) { QFont font = this->font(); font.setPointSize(8); setFont(font); - szHint = QSize(-1, -1); - minSzHint = QSize(125, 75); -} - -QSize ColorDock::sizeHint() const -{ - return szHint; -} - -QSize ColorDock::minimumSizeHint() const -{ - return minSzHint; } void ColorDock::paintEvent(QPaintEvent *) @@ -178,6 +173,7 @@ static QSpinBox *createSpinBox(int value, QWidget *parent, int max = 1000) void ColorDock::changeSizeHints() { QDialog dialog(this); + dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); dialog.setWindowTitle(color); QVBoxLayout *topLayout = new QVBoxLayout(&dialog); @@ -188,7 +184,7 @@ void ColorDock::changeSizeHints() inputLayout->addWidget(new QLabel(tr("Size Hint:"), &dialog), 0, 0); inputLayout->addWidget(new QLabel(tr("Min Size Hint:"), &dialog), 1, 0); inputLayout->addWidget(new QLabel(tr("Max Size:"), &dialog), 2, 0); - inputLayout->addWidget(new QLabel(tr("Dockwgt Max Size:"), &dialog), 3, 0); + inputLayout->addWidget(new QLabel(tr("Dock Widget Max Size:"), &dialog), 3, 0); QSpinBox *szHintW = createSpinBox(szHint.width(), &dialog); inputLayout->addWidget(szHintW, 0, 1); @@ -217,19 +213,13 @@ void ColorDock::changeSizeHints() topLayout->addStretch(); - QHBoxLayout *buttonBox = new QHBoxLayout(); - topLayout->addLayout(buttonBox); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::reject); - QPushButton *okButton = new QPushButton(tr("Ok"), &dialog); - QPushButton *cancelButton = new QPushButton(tr("Cancel"), &dialog); - connect(okButton, SIGNAL(clicked()), &dialog, SLOT(accept())); - connect(cancelButton, SIGNAL(clicked()), &dialog, SLOT(reject())); - buttonBox->addStretch(); - buttonBox->addWidget(cancelButton); - buttonBox->addWidget(okButton); + topLayout->addWidget(buttonBox); - - if (!dialog.exec()) + if (dialog.exec() != QDialog::Accepted) return; szHint = QSize(szHintW->value(), szHintH->value()); @@ -244,63 +234,62 @@ void ColorDock::changeSizeHints() void ColorDock::setCustomSizeHint(const QSize &size) { - szHint = size; - updateGeometry(); + if (szHint != size) { + szHint = size; + updateGeometry(); + } } -ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFlags flags) - : QDockWidget(parent, flags) +ColorSwatch::ColorSwatch(const QString &colorName, QMainWindow *parent, Qt::WindowFlags flags) + : QDockWidget(parent, flags), mainWindow(parent) { setObjectName(colorName + QLatin1String(" Dock Widget")); setWindowTitle(objectName() + QLatin1String(" [*]")); - QFrame *swatch = new ColorDock(colorName, this); + ColorDock *swatch = new ColorDock(colorName, this); swatch->setFrameStyle(QFrame::Box | QFrame::Sunken); setWidget(swatch); - changeSizeHintsAction = new QAction(tr("Change Size Hints"), this); - connect(changeSizeHintsAction, SIGNAL(triggered()), swatch, SLOT(changeSizeHints())); - closableAction = new QAction(tr("Closable"), this); closableAction->setCheckable(true); - connect(closableAction, SIGNAL(triggered(bool)), SLOT(changeClosable(bool))); + connect(closableAction, &QAction::triggered, this, &ColorSwatch::changeClosable); movableAction = new QAction(tr("Movable"), this); movableAction->setCheckable(true); - connect(movableAction, SIGNAL(triggered(bool)), SLOT(changeMovable(bool))); + connect(movableAction, &QAction::triggered, this, &ColorSwatch::changeMovable); floatableAction = new QAction(tr("Floatable"), this); floatableAction->setCheckable(true); - connect(floatableAction, SIGNAL(triggered(bool)), SLOT(changeFloatable(bool))); + connect(floatableAction, &QAction::triggered, this, &ColorSwatch::changeFloatable); verticalTitleBarAction = new QAction(tr("Vertical title bar"), this); verticalTitleBarAction->setCheckable(true); - connect(verticalTitleBarAction, SIGNAL(triggered(bool)), - SLOT(changeVerticalTitleBar(bool))); + connect(verticalTitleBarAction, &QAction::triggered, + this, &ColorSwatch::changeVerticalTitleBar); floatingAction = new QAction(tr("Floating"), this); floatingAction->setCheckable(true); - connect(floatingAction, SIGNAL(triggered(bool)), SLOT(changeFloating(bool))); + connect(floatingAction, &QAction::triggered, this, &ColorSwatch::changeFloating); allowedAreasActions = new QActionGroup(this); allowedAreasActions->setExclusive(false); allowLeftAction = new QAction(tr("Allow on Left"), this); allowLeftAction->setCheckable(true); - connect(allowLeftAction, SIGNAL(triggered(bool)), SLOT(allowLeft(bool))); + connect(allowLeftAction, &QAction::triggered, this, &ColorSwatch::allowLeft); allowRightAction = new QAction(tr("Allow on Right"), this); allowRightAction->setCheckable(true); - connect(allowRightAction, SIGNAL(triggered(bool)), SLOT(allowRight(bool))); + connect(allowRightAction, &QAction::triggered, this, &ColorSwatch::allowRight); allowTopAction = new QAction(tr("Allow on Top"), this); allowTopAction->setCheckable(true); - connect(allowTopAction, SIGNAL(triggered(bool)), SLOT(allowTop(bool))); + connect(allowTopAction, &QAction::triggered, this, &ColorSwatch::allowTop); allowBottomAction = new QAction(tr("Allow on Bottom"), this); allowBottomAction->setCheckable(true); - connect(allowBottomAction, SIGNAL(triggered(bool)), SLOT(allowBottom(bool))); + connect(allowBottomAction, &QAction::triggered, this, &ColorSwatch::allowBottom); allowedAreasActions->addAction(allowLeftAction); allowedAreasActions->addAction(allowRightAction); @@ -312,56 +301,56 @@ ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFl leftAction = new QAction(tr("Place on Left") , this); leftAction->setCheckable(true); - connect(leftAction, SIGNAL(triggered(bool)), SLOT(placeLeft(bool))); + connect(leftAction, &QAction::triggered, this, &ColorSwatch::placeLeft); rightAction = new QAction(tr("Place on Right") , this); rightAction->setCheckable(true); - connect(rightAction, SIGNAL(triggered(bool)), SLOT(placeRight(bool))); + connect(rightAction, &QAction::triggered, this, &ColorSwatch::placeRight); topAction = new QAction(tr("Place on Top") , this); topAction->setCheckable(true); - connect(topAction, SIGNAL(triggered(bool)), SLOT(placeTop(bool))); + connect(topAction, &QAction::triggered, this, &ColorSwatch::placeTop); bottomAction = new QAction(tr("Place on Bottom") , this); bottomAction->setCheckable(true); - connect(bottomAction, SIGNAL(triggered(bool)), SLOT(placeBottom(bool))); + connect(bottomAction, &QAction::triggered, this, &ColorSwatch::placeBottom); areaActions->addAction(leftAction); areaActions->addAction(rightAction); areaActions->addAction(topAction); areaActions->addAction(bottomAction); - connect(movableAction, SIGNAL(triggered(bool)), areaActions, SLOT(setEnabled(bool))); + connect(movableAction, &QAction::triggered, areaActions, &QActionGroup::setEnabled); - connect(movableAction, SIGNAL(triggered(bool)), allowedAreasActions, SLOT(setEnabled(bool))); + connect(movableAction, &QAction::triggered, allowedAreasActions, &QActionGroup::setEnabled); - connect(floatableAction, SIGNAL(triggered(bool)), floatingAction, SLOT(setEnabled(bool))); + connect(floatableAction, &QAction::triggered, floatingAction, &QAction::setEnabled); - connect(floatingAction, SIGNAL(triggered(bool)), floatableAction, SLOT(setDisabled(bool))); - connect(movableAction, SIGNAL(triggered(bool)), floatableAction, SLOT(setEnabled(bool))); + connect(floatingAction, &QAction::triggered, floatableAction, &QAction::setDisabled); + connect(movableAction, &QAction::triggered, floatableAction, &QAction::setEnabled); tabMenu = new QMenu(this); tabMenu->setTitle(tr("Tab into")); - connect(tabMenu, SIGNAL(triggered(QAction*)), this, SLOT(tabInto(QAction*))); + connect(tabMenu, &QMenu::triggered, this, &ColorSwatch::tabInto); splitHMenu = new QMenu(this); splitHMenu->setTitle(tr("Split horizontally into")); - connect(splitHMenu, SIGNAL(triggered(QAction*)), this, SLOT(splitInto(QAction*))); + connect(splitHMenu, &QMenu::triggered, this, &ColorSwatch::splitInto); splitVMenu = new QMenu(this); splitVMenu->setTitle(tr("Split vertically into")); - connect(splitVMenu, SIGNAL(triggered(QAction*)), this, SLOT(splitInto(QAction*))); + connect(splitVMenu, &QMenu::triggered, this, &ColorSwatch::splitInto); - windowModifiedAction = new QAction(tr("Modified"), this); + QAction *windowModifiedAction = new QAction(tr("Modified"), this); windowModifiedAction->setCheckable(true); windowModifiedAction->setChecked(false); - connect(windowModifiedAction, SIGNAL(toggled(bool)), this, SLOT(setWindowModified(bool))); + connect(windowModifiedAction, &QAction::toggled, this, &QWidget::setWindowModified); menu = new QMenu(colorName, this); menu->addAction(toggleViewAction()); - QAction *action = menu->addAction(tr("Raise")); - connect(action, SIGNAL(triggered()), this, SLOT(raise())); - menu->addAction(changeSizeHintsAction); + menu->addAction(tr("Raise"), this, &QWidget::raise); + menu->addAction(tr("Change Size Hints..."), swatch, &ColorDock::changeSizeHints); + menu->addSeparator(); menu->addAction(closableAction); menu->addAction(movableAction); @@ -379,18 +368,17 @@ ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFl menu->addSeparator(); menu->addAction(windowModifiedAction); - connect(menu, SIGNAL(aboutToShow()), this, SLOT(updateContextMenu())); + connect(menu, &QMenu::aboutToShow, this, &ColorSwatch::updateContextMenu); - if(colorName == "Black") { - leftAction->setShortcut(Qt::CTRL|Qt::Key_W); - rightAction->setShortcut(Qt::CTRL|Qt::Key_E); - toggleViewAction()->setShortcut(Qt::CTRL|Qt::Key_R); + if (colorName == QLatin1String("Black")) { + leftAction->setShortcut(Qt::CTRL | Qt::Key_W); + rightAction->setShortcut(Qt::CTRL | Qt::Key_E); + toggleViewAction()->setShortcut(Qt::CTRL | Qt::Key_R); } } void ColorSwatch::updateContextMenu() { - QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(this); const Qt::DockWidgetAreas areas = allowedAreas(); @@ -448,48 +436,36 @@ void ColorSwatch::updateContextMenu() splitVMenu->clear(); QList<ColorSwatch*> dock_list = mainWindow->findChildren<ColorSwatch*>(); foreach (ColorSwatch *dock, dock_list) { -// if (!dock->isVisible() || dock->isFloating()) -// continue; tabMenu->addAction(dock->objectName()); splitHMenu->addAction(dock->objectName()); splitVMenu->addAction(dock->objectName()); } } -void ColorSwatch::splitInto(QAction *action) +static ColorSwatch *findByName(const QMainWindow *mainWindow, const QString &name) { - QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); - QList<ColorSwatch*> dock_list = mainWindow->findChildren<ColorSwatch*>(); - ColorSwatch *target = 0; - foreach (ColorSwatch *dock, dock_list) { - if (action->text() == dock->objectName()) { - target = dock; - break; - } + foreach (ColorSwatch *dock, mainWindow->findChildren<ColorSwatch*>()) { + if (name == dock->objectName()) + return dock; } - if (target == 0) + return Q_NULLPTR; +} + +void ColorSwatch::splitInto(QAction *action) +{ + ColorSwatch *target = findByName(mainWindow, action->text()); + if (!target) return; - Qt::Orientation o = action->parent() == splitHMenu - ? Qt::Horizontal : Qt::Vertical; + const Qt::Orientation o = action->parent() == splitHMenu + ? Qt::Horizontal : Qt::Vertical; mainWindow->splitDockWidget(target, this, o); } void ColorSwatch::tabInto(QAction *action) { - QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); - QList<ColorSwatch*> dock_list = mainWindow->findChildren<ColorSwatch*>(); - ColorSwatch *target = 0; - foreach (ColorSwatch *dock, dock_list) { - if (action->text() == dock->objectName()) { - target = dock; - break; - } - } - if (target == 0) - return; - - mainWindow->tabifyDockWidget(target, this); + if (ColorSwatch *target = findByName(mainWindow, action->text())) + mainWindow->tabifyDockWidget(target, this); } void ColorSwatch::contextMenuEvent(QContextMenuEvent *event) @@ -506,7 +482,6 @@ void ColorSwatch::resizeEvent(QResizeEvent *e) QDockWidget::resizeEvent(e); } - void ColorSwatch::allow(Qt::DockWidgetArea area, bool a) { Qt::DockWidgetAreas areas = allowedAreas(); @@ -523,9 +498,9 @@ void ColorSwatch::allow(Qt::DockWidgetArea area, bool a) void ColorSwatch::place(Qt::DockWidgetArea area, bool p) { - if (!p) return; + if (!p) + return; - QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); mainWindow->addDockWidget(area, this); if (allowedAreasActions->isEnabled()) { @@ -596,10 +571,10 @@ QSize BlueTitleBar::minimumSizeHint() const BlueTitleBar::BlueTitleBar(QWidget *parent) : QWidget(parent) + , leftPm(QPixmap(":/res/titlebarLeft.png")) + , centerPm(QPixmap(":/res/titlebarCenter.png")) + , rightPm(QPixmap(":/res/titlebarRight.png")) { - leftPm = QPixmap(":/res/titlebarLeft.png"); - centerPm = QPixmap(":/res/titlebarCenter.png"); - rightPm = QPixmap(":/res/titlebarRight.png"); } void BlueTitleBar::paintEvent(QPaintEvent*) @@ -687,7 +662,7 @@ void BlueTitleBar::updateMask() { QPainter painter(&bitmap); - ///initialize to transparent + // initialize to transparent painter.fillRect(rect, Qt::color0); QRect contents = rect; @@ -696,10 +671,7 @@ void BlueTitleBar::updateMask() contents.setBottom(contents.bottom()-y()); painter.fillRect(contents, Qt::color1); - - - //let's pait the titlebar - + // let's paint the titlebar QRect titleRect = this->geometry(); if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) { @@ -722,7 +694,6 @@ void BlueTitleBar::updateMask() QRect rect = titleRect; - painter.drawPixmap(rect.topLeft(), leftPm.mask()); painter.fillRect(rect.left() + leftPm.width(), rect.top(), rect.width() - leftPm.width() - rightPm.width(), diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.h b/examples/widgets/mainwindows/mainwindow/colorswatch.h index 6d02592b22..8827a7dca7 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.h +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.h @@ -44,45 +44,15 @@ class ColorSwatch : public QDockWidget { Q_OBJECT - QAction *closableAction; - QAction *movableAction; - QAction *floatableAction; - QAction *floatingAction; - QAction *verticalTitleBarAction; - - QActionGroup *allowedAreasActions; - QAction *allowLeftAction; - QAction *allowRightAction; - QAction *allowTopAction; - QAction *allowBottomAction; - - QActionGroup *areaActions; - QAction *leftAction; - QAction *rightAction; - QAction *topAction; - QAction *bottomAction; - - QAction *changeSizeHintsAction; - - QMenu *tabMenu; - QMenu *splitHMenu; - QMenu *splitVMenu; - - QAction *windowModifiedAction; - public: - explicit ColorSwatch(const QString &colorName, QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit ColorSwatch(const QString &colorName, QMainWindow *parent = Q_NULLPTR, Qt::WindowFlags flags = 0); - QMenu *menu; void setCustomSizeHint(const QSize &size); + QMenu *colorSwatchMenu() const { return menu; } protected: - virtual void contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; - virtual void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; - -private: - void allow(Qt::DockWidgetArea area, bool allow); - void place(Qt::DockWidgetArea area, bool place); + void contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; private slots: void changeClosable(bool on); @@ -104,25 +74,57 @@ private slots: void splitInto(QAction *action); void tabInto(QAction *action); + +private: + void allow(Qt::DockWidgetArea area, bool allow); + void place(Qt::DockWidgetArea area, bool place); + + QAction *closableAction; + QAction *movableAction; + QAction *floatableAction; + QAction *floatingAction; + QAction *verticalTitleBarAction; + + QActionGroup *allowedAreasActions; + QAction *allowLeftAction; + QAction *allowRightAction; + QAction *allowTopAction; + QAction *allowBottomAction; + + QActionGroup *areaActions; + QAction *leftAction; + QAction *rightAction; + QAction *topAction; + QAction *bottomAction; + + QMenu *tabMenu; + QMenu *splitHMenu; + QMenu *splitVMenu; + QMenu *menu; + + QMainWindow *mainWindow; }; class BlueTitleBar : public QWidget { Q_OBJECT public: - BlueTitleBar(QWidget *parent = 0); + explicit BlueTitleBar(QWidget *parent = Q_NULLPTR); QSize sizeHint() const Q_DECL_OVERRIDE { return minimumSizeHint(); } QSize minimumSizeHint() const Q_DECL_OVERRIDE; + protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + public slots: void updateMask(); private: - QPixmap leftPm, centerPm, rightPm; + const QPixmap leftPm; + const QPixmap centerPm; + const QPixmap rightPm; }; - -#endif +#endif // COLORSWATCH_H diff --git a/examples/widgets/mainwindows/mainwindow/main.cpp b/examples/widgets/mainwindows/mainwindow/main.cpp index 2192074791..b32b595a2d 100644 --- a/examples/widgets/mainwindows/mainwindow/main.cpp +++ b/examples/widgets/mainwindows/mainwindow/main.cpp @@ -37,9 +37,10 @@ #include <QPainterPath> #include <QPainter> #include <QMap> -#include <qdebug.h> +#include <QDebug> -void render_qt_text(QPainter *painter, int w, int h, const QColor &color) { +void render_qt_text(QPainter *painter, int w, int h, const QColor &color) +{ QPainterPath path; path.moveTo(-0.083695, 0.283849); path.cubicTo(-0.049581, 0.349613, -0.012720, 0.397969, 0.026886, 0.428917); @@ -108,47 +109,67 @@ void render_qt_text(QPainter *painter, int w, int h, const QColor &color) { painter->drawPath(path); } -void usage() +static void usage() { qWarning() << "Usage: mainwindow [-SizeHint<color> <width>x<height>] ..."; exit(1); } -QMap<QString, QSize> parseCustomSizeHints(int argc, char **argv) -{ - QMap<QString, QSize> result; - - for (int i = 1; i < argc; ++i) { - QString arg = QString::fromLocal8Bit(argv[i]); +enum ParseCommandLineArgumentsResult { + CommandLineArgumentsOk, + CommandLineArgumentsError, + HelpRequested +}; +static ParseCommandLineArgumentsResult + parseCustomSizeHints(const QStringList &arguments, MainWindow::CustomSizeHintMap *result) +{ + result->clear(); + const int argumentCount = arguments.size(); + for (int i = 1; i < argumentCount; ++i) { + const QString &arg = arguments.at(i); if (arg.startsWith(QLatin1String("-SizeHint"))) { - QString name = arg.mid(9); + const QString name = arg.mid(9); if (name.isEmpty()) - usage(); - if (++i == argc) - usage(); - QString sizeStr = QString::fromLocal8Bit(argv[i]); - int idx = sizeStr.indexOf(QLatin1Char('x')); + return CommandLineArgumentsError; + if (++i == argumentCount) + return CommandLineArgumentsError; + const QString sizeStr = arguments.at(i); + const int idx = sizeStr.indexOf(QLatin1Char('x')); if (idx == -1) - usage(); + return CommandLineArgumentsError; bool ok; - int w = sizeStr.left(idx).toInt(&ok); + const int w = sizeStr.leftRef(idx).toInt(&ok); if (!ok) - usage(); - int h = sizeStr.mid(idx + 1).toInt(&ok); + return CommandLineArgumentsError; + const int h = sizeStr.midRef(idx + 1).toInt(&ok); if (!ok) - usage(); - result[name] = QSize(w, h); + return CommandLineArgumentsError; + result->insert(name, QSize(w, h)); + } else if (arg == QLatin1String("-h") || arg == QLatin1String("--help")) { + return HelpRequested; + } else { + return CommandLineArgumentsError; } } - return result; + return CommandLineArgumentsOk; } int main(int argc, char **argv) { QApplication app(argc, argv); - QMap<QString, QSize> customSizeHints = parseCustomSizeHints(argc, argv); + MainWindow::CustomSizeHintMap customSizeHints; + switch (parseCustomSizeHints(QCoreApplication::arguments(), &customSizeHints)) { + case CommandLineArgumentsOk: + break; + case CommandLineArgumentsError: + usage(); + return -1; + case HelpRequested: + usage(); + return 0; + } MainWindow mainWin(customSizeHints); mainWin.resize(800, 600); mainWin.show(); diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp index 6349f7aa2e..91579ae611 100644 --- a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp +++ b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp @@ -44,6 +44,7 @@ #include <QFile> #include <QDataStream> #include <QFileDialog> +#include <QDialogButtonBox> #include <QMessageBox> #include <QSignalMapper> #include <QApplication> @@ -53,9 +54,10 @@ #include <QComboBox> #include <QLabel> #include <QPushButton> -#include <qdebug.h> +#include <QTextEdit> +#include <QDebug> -static const char * const message = +static const char message[] = "<p><b>Qt Main Window Example</b></p>" "<p>This is a demonstration of the QMainWindow, QToolBar and " @@ -75,14 +77,14 @@ static const char * const message = Q_DECLARE_METATYPE(QDockWidget::DockWidgetFeatures) -MainWindow::MainWindow(const QMap<QString, QSize> &customSizeHints, - QWidget *parent, Qt::WindowFlags flags) +MainWindow::MainWindow(const CustomSizeHintMap &customSizeHints, + QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) { setObjectName("MainWindow"); setWindowTitle("Qt Main Window Example"); - center = new QTextEdit(this); + QTextEdit *center = new QTextEdit(this); center->setReadOnly(true); center->setMinimumSize(400, 205); setCentralWidget(center); @@ -116,49 +118,48 @@ void MainWindow::setupMenuBar() { QMenu *menu = menuBar()->addMenu(tr("&File")); - QAction *action = menu->addAction(tr("Save layout...")); - connect(action, SIGNAL(triggered()), this, SLOT(saveLayout())); - - action = menu->addAction(tr("Load layout...")); - connect(action, SIGNAL(triggered()), this, SLOT(loadLayout())); - - action = menu->addAction(tr("Switch layout direction")); - connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection())); + menu->addAction(tr("Save layout..."), this, &MainWindow::saveLayout); + menu->addAction(tr("Load layout..."), this, &MainWindow::loadLayout); + menu->addAction(tr("Switch layout direction"),this, &MainWindow::switchLayoutDirection); menu->addSeparator(); - - menu->addAction(tr("&Quit"), this, SLOT(close())); + menu->addAction(tr("&Quit"), this, &QWidget::close); mainWindowMenu = menuBar()->addMenu(tr("Main window")); - action = mainWindowMenu->addAction(tr("Animated docks")); + QAction *action = mainWindowMenu->addAction(tr("Animated docks")); action->setCheckable(true); action->setChecked(dockOptions() & AnimatedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Allow nested docks")); action->setCheckable(true); action->setChecked(dockOptions() & AllowNestedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Allow tabbed docks")); action->setCheckable(true); action->setChecked(dockOptions() & AllowTabbedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Force tabbed docks")); action->setCheckable(true); action->setChecked(dockOptions() & ForceTabbedDocks); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); action = mainWindowMenu->addAction(tr("Vertical tabs")); action->setCheckable(true); action->setChecked(dockOptions() & VerticalTabs); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); + + action = mainWindowMenu->addAction(tr("Grouped dragging")); + action->setCheckable(true); + action->setChecked(dockOptions() & GroupedDragging); + connect(action, &QAction::toggled, this, &MainWindow::setDockOptions); QMenu *toolBarMenu = menuBar()->addMenu(tr("Tool bars")); for (int i = 0; i < toolBars.count(); ++i) - toolBarMenu->addMenu(toolBars.at(i)->menu); + toolBarMenu->addMenu(toolBars.at(i)->toolbarMenu()); #ifdef Q_OS_OSX toolBarMenu->addSeparator(); @@ -166,7 +167,7 @@ void MainWindow::setupMenuBar() action = toolBarMenu->addAction(tr("Unified")); action->setCheckable(true); action->setChecked(unifiedTitleAndToolBarOnMac()); - connect(action, SIGNAL(toggled(bool)), this, SLOT(setUnifiedTitleAndToolBarOnMac(bool))); + connect(action, &QAction::toggled, this, &QMainWindow::setUnifiedTitleAndToolBarOnMac); #endif dockWidgetMenu = menuBar()->addMenu(tr("&Dock Widgets")); @@ -187,6 +188,8 @@ void MainWindow::setDockOptions() opts |= ForceTabbedDocks; if (actions.at(4)->isChecked()) opts |= VerticalTabs; + if (actions.at(5)->isChecked()) + opts |= GroupedDragging; QMainWindow::setDockOptions(opts); } @@ -200,8 +203,7 @@ void MainWindow::saveLayout() QFile file(fileName); if (!file.open(QFile::WriteOnly)) { QString msg = tr("Failed to open %1\n%2") - .arg(fileName) - .arg(file.errorString()); + .arg(QDir::toNativeSeparators(fileName), file.errorString()); QMessageBox::warning(this, tr("Error"), msg); return; } @@ -217,8 +219,7 @@ void MainWindow::saveLayout() if (!ok) { QString msg = tr("Error writing to %1\n%2") - .arg(fileName) - .arg(file.errorString()); + .arg(QDir::toNativeSeparators(fileName), file.errorString()); QMessageBox::warning(this, tr("Error"), msg); return; } @@ -233,8 +234,7 @@ void MainWindow::loadLayout() QFile file(fileName); if (!file.open(QFile::ReadOnly)) { QString msg = tr("Failed to open %1\n%2") - .arg(fileName) - .arg(file.errorString()); + .arg(QDir::toNativeSeparators(fileName), file.errorString()); QMessageBox::warning(this, tr("Error"), msg); return; } @@ -259,56 +259,65 @@ void MainWindow::loadLayout() ok = restoreState(layout_data); if (!ok) { - QString msg = tr("Error reading %1") - .arg(fileName); + QString msg = tr("Error reading %1").arg(QDir::toNativeSeparators(fileName)); QMessageBox::warning(this, tr("Error"), msg); return; } } -QAction *addAction(QMenu *menu, const QString &text, QActionGroup *group, QSignalMapper *mapper, - int id) +class DockWidgetAreaCornerFunctor { +public: + explicit DockWidgetAreaCornerFunctor(QMainWindow *mw, Qt::Corner c, Qt::DockWidgetArea a) + : m_mainWindow(mw), m_area(a), m_corner(c) {} + + void operator()() const { m_mainWindow->setCorner(m_corner, m_area); } + +private: + QMainWindow *m_mainWindow; + Qt::DockWidgetArea m_area; + Qt::Corner m_corner; +}; + +static QAction *addCornerAction(const QString &text, QMainWindow *mw, QMenu *menu, QActionGroup *group, + Qt::Corner c, Qt::DockWidgetArea a) { - bool first = group->actions().isEmpty(); - QAction *result = menu->addAction(text); + QAction *result = menu->addAction(text, mw, DockWidgetAreaCornerFunctor(mw, c, a)); result->setCheckable(true); - result->setChecked(first); group->addAction(result); - QObject::connect(result, SIGNAL(triggered()), mapper, SLOT(map())); - mapper->setMapping(result, id); return result; } -void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) +void MainWindow::setupDockWidgets(const CustomSizeHintMap &customSizeHints) { qRegisterMetaType<QDockWidget::DockWidgetFeatures>(); - mapper = new QSignalMapper(this); - connect(mapper, SIGNAL(mapped(int)), this, SLOT(setCorner(int))); - - QMenu *corner_menu = dockWidgetMenu->addMenu(tr("Top left corner")); + QMenu *cornerMenu = dockWidgetMenu->addMenu(tr("Top left corner")); QActionGroup *group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Top dock area"), group, mapper, 0); - ::addAction(corner_menu, tr("Left dock area"), group, mapper, 1); + QAction *cornerAction = addCornerAction(tr("Top dock area"), this, cornerMenu, group, Qt::TopLeftCorner, Qt::TopDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Left dock area"), this, cornerMenu, group, Qt::TopLeftCorner, Qt::LeftDockWidgetArea); - corner_menu = dockWidgetMenu->addMenu(tr("Top right corner")); + cornerMenu = dockWidgetMenu->addMenu(tr("Top right corner")); group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Top dock area"), group, mapper, 2); - ::addAction(corner_menu, tr("Right dock area"), group, mapper, 3); + cornerAction = addCornerAction(tr("Top dock area"), this, cornerMenu, group, Qt::TopRightCorner, Qt::TopDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Right dock area"), this, cornerMenu, group, Qt::TopRightCorner, Qt::RightDockWidgetArea); - corner_menu = dockWidgetMenu->addMenu(tr("Bottom left corner")); + cornerMenu = dockWidgetMenu->addMenu(tr("Bottom left corner")); group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 4); - ::addAction(corner_menu, tr("Left dock area"), group, mapper, 5); + cornerAction = addCornerAction(tr("Bottom dock area"), this, cornerMenu, group, Qt::BottomLeftCorner, Qt::BottomDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Left dock area"), this, cornerMenu, group, Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - corner_menu = dockWidgetMenu->addMenu(tr("Bottom right corner")); + cornerMenu = dockWidgetMenu->addMenu(tr("Bottom right corner")); group = new QActionGroup(this); group->setExclusive(true); - ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 6); - ::addAction(corner_menu, tr("Right dock area"), group, mapper, 7); + cornerAction = addCornerAction(tr("Bottom dock area"), this, cornerMenu, group, Qt::BottomRightCorner, Qt::BottomDockWidgetArea); + cornerAction->setChecked(true); + addCornerAction(tr("Right dock area"), this, cornerMenu, group, Qt::BottomRightCorner, Qt::RightDockWidgetArea); dockWidgetMenu->addSeparator(); @@ -330,16 +339,16 @@ void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) }; const int setCount = sizeof(sets) / sizeof(Set); + const QIcon qtIcon(QPixmap(":/res/qt.png")); for (int i = 0; i < setCount; ++i) { ColorSwatch *swatch = new ColorSwatch(tr(sets[i].name), this, Qt::WindowFlags(sets[i].flags)); - if (i%2) - swatch->setWindowIcon(QIcon(QPixmap(":/res/qt.png"))); + if (i % 2) + swatch->setWindowIcon(qtIcon); if (qstrcmp(sets[i].name, "Blue") == 0) { BlueTitleBar *titlebar = new BlueTitleBar(swatch); swatch->setTitleBarWidget(titlebar); - connect(swatch, SIGNAL(topLevelChanged(bool)), titlebar, SLOT(updateMask())); - connect(swatch, SIGNAL(featuresChanged(QDockWidget::DockWidgetFeatures)), titlebar, SLOT(updateMask()), Qt::QueuedConnection); - + connect(swatch, &QDockWidget::topLevelChanged, titlebar, &BlueTitleBar::updateMask); + connect(swatch, &QDockWidget::featuresChanged, titlebar, &BlueTitleBar::updateMask, Qt::QueuedConnection); } QString name = QString::fromLatin1(sets[i].name); @@ -347,69 +356,32 @@ void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) swatch->setCustomSizeHint(customSizeHints.value(name)); addDockWidget(sets[i].area, swatch); - dockWidgetMenu->addMenu(swatch->menu); + dockWidgetMenu->addMenu(swatch->colorSwatchMenu()); } - createDockWidgetAction = new QAction(tr("Add dock widget..."), this); - connect(createDockWidgetAction, SIGNAL(triggered()), this, SLOT(createDockWidget())); destroyDockWidgetMenu = new QMenu(tr("Destroy dock widget"), this); destroyDockWidgetMenu->setEnabled(false); - connect(destroyDockWidgetMenu, SIGNAL(triggered(QAction*)), this, SLOT(destroyDockWidget(QAction*))); + connect(destroyDockWidgetMenu, &QMenu::triggered, this, &MainWindow::destroyDockWidget); dockWidgetMenu->addSeparator(); - dockWidgetMenu->addAction(createDockWidgetAction); + dockWidgetMenu->addAction(tr("Add dock widget..."), this, &MainWindow::createDockWidget); dockWidgetMenu->addMenu(destroyDockWidgetMenu); } -void MainWindow::setCorner(int id) -{ - switch (id) { - case 0: - QMainWindow::setCorner(Qt::TopLeftCorner, Qt::TopDockWidgetArea); - break; - case 1: - QMainWindow::setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); - break; - case 2: - QMainWindow::setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea); - break; - case 3: - QMainWindow::setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); - break; - case 4: - QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea); - break; - case 5: - QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - break; - case 6: - QMainWindow::setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea); - break; - case 7: - QMainWindow::setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); - break; - } -} - -void MainWindow::showEvent(QShowEvent *event) -{ - QMainWindow::showEvent(event); -} - void MainWindow::switchLayoutDirection() { if (layoutDirection() == Qt::LeftToRight) - qApp->setLayoutDirection(Qt::RightToLeft); + QApplication::setLayoutDirection(Qt::RightToLeft); else - qApp->setLayoutDirection(Qt::LeftToRight); + QApplication::setLayoutDirection(Qt::LeftToRight); } class CreateDockWidgetDialog : public QDialog { public: - CreateDockWidgetDialog(QWidget *parent = 0); + explicit CreateDockWidgetDialog(QWidget *parent = Q_NULLPTR); - QString objectName() const; + QString enteredObjectName() const { return m_objectName->text(); } Qt::DockWidgetArea location() const; private: @@ -419,15 +391,17 @@ private: CreateDockWidgetDialog::CreateDockWidgetDialog(QWidget *parent) : QDialog(parent) + , m_objectName(new QLineEdit(this)) + , m_location(new QComboBox(this)) { + setWindowTitle(tr("Add Dock Widget")); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QGridLayout *layout = new QGridLayout(this); layout->addWidget(new QLabel(tr("Object name:")), 0, 0); - m_objectName = new QLineEdit; layout->addWidget(m_objectName, 0, 1); layout->addWidget(new QLabel(tr("Location:")), 1, 0); - m_location = new QComboBox; m_location->setEditable(false); m_location->addItem(tr("Top")); m_location->addItem(tr("Left")); @@ -436,23 +410,10 @@ CreateDockWidgetDialog::CreateDockWidgetDialog(QWidget *parent) m_location->addItem(tr("Restore")); layout->addWidget(m_location, 1, 1); - QHBoxLayout *buttonLayout = new QHBoxLayout; - layout->addLayout(buttonLayout, 2, 0, 1, 2); - buttonLayout->addStretch(); - - QPushButton *cancelButton = new QPushButton(tr("Cancel")); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); - buttonLayout->addWidget(cancelButton); - QPushButton *okButton = new QPushButton(tr("Ok")); - connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); - buttonLayout->addWidget(okButton); - - okButton->setDefault(true); -} - -QString CreateDockWidgetDialog::objectName() const -{ - return m_objectName->text(); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::reject); + layout->addWidget(buttonBox, 2, 0, 1, 2); } Qt::DockWidgetArea CreateDockWidgetDialog::location() const @@ -471,13 +432,13 @@ Qt::DockWidgetArea CreateDockWidgetDialog::location() const void MainWindow::createDockWidget() { CreateDockWidgetDialog dialog(this); - int ret = dialog.exec(); - if (ret == QDialog::Rejected) + if (dialog.exec() == QDialog::Rejected) return; QDockWidget *dw = new QDockWidget; - dw->setObjectName(dialog.objectName()); - dw->setWindowTitle(dialog.objectName()); + const QString name = dialog.enteredObjectName(); + dw->setObjectName(name); + dw->setWindowTitle(name); dw->setWidget(new QTextEdit); Qt::DockWidgetArea area = dialog.location(); @@ -499,7 +460,7 @@ void MainWindow::createDockWidget() extraDockWidgets.append(dw); destroyDockWidgetMenu->setEnabled(true); - destroyDockWidgetMenu->addAction(new QAction(dialog.objectName(), this)); + destroyDockWidgetMenu->addAction(new QAction(name, this)); } void MainWindow::destroyDockWidget(QAction *action) diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.h b/examples/widgets/mainwindows/mainwindow/mainwindow.h index f9a6176b2d..162e977520 100644 --- a/examples/widgets/mainwindows/mainwindow/mainwindow.h +++ b/examples/widgets/mainwindows/mainwindow/mainwindow.h @@ -35,37 +35,25 @@ #define MAINWINDOW_H #include <QMainWindow> -#include <QTextEdit> class ToolBar; QT_FORWARD_DECLARE_CLASS(QMenu) -QT_FORWARD_DECLARE_CLASS(QSignalMapper) class MainWindow : public QMainWindow { Q_OBJECT - QTextEdit *center; - QList<ToolBar*> toolBars; - QMenu *dockWidgetMenu; - QMenu *mainWindowMenu; - QSignalMapper *mapper; - QList<QDockWidget*> extraDockWidgets; - QAction *createDockWidgetAction; - QMenu *destroyDockWidgetMenu; - public: - MainWindow(const QMap<QString, QSize> &customSizeHints, - QWidget *parent = 0, Qt::WindowFlags flags = 0); + typedef QMap<QString, QSize> CustomSizeHintMap; -protected: - void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; + explicit MainWindow(const CustomSizeHintMap &customSizeHints, + QWidget *parent = Q_NULLPTR, + Qt::WindowFlags flags = 0); public slots: void actionTriggered(QAction *action); void saveLayout(); void loadLayout(); - void setCorner(int id); void switchLayoutDirection(); void setDockOptions(); @@ -75,8 +63,13 @@ public slots: private: void setupToolBar(); void setupMenuBar(); - void setupDockWidgets(const QMap<QString, QSize> &customSizeHints); -}; + void setupDockWidgets(const CustomSizeHintMap &customSizeHints); + QList<ToolBar*> toolBars; + QMenu *dockWidgetMenu; + QMenu *mainWindowMenu; + QList<QDockWidget *> extraDockWidgets; + QMenu *destroyDockWidgetMenu; +}; -#endif +#endif // MAINWINDOW_H diff --git a/examples/widgets/mainwindows/mainwindow/toolbar.cpp b/examples/widgets/mainwindows/mainwindow/toolbar.cpp index 280ba965d6..a9b308370a 100644 --- a/examples/widgets/mainwindows/mainwindow/toolbar.cpp +++ b/examples/widgets/mainwindows/mainwindow/toolbar.cpp @@ -63,15 +63,15 @@ static QPixmap genIcon(const QSize &iconSize, int number, const QColor &color) { return genIcon(iconSize, QString::number(number), color); } ToolBar::ToolBar(const QString &title, QWidget *parent) - : QToolBar(parent), spinbox(0), spinboxAction(0) + : QToolBar(parent) + , spinbox(Q_NULLPTR) + , spinboxAction(Q_NULLPTR) { - tip = 0; setWindowTitle(title); setObjectName(title); setIconSize(QSize(32, 32)); - QColor bg(palette().background().color()); menu = new QMenu("One", this); menu->setIcon(genIcon(iconSize(), 1, Qt::black)); menu->addAction(genIcon(iconSize(), "A", Qt::blue), "A"); @@ -90,43 +90,43 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) addAction(genIcon(iconSize(), 6, Qt::yellow), "Six"); orderAction = new QAction(this); orderAction->setText(tr("Order Items in Tool Bar")); - connect(orderAction, SIGNAL(triggered()), SLOT(order())); + connect(orderAction, &QAction::triggered, this, &ToolBar::order); randomizeAction = new QAction(this); randomizeAction->setText(tr("Randomize Items in Tool Bar")); - connect(randomizeAction, SIGNAL(triggered()), SLOT(randomize())); + connect(randomizeAction, &QAction::triggered, this, &ToolBar::randomize); addSpinBoxAction = new QAction(this); addSpinBoxAction->setText(tr("Add Spin Box")); - connect(addSpinBoxAction, SIGNAL(triggered()), SLOT(addSpinBox())); + connect(addSpinBoxAction, &QAction::triggered, this, &ToolBar::addSpinBox); removeSpinBoxAction = new QAction(this); removeSpinBoxAction->setText(tr("Remove Spin Box")); removeSpinBoxAction->setEnabled(false); - connect(removeSpinBoxAction, SIGNAL(triggered()), SLOT(removeSpinBox())); + connect(removeSpinBoxAction, &QAction::triggered, this, &ToolBar::removeSpinBox); movableAction = new QAction(tr("Movable"), this); movableAction->setCheckable(true); - connect(movableAction, SIGNAL(triggered(bool)), SLOT(changeMovable(bool))); + connect(movableAction, &QAction::triggered, this, &ToolBar::changeMovable); allowedAreasActions = new QActionGroup(this); allowedAreasActions->setExclusive(false); allowLeftAction = new QAction(tr("Allow on Left"), this); allowLeftAction->setCheckable(true); - connect(allowLeftAction, SIGNAL(triggered(bool)), SLOT(allowLeft(bool))); + connect(allowLeftAction, &QAction::triggered, this, &ToolBar::allowLeft); allowRightAction = new QAction(tr("Allow on Right"), this); allowRightAction->setCheckable(true); - connect(allowRightAction, SIGNAL(triggered(bool)), SLOT(allowRight(bool))); + connect(allowRightAction, &QAction::triggered, this, &ToolBar::allowRight); allowTopAction = new QAction(tr("Allow on Top"), this); allowTopAction->setCheckable(true); - connect(allowTopAction, SIGNAL(triggered(bool)), SLOT(allowTop(bool))); + connect(allowTopAction, &QAction::triggered, this, &ToolBar::allowTop); allowBottomAction = new QAction(tr("Allow on Bottom"), this); allowBottomAction->setCheckable(true); - connect(allowBottomAction, SIGNAL(triggered(bool)), SLOT(allowBottom(bool))); + connect(allowBottomAction, &QAction::triggered, this, &ToolBar::allowBottom); allowedAreasActions->addAction(allowLeftAction); allowedAreasActions->addAction(allowRightAction); @@ -138,31 +138,28 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) leftAction = new QAction(tr("Place on Left") , this); leftAction->setCheckable(true); - connect(leftAction, SIGNAL(triggered(bool)), SLOT(placeLeft(bool))); + connect(leftAction, &QAction::triggered, this, &ToolBar::placeLeft); rightAction = new QAction(tr("Place on Right") , this); rightAction->setCheckable(true); - connect(rightAction, SIGNAL(triggered(bool)), SLOT(placeRight(bool))); + connect(rightAction, &QAction::triggered, this, &ToolBar::placeRight); topAction = new QAction(tr("Place on Top") , this); topAction->setCheckable(true); - connect(topAction, SIGNAL(triggered(bool)), SLOT(placeTop(bool))); + connect(topAction, &QAction::triggered, this, &ToolBar::placeTop); bottomAction = new QAction(tr("Place on Bottom") , this); bottomAction->setCheckable(true); - connect(bottomAction, SIGNAL(triggered(bool)), SLOT(placeBottom(bool))); + connect(bottomAction, &QAction::triggered, this, &ToolBar::placeBottom); areaActions->addAction(leftAction); areaActions->addAction(rightAction); areaActions->addAction(topAction); areaActions->addAction(bottomAction); - toolBarBreakAction = new QAction(tr("Insert break"), this); - connect(toolBarBreakAction, SIGNAL(triggered(bool)), this, SLOT(insertToolBarBreak())); + connect(movableAction, &QAction::triggered, areaActions, &QActionGroup::setEnabled); - connect(movableAction, SIGNAL(triggered(bool)), areaActions, SLOT(setEnabled(bool))); - - connect(movableAction, SIGNAL(triggered(bool)), allowedAreasActions, SLOT(setEnabled(bool))); + connect(movableAction, &QAction::triggered, allowedAreasActions, &QActionGroup::setEnabled); menu = new QMenu(title, this); menu->addAction(toggleViewAction()); @@ -179,9 +176,9 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) menu->addSeparator(); menu->addActions(areaActions->actions()); menu->addSeparator(); - menu->addAction(toolBarBreakAction); + menu->addAction(tr("Insert break"), this, &ToolBar::insertToolBarBreak); - connect(menu, SIGNAL(aboutToShow()), this, SLOT(updateMenu())); + connect(menu, &QMenu::aboutToShow, this, &ToolBar::updateMenu); randomize(); } @@ -223,10 +220,9 @@ void ToolBar::updateMenu() void ToolBar::order() { - QList<QAction *> ordered, actions1 = actions(), - actions2 = findChildren<QAction *>(); - while (!actions2.isEmpty()) { - QAction *action = actions2.takeFirst(); + QList<QAction *> ordered; + QList<QAction *> actions1 = actions(); + foreach (QAction *action, findChildren<QAction *>()) { if (!actions1.contains(action)) continue; actions1.removeAll(action); @@ -241,7 +237,8 @@ void ToolBar::order() void ToolBar::randomize() { - QList<QAction *> randomized, actions = this->actions(); + QList<QAction *> randomized; + QList<QAction *> actions = this->actions(); while (!actions.isEmpty()) { QAction *action = actions.takeAt(rand() % actions.size()); randomized.append(action); @@ -254,9 +251,8 @@ void ToolBar::randomize() void ToolBar::addSpinBox() { - if (!spinbox) { + if (!spinbox) spinbox = new QSpinBox(this); - } if (!spinboxAction) spinboxAction = addWidget(spinbox); else @@ -341,35 +337,3 @@ void ToolBar::insertToolBarBreak() mainWindow->insertToolBarBreak(this); } - -void ToolBar::enterEvent(QEvent*) -{ -/* - These labels on top of toolbars look darn ugly - - if (tip == 0) { - tip = new QLabel(windowTitle(), this); - QPalette pal = tip->palette(); - QColor c = Qt::black; - c.setAlpha(100); - pal.setColor(QPalette::Window, c); - pal.setColor(QPalette::Foreground, Qt::white); - tip->setPalette(pal); - tip->setAutoFillBackground(true); - tip->setMargin(3); - tip->setText(windowTitle()); - } - QPoint c = rect().center(); - QSize hint = tip->sizeHint(); - tip->setGeometry(c.x() - hint.width()/2, c.y() - hint.height()/2, - hint.width(), hint.height()); - - tip->show(); -*/ -} - -void ToolBar::leaveEvent(QEvent*) -{ - if (tip != 0) - tip->hide(); -} diff --git a/examples/widgets/mainwindows/mainwindow/toolbar.h b/examples/widgets/mainwindows/mainwindow/toolbar.h index b1674a2034..2629d9d7a7 100644 --- a/examples/widgets/mainwindows/mainwindow/toolbar.h +++ b/examples/widgets/mainwindows/mainwindow/toolbar.h @@ -40,49 +40,15 @@ QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QActionGroup) QT_FORWARD_DECLARE_CLASS(QMenu) QT_FORWARD_DECLARE_CLASS(QSpinBox) -QT_FORWARD_DECLARE_CLASS(QLabel) class ToolBar : public QToolBar { Q_OBJECT - QSpinBox *spinbox; - QAction *spinboxAction; - - QAction *orderAction; - QAction *randomizeAction; - QAction *addSpinBoxAction; - QAction *removeSpinBoxAction; - - QAction *movableAction; - - QActionGroup *allowedAreasActions; - QAction *allowLeftAction; - QAction *allowRightAction; - QAction *allowTopAction; - QAction *allowBottomAction; - - QActionGroup *areaActions; - QAction *leftAction; - QAction *rightAction; - QAction *topAction; - QAction *bottomAction; - - QAction *toolBarBreakAction; - public: - ToolBar(const QString &title, QWidget *parent); - - QMenu *menu; + explicit ToolBar(const QString &title, QWidget *parent); -protected: - void enterEvent(QEvent*) Q_DECL_OVERRIDE; - void leaveEvent(QEvent*) Q_DECL_OVERRIDE; - -private: - void allow(Qt::ToolBarArea area, bool allow); - void place(Qt::ToolBarArea area, bool place); - QLabel *tip; + QMenu *toolbarMenu() const { return menu; } private slots: void order(); @@ -105,6 +71,32 @@ private slots: void updateMenu(); void insertToolBarBreak(); +private: + void allow(Qt::ToolBarArea area, bool allow); + void place(Qt::ToolBarArea area, bool place); + + QSpinBox *spinbox; + QAction *spinboxAction; + + QMenu *menu; + QAction *orderAction; + QAction *randomizeAction; + QAction *addSpinBoxAction; + QAction *removeSpinBoxAction; + + QAction *movableAction; + + QActionGroup *allowedAreasActions; + QAction *allowLeftAction; + QAction *allowRightAction; + QAction *allowTopAction; + QAction *allowBottomAction; + + QActionGroup *areaActions; + QAction *leftAction; + QAction *rightAction; + QAction *topAction; + QAction *bottomAction; }; -#endif +#endif // TOOLBAR_H diff --git a/examples/widgets/mainwindows/mainwindows.pro b/examples/widgets/mainwindows/mainwindows.pro index 52179ec9bd..dcda89abaf 100644 --- a/examples/widgets/mainwindows/mainwindows.pro +++ b/examples/widgets/mainwindows/mainwindows.pro @@ -4,5 +4,4 @@ SUBDIRS = application \ mainwindow \ mdi \ menus \ - recentfiles \ sdi diff --git a/examples/widgets/mainwindows/mdi/main.cpp b/examples/widgets/mainwindows/mdi/main.cpp index 5976c85c1c..f02285d1cf 100644 --- a/examples/widgets/mainwindows/mdi/main.cpp +++ b/examples/widgets/mainwindows/mdi/main.cpp @@ -49,6 +49,8 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(mdi); QApplication app(argc, argv); + QCoreApplication::setApplicationName("MDI Example"); + QCoreApplication::setOrganizationName("QtProject"); QCoreApplication::setApplicationVersion(QT_VERSION_STR); QCommandLineParser parser; parser.setApplicationDescription("Qt MDI Example"); diff --git a/examples/widgets/mainwindows/mdi/mainwindow.cpp b/examples/widgets/mainwindows/mdi/mainwindow.cpp index 83ffbf6557..35136c81c4 100644 --- a/examples/widgets/mainwindows/mdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/mdi/mainwindow.cpp @@ -44,20 +44,15 @@ #include "mdichild.h" MainWindow::MainWindow() + : mdiArea(new QMdiArea) { - mdiArea = new QMdiArea; mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setCentralWidget(mdiArea); - connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), - this, SLOT(updateMenus())); - windowMapper = new QSignalMapper(this); - connect(windowMapper, SIGNAL(mapped(QWidget*)), - this, SLOT(setActiveSubWindow(QWidget*))); + connect(mdiArea, &QMdiArea::subWindowActivated, + this, &MainWindow::updateMenus); createActions(); - createMenus(); - createToolBars(); createStatusBar(); updateMenus(); @@ -87,20 +82,24 @@ void MainWindow::newFile() void MainWindow::open() { - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) { - QMdiSubWindow *existing = findMdiChild(fileName); - if (existing) { - mdiArea->setActiveSubWindow(existing); - return; - } + const QString fileName = QFileDialog::getOpenFileName(this); + if (!fileName.isEmpty()) + openFile(fileName); +} - if (openFile(fileName)) - statusBar()->showMessage(tr("File loaded"), 2000); +bool MainWindow::openFile(const QString &fileName) +{ + if (QMdiSubWindow *existing = findMdiChild(fileName)) { + mdiArea->setActiveSubWindow(existing); + return true; } + const bool succeeded = loadFile(fileName); + if (succeeded) + statusBar()->showMessage(tr("File loaded"), 2000); + return succeeded; } -bool MainWindow::openFile(const QString &fileName) +bool MainWindow::loadFile(const QString &fileName) { MdiChild *child = createMdiChild(); const bool succeeded = child->loadFile(fileName); @@ -108,9 +107,87 @@ bool MainWindow::openFile(const QString &fileName) child->show(); else child->close(); + MainWindow::prependToRecentFiles(fileName); return succeeded; } +static inline QString recentFilesKey() { return QStringLiteral("recentFileList"); } +static inline QString fileKey() { return QStringLiteral("file"); } + +static QStringList readRecentFiles(QSettings &settings) +{ + QStringList result; + const int count = settings.beginReadArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + result.append(settings.value(fileKey()).toString()); + } + settings.endArray(); + return result; +} + +static void writeRecentFiles(const QStringList &files, QSettings &settings) +{ + const int count = files.size(); + settings.beginWriteArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + settings.setValue(fileKey(), files.at(i)); + } + settings.endArray(); +} + +bool MainWindow::hasRecentFiles() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const int count = settings.beginReadArray(recentFilesKey()); + settings.endArray(); + return count > 0; +} + +void MainWindow::prependToRecentFiles(const QString &fileName) +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList oldRecentFiles = readRecentFiles(settings); + QStringList recentFiles = oldRecentFiles; + recentFiles.removeAll(fileName); + recentFiles.prepend(fileName); + if (oldRecentFiles != recentFiles) + writeRecentFiles(recentFiles, settings); + + setRecentFilesVisible(!recentFiles.isEmpty()); +} + +void MainWindow::setRecentFilesVisible(bool visible) +{ + recentFileSubMenuAct->setVisible(visible); + recentFileSeparator->setVisible(visible); +} + +void MainWindow::updateRecentFileActions() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList recentFiles = readRecentFiles(settings); + const int count = qMin(int(MaxRecentFiles), recentFiles.size()); + int i = 0; + for ( ; i < count; ++i) { + const QString fileName = QFileInfo(recentFiles.at(i)).fileName(); + recentFileActs[i]->setText(tr("&%1 %2").arg(i + 1).arg(fileName)); + recentFileActs[i]->setData(recentFiles.at(i)); + recentFileActs[i]->setVisible(true); + } + for ( ; i < MaxRecentFiles; ++i) + recentFileActs[i]->setVisible(false); +} + +void MainWindow::openRecentFile() +{ + if (const QAction *action = qobject_cast<const QAction *>(sender())) + openFile(action->data().toString()); +} + void MainWindow::save() { if (activeMdiChild() && activeMdiChild()->save()) @@ -119,8 +196,11 @@ void MainWindow::save() void MainWindow::saveAs() { - if (activeMdiChild() && activeMdiChild()->saveAs()) + MdiChild *child = activeMdiChild(); + if (child && child->saveAs()) { statusBar()->showMessage(tr("File saved"), 2000); + MainWindow::prependToRecentFiles(child->currentFile()); + } } #ifndef QT_NO_CLIPBOARD @@ -164,7 +244,7 @@ void MainWindow::updateMenus() cascadeAct->setEnabled(hasMdiChild); nextAct->setEnabled(hasMdiChild); previousAct->setEnabled(hasMdiChild); - separatorAct->setVisible(hasMdiChild); + windowMenuSeparatorAct->setVisible(hasMdiChild); #ifndef QT_NO_CLIPBOARD bool hasSelection = (activeMdiChild() && @@ -174,6 +254,16 @@ void MainWindow::updateMenus() #endif } +class ActiveMdiSubWindowFunctor { +public: + explicit ActiveMdiSubWindowFunctor(QMdiArea *mdiArea, QMdiSubWindow *activeWindow) : m_mdiArea(mdiArea), m_activeWindow(activeWindow) {} + void operator()() const { m_mdiArea->setActiveSubWindow(m_activeWindow); } + +private: + QMdiArea *m_mdiArea; + QMdiSubWindow *m_activeWindow; +}; + void MainWindow::updateWindowMenu() { windowMenu->clear(); @@ -185,13 +275,14 @@ void MainWindow::updateWindowMenu() windowMenu->addSeparator(); windowMenu->addAction(nextAct); windowMenu->addAction(previousAct); - windowMenu->addAction(separatorAct); + windowMenu->addAction(windowMenuSeparatorAct); QList<QMdiSubWindow *> windows = mdiArea->subWindowList(); - separatorAct->setVisible(!windows.isEmpty()); + windowMenuSeparatorAct->setVisible(!windows.isEmpty()); for (int i = 0; i < windows.size(); ++i) { - MdiChild *child = qobject_cast<MdiChild *>(windows.at(i)->widget()); + QMdiSubWindow *mdiSubWindow = windows.at(i); + MdiChild *child = qobject_cast<MdiChild *>(mdiSubWindow->widget()); QString text; if (i < 9) { @@ -201,11 +292,9 @@ void MainWindow::updateWindowMenu() text = tr("%1 %2").arg(i + 1) .arg(child->userFriendlyCurrentFile()); } - QAction *action = windowMenu->addAction(text); + QAction *action = windowMenu->addAction(text, mdiSubWindow, ActiveMdiSubWindowFunctor(mdiArea, mdiSubWindow)); action->setCheckable(true); action ->setChecked(child == activeMdiChild()); - connect(action, SIGNAL(triggered()), windowMapper, SLOT(map())); - windowMapper->setMapping(action, windows.at(i)); } } @@ -215,10 +304,8 @@ MdiChild *MainWindow::createMdiChild() mdiArea->addSubWindow(child); #ifndef QT_NO_CLIPBOARD - connect(child, SIGNAL(copyAvailable(bool)), - cutAct, SLOT(setEnabled(bool))); - connect(child, SIGNAL(copyAvailable(bool)), - copyAct, SLOT(setEnabled(bool))); + connect(child, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(child, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled); #endif return child; @@ -226,139 +313,143 @@ MdiChild *MainWindow::createMdiChild() void MainWindow::createActions() { - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + newAct = new QAction(newIcon, tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + saveAct = new QAction(saveIcon, tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileToolBar->addAction(saveAct); - saveAsAct = new QAction(tr("Save &As..."), this); + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + saveAsAct = new QAction(saveAsIcon, tr("Save &As..."), this); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); + connect(saveAsAct, &QAction::triggered, this, &MainWindow::saveAs); + fileMenu->addAction(saveAsAct); + + fileMenu->addSeparator(); + + QMenu *recentMenu = fileMenu->addMenu(tr("Recent...")); + connect(recentMenu, &QMenu::aboutToShow, this, &MainWindow::updateRecentFileActions); + recentFileSubMenuAct = recentMenu->menuAction(); + + for (int i = 0; i < MaxRecentFiles; ++i) { + recentFileActs[i] = recentMenu->addAction(QString(), this, &MainWindow::openRecentFile); + recentFileActs[i]->setVisible(false); + } + + recentFileSeparator = fileMenu->addSeparator(); + + setRecentFilesVisible(MainWindow::hasRecentFiles()); + + fileMenu->addAction(tr("Switch layout direction"), this, &MainWindow::switchLayoutDirection); + + fileMenu->addSeparator(); //! [0] - exitAct = new QAction(tr("E&xit"), this); + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), qApp, &QApplication::closeAllWindows); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); + fileMenu->addAction(exitAct); //! [0] #ifndef QT_NO_CLIPBOARD - cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + cutAct = new QAction(cutIcon, tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), this, SLOT(cut())); + connect(cutAct, &QAction::triggered, this, &MainWindow::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); - copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + copyAct = new QAction(copyIcon, tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), this, SLOT(copy())); + connect(copyAct, &QAction::triggered, this, &MainWindow::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); - pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + pasteAct = new QAction(pasteIcon, tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); + connect(pasteAct, &QAction::triggered, this, &MainWindow::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); #endif + windowMenu = menuBar()->addMenu(tr("&Window")); + connect(windowMenu, &QMenu::aboutToShow, this, &MainWindow::updateWindowMenu); + closeAct = new QAction(tr("Cl&ose"), this); closeAct->setStatusTip(tr("Close the active window")); - connect(closeAct, SIGNAL(triggered()), - mdiArea, SLOT(closeActiveSubWindow())); + connect(closeAct, &QAction::triggered, + mdiArea, &QMdiArea::closeActiveSubWindow); closeAllAct = new QAction(tr("Close &All"), this); closeAllAct->setStatusTip(tr("Close all the windows")); - connect(closeAllAct, SIGNAL(triggered()), - mdiArea, SLOT(closeAllSubWindows())); + connect(closeAllAct, &QAction::triggered, mdiArea, &QMdiArea::closeAllSubWindows); tileAct = new QAction(tr("&Tile"), this); tileAct->setStatusTip(tr("Tile the windows")); - connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows())); + connect(tileAct, &QAction::triggered, mdiArea, &QMdiArea::tileSubWindows); cascadeAct = new QAction(tr("&Cascade"), this); cascadeAct->setStatusTip(tr("Cascade the windows")); - connect(cascadeAct, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows())); + connect(cascadeAct, &QAction::triggered, mdiArea, &QMdiArea::cascadeSubWindows); nextAct = new QAction(tr("Ne&xt"), this); nextAct->setShortcuts(QKeySequence::NextChild); nextAct->setStatusTip(tr("Move the focus to the next window")); - connect(nextAct, SIGNAL(triggered()), - mdiArea, SLOT(activateNextSubWindow())); + connect(nextAct, &QAction::triggered, mdiArea, &QMdiArea::activateNextSubWindow); previousAct = new QAction(tr("Pre&vious"), this); previousAct->setShortcuts(QKeySequence::PreviousChild); previousAct->setStatusTip(tr("Move the focus to the previous " "window")); - connect(previousAct, SIGNAL(triggered()), - mdiArea, SLOT(activatePreviousSubWindow())); - - separatorAct = new QAction(this); - separatorAct->setSeparator(true); - - aboutAct = new QAction(tr("&About"), this); - aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - QAction *action = fileMenu->addAction(tr("Switch layout direction")); - connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection())); - fileMenu->addAction(exitAct); + connect(previousAct, &QAction::triggered, mdiArea, &QMdiArea::activatePreviousSubWindow); - editMenu = menuBar()->addMenu(tr("&Edit")); -#ifndef QT_NO_CLIPBOARD - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); -#endif + windowMenuSeparatorAct = new QAction(this); + windowMenuSeparatorAct->setSeparator(true); - windowMenu = menuBar()->addMenu(tr("&Window")); updateWindowMenu(); - connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu())); menuBar()->addSeparator(); - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); -void MainWindow::createToolBars() -{ - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); - fileToolBar->addAction(openAct); - fileToolBar->addAction(saveAct); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); + aboutAct->setStatusTip(tr("Show the application's About box")); -#ifndef QT_NO_CLIPBOARD - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); -#endif + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); + aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); } void MainWindow::createStatusBar() @@ -368,28 +459,32 @@ void MainWindow::createStatusBar() void MainWindow::readSettings() { - QSettings settings("QtProject", "MDI Example"); - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); - move(pos); - resize(size); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } } void MainWindow::writeSettings() { - QSettings settings("QtProject", "MDI Example"); - settings.setValue("pos", pos()); - settings.setValue("size", size()); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); } -MdiChild *MainWindow::activeMdiChild() +MdiChild *MainWindow::activeMdiChild() const { if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow()) return qobject_cast<MdiChild *>(activeSubWindow->widget()); return 0; } -QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) +QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) const { QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); @@ -404,14 +499,7 @@ QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) void MainWindow::switchLayoutDirection() { if (layoutDirection() == Qt::LeftToRight) - qApp->setLayoutDirection(Qt::RightToLeft); + QGuiApplication::setLayoutDirection(Qt::RightToLeft); else - qApp->setLayoutDirection(Qt::LeftToRight); -} - -void MainWindow::setActiveSubWindow(QWidget *window) -{ - if (!window) - return; - mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window)); + QGuiApplication::setLayoutDirection(Qt::LeftToRight); } diff --git a/examples/widgets/mainwindows/mdi/mainwindow.h b/examples/widgets/mainwindows/mdi/mainwindow.h index fa8e0131e9..3ac60282fd 100644 --- a/examples/widgets/mainwindows/mdi/mainwindow.h +++ b/examples/widgets/mainwindows/mdi/mainwindow.h @@ -49,7 +49,6 @@ class QAction; class QMenu; class QMdiArea; class QMdiSubWindow; -class QSignalMapper; QT_END_NAMESPACE class MainWindow : public QMainWindow @@ -69,6 +68,8 @@ private slots: void open(); void save(); void saveAs(); + void updateRecentFileActions(); + void openRecentFile(); #ifndef QT_NO_CLIPBOARD void cut(); void copy(); @@ -79,32 +80,30 @@ private slots: void updateWindowMenu(); MdiChild *createMdiChild(); void switchLayoutDirection(); - void setActiveSubWindow(QWidget *window); private: + enum { MaxRecentFiles = 5 }; + void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); - MdiChild *activeMdiChild(); - QMdiSubWindow *findMdiChild(const QString &fileName); + bool loadFile(const QString &fileName); + static bool hasRecentFiles(); + void prependToRecentFiles(const QString &fileName); + void setRecentFilesVisible(bool visible); + MdiChild *activeMdiChild() const; + QMdiSubWindow *findMdiChild(const QString &fileName) const; QMdiArea *mdiArea; - QSignalMapper *windowMapper; - QMenu *fileMenu; - QMenu *editMenu; QMenu *windowMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; QAction *newAct; - QAction *openAct; QAction *saveAct; QAction *saveAsAct; - QAction *exitAct; + QAction *recentFileActs[MaxRecentFiles]; + QAction *recentFileSeparator; + QAction *recentFileSubMenuAct; #ifndef QT_NO_CLIPBOARD QAction *cutAct; QAction *copyAct; @@ -116,9 +115,7 @@ private: QAction *cascadeAct; QAction *nextAct; QAction *previousAct; - QAction *separatorAct; - QAction *aboutAct; - QAction *aboutQtAct; + QAction *windowMenuSeparatorAct; }; #endif diff --git a/examples/widgets/mainwindows/mdi/mdichild.cpp b/examples/widgets/mainwindows/mdi/mdichild.cpp index 242e8248a2..73364eb3ee 100644 --- a/examples/widgets/mainwindows/mdi/mdichild.cpp +++ b/examples/widgets/mainwindows/mdi/mdichild.cpp @@ -56,8 +56,8 @@ void MdiChild::newFile() curFile = tr("document%1.txt").arg(sequenceNumber++); setWindowTitle(curFile + "[*]"); - connect(document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(document(), &QTextDocument::contentsChanged, + this, &MdiChild::documentWasModified); } bool MdiChild::loadFile(const QString &fileName) @@ -78,8 +78,8 @@ bool MdiChild::loadFile(const QString &fileName) setCurrentFile(fileName); - connect(document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(document(), &QTextDocument::contentsChanged, + this, &MdiChild::documentWasModified); return true; } @@ -109,8 +109,7 @@ bool MdiChild::saveFile(const QString &fileName) if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("MDI"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return false; } @@ -144,18 +143,22 @@ void MdiChild::documentWasModified() bool MdiChild::maybeSave() { - if (document()->isModified()) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("MDI"), - tr("'%1' has been modified.\n" - "Do you want to save your changes?") - .arg(userFriendlyCurrentFile()), - QMessageBox::Save | QMessageBox::Discard - | QMessageBox::Cancel); - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; + if (!document()->isModified()) + return true; + const QMessageBox::StandardButton ret + = QMessageBox::warning(this, tr("MDI"), + tr("'%1' has been modified.\n" + "Do you want to save your changes?") + .arg(userFriendlyCurrentFile()), + QMessageBox::Save | QMessageBox::Discard + | QMessageBox::Cancel); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; } return true; } diff --git a/examples/widgets/mainwindows/menus/mainwindow.cpp b/examples/widgets/mainwindows/menus/mainwindow.cpp index 31515394bd..d487e3a277 100644 --- a/examples/widgets/mainwindows/menus/mainwindow.cpp +++ b/examples/widgets/mainwindows/menus/mainwindow.cpp @@ -198,63 +198,63 @@ void MainWindow::createActions() newAct = new QAction(tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); //! [4] openAct = new QAction(tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); //! [5] saveAct = new QAction(tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); printAct = new QAction(tr("&Print..."), this); printAct->setShortcuts(QKeySequence::Print); printAct->setStatusTip(tr("Print the document")); - connect(printAct, SIGNAL(triggered()), this, SLOT(print())); + connect(printAct, &QAction::triggered, this, &MainWindow::print); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); + connect(exitAct, &QAction::triggered, this, &QWidget::close); undoAct = new QAction(tr("&Undo"), this); undoAct->setShortcuts(QKeySequence::Undo); undoAct->setStatusTip(tr("Undo the last operation")); - connect(undoAct, SIGNAL(triggered()), this, SLOT(undo())); + connect(undoAct, &QAction::triggered, this, &MainWindow::undo); redoAct = new QAction(tr("&Redo"), this); redoAct->setShortcuts(QKeySequence::Redo); redoAct->setStatusTip(tr("Redo the last operation")); - connect(redoAct, SIGNAL(triggered()), this, SLOT(redo())); + connect(redoAct, &QAction::triggered, this, &MainWindow::redo); cutAct = new QAction(tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), this, SLOT(cut())); + connect(cutAct, &QAction::triggered, this, &MainWindow::cut); copyAct = new QAction(tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), this, SLOT(copy())); + connect(copyAct, &QAction::triggered, this, &MainWindow::copy); pasteAct = new QAction(tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); + connect(pasteAct, &QAction::triggered, this, &MainWindow::paste); boldAct = new QAction(tr("&Bold"), this); boldAct->setCheckable(true); boldAct->setShortcut(QKeySequence::Bold); boldAct->setStatusTip(tr("Make the text bold")); - connect(boldAct, SIGNAL(triggered()), this, SLOT(bold())); + connect(boldAct, &QAction::triggered, this, &MainWindow::bold); QFont boldFont = boldAct->font(); boldFont.setBold(true); @@ -264,7 +264,7 @@ void MainWindow::createActions() italicAct->setCheckable(true); italicAct->setShortcut(QKeySequence::Italic); italicAct->setStatusTip(tr("Make the text italic")); - connect(italicAct, SIGNAL(triggered()), this, SLOT(italic())); + connect(italicAct, &QAction::triggered, this, &MainWindow::italic); QFont italicFont = italicAct->font(); italicFont.setItalic(true); @@ -273,45 +273,45 @@ void MainWindow::createActions() setLineSpacingAct = new QAction(tr("Set &Line Spacing..."), this); setLineSpacingAct->setStatusTip(tr("Change the gap between the lines of a " "paragraph")); - connect(setLineSpacingAct, SIGNAL(triggered()), this, SLOT(setLineSpacing())); + connect(setLineSpacingAct, &QAction::triggered, this, &MainWindow::setLineSpacing); setParagraphSpacingAct = new QAction(tr("Set &Paragraph Spacing..."), this); setParagraphSpacingAct->setStatusTip(tr("Change the gap between paragraphs")); - connect(setParagraphSpacingAct, SIGNAL(triggered()), - this, SLOT(setParagraphSpacing())); + connect(setParagraphSpacingAct, &QAction::triggered, + this, &MainWindow::setParagraphSpacing); aboutAct = new QAction(tr("&About"), this); aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); + connect(aboutAct, &QAction::triggered, this, &MainWindow::about); aboutQtAct = new QAction(tr("About &Qt"), this); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - connect(aboutQtAct, SIGNAL(triggered()), this, SLOT(aboutQt())); + connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); + connect(aboutQtAct, &QAction::triggered, this, &MainWindow::aboutQt); leftAlignAct = new QAction(tr("&Left Align"), this); leftAlignAct->setCheckable(true); leftAlignAct->setShortcut(tr("Ctrl+L")); leftAlignAct->setStatusTip(tr("Left align the selected text")); - connect(leftAlignAct, SIGNAL(triggered()), this, SLOT(leftAlign())); + connect(leftAlignAct, &QAction::triggered, this, &MainWindow::leftAlign); rightAlignAct = new QAction(tr("&Right Align"), this); rightAlignAct->setCheckable(true); rightAlignAct->setShortcut(tr("Ctrl+R")); rightAlignAct->setStatusTip(tr("Right align the selected text")); - connect(rightAlignAct, SIGNAL(triggered()), this, SLOT(rightAlign())); + connect(rightAlignAct, &QAction::triggered, this, &MainWindow::rightAlign); justifyAct = new QAction(tr("&Justify"), this); justifyAct->setCheckable(true); justifyAct->setShortcut(tr("Ctrl+J")); justifyAct->setStatusTip(tr("Justify the selected text")); - connect(justifyAct, SIGNAL(triggered()), this, SLOT(justify())); + connect(justifyAct, &QAction::triggered, this, &MainWindow::justify); centerAct = new QAction(tr("&Center"), this); centerAct->setCheckable(true); centerAct->setShortcut(tr("Ctrl+E")); centerAct->setStatusTip(tr("Center the selected text")); - connect(centerAct, SIGNAL(triggered()), this, SLOT(center())); + connect(centerAct, &QAction::triggered, this, &MainWindow::center); //! [6] //! [7] alignmentGroup = new QActionGroup(this); diff --git a/examples/widgets/mainwindows/recentfiles/mainwindow.cpp b/examples/widgets/mainwindows/recentfiles/mainwindow.cpp deleted file mode 100644 index b89797092a..0000000000 --- a/examples/widgets/mainwindows/recentfiles/mainwindow.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtWidgets> - -#include "mainwindow.h" - -MainWindow::MainWindow() -{ - setAttribute(Qt::WA_DeleteOnClose); - - textEdit = new QTextEdit; - setCentralWidget(textEdit); - - createActions(); - createMenus(); - (void)statusBar(); - - setWindowFilePath(QString()); - resize(400, 300); -} - -void MainWindow::newFile() -{ - MainWindow *other = new MainWindow; - other->show(); -} - -void MainWindow::open() -{ - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) - loadFile(fileName); -} - -void MainWindow::save() -{ - if (curFile.isEmpty()) - saveAs(); - else - saveFile(curFile); -} - -void MainWindow::saveAs() -{ - QString fileName = QFileDialog::getSaveFileName(this); - if (fileName.isEmpty()) - return; - - saveFile(fileName); -} - -void MainWindow::openRecentFile() -{ - QAction *action = qobject_cast<QAction *>(sender()); - if (action) - loadFile(action->data().toString()); -} - -void MainWindow::about() -{ - QMessageBox::about(this, tr("About Recent Files"), - tr("The <b>Recent Files</b> example demonstrates how to provide a " - "recently used file menu in a Qt application.")); -} - -void MainWindow::createActions() -{ - newAct = new QAction(tr("&New"), this); - newAct->setShortcuts(QKeySequence::New); - newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); - - openAct = new QAction(tr("&Open..."), this); - openAct->setShortcuts(QKeySequence::Open); - openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); - - saveAct = new QAction(tr("&Save"), this); - saveAct->setShortcuts(QKeySequence::Save); - saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); - - saveAsAct = new QAction(tr("Save &As..."), this); - saveAsAct->setShortcuts(QKeySequence::SaveAs); - saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); - - for (int i = 0; i < MaxRecentFiles; ++i) { - recentFileActs[i] = new QAction(this); - recentFileActs[i]->setVisible(false); - connect(recentFileActs[i], SIGNAL(triggered()), - this, SLOT(openRecentFile())); - } - - exitAct = new QAction(tr("E&xit"), this); - exitAct->setShortcuts(QKeySequence::Quit); - exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); - - aboutAct = new QAction(tr("&About"), this); - aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -} - -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - separatorAct = fileMenu->addSeparator(); - for (int i = 0; i < MaxRecentFiles; ++i) - fileMenu->addAction(recentFileActs[i]); - fileMenu->addSeparator(); - fileMenu->addAction(exitAct); - updateRecentFileActions(); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} - -void MainWindow::loadFile(const QString &fileName) -{ - QFile file(fileName); - if (!file.open(QFile::ReadOnly | QFile::Text)) { - QMessageBox::warning(this, tr("Recent Files"), - tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return; - } - - QTextStream in(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); - textEdit->setPlainText(in.readAll()); - QApplication::restoreOverrideCursor(); - - setCurrentFile(fileName); - statusBar()->showMessage(tr("File loaded"), 2000); -} - -void MainWindow::saveFile(const QString &fileName) -{ - QFile file(fileName); - if (!file.open(QFile::WriteOnly | QFile::Text)) { - QMessageBox::warning(this, tr("Recent Files"), - tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return; - } - - QTextStream out(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); - out << textEdit->toPlainText(); - QApplication::restoreOverrideCursor(); - - setCurrentFile(fileName); - statusBar()->showMessage(tr("File saved"), 2000); -} - -void MainWindow::setCurrentFile(const QString &fileName) -{ - curFile = fileName; - setWindowFilePath(curFile); - - QSettings settings; - QStringList files = settings.value("recentFileList").toStringList(); - files.removeAll(fileName); - files.prepend(fileName); - while (files.size() > MaxRecentFiles) - files.removeLast(); - - settings.setValue("recentFileList", files); - - foreach (QWidget *widget, QApplication::topLevelWidgets()) { - MainWindow *mainWin = qobject_cast<MainWindow *>(widget); - if (mainWin) - mainWin->updateRecentFileActions(); - } -} - -void MainWindow::updateRecentFileActions() -{ - QSettings settings; - QStringList files = settings.value("recentFileList").toStringList(); - - int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles); - - for (int i = 0; i < numRecentFiles; ++i) { - QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i])); - recentFileActs[i]->setText(text); - recentFileActs[i]->setData(files[i]); - recentFileActs[i]->setVisible(true); - } - for (int j = numRecentFiles; j < MaxRecentFiles; ++j) - recentFileActs[j]->setVisible(false); - - separatorAct->setVisible(numRecentFiles > 0); -} - -QString MainWindow::strippedName(const QString &fullFileName) -{ - return QFileInfo(fullFileName).fileName(); -} diff --git a/examples/widgets/mainwindows/recentfiles/recentfiles.pro b/examples/widgets/mainwindows/recentfiles/recentfiles.pro deleted file mode 100644 index ccf948f560..0000000000 --- a/examples/widgets/mainwindows/recentfiles/recentfiles.pro +++ /dev/null @@ -1,9 +0,0 @@ -QT += widgets - -HEADERS = mainwindow.h -SOURCES = main.cpp \ - mainwindow.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mainwindows/recentfiles -INSTALLS += target diff --git a/examples/widgets/mainwindows/sdi/main.cpp b/examples/widgets/mainwindows/sdi/main.cpp index d3350da946..4b125722d8 100644 --- a/examples/widgets/mainwindows/sdi/main.cpp +++ b/examples/widgets/mainwindows/sdi/main.cpp @@ -39,6 +39,7 @@ ****************************************************************************/ #include <QApplication> +#include <QCommandLineParser> #include "mainwindow.h" @@ -46,9 +47,27 @@ int main(int argc, char *argv[]) { Q_INIT_RESOURCE(sdi); QApplication app(argc, argv); - app.setApplicationName("SDI Example"); - app.setOrganizationName("QtProject"); - MainWindow *mainWin = new MainWindow; + QCoreApplication::setApplicationName("SDI Example"); + QCoreApplication::setOrganizationName("QtProject"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::applicationName()); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("file", "The file(s) to open."); + parser.process(app); + + MainWindow *mainWin = Q_NULLPTR; + foreach (const QString &file, parser.positionalArguments()) { + MainWindow *newWin = new MainWindow(file); + newWin->tile(mainWin); + newWin->show(); + mainWin = newWin; + } + + if (!mainWin) + mainWin = new MainWindow; mainWin->show(); + return app.exec(); } diff --git a/examples/widgets/mainwindows/sdi/mainwindow.cpp b/examples/widgets/mainwindows/sdi/mainwindow.cpp index 1d6226e45c..29618f9ac2 100644 --- a/examples/widgets/mainwindows/sdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/sdi/mainwindow.cpp @@ -45,7 +45,7 @@ MainWindow::MainWindow() { init(); - setCurrentFile(""); + setCurrentFile(QString()); } MainWindow::MainWindow(const QString &fileName) @@ -67,44 +67,44 @@ void MainWindow::closeEvent(QCloseEvent *event) void MainWindow::newFile() { MainWindow *other = new MainWindow; - other->move(x() + 40, y() + 40); + other->tile(this); other->show(); } void MainWindow::open() { - QString fileName = QFileDialog::getOpenFileName(this); - if (!fileName.isEmpty()) { - MainWindow *existing = findMainWindow(fileName); - if (existing) { - existing->show(); - existing->raise(); - existing->activateWindow(); - return; - } - - if (isUntitled && textEdit->document()->isEmpty() - && !isWindowModified()) { - loadFile(fileName); - } else { - MainWindow *other = new MainWindow(fileName); - if (other->isUntitled) { - delete other; - return; - } - other->move(x() + 40, y() + 40); - other->show(); - } + const QString fileName = QFileDialog::getOpenFileName(this); + if (!fileName.isEmpty()) + openFile(fileName); +} + +void MainWindow::openFile(const QString &fileName) +{ + MainWindow *existing = findMainWindow(fileName); + if (existing) { + existing->show(); + existing->raise(); + existing->activateWindow(); + return; + } + + if (isUntitled && textEdit->document()->isEmpty() && !isWindowModified()) { + loadFile(fileName); + return; } + + MainWindow *other = new MainWindow(fileName); + if (other->isUntitled) { + delete other; + return; + } + other->tile(this); + other->show(); } bool MainWindow::save() { - if (isUntitled) { - return saveAs(); - } else { - return saveFile(curFile); - } + return isUntitled ? saveAs() : saveFile(curFile); } bool MainWindow::saveAs() @@ -139,123 +139,131 @@ void MainWindow::init() setCentralWidget(textEdit); createActions(); - createMenus(); - createToolBars(); createStatusBar(); readSettings(); - connect(textEdit->document(), SIGNAL(contentsChanged()), - this, SLOT(documentWasModified())); + connect(textEdit->document(), &QTextDocument::contentsChanged, + this, &MainWindow::documentWasModified); setUnifiedTitleAndToolBarOnMac(true); } +void MainWindow::tile(const QMainWindow *previous) +{ + if (!previous) + return; + int topFrameWidth = previous->geometry().top() - previous->pos().y(); + if (!topFrameWidth) + topFrameWidth = 40; + const QPoint pos = previous->pos() + 2 * QPoint(topFrameWidth, topFrameWidth); + if (QApplication::desktop()->availableGeometry(this).contains(rect().bottomRight() + pos)) + move(pos); +} + +//! [implicit tr context] void MainWindow::createActions() { - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); +//! [implicit tr context] + QToolBar *fileToolBar = addToolBar(tr("File")); + + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newAct = new QAction(newIcon, tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); - saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); - connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); - saveAsAct = new QAction(tr("Save &As..."), this); + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + QAction *saveAsAct = fileMenu->addAction(saveAsIcon, tr("Save &As..."), this, &MainWindow::saveAs); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); - connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); - closeAct = new QAction(tr("&Close"), this); + fileMenu->addSeparator(); + + QMenu *recentMenu = fileMenu->addMenu(tr("Recent...")); + connect(recentMenu, &QMenu::aboutToShow, this, &MainWindow::updateRecentFileActions); + recentFileSubMenuAct = recentMenu->menuAction(); + + for (int i = 0; i < MaxRecentFiles; ++i) { + recentFileActs[i] = recentMenu->addAction(QString(), this, &MainWindow::openRecentFile); + recentFileActs[i]->setVisible(false); + } + + recentFileSeparator = fileMenu->addSeparator(); + + setRecentFilesVisible(MainWindow::hasRecentFiles()); + + QAction *closeAct = fileMenu->addAction(tr("&Close"), this, &QWidget::close); closeAct->setShortcut(tr("Ctrl+W")); closeAct->setStatusTip(tr("Close this window")); - connect(closeAct, SIGNAL(triggered()), this, SLOT(close())); - exitAct = new QAction(tr("E&xit"), this); + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), qApp, &QApplication::closeAllWindows); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); - cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut())); + connect(cutAct, &QAction::triggered, textEdit, &QTextEdit::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); - copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + QAction *copyAct = new QAction(copyIcon, tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy())); + connect(copyAct, &QAction::triggered, textEdit, &QTextEdit::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); - pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + QAction *pasteAct = new QAction(pasteIcon, tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); - connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste())); + connect(pasteAct, &QAction::triggered, textEdit, &QTextEdit::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); + + menuBar()->addSeparator(); - aboutAct = new QAction(tr("&About"), this); + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); aboutAct->setStatusTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - aboutQtAct = new QAction(tr("About &Qt"), this); + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - cutAct->setEnabled(false); copyAct->setEnabled(false); - connect(textEdit, SIGNAL(copyAvailable(bool)), - cutAct, SLOT(setEnabled(bool))); - connect(textEdit, SIGNAL(copyAvailable(bool)), - copyAct, SLOT(setEnabled(bool))); -} - -//! [implicit tr context] -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); -//! [implicit tr context] - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(closeAct); - fileMenu->addAction(exitAct); - - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); -} - -void MainWindow::createToolBars() -{ -//! [0] - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); - fileToolBar->addAction(openAct); -//! [0] - fileToolBar->addAction(saveAct); - - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); + connect(textEdit, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(textEdit, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled); } void MainWindow::createStatusBar() @@ -265,33 +273,41 @@ void MainWindow::createStatusBar() void MainWindow::readSettings() { - QSettings settings; - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); - move(pos); - resize(size); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } } void MainWindow::writeSettings() { - QSettings settings; - settings.setValue("pos", pos()); - settings.setValue("size", size()); + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); } bool MainWindow::maybeSave() { - if (textEdit->document()->isModified()) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("SDI"), - tr("The document has been modified.\n" - "Do you want to save your changes?"), - QMessageBox::Save | QMessageBox::Discard - | QMessageBox::Cancel); - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; + if (!textEdit->document()->isModified()) + return true; + const QMessageBox::StandardButton ret + = QMessageBox::warning(this, tr("SDI"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard + | QMessageBox::Cancel); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; } return true; } @@ -303,8 +319,7 @@ void MainWindow::loadFile(const QString &fileName) if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("SDI"), tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } @@ -317,14 +332,90 @@ void MainWindow::loadFile(const QString &fileName) statusBar()->showMessage(tr("File loaded"), 2000); } +void MainWindow::setRecentFilesVisible(bool visible) +{ + recentFileSubMenuAct->setVisible(visible); + recentFileSeparator->setVisible(visible); +} + +static inline QString recentFilesKey() { return QStringLiteral("recentFileList"); } +static inline QString fileKey() { return QStringLiteral("file"); } + +static QStringList readRecentFiles(QSettings &settings) +{ + QStringList result; + const int count = settings.beginReadArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + result.append(settings.value(fileKey()).toString()); + } + settings.endArray(); + return result; +} + +static void writeRecentFiles(const QStringList &files, QSettings &settings) +{ + const int count = files.size(); + settings.beginWriteArray(recentFilesKey()); + for (int i = 0; i < count; ++i) { + settings.setArrayIndex(i); + settings.setValue(fileKey(), files.at(i)); + } + settings.endArray(); +} + +bool MainWindow::hasRecentFiles() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const int count = settings.beginReadArray(recentFilesKey()); + settings.endArray(); + return count > 0; +} + +void MainWindow::prependToRecentFiles(const QString &fileName) +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList oldRecentFiles = readRecentFiles(settings); + QStringList recentFiles = oldRecentFiles; + recentFiles.removeAll(fileName); + recentFiles.prepend(fileName); + if (oldRecentFiles != recentFiles) + writeRecentFiles(recentFiles, settings); + + setRecentFilesVisible(!recentFiles.isEmpty()); +} + +void MainWindow::updateRecentFileActions() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QStringList recentFiles = readRecentFiles(settings); + const int count = qMin(int(MaxRecentFiles), recentFiles.size()); + int i = 0; + for ( ; i < count; ++i) { + const QString fileName = MainWindow::strippedName(recentFiles.at(i)); + recentFileActs[i]->setText(tr("&%1 %2").arg(i + 1).arg(fileName)); + recentFileActs[i]->setData(recentFiles.at(i)); + recentFileActs[i]->setVisible(true); + } + for ( ; i < MaxRecentFiles; ++i) + recentFileActs[i]->setVisible(false); +} + +void MainWindow::openRecentFile() +{ + if (const QAction *action = qobject_cast<const QAction *>(sender())) + openFile(action->data().toString()); +} + bool MainWindow::saveFile(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("SDI"), tr("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + .arg(QDir::toNativeSeparators(fileName), file.errorString())); return false; } @@ -351,6 +442,10 @@ void MainWindow::setCurrentFile(const QString &fileName) textEdit->document()->setModified(false); setWindowModified(false); + + if (!isUntitled && windowFilePath() != curFile) + MainWindow::prependToRecentFiles(curFile); + setWindowFilePath(curFile); } @@ -359,14 +454,15 @@ QString MainWindow::strippedName(const QString &fullFileName) return QFileInfo(fullFileName).fileName(); } -MainWindow *MainWindow::findMainWindow(const QString &fileName) +MainWindow *MainWindow::findMainWindow(const QString &fileName) const { QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); - foreach (QWidget *widget, qApp->topLevelWidgets()) { + foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast<MainWindow *>(widget); if (mainWin && mainWin->curFile == canonicalFilePath) return mainWin; } + return 0; } diff --git a/examples/widgets/mainwindows/sdi/mainwindow.h b/examples/widgets/mainwindows/sdi/mainwindow.h index f1860a8511..66ac618c72 100644 --- a/examples/widgets/mainwindows/sdi/mainwindow.h +++ b/examples/widgets/mainwindows/sdi/mainwindow.h @@ -42,6 +42,7 @@ #define MAINWINDOW_H #include <QMainWindow> +#include <QList> QT_BEGIN_NAMESPACE class QAction; @@ -57,7 +58,9 @@ class MainWindow : public QMainWindow public: MainWindow(); //! [class definition with macro] - MainWindow(const QString &fileName); + explicit MainWindow(const QString &fileName); + + void tile(const QMainWindow *previous); protected: void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; @@ -67,44 +70,38 @@ private slots: void open(); bool save(); bool saveAs(); + void updateRecentFileActions(); + void openRecentFile(); void about(); void documentWasModified(); private: + enum { MaxRecentFiles = 5 }; + void init(); void createActions(); - void createMenus(); - void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); bool maybeSave(); + void openFile(const QString &fileName); void loadFile(const QString &fileName); + static bool hasRecentFiles(); + void prependToRecentFiles(const QString &fileName); + void setRecentFilesVisible(bool visible); bool saveFile(const QString &fileName); void setCurrentFile(const QString &fileName); - QString strippedName(const QString &fullFileName); - MainWindow *findMainWindow(const QString &fileName); + static QString strippedName(const QString &fullFileName); + MainWindow *findMainWindow(const QString &fileName) const; QTextEdit *textEdit; + + QAction *recentFileActs[MaxRecentFiles]; + QAction *recentFileSeparator; + QAction *recentFileSubMenuAct; + QString curFile; bool isUntitled; - - QMenu *fileMenu; - QMenu *editMenu; - QMenu *helpMenu; - QToolBar *fileToolBar; - QToolBar *editToolBar; - QAction *newAct; - QAction *openAct; - QAction *saveAct; - QAction *saveAsAct; - QAction *closeAct; - QAction *exitAct; - QAction *cutAct; - QAction *copyAct; - QAction *pasteAct; - QAction *aboutAct; - QAction *aboutQtAct; }; #endif diff --git a/examples/widgets/painting/fontsampler/mainwindow.cpp b/examples/widgets/painting/fontsampler/mainwindow.cpp index bff8ae9c22..53a2aac82e 100644 --- a/examples/widgets/painting/fontsampler/mainwindow.cpp +++ b/examples/widgets/painting/fontsampler/mainwindow.cpp @@ -80,7 +80,7 @@ void MainWindow::setupFontTree() QTreeWidgetItem *familyItem = new QTreeWidgetItem(fontTree); familyItem->setText(0, family); familyItem->setCheckState(0, Qt::Unchecked); - familyItem->setFlags(familyItem->flags() | Qt::ItemIsTristate); + familyItem->setFlags(familyItem->flags() | Qt::ItemIsAutoTristate); foreach (QString style, styles) { QTreeWidgetItem *styleItem = new QTreeWidgetItem(familyItem); diff --git a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro index 19f471b5cf..93cd950b0b 100644 --- a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro +++ b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro @@ -14,5 +14,5 @@ INSTALLS += target wince { addFiles.files = main.cpp mainwindow.cpp addFiles.path = . - DEPLOYMENT += addFiles + INSTALLS += addFiles } diff --git a/examples/widgets/tools/regularexpression/images/copy.png b/examples/widgets/tools/regularexpression/images/copy.png Binary files differnew file mode 100644 index 0000000000..2aeb28288f --- /dev/null +++ b/examples/widgets/tools/regularexpression/images/copy.png diff --git a/examples/widgets/mainwindows/recentfiles/main.cpp b/examples/widgets/tools/regularexpression/main.cpp index 23ff3eda16..a5ef410688 100644 --- a/examples/widgets/mainwindows/recentfiles/main.cpp +++ b/examples/widgets/tools/regularexpression/main.cpp @@ -38,16 +38,14 @@ ** ****************************************************************************/ -#include <QApplication> +#include "regularexpressiondialog.h" -#include "mainwindow.h" +#include <QApplication> int main(int argc, char *argv[]) { QApplication app(argc, argv); - app.setOrganizationName("QtProject"); - app.setApplicationName("Recent Files Example"); - MainWindow *mainWin = new MainWindow; - mainWin->show(); + RegularExpressionDialog dialog; + dialog.show(); return app.exec(); } diff --git a/examples/widgets/tools/regularexpression/regularexpression.pro b/examples/widgets/tools/regularexpression/regularexpression.pro new file mode 100644 index 0000000000..8e72e171b8 --- /dev/null +++ b/examples/widgets/tools/regularexpression/regularexpression.pro @@ -0,0 +1,11 @@ +QT += widgets + +HEADERS = regularexpressiondialog.h +SOURCES = regularexpressiondialog.cpp \ + main.cpp + +RESOURCES += regularexpression.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/regularexpression +INSTALLS += target diff --git a/examples/widgets/tools/regularexpression/regularexpression.qrc b/examples/widgets/tools/regularexpression/regularexpression.qrc new file mode 100644 index 0000000000..ce7e104af3 --- /dev/null +++ b/examples/widgets/tools/regularexpression/regularexpression.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>images/copy.png</file> +</qresource> +</RCC> diff --git a/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp b/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp new file mode 100644 index 0000000000..d40b4b325d --- /dev/null +++ b/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp @@ -0,0 +1,349 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +** Copyright (C) 2015 Samuel Gaist <samuel.gaist@edeltech.ch> +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "regularexpressiondialog.h" + +#include <QApplication> + +#include <QCheckBox> +#include <QComboBox> +#include <QLabel> +#include <QLineEdit> +#include <QSpinBox> +#include <QPlainTextEdit> +#include <QTreeWidget> + +#include <QAction> +#include <QClipboard> + +#include <QHBoxLayout> +#include <QGridLayout> +#include <QFormLayout> + +#include <QRegularExpression> +#include <QRegularExpressionMatch> +#include <QRegularExpressionMatchIterator> + +Q_DECLARE_METATYPE(QRegularExpression::MatchType) + +RegularExpressionDialog::RegularExpressionDialog(QWidget *parent) + : QDialog(parent) +{ + setupUi(); + setWindowTitle(tr("QRegularExpression Example")); + + connect(patternLineEdit, &QLineEdit::textChanged, this, &RegularExpressionDialog::refresh); + connect(subjectTextEdit, &QPlainTextEdit::textChanged, this, &RegularExpressionDialog::refresh); + + connect(caseInsensitiveOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + connect(dotMatchesEverythingOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + connect(multilineOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + connect(extendedPatternSyntaxOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + connect(invertedGreedinessOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + connect(dontCaptureOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + connect(useUnicodePropertiesOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + connect(optimizeOnFirstUsageOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + connect(dontAutomaticallyOptimizeOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + + connect(offsetSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), + this, &RegularExpressionDialog::refresh); + + connect(matchTypeComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + this, &RegularExpressionDialog::refresh); + + connect(anchoredMatchOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + connect(dontCheckSubjectStringMatchOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); + + patternLineEdit->setText(tr("(\\+?\\d+)-(?<prefix>\\d+)-(?<number>\\w+)")); + subjectTextEdit->setPlainText(tr("My office number is +43-152-0123456, my mobile is 001-41-255512 instead.")); + + refresh(); +} + +void RegularExpressionDialog::refresh() +{ + setUpdatesEnabled(false); + + const QString pattern = patternLineEdit->text(); + const QString text = subjectTextEdit->toPlainText(); + + offsetSpinBox->setMaximum(qMax(0, text.length() - 1)); + + QString escaped = pattern; + escaped.replace(QLatin1String("\\"), QLatin1String("\\\\")); + escaped.replace(QLatin1String("\""), QLatin1String("\\\"")); + escaped.prepend(QLatin1String("\"")); + escaped.append(QLatin1String("\"")); + escapedPatternLineEdit->setText(escaped); + + QRegularExpression rx(pattern); + QRegularExpression::MatchType matchType = matchTypeComboBox->currentData().value<QRegularExpression::MatchType>(); + QRegularExpression::PatternOptions patternOptions = QRegularExpression::NoPatternOption; + QRegularExpression::MatchOptions matchOptions = QRegularExpression::NoMatchOption; + + if (anchoredMatchOptionCheckBox->isChecked()) + matchOptions |= QRegularExpression::AnchoredMatchOption; + if (dontCheckSubjectStringMatchOptionCheckBox->isChecked()) + matchOptions |= QRegularExpression::DontCheckSubjectStringMatchOption; + + if (caseInsensitiveOptionCheckBox->isChecked()) + patternOptions |= QRegularExpression::CaseInsensitiveOption; + if (dotMatchesEverythingOptionCheckBox->isChecked()) + patternOptions |= QRegularExpression::DotMatchesEverythingOption; + if (multilineOptionCheckBox->isChecked()) + patternOptions |= QRegularExpression::MultilineOption; + if (extendedPatternSyntaxOptionCheckBox->isChecked()) + patternOptions |= QRegularExpression::ExtendedPatternSyntaxOption; + if (invertedGreedinessOptionCheckBox->isChecked()) + patternOptions |= QRegularExpression::InvertedGreedinessOption; + if (dontCaptureOptionCheckBox->isChecked()) + patternOptions |= QRegularExpression::DontCaptureOption; + if (useUnicodePropertiesOptionCheckBox->isChecked()) + patternOptions |= QRegularExpression::UseUnicodePropertiesOption; + if (optimizeOnFirstUsageOptionCheckBox->isChecked()) + patternOptions |= QRegularExpression::OptimizeOnFirstUsageOption; + if (dontAutomaticallyOptimizeOptionCheckBox->isChecked()) + patternOptions |= QRegularExpression::DontAutomaticallyOptimizeOption; + + rx.setPatternOptions(patternOptions); + + QPalette palette = patternLineEdit->palette(); + if (rx.isValid()) + palette.setColor(QPalette::Text, subjectTextEdit->palette().color(QPalette::Text)); + else + palette.setColor(QPalette::Text, Qt::red); + patternLineEdit->setPalette(palette); + + matchDetailsTreeWidget->clear(); + matchDetailsTreeWidget->setEnabled(rx.isValid()); + + if (rx.isValid()) { + const int capturingGroupsCount = rx.captureCount() + 1; + + QRegularExpressionMatchIterator iterator = rx.globalMatch(text, offsetSpinBox->value(), matchType, matchOptions); + int i = 0; + + while (iterator.hasNext()) { + QRegularExpressionMatch match = iterator.next(); + + QTreeWidgetItem *matchDetailTopItem = new QTreeWidgetItem(matchDetailsTreeWidget); + matchDetailTopItem->setText(0, QString::number(i)); + + for (int captureGroupIndex = 0; captureGroupIndex < capturingGroupsCount; ++captureGroupIndex) { + QTreeWidgetItem *matchDetailItem = new QTreeWidgetItem(matchDetailTopItem); + matchDetailItem->setText(1, QString::number(captureGroupIndex)); + matchDetailItem->setText(2, match.captured(captureGroupIndex)); + } + + ++i; + } + } + + matchDetailsTreeWidget->expandAll(); + + namedGroupsTreeWidget->clear(); + namedGroupsTreeWidget->setEnabled(rx.isValid()); + + if (rx.isValid()) { + regexpStatusLabel->setText(tr("Valid")); + + const QStringList namedCaptureGroups = rx.namedCaptureGroups(); + for (int i = 0; i < namedCaptureGroups.size(); ++i) { + const QString currentNamedCaptureGroup = namedCaptureGroups.at(i); + + QTreeWidgetItem *namedGroupItem = new QTreeWidgetItem(namedGroupsTreeWidget); + namedGroupItem->setText(0, QString::number(i)); + namedGroupItem->setText(1, currentNamedCaptureGroup.isNull() ? tr("<no name>") : currentNamedCaptureGroup); + } + } else { + regexpStatusLabel->setText(tr("Invalid: syntax error at position %1 (%2)") + .arg(rx.patternErrorOffset()) + .arg(rx.errorString())); + } + + setUpdatesEnabled(true); +} + +void RegularExpressionDialog::copyEscapedPatternToClipboard() +{ +#ifndef QT_NO_CLIPBOARD + QClipboard *clipboard = QGuiApplication::clipboard(); + if (clipboard) + clipboard->setText(escapedPatternLineEdit->text()); +#endif +} + +void RegularExpressionDialog::setupUi() +{ + QWidget *leftHalfContainer = setupLeftUi(); + + QFrame *verticalSeparator = new QFrame; + verticalSeparator->setFrameStyle(QFrame::VLine | QFrame::Sunken); + + QWidget *rightHalfContainer = setupRightUi(); + + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->addWidget(leftHalfContainer); + mainLayout->addWidget(verticalSeparator); + mainLayout->addWidget(rightHalfContainer); + + setLayout(mainLayout); +} + +QWidget *RegularExpressionDialog::setupLeftUi() +{ + QWidget *container = new QWidget; + + QFormLayout *layout = new QFormLayout(container); + layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); + layout->setMargin(0); + + QLabel *regexpAndSubjectLabel = new QLabel(tr("<h3>Regular expression and text input</h3>")); + layout->addRow(regexpAndSubjectLabel); + + patternLineEdit = new QLineEdit; + patternLineEdit->setClearButtonEnabled(true); + layout->addRow(tr("&Pattern:"), patternLineEdit); + + escapedPatternLineEdit = new QLineEdit; + escapedPatternLineEdit->setReadOnly(true); + QPalette palette = escapedPatternLineEdit->palette(); + palette.setBrush(QPalette::Base, palette.brush(QPalette::Disabled, QPalette::Base)); + escapedPatternLineEdit->setPalette(palette); + +#ifndef QT_NO_CLIPBOARD + QAction *copyEscapedPatternAction = new QAction(this); + copyEscapedPatternAction->setText(tr("Copy to clipboard")); + copyEscapedPatternAction->setIcon(QIcon(QStringLiteral(":/images/copy.png"))); + connect(copyEscapedPatternAction, &QAction::triggered, this, &RegularExpressionDialog::copyEscapedPatternToClipboard); + escapedPatternLineEdit->addAction(copyEscapedPatternAction, QLineEdit::TrailingPosition); +#endif + + layout->addRow(tr("&Escaped pattern:"), escapedPatternLineEdit); + + subjectTextEdit = new QPlainTextEdit; + layout->addRow(tr("&Subject text:"), subjectTextEdit); + + caseInsensitiveOptionCheckBox = new QCheckBox(tr("Case insensitive (/i)")); + dotMatchesEverythingOptionCheckBox = new QCheckBox(tr("Dot matches everything (/s)")); + multilineOptionCheckBox = new QCheckBox(tr("Multiline (/m)")); + extendedPatternSyntaxOptionCheckBox = new QCheckBox(tr("Extended pattern (/x)")); + invertedGreedinessOptionCheckBox = new QCheckBox(tr("Inverted greediness")); + dontCaptureOptionCheckBox = new QCheckBox(tr("Don't capture")); + useUnicodePropertiesOptionCheckBox = new QCheckBox(tr("Use unicode properties (/u)")); + optimizeOnFirstUsageOptionCheckBox = new QCheckBox(tr("Optimize on first usage")); + dontAutomaticallyOptimizeOptionCheckBox = new QCheckBox(tr("Don't automatically optimize")); + + QGridLayout *patternOptionsCheckBoxLayout = new QGridLayout; + int gridRow = 0; + patternOptionsCheckBoxLayout->addWidget(caseInsensitiveOptionCheckBox, gridRow, 1); + patternOptionsCheckBoxLayout->addWidget(dotMatchesEverythingOptionCheckBox, gridRow, 2); + ++gridRow; + patternOptionsCheckBoxLayout->addWidget(multilineOptionCheckBox, gridRow, 1); + patternOptionsCheckBoxLayout->addWidget(extendedPatternSyntaxOptionCheckBox, gridRow, 2); + ++gridRow; + patternOptionsCheckBoxLayout->addWidget(invertedGreedinessOptionCheckBox, gridRow, 1); + patternOptionsCheckBoxLayout->addWidget(dontCaptureOptionCheckBox, gridRow, 2); + ++gridRow; + patternOptionsCheckBoxLayout->addWidget(useUnicodePropertiesOptionCheckBox, gridRow, 1); + patternOptionsCheckBoxLayout->addWidget(optimizeOnFirstUsageOptionCheckBox, gridRow, 2); + ++gridRow; + patternOptionsCheckBoxLayout->addWidget(dontAutomaticallyOptimizeOptionCheckBox, gridRow, 1); + + layout->addRow(tr("Pattern options:"), patternOptionsCheckBoxLayout); + + offsetSpinBox = new QSpinBox; + layout->addRow(tr("Match &offset:"), offsetSpinBox); + + matchTypeComboBox = new QComboBox; + matchTypeComboBox->addItem(tr("Normal"), QVariant::fromValue(QRegularExpression::NormalMatch)); + matchTypeComboBox->addItem(tr("Partial prefer complete"), QVariant::fromValue(QRegularExpression::PartialPreferCompleteMatch)); + matchTypeComboBox->addItem(tr("Partial prefer first"), QVariant::fromValue(QRegularExpression::PartialPreferFirstMatch)); + matchTypeComboBox->addItem(tr("No match"), QVariant::fromValue(QRegularExpression::NoMatch)); + layout->addRow(tr("Match &type:"), matchTypeComboBox); + + dontCheckSubjectStringMatchOptionCheckBox = new QCheckBox(tr("Don't check subject string")); + anchoredMatchOptionCheckBox = new QCheckBox(tr("Anchored match")); + + QGridLayout *matchOptionsCheckBoxLayout = new QGridLayout; + matchOptionsCheckBoxLayout->addWidget(dontCheckSubjectStringMatchOptionCheckBox, 0, 0); + matchOptionsCheckBoxLayout->addWidget(anchoredMatchOptionCheckBox, 0, 1); + layout->addRow(tr("Match options:"), matchOptionsCheckBoxLayout); + + return container; +} + +QWidget *RegularExpressionDialog::setupRightUi() +{ + QWidget *container = new QWidget; + + QFormLayout *layout = new QFormLayout(container); + layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); + layout->setMargin(0); + + QLabel *matchInfoLabel = new QLabel(tr("<h3>Match information</h3>")); + layout->addRow(matchInfoLabel); + + matchDetailsTreeWidget = new QTreeWidget; + matchDetailsTreeWidget->setHeaderLabels(QStringList() << tr("Match index") << tr("Group index") << tr("Captured string")); + matchDetailsTreeWidget->setSizeAdjustPolicy(QTreeWidget::AdjustToContents); + layout->addRow(tr("Match details:"), matchDetailsTreeWidget); + + QFrame *horizontalSeparator = new QFrame; + horizontalSeparator->setFrameStyle(QFrame::HLine | QFrame::Sunken); + layout->addRow(horizontalSeparator); + + QLabel *regexpInfoLabel = new QLabel(tr("<h3>Regular expression information</h3>")); + layout->addRow(regexpInfoLabel); + + regexpStatusLabel = new QLabel(tr("Valid")); + regexpStatusLabel->setWordWrap(true); + layout->addRow(tr("Pattern status:"), regexpStatusLabel); + + namedGroupsTreeWidget = new QTreeWidget; + namedGroupsTreeWidget->setHeaderLabels(QStringList() << tr("Index") << tr("Named group")); + namedGroupsTreeWidget->setSizeAdjustPolicy(QTreeWidget::AdjustToContents); + namedGroupsTreeWidget->setRootIsDecorated(false); + layout->addRow(tr("Named groups:"), namedGroupsTreeWidget); + + return container; +} diff --git a/examples/widgets/tools/regularexpression/regularexpressiondialog.h b/examples/widgets/tools/regularexpression/regularexpressiondialog.h new file mode 100644 index 0000000000..1b3b147c14 --- /dev/null +++ b/examples/widgets/tools/regularexpression/regularexpressiondialog.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +** Copyright (C) 2015 Samuel Gaist <samuel.gaist@edeltech.ch> +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef REGULAREXPRESSIONDIALOG_H +#define REGULAREXPRESSIONDIALOG_H + +#include <QDialog> + +QT_BEGIN_NAMESPACE +class QCheckBox; +class QComboBox; +class QLabel; +class QLineEdit; +class QSpinBox; +class QPlainTextEdit; +class QTreeWidget; +QT_END_NAMESPACE + +class RegularExpressionDialog : public QDialog +{ + Q_OBJECT + +public: + RegularExpressionDialog(QWidget *parent = 0); + +private: + void refresh(); + void copyEscapedPatternToClipboard(); + void setupUi(); + QWidget *setupLeftUi(); + QWidget *setupRightUi(); + + QLineEdit *patternLineEdit; + QLineEdit *escapedPatternLineEdit; + + QPlainTextEdit *subjectTextEdit; + + QCheckBox *caseInsensitiveOptionCheckBox; + QCheckBox *dotMatchesEverythingOptionCheckBox; + QCheckBox *multilineOptionCheckBox; + QCheckBox *extendedPatternSyntaxOptionCheckBox; + QCheckBox *invertedGreedinessOptionCheckBox; + QCheckBox *dontCaptureOptionCheckBox; + QCheckBox *useUnicodePropertiesOptionCheckBox; + QCheckBox *optimizeOnFirstUsageOptionCheckBox; + QCheckBox *dontAutomaticallyOptimizeOptionCheckBox; + + QSpinBox *offsetSpinBox; + + QComboBox *matchTypeComboBox; + + QCheckBox *anchoredMatchOptionCheckBox; + QCheckBox *dontCheckSubjectStringMatchOptionCheckBox; + + QTreeWidget *matchDetailsTreeWidget; + + QLabel *regexpStatusLabel; + QTreeWidget *namedGroupsTreeWidget; +}; + +#endif diff --git a/examples/widgets/tools/tools.pro b/examples/widgets/tools/tools.pro index 7178411110..282f8dedea 100644 --- a/examples/widgets/tools/tools.pro +++ b/examples/widgets/tools/tools.pro @@ -8,6 +8,7 @@ SUBDIRS = \ plugandpaintplugins \ plugandpaint \ regexp \ + regularexpression \ settingseditor \ styleplugin \ treemodelcompleter \ diff --git a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp index 45ded876a7..6764423d71 100644 --- a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp @@ -370,7 +370,6 @@ void AddressBook::loadFromFile() QDataStream in(&file); in.setVersion(QDataStream::Qt_4_3); - contacts.empty(); // empty existing contacts in >> contacts; QMap<QString, QString>::iterator i = contacts.begin(); diff --git a/examples/widgets/widgets/icons/icons.pro b/examples/widgets/widgets/icons/icons.pro index 21165163aa..4312a40e95 100644 --- a/examples/widgets/widgets/icons/icons.pro +++ b/examples/widgets/widgets/icons/icons.pro @@ -24,5 +24,5 @@ wince { } else { imageFiles.path = images } - DEPLOYMENT += imageFiles + INSTALLS += imageFiles } diff --git a/examples/widgets/widgets/movie/movie.pro b/examples/widgets/widgets/movie/movie.pro index 86d85552c2..94d86454d8 100644 --- a/examples/widgets/widgets/movie/movie.pro +++ b/examples/widgets/widgets/movie/movie.pro @@ -14,5 +14,5 @@ INSTALLS += target wince { addFiles.files += *.gif addFiles.path = . - DEPLOYMENT += addFiles + INSTALLS += addFiles } diff --git a/examples/widgets/widgets/tablet/images.qrc b/examples/widgets/widgets/tablet/images.qrc new file mode 100644 index 0000000000..eb3eabbace --- /dev/null +++ b/examples/widgets/widgets/tablet/images.qrc @@ -0,0 +1,8 @@ +<RCC> + <qresource> + <file>images/cursor-airbrush.png</file> + <file>images/cursor-eraser.png</file> + <file>images/cursor-felt-marker.png</file> + <file>images/cursor-pencil.png</file> + </qresource> +</RCC> diff --git a/examples/widgets/widgets/tablet/images/cursor-airbrush.png b/examples/widgets/widgets/tablet/images/cursor-airbrush.png Binary files differnew file mode 100644 index 0000000000..bea756ed6f --- /dev/null +++ b/examples/widgets/widgets/tablet/images/cursor-airbrush.png diff --git a/examples/widgets/widgets/tablet/images/cursor-eraser.png b/examples/widgets/widgets/tablet/images/cursor-eraser.png Binary files differnew file mode 100644 index 0000000000..e5488a89f2 --- /dev/null +++ b/examples/widgets/widgets/tablet/images/cursor-eraser.png diff --git a/examples/widgets/widgets/tablet/images/cursor-felt-marker.png b/examples/widgets/widgets/tablet/images/cursor-felt-marker.png Binary files differnew file mode 100644 index 0000000000..132f09aa39 --- /dev/null +++ b/examples/widgets/widgets/tablet/images/cursor-felt-marker.png diff --git a/examples/widgets/widgets/tablet/images/cursor-pencil.png b/examples/widgets/widgets/tablet/images/cursor-pencil.png Binary files differnew file mode 100644 index 0000000000..cc2f447d02 --- /dev/null +++ b/examples/widgets/widgets/tablet/images/cursor-pencil.png diff --git a/examples/widgets/widgets/tablet/mainwindow.cpp b/examples/widgets/widgets/tablet/mainwindow.cpp index aed84c50df..5e84f5b6a2 100644 --- a/examples/widgets/widgets/tablet/mainwindow.cpp +++ b/examples/widgets/widgets/tablet/mainwindow.cpp @@ -52,7 +52,7 @@ MainWindow::MainWindow(TabletCanvas *canvas) myCanvas->setColor(Qt::red); myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure); - myCanvas->setAlphaChannelType(TabletCanvas::NoAlpha); + myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure); myCanvas->setColorSaturationType(TabletCanvas::NoSaturation); setWindowTitle(tr("Tablet Example")); @@ -75,6 +75,8 @@ void MainWindow::alphaActionTriggered(QAction *action) { if (action == alphaChannelPressureAction) { myCanvas->setAlphaChannelType(TabletCanvas::AlphaPressure); + } else if (action == alphaChannelTangentialPressureAction) { + myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure); } else if (action == alphaChannelTiltAction) { myCanvas->setAlphaChannelType(TabletCanvas::AlphaTilt); } else { @@ -157,15 +159,19 @@ void MainWindow::createActions() alphaChannelPressureAction = new QAction(tr("&Pressure"), this); alphaChannelPressureAction->setCheckable(true); + alphaChannelTangentialPressureAction = new QAction(tr("T&angential Pressure"), this); + alphaChannelTangentialPressureAction->setCheckable(true); + alphaChannelTangentialPressureAction->setChecked(true); + alphaChannelTiltAction = new QAction(tr("&Tilt"), this); alphaChannelTiltAction->setCheckable(true); noAlphaChannelAction = new QAction(tr("No Alpha Channel"), this); noAlphaChannelAction->setCheckable(true); - noAlphaChannelAction->setChecked(true); alphaChannelGroup = new QActionGroup(this); alphaChannelGroup->addAction(alphaChannelPressureAction); + alphaChannelGroup->addAction(alphaChannelTangentialPressureAction); alphaChannelGroup->addAction(alphaChannelTiltAction); alphaChannelGroup->addAction(noAlphaChannelAction); connect(alphaChannelGroup, SIGNAL(triggered(QAction*)), @@ -259,6 +265,7 @@ void MainWindow::createMenus() alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel")); alphaChannelMenu->addAction(alphaChannelPressureAction); + alphaChannelMenu->addAction(alphaChannelTangentialPressureAction); alphaChannelMenu->addAction(alphaChannelTiltAction); alphaChannelMenu->addAction(noAlphaChannelAction); diff --git a/examples/widgets/widgets/tablet/mainwindow.h b/examples/widgets/widgets/tablet/mainwindow.h index 5e77ea1acf..c6ac2e6026 100644 --- a/examples/widgets/widgets/tablet/mainwindow.h +++ b/examples/widgets/widgets/tablet/mainwindow.h @@ -79,6 +79,7 @@ private: QActionGroup *alphaChannelGroup; QAction *alphaChannelPressureAction; + QAction *alphaChannelTangentialPressureAction; QAction *alphaChannelTiltAction; QAction *noAlphaChannelAction; diff --git a/examples/widgets/widgets/tablet/tablet.pro b/examples/widgets/widgets/tablet/tablet.pro index de81e7b198..9b8927f483 100644 --- a/examples/widgets/widgets/tablet/tablet.pro +++ b/examples/widgets/widgets/tablet/tablet.pro @@ -1,12 +1,13 @@ QT += widgets HEADERS = mainwindow.h \ - tabletcanvas.h \ - tabletapplication.h + tabletcanvas.h \ + tabletapplication.h SOURCES = mainwindow.cpp \ - main.cpp \ - tabletcanvas.cpp \ - tabletapplication.cpp + main.cpp \ + tabletcanvas.cpp \ + tabletapplication.cpp +RESOURCES += images.qrc # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/tablet diff --git a/examples/widgets/widgets/tablet/tabletapplication.cpp b/examples/widgets/widgets/tablet/tabletapplication.cpp index c3210f822c..3e1356ee9c 100644 --- a/examples/widgets/widgets/tablet/tabletapplication.cpp +++ b/examples/widgets/widgets/tablet/tabletapplication.cpp @@ -47,8 +47,7 @@ bool TabletApplication::event(QEvent *event) { if (event->type() == QEvent::TabletEnterProximity || event->type() == QEvent::TabletLeaveProximity) { - myCanvas->setTabletDevice( - static_cast<QTabletEvent *>(event)->device()); + myCanvas->setTabletDevice(static_cast<QTabletEvent *>(event)); return true; } return QApplication::event(event); diff --git a/examples/widgets/widgets/tablet/tabletcanvas.cpp b/examples/widgets/widgets/tablet/tabletcanvas.cpp index 20d6291292..8ff3d41e0e 100644 --- a/examples/widgets/widgets/tablet/tabletcanvas.cpp +++ b/examples/widgets/widgets/tablet/tabletcanvas.cpp @@ -47,14 +47,13 @@ TabletCanvas::TabletCanvas() { resize(500, 500); - myBrush = QBrush(); - myPen = QPen(); + myColor = Qt::red; + myBrush = QBrush(myColor); + myPen = QPen(myBrush, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); initPixmap(); setAutoFillBackground(true); deviceDown = false; - myColor = Qt::red; - myTabletDevice = QTabletEvent::Stylus; - alphaChannelType = NoAlpha; + alphaChannelType = AlphaTangentialPressure; colorSaturationType = NoSaturation; lineWidthType = LineWidthPressure; } @@ -99,24 +98,25 @@ void TabletCanvas::tabletEvent(QTabletEvent *event) case QEvent::TabletPress: if (!deviceDown) { deviceDown = true; - polyLine[0] = polyLine[1] = polyLine[2] = event->pos(); + lastPoint.pos = event->posF(); + lastPoint.rotation = event->rotation(); } break; - case QEvent::TabletRelease: - if (deviceDown) - deviceDown = false; - break; case QEvent::TabletMove: - polyLine[2] = polyLine[1]; - polyLine[1] = polyLine[0]; - polyLine[0] = event->pos(); - + if (event->device() == QTabletEvent::RotationStylus) + updateCursor(event); if (deviceDown) { updateBrush(event); QPainter painter(&pixmap); paintPixmap(painter, event); + lastPoint.pos = event->posF(); + lastPoint.rotation = event->rotation(); } break; + case QEvent::TabletRelease: + if (deviceDown && event->buttons() == Qt::NoButton) + deviceDown = false; + break; default: break; } @@ -135,23 +135,44 @@ void TabletCanvas::paintEvent(QPaintEvent *) //! [5] void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) { - QPoint brushAdjust(10, 10); + painter.setRenderHint(QPainter::Antialiasing); - switch (myTabletDevice) { + switch (event->device()) { +//! [6] case QTabletEvent::Airbrush: - myBrush.setColor(myColor); - myBrush.setStyle(brushPattern(event->pressure())); - painter.setPen(Qt::NoPen); - painter.setBrush(myBrush); - - for (int i = 0; i < 3; ++i) { - painter.drawEllipse(QRect(polyLine[i] - brushAdjust, - polyLine[i] + brushAdjust)); + { + painter.setPen(Qt::NoPen); + QRadialGradient grad(lastPoint.pos, myPen.widthF() * 10.0); + QColor color = myBrush.color(); + color.setAlphaF(color.alphaF() * 0.25); + grad.setColorAt(0, myBrush.color()); + grad.setColorAt(0.5, Qt::transparent); + painter.setBrush(grad); + qreal radius = grad.radius(); + painter.drawEllipse(event->posF(), radius, radius); + } + break; + case QTabletEvent::RotationStylus: + { + myBrush.setStyle(Qt::SolidPattern); + painter.setPen(Qt::NoPen); + painter.setBrush(myBrush); + QPolygonF poly; + qreal halfWidth = myPen.widthF(); + QPointF brushAdjust(qSin(qDegreesToRadians(lastPoint.rotation)) * halfWidth, + qCos(qDegreesToRadians(lastPoint.rotation)) * halfWidth); + poly << lastPoint.pos + brushAdjust; + poly << lastPoint.pos - brushAdjust; + brushAdjust = QPointF(qSin(qDegreesToRadians(event->rotation())) * halfWidth, + qCos(qDegreesToRadians(event->rotation())) * halfWidth); + poly << event->posF() - brushAdjust; + poly << event->posF() + brushAdjust; + painter.drawConvexPolygon(poly); } break; +//! [6] case QTabletEvent::Puck: case QTabletEvent::FourDMouse: - case QTabletEvent::RotationStylus: { const QString error(tr("This input device is not supported by the example.")); #ifndef QT_NO_STATUSTIP @@ -174,42 +195,15 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) } // FALL-THROUGH case QTabletEvent::Stylus: - painter.setBrush(myBrush); painter.setPen(myPen); - painter.drawLine(polyLine[1], event->pos()); + painter.drawLine(lastPoint.pos, event->posF()); break; } } //! [5] -//! [6] -Qt::BrushStyle TabletCanvas::brushPattern(qreal value) -{ - int pattern = int((value) * 100.0) % 7; - - switch (pattern) { - case 0: - return Qt::SolidPattern; - case 1: - return Qt::Dense1Pattern; - case 2: - return Qt::Dense2Pattern; - case 3: - return Qt::Dense3Pattern; - case 4: - return Qt::Dense4Pattern; - case 5: - return Qt::Dense5Pattern; - case 6: - return Qt::Dense6Pattern; - default: - return Qt::Dense7Pattern; - } -} -//! [6] - //! [7] -void TabletCanvas::updateBrush(QTabletEvent *event) +void TabletCanvas::updateBrush(const QTabletEvent *event) { int hue, saturation, value, alpha; myColor.getHsv(&hue, &saturation, &value, &alpha); @@ -220,7 +214,13 @@ void TabletCanvas::updateBrush(QTabletEvent *event) switch (alphaChannelType) { case AlphaPressure: - myColor.setAlpha(int(event->pressure() * 255.0)); + myColor.setAlphaF(event->pressure()); + break; + case AlphaTangentialPressure: + if (event->device() == QTabletEvent::Airbrush) + myColor.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0)); + else + myColor.setAlpha(255); break; case AlphaTilt: myColor.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127))); @@ -268,8 +268,47 @@ void TabletCanvas::updateBrush(QTabletEvent *event) } //! [11] +void TabletCanvas::updateCursor(const QTabletEvent *event) +{ + QCursor cursor; + if (event->type() != QEvent::TabletLeaveProximity) { + if (event->pointerType() == QTabletEvent::Eraser) { + cursor = QCursor(QPixmap(":/images/cursor-eraser.png"), 3, 28); + } else { + switch (event->device()) { + case QTabletEvent::Stylus: + cursor = QCursor(QPixmap(":/images/cursor-pencil.png"), 0, 0); + break; + case QTabletEvent::Airbrush: + cursor = QCursor(QPixmap(":/images/cursor-airbrush.png"), 3, 4); + break; + case QTabletEvent::RotationStylus: { + QImage origImg(QLatin1String(":/images/cursor-felt-marker.png")); + QImage img(32, 32, QImage::Format_ARGB32); + QColor solid = myColor; + solid.setAlpha(255); + img.fill(solid); + QPainter painter(&img); + QTransform transform = painter.transform(); + transform.translate(16, 16); + transform.rotate(-event->rotation()); + painter.setTransform(transform); + painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + painter.drawImage(-24, -24, origImg); + painter.setCompositionMode(QPainter::CompositionMode_HardLight); + painter.drawImage(-24, -24, origImg); + painter.end(); + cursor = QCursor(QPixmap::fromImage(img), 16, 16); + } break; + default: + break; + } + } + } + setCursor(cursor); +} + void TabletCanvas::resizeEvent(QResizeEvent *) { initPixmap(); - polyLine[0] = polyLine[1] = polyLine[2] = QPoint(); } diff --git a/examples/widgets/widgets/tablet/tabletcanvas.h b/examples/widgets/widgets/tablet/tabletcanvas.h index 873f3a7ab0..a7335dbaf0 100644 --- a/examples/widgets/widgets/tablet/tabletcanvas.h +++ b/examples/widgets/widgets/tablet/tabletcanvas.h @@ -61,7 +61,7 @@ class TabletCanvas : public QWidget Q_OBJECT public: - enum AlphaChannelType { AlphaPressure, AlphaTilt, NoAlpha }; + enum AlphaChannelType { AlphaPressure, AlphaTangentialPressure, AlphaTilt, NoAlpha }; enum ColorSaturationType { SaturationVTilt, SaturationHTilt, SaturationPressure, NoSaturation }; enum LineWidthType { LineWidthPressure, LineWidthTilt, NoLineWidth }; @@ -80,8 +80,8 @@ public: { myColor = color; } QColor color() const { return myColor; } - void setTabletDevice(QTabletEvent::TabletDevice device) - { myTabletDevice = device; } + void setTabletDevice(QTabletEvent *event) + { myTabletDevice = event->device(); updateCursor(event); } int maximum(int a, int b) { return a > b ? a : b; } @@ -94,7 +94,8 @@ private: void initPixmap(); void paintPixmap(QPainter &painter, QTabletEvent *event); Qt::BrushStyle brushPattern(qreal value); - void updateBrush(QTabletEvent *event); + void updateBrush(const QTabletEvent *event); + void updateCursor(const QTabletEvent *event); AlphaChannelType alphaChannelType; ColorSaturationType colorSaturationType; @@ -107,7 +108,11 @@ private: QBrush myBrush; QPen myPen; bool deviceDown; - QPoint polyLine[3]; + + struct Point { + QPointF pos; + qreal rotation; + } lastPoint; }; //! [0] diff --git a/examples/xml/dombookmarks/dombookmarks.pro b/examples/xml/dombookmarks/dombookmarks.pro index baf63fa191..0ab4f0266d 100644 --- a/examples/xml/dombookmarks/dombookmarks.pro +++ b/examples/xml/dombookmarks/dombookmarks.pro @@ -14,6 +14,6 @@ INSTALLS += target wince { addFiles.files = frank.xbel jennifer.xbel addFiles.path = "\\My Documents" - DEPLOYMENT += addFiles + INSTALLS += addFiles } diff --git a/examples/xml/htmlinfo/htmlinfo.pro b/examples/xml/htmlinfo/htmlinfo.pro index c0b82965ee..8adaa780b8 100644 --- a/examples/xml/htmlinfo/htmlinfo.pro +++ b/examples/xml/htmlinfo/htmlinfo.pro @@ -9,7 +9,7 @@ win32: CONFIG += console wince { htmlfiles.files = *.html htmlfiles.path = . - DEPLOYMENT += htmlfiles + INSTALLS += htmlfiles } # install diff --git a/examples/xml/saxbookmarks/saxbookmarks.pro b/examples/xml/saxbookmarks/saxbookmarks.pro index 353e1559cc..96a48ef5d4 100644 --- a/examples/xml/saxbookmarks/saxbookmarks.pro +++ b/examples/xml/saxbookmarks/saxbookmarks.pro @@ -16,5 +16,5 @@ INSTALLS += target wince { addFiles.files = frank.xbel jennifer.xbel addFiles.path = "\\My Documents" - DEPLOYMENT += addFiles + INSTALLS += addFiles } |