diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2012-10-26 12:28:31 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2012-10-26 12:28:53 +0200 |
commit | 6e5818f2bbc8443b9308252a5e1543e014ef439d (patch) | |
tree | 07922adee2f13e818b9439c8a0bdf871dda59039 /src/gui | |
parent | 32aac0a1c009ee940920fd12f277180dd80b8eff (diff) | |
parent | deac55becd18efa4504eb686a1bb8081a5cd488a (diff) |
Merge remote-tracking branch 'gerrit/master' into newdocs
Change-Id: I10cf9f915c602c8e5a0e7d7c9e17b7bc5ca00640
Diffstat (limited to 'src/gui')
66 files changed, 2831 insertions, 166 deletions
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf index e18a4e592f..694a1d8e11 100644 --- a/src/gui/doc/qtgui.qdocconf +++ b/src/gui/doc/qtgui.qdocconf @@ -47,12 +47,7 @@ sourcedirs += .. \ ../../../examples/gui/doc exampledirs += ../../../examples/gui \ - ../../../doc/src/snippets \ - ../ \ + ../../../examples/widgets \ snippets -excludedirs += snippets - -imagedirs += images \ - ../../../doc/src/images \ - ../../../examples/gui/doc/images +imagedirs += images diff --git a/src/gui/doc/snippets/clipboard/clipboard.pro b/src/gui/doc/snippets/clipboard/clipboard.pro new file mode 100644 index 0000000000..a26fea6b57 --- /dev/null +++ b/src/gui/doc/snippets/clipboard/clipboard.pro @@ -0,0 +1,3 @@ +HEADERS = clipwindow.h +SOURCES = clipwindow.cpp \ + main.cpp diff --git a/src/gui/doc/snippets/clipboard/clipwindow.cpp b/src/gui/doc/snippets/clipboard/clipwindow.cpp new file mode 100644 index 0000000000..376d92afac --- /dev/null +++ b/src/gui/doc/snippets/clipboard/clipwindow.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui> + +#include "clipwindow.h" + +ClipWindow::ClipWindow(QWidget *parent) + : QMainWindow(parent) +{ + clipboard = QApplication::clipboard(); + + QWidget *centralWidget = new QWidget(this); + QWidget *currentItem = new QWidget(centralWidget); + QLabel *mimeTypeLabel = new QLabel(tr("MIME types:"), currentItem); + mimeTypeCombo = new QComboBox(currentItem); + QLabel *dataLabel = new QLabel(tr("Data:"), currentItem); + dataInfoLabel = new QLabel("", currentItem); + + previousItems = new QListWidget(centralWidget); + +//! [0] + connect(clipboard, SIGNAL(dataChanged()), this, SLOT(updateClipboard())); +//! [0] + connect(mimeTypeCombo, SIGNAL(activated(const QString &)), + this, SLOT(updateData(const QString &))); + + QVBoxLayout *currentLayout = new QVBoxLayout(currentItem); + currentLayout->addWidget(mimeTypeLabel); + currentLayout->addWidget(mimeTypeCombo); + currentLayout->addWidget(dataLabel); + currentLayout->addWidget(dataInfoLabel); + currentLayout->addStretch(1); + + QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget); + mainLayout->addWidget(currentItem, 1); + mainLayout->addWidget(previousItems); + + setCentralWidget(centralWidget); + setWindowTitle(tr("Clipboard")); +} + +//! [1] +void ClipWindow::updateClipboard() +{ + QStringList formats = clipboard->mimeData()->formats(); + QByteArray data = clipboard->mimeData()->data(format); +//! [1] + + mimeTypeCombo->clear(); + mimeTypeCombo->insertStringList(formats); + + int size = clipboard->mimeData()->data(formats[0]).size(); + QListWidgetItem *newItem = new QListWidgetItem(previousItems); + newItem->setText(tr("%1 (%2 bytes)").arg(formats[0]).arg(size)); + + updateData(formats[0]); +//! [2] +} +//! [2] + +void ClipWindow::updateData(const QString &format) +{ + QByteArray data = clipboard->mimeData()->data(format); + dataInfoLabel->setText(tr("%1 bytes").arg(data.size())); +} diff --git a/src/gui/doc/snippets/clipboard/clipwindow.h b/src/gui/doc/snippets/clipboard/clipwindow.h new file mode 100644 index 0000000000..2ab42c9174 --- /dev/null +++ b/src/gui/doc/snippets/clipboard/clipwindow.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 CLIPWINDOW_H +#define CLIPWINDOW_H + +#include <QMainWindow> + +class QClipboard; +class QComboBox; +class QLabel; +class QListWidget; +class QMimeData; +class QWidget; + +class ClipWindow : public QMainWindow +{ + Q_OBJECT + +public: + ClipWindow(QWidget *parent = 0); + +public slots: + void updateClipboard(); + void updateData(const QString &format); + +private: + int currentItem; + QClipboard *clipboard; + QComboBox *mimeTypeCombo; + QLabel *dataInfoLabel; + QListWidget *previousItems; +}; + +#endif diff --git a/src/gui/doc/snippets/clipboard/main.cpp b/src/gui/doc/snippets/clipboard/main.cpp new file mode 100644 index 0000000000..f94fe4994a --- /dev/null +++ b/src/gui/doc/snippets/clipboard/main.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QApplication> + +#include "clipwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + ClipWindow *window = new ClipWindow; + window->resize(640, 480); + window->show(); + return app.exec(); +} diff --git a/src/gui/doc/snippets/draganddrop/draganddrop.pro b/src/gui/doc/snippets/draganddrop/draganddrop.pro new file mode 100644 index 0000000000..67bc32bd10 --- /dev/null +++ b/src/gui/doc/snippets/draganddrop/draganddrop.pro @@ -0,0 +1,5 @@ +HEADERS = dragwidget.h \ + mainwindow.h +SOURCES = dragwidget.cpp \ + main.cpp \ + mainwindow.cpp diff --git a/src/gui/doc/snippets/draganddrop/dragwidget.cpp b/src/gui/doc/snippets/draganddrop/dragwidget.cpp new file mode 100644 index 0000000000..aa2075a977 --- /dev/null +++ b/src/gui/doc/snippets/draganddrop/dragwidget.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui> + +#include "dragwidget.h" + +DragWidget::DragWidget(QWidget *parent) + : QFrame(parent) +{ + setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + dragDropLabel = new QLabel("", this); + dragDropLabel->setAlignment(Qt::AlignHCenter); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addStretch(0); + layout->addWidget(dragDropLabel); + layout->addStretch(0); + + setAcceptDrops(true); +} + +// Accept all actions, but deal with them separately later. +//! [0] +void DragWidget::dragEnterEvent(QDragEnterEvent *event) +{ + event->acceptProposedAction(); +} +//! [0] + +//! [1] +void DragWidget::dropEvent(QDropEvent *event) +{ + if (event->source() == this && event->possibleActions() & Qt::MoveAction) + return; +//! [1] + +//! [2] + if (event->proposedAction() == Qt::MoveAction) { + event->acceptProposedAction(); + // Process the data from the event. +//! [2] + emit dragResult(tr("The data was moved here.")); +//! [3] + } else if (event->proposedAction() == Qt::CopyAction) { + event->acceptProposedAction(); + // Process the data from the event. +//! [3] + emit dragResult(tr("The data was copied here.")); +//! [4] + } else { + // Ignore the drop. + return; + } +//! [4] + // End of quote + + emit mimeTypes(event->mimeData()->formats()); + setData(event->mimeData()->formats()[0], + event->mimeData()->data(event->mimeData()->formats()[0])); +//! [5] +} +//! [5] + +//! [6] +void DragWidget::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + dragStartPosition = event->pos(); +} +//! [6] + +//! [7] +void DragWidget::mouseMoveEvent(QMouseEvent *event) +{ + if (!(event->buttons() & Qt::LeftButton)) + return; + if ((event->pos() - dragStartPosition).manhattanLength() + < QApplication::startDragDistance()) + return; + + QDrag *drag = new QDrag(this); + QMimeData *mimeData = new QMimeData; + + mimeData->setData(mimeType, data); + drag->setMimeData(mimeData); + + Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction); +//! [7] + + switch (dropAction) { + case Qt::CopyAction: + emit dragResult(tr("The text was copied.")); + break; + case Qt::MoveAction: + emit dragResult(tr("The text was moved.")); + break; + default: + emit dragResult(tr("Unknown action.")); + break; + } +//! [8] +} +//! [8] + +void DragWidget::setData(const QString &mimetype, const QByteArray &newData) +{ + mimeType = mimetype; + data = QByteArray(newData); + + dragDropLabel->setText(tr("%1 bytes").arg(data.size())); + + QStringList formats; + formats << mimetype; + emit mimeTypes(formats); +} diff --git a/src/gui/doc/snippets/draganddrop/dragwidget.h b/src/gui/doc/snippets/draganddrop/dragwidget.h new file mode 100644 index 0000000000..cd12c08884 --- /dev/null +++ b/src/gui/doc/snippets/draganddrop/dragwidget.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 DRAGWIDGET_H +#define DRAGWIDGET_H + +#include <QByteArray> +#include <QFrame> +#include <QString> +#include <QStringList> + +class QComboBox; +class QFrame; +class QLabel; +class QTextBrowser; + +class DragWidget : public QFrame +{ + Q_OBJECT + +public: + DragWidget(QWidget *parent); + void setData(const QString &mimetype, const QByteArray &newData); + +signals: + void dragResult(const QString &actionText); + void mimeTypes(const QStringList &types); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + +private: + QByteArray data; + QLabel *dragDropLabel; + QPoint dragStartPosition; + QString mimeType; +}; + +#endif diff --git a/src/gui/doc/snippets/draganddrop/main.cpp b/src/gui/doc/snippets/draganddrop/main.cpp new file mode 100644 index 0000000000..c15b641249 --- /dev/null +++ b/src/gui/doc/snippets/draganddrop/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui> + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MainWindow *window1 = new MainWindow; + MainWindow *window2 = new MainWindow; + window1->show(); + window2->show(); + return app.exec(); +} diff --git a/src/gui/doc/snippets/draganddrop/mainwindow.cpp b/src/gui/doc/snippets/draganddrop/mainwindow.cpp new file mode 100644 index 0000000000..4c443bbc09 --- /dev/null +++ b/src/gui/doc/snippets/draganddrop/mainwindow.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui> + +#include "dragwidget.h" +#include "mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) +{ + QFrame *centralWidget = new QFrame(this); + + QLabel *mimeTypeLabel = new QLabel(tr("MIME types:"), centralWidget); + mimeTypeCombo = new QComboBox(centralWidget); + + QLabel *dataLabel = new QLabel(tr("Amount of data (bytes):"), centralWidget); + dragWidget = new DragWidget(centralWidget); + + connect(dragWidget, SIGNAL(mimeTypes(const QStringList &)), + this, SLOT(setMimeTypes(const QStringList &))); + connect(dragWidget, SIGNAL(dragResult(const QString &)), + this, SLOT(setDragResult(const QString &))); + + QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget); + mainLayout->addWidget(mimeTypeLabel); + mainLayout->addWidget(mimeTypeCombo); + mainLayout->addSpacing(32); + mainLayout->addWidget(dataLabel); + mainLayout->addWidget(dragWidget); + + statusBar(); + dragWidget->setData(QString("text/plain"), QByteArray("Hello world")); + setCentralWidget(centralWidget); + setWindowTitle(tr("Drag and Drop")); +} + +void MainWindow::setDragResult(const QString &actionText) +{ + statusBar()->showMessage(actionText); +} + +void MainWindow::setMimeTypes(const QStringList &types) +{ + mimeTypeCombo->clear(); + mimeTypeCombo->addItems(types); +} diff --git a/src/gui/doc/snippets/draganddrop/mainwindow.h b/src/gui/doc/snippets/draganddrop/mainwindow.h new file mode 100644 index 0000000000..5b9018e1a2 --- /dev/null +++ b/src/gui/doc/snippets/draganddrop/mainwindow.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> +#include <QPixmap> +#include <QPoint> + +class QComboBox; +class QLabel; +class QLineEdit; +class QMouseEvent; +class QTextEdit; +class DragWidget; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = 0); + +public slots: + void setDragResult(const QString &actionText); + void setMimeTypes(const QStringList &types); + +private: + QComboBox *mimeTypeCombo; + DragWidget *dragWidget; +}; + +#endif diff --git a/src/gui/doc/snippets/dragging/dragging.pro b/src/gui/doc/snippets/dragging/dragging.pro new file mode 100644 index 0000000000..0a16eb19bf --- /dev/null +++ b/src/gui/doc/snippets/dragging/dragging.pro @@ -0,0 +1,5 @@ +QT += widgets +HEADERS += mainwindow.h +RESOURCES += images.qrc +SOURCES += main.cpp \ + mainwindow.cpp diff --git a/src/gui/doc/snippets/dragging/images.qrc b/src/gui/doc/snippets/dragging/images.qrc new file mode 100644 index 0000000000..30b8a2986e --- /dev/null +++ b/src/gui/doc/snippets/dragging/images.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>images/file.png</file> +</qresource> +</RCC> diff --git a/src/gui/doc/snippets/dragging/images/file.png b/src/gui/doc/snippets/dragging/images/file.png Binary files differnew file mode 100644 index 0000000000..9520080ed0 --- /dev/null +++ b/src/gui/doc/snippets/dragging/images/file.png diff --git a/src/gui/doc/snippets/dragging/main.cpp b/src/gui/doc/snippets/dragging/main.cpp new file mode 100644 index 0000000000..1eb4112e60 --- /dev/null +++ b/src/gui/doc/snippets/dragging/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui> + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MainWindow *window = new MainWindow; + window->show(); + return app.exec(); +} diff --git a/src/gui/doc/snippets/dragging/mainwindow.h b/src/gui/doc/snippets/dragging/mainwindow.h new file mode 100644 index 0000000000..216afbc6db --- /dev/null +++ b/src/gui/doc/snippets/dragging/mainwindow.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> +#include <QPixmap> +#include <QPoint> + +class QLabel; +class QLineEdit; +class QMouseEvent; +class QTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = 0); + +protected: + void mousePressEvent(QMouseEvent *event); + +private: + QLabel *iconLabel; + QLineEdit *nameEdit; + QPixmap iconPixmap; + QPoint dragStartPosition; + QTextEdit *commentEdit; +}; + +#endif diff --git a/src/gui/doc/snippets/dropevents/dropevents.pro b/src/gui/doc/snippets/dropevents/dropevents.pro new file mode 100644 index 0000000000..6283406f25 --- /dev/null +++ b/src/gui/doc/snippets/dropevents/dropevents.pro @@ -0,0 +1,3 @@ +HEADERS = window.h +SOURCES = main.cpp \ + window.cpp diff --git a/src/gui/doc/snippets/dropevents/main.cpp b/src/gui/doc/snippets/dropevents/main.cpp new file mode 100644 index 0000000000..1337f7f921 --- /dev/null +++ b/src/gui/doc/snippets/dropevents/main.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui> + +#include "window.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + Window *window = new Window; + window->show(); + return app.exec(); +} diff --git a/src/gui/doc/snippets/dropevents/window.cpp b/src/gui/doc/snippets/dropevents/window.cpp new file mode 100644 index 0000000000..f3c4a0c610 --- /dev/null +++ b/src/gui/doc/snippets/dropevents/window.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui> + +#include "window.h" + +//! [0] +Window::Window(QWidget *parent) + : QWidget(parent) +{ +//! [0] + QLabel *textLabel = new QLabel(tr("Data:"), this); + textBrowser = new QTextBrowser(this); + + QLabel *mimeTypeLabel = new QLabel(tr("MIME types:"), this); + mimeTypeCombo = new QComboBox(this); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(textLabel); + layout->addWidget(textBrowser); + layout->addWidget(mimeTypeLabel); + layout->addWidget(mimeTypeCombo); + +//! [1] + setAcceptDrops(true); +//! [1] + setWindowTitle(tr("Drop Events")); +//! [2] +} +//! [2] + +//! [3] +void Window::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasFormat("text/plain")) + event->acceptProposedAction(); +} +//! [3] + +//! [4] +void Window::dropEvent(QDropEvent *event) +{ + textBrowser->setPlainText(event->mimeData()->text()); + mimeTypeCombo->clear(); + mimeTypeCombo->addItems(event->mimeData()->formats()); + + event->acceptProposedAction(); +} +//! [4] diff --git a/src/gui/doc/snippets/dropevents/window.h b/src/gui/doc/snippets/dropevents/window.h new file mode 100644 index 0000000000..dd5487a7e2 --- /dev/null +++ b/src/gui/doc/snippets/dropevents/window.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 WINDOW_H +#define WINDOW_H + +#include <QString> +#include <QStringList> +#include <QWidget> + +class QComboBox; +class QFrame; +class QTextBrowser; + +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(QWidget *parent = 0); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private: + QComboBox *mimeTypeCombo; + QFrame *dropFrame; + QTextBrowser *textBrowser; + QString oldText; + QStringList oldMimeTypes; +}; + +#endif diff --git a/src/gui/doc/snippets/droprectangle/droprectangle.pro b/src/gui/doc/snippets/droprectangle/droprectangle.pro new file mode 100644 index 0000000000..6283406f25 --- /dev/null +++ b/src/gui/doc/snippets/droprectangle/droprectangle.pro @@ -0,0 +1,3 @@ +HEADERS = window.h +SOURCES = main.cpp \ + window.cpp diff --git a/src/gui/doc/snippets/droprectangle/main.cpp b/src/gui/doc/snippets/droprectangle/main.cpp new file mode 100644 index 0000000000..e436e24e97 --- /dev/null +++ b/src/gui/doc/snippets/droprectangle/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui> + +#include "window.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + Window *window = new Window; + window->show(); + return app.exec(); +} diff --git a/src/gui/doc/snippets/droprectangle/window.cpp b/src/gui/doc/snippets/droprectangle/window.cpp new file mode 100644 index 0000000000..d488a8742b --- /dev/null +++ b/src/gui/doc/snippets/droprectangle/window.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui> + +#include "window.h" + +Window::Window(QWidget *parent) + : QWidget(parent) +{ + QLabel *textLabel = new QLabel(tr("Data:"), this); + textBrowser = new QTextBrowser(this); + + QLabel *mimeTypeLabel = new QLabel(tr("MIME types:"), this); + mimeTypeCombo = new QComboBox(this); + + dropFrame = new QFrame(this); + dropFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + QLabel *dropLabel = new QLabel(tr("Drop items here"), dropFrame); + dropLabel->setAlignment(Qt::AlignHCenter); + + QVBoxLayout *dropFrameLayout = new QVBoxLayout(dropFrame); + dropFrameLayout->addWidget(dropLabel); + + QHBoxLayout *dropLayout = new QHBoxLayout; + dropLayout->addStretch(0); + dropLayout->addWidget(dropFrame); + dropLayout->addStretch(0); + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(textLabel); + mainLayout->addWidget(textBrowser); + mainLayout->addWidget(mimeTypeLabel); + mainLayout->addWidget(mimeTypeCombo); + mainLayout->addSpacing(32); + mainLayout->addLayout(dropLayout); + + setAcceptDrops(true); + setWindowTitle(tr("Drop Rectangle")); +} + +//! [0] +void Window::dragMoveEvent(QDragMoveEvent *event) +{ + if (event->mimeData()->hasFormat("text/plain") + && event->answerRect().intersects(dropFrame->geometry())) + + event->acceptProposedAction(); +} +//! [0] + +void Window::dropEvent(QDropEvent *event) +{ + textBrowser->setPlainText(event->mimeData()->text()); + mimeTypeCombo->clear(); + mimeTypeCombo->addItems(event->mimeData()->formats()); + + event->acceptProposedAction(); +} diff --git a/src/gui/doc/snippets/droprectangle/window.h b/src/gui/doc/snippets/droprectangle/window.h new file mode 100644 index 0000000000..b07d030d13 --- /dev/null +++ b/src/gui/doc/snippets/droprectangle/window.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 WINDOW_H +#define WINDOW_H + +#include <QString> +#include <QStringList> +#include <QWidget> + +class QComboBox; +class QFrame; +class QTextBrowser; + +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(QWidget *parent = 0); + +protected: + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); + +private: + QComboBox *mimeTypeCombo; + QFrame *dropFrame; + QTextBrowser *textBrowser; + QString oldText; + QStringList oldMimeTypes; +}; + +#endif diff --git a/src/gui/doc/snippets/separations/finalwidget.h b/src/gui/doc/snippets/separations/finalwidget.h new file mode 100644 index 0000000000..e7247d31c0 --- /dev/null +++ b/src/gui/doc/snippets/separations/finalwidget.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 FINALWIDGET_H +#define FINALWIDGET_H + +#include <QFrame> +#include <QImage> +#include <QPoint> +#include <QSize> + +class QGridLayout; +class QLabel; +class QMouseEvent; +class QWidget; + +class FinalWidget : public QFrame +{ + Q_OBJECT + +public: + FinalWidget(QWidget *parent, const QString &name, const QSize &labelSize); + void setPixmap(const QPixmap &pixmap); + const QPixmap *pixmap() const; + +protected: + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + +private: + void createImage(); + + bool hasImage; + QImage originalImage; + QLabel *imageLabel; + QLabel *nameLabel; + QPoint dragStartPosition; +}; + +#endif diff --git a/src/gui/doc/snippets/separations/main.cpp b/src/gui/doc/snippets/separations/main.cpp new file mode 100644 index 0000000000..963dab3635 --- /dev/null +++ b/src/gui/doc/snippets/separations/main.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 <QApplication> +#include "viewer.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + Viewer viewer; + viewer.show(); + return app.exec(); +} diff --git a/src/gui/doc/snippets/separations/screenwidget.cpp b/src/gui/doc/snippets/separations/screenwidget.cpp new file mode 100644 index 0000000000..328b1d0624 --- /dev/null +++ b/src/gui/doc/snippets/separations/screenwidget.cpp @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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$ +** +****************************************************************************/ + +/* +screenwidget.cpp + +A widget to display colour components from an image using independently +selected colors. Controls are provided to allow the image to be inverted, and +the color to be selection via a standard dialog. The image is displayed in a +label widget. +*/ + +#include <QApplication> +#include <QColorDialog> +#include <QGridLayout> +#include <QImage> +#include <QLabel> +#include <QMenu> +#include <QMimeData> +#include <QMouseEvent> +#include <QPixmap> +#include <QPushButton> +#include <QWidget> + +#include "screenwidget.h" + +/*! +Initializes the paint color, the mask color (cyan, magenta, +or yellow), connects the color selector and invert checkbox to functions, +and creates a two-by-two grid layout. +*/ + +ScreenWidget::ScreenWidget(QWidget *parent, QColor initialColor, + const QString &name, Separation mask, + const QSize &labelSize) + : QFrame(parent) +{ + paintColor = initialColor; + maskColor = mask; + inverted = false; + + imageLabel = new QLabel; + imageLabel->setFrameShadow(QFrame::Sunken); + imageLabel->setFrameShape(QFrame::StyledPanel); + imageLabel->setMinimumSize(labelSize); + + nameLabel = new QLabel(name); + colorButton = new QPushButton(tr("Modify...")); + colorButton->setBackgroundRole(QPalette::Button); + colorButton->setMinimumSize(32, 32); + + QPalette palette(colorButton->palette()); + palette.setColor(QPalette::Button, initialColor); + colorButton->setPalette(palette); + + invertButton = new QPushButton(tr("Invert")); + //invertButton->setToggleButton(true); + //invertButton->setOn(inverted); + invertButton->setEnabled(false); + + connect(colorButton, SIGNAL(clicked()), this, SLOT(setColor())); + connect(invertButton, SIGNAL(clicked()), this, SLOT(invertImage())); + + QGridLayout *gridLayout = new QGridLayout; + gridLayout->addWidget(imageLabel, 0, 0, 1, 2); + gridLayout->addWidget(nameLabel, 1, 0); + gridLayout->addWidget(colorButton, 1, 1); + gridLayout->addWidget(invertButton, 2, 1, 1, 1); + setLayout(gridLayout); +} + +/*! + Creates a new image by separating out the cyan, magenta, or yellow + component, depending on the mask color specified in the constructor. + + The amount of the component found in each pixel of the image is used + to determine how much of a user-selected ink is used for each pixel + in the new image for the label widget. +*/ + +void ScreenWidget::createImage() +{ + newImage = originalImage.copy(); + + // Create CMY components for the ink being used. + float cyanInk = (255 - paintColor.red())/255.0; + float magentaInk = (255 - paintColor.green())/255.0; + float yellowInk = (255 - paintColor.blue())/255.0; + + int (*convert)(QRgb); + + switch (maskColor) { + case Cyan: + convert = qRed; + break; + case Magenta: + convert = qGreen; + break; + case Yellow: + convert = qBlue; + break; + } + + for (int y = 0; y < newImage.height(); ++y) { + for (int x = 0; x < newImage.width(); ++x) { + QRgb p(originalImage.pixel(x, y)); + + // Separate the source pixel into its cyan component. + int amount; + + if (inverted) + amount = convert(p); + else + amount = 255 - convert(p); + + QColor newColor( + 255 - qMin(int(amount * cyanInk), 255), + 255 - qMin(int(amount * magentaInk), 255), + 255 - qMin(int(amount * yellowInk), 255)); + + newImage.setPixel(x, y, newColor.rgb()); + } + } + + imageLabel->setPixmap(QPixmap::fromImage(newImage)); +} + +/*! + Returns a pointer to the modified image. +*/ + +QImage* ScreenWidget::image() +{ + return &newImage; +} + +/*! + Sets whether the amount of ink applied to the canvas is to be inverted + (subtracted from the maximum value) before the ink is applied. +*/ + +void ScreenWidget::invertImage() +{ + //inverted = invertButton->isOn(); + inverted = !inverted; + createImage(); + emit imageChanged(); +} + +/*! + Separate the current image into cyan, magenta, and yellow components. + Create a representation of how each component might appear when applied + to a blank white piece of paper. +*/ + +void ScreenWidget::setColor() +{ + QColor newColor = QColorDialog::getColor(paintColor); + + if (newColor.isValid()) { + paintColor = newColor; + QPalette palette(colorButton->palette()); + palette.setColor(QPalette::Button, paintColor); + colorButton->setPalette(palette); + createImage(); + emit imageChanged(); + } +} + +/*! + Records the original image selected by the user, creates a color + separation, and enables the invert image checkbox. +*/ + +void ScreenWidget::setImage(QImage &image) +{ + originalImage = image; + createImage(); + invertButton->setEnabled(true); +} diff --git a/src/gui/doc/snippets/separations/screenwidget.h b/src/gui/doc/snippets/separations/screenwidget.h new file mode 100644 index 0000000000..82d079f533 --- /dev/null +++ b/src/gui/doc/snippets/separations/screenwidget.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 SCREENWIDGET_H +#define SCREENWIDGET_H + +#include <QColor> +#include <QFrame> +#include <QImage> +#include <QSize> + +class QGridLayout; +class QLabel; +class QPushButton; +class QWidget; + +class ScreenWidget : public QFrame +{ + Q_OBJECT +public: + enum Separation { Cyan, Magenta, Yellow }; + + ScreenWidget(QWidget *parent, QColor initialColor, const QString &name, + Separation mask, const QSize &labelSize); + void setImage(QImage &image); + QImage* image(); + +signals: + void imageChanged(); + +public slots: + void setColor(); + void invertImage(); + +private: + void createImage(); + + bool inverted; + QColor paintColor; + QImage newImage; + QImage originalImage; + QLabel *imageLabel; + QLabel *nameLabel; + QPushButton *colorButton; + QPushButton *invertButton; + Separation maskColor; +}; + +#endif diff --git a/src/gui/doc/snippets/separations/separations.pro b/src/gui/doc/snippets/separations/separations.pro new file mode 100644 index 0000000000..48af2c8472 --- /dev/null +++ b/src/gui/doc/snippets/separations/separations.pro @@ -0,0 +1,7 @@ +HEADERS = finalwidget.h \ + screenwidget.h \ + viewer.h +SOURCES = finalwidget.cpp \ + main.cpp \ + screenwidget.cpp \ + viewer.cpp diff --git a/src/gui/doc/snippets/separations/separations.qdoc b/src/gui/doc/snippets/separations/separations.qdoc new file mode 100644 index 0000000000..005ee7be22 --- /dev/null +++ b/src/gui/doc/snippets/separations/separations.qdoc @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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$ +** +****************************************************************************/ + +/* + \example painting/separations + \title Color Separations Example + + This example enables simple color manipulation of images and demonstrates a + number of image-related features of Qt, from per-pixel image manipulation to + drag and drop handling of images. + + \image separations-example.png + + The application allows the user to load an image, shown in the top-left + part of the main window, and to adjust its color balance by replacing its + initial cyan, magenta, and yellow components with different colors. +*/ diff --git a/src/gui/doc/snippets/separations/viewer.cpp b/src/gui/doc/snippets/separations/viewer.cpp new file mode 100644 index 0000000000..1cb7d2d0d5 --- /dev/null +++ b/src/gui/doc/snippets/separations/viewer.cpp @@ -0,0 +1,328 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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$ +** +****************************************************************************/ + +/* +viewer.cpp + +Provides a main window for displaying a user-specified original image +with three color separations in a grid layout. + +A main menu provides entries for selecting files, and adjusting the +brightness of the separations. +*/ + +#include <QtGui> + +#include "finalwidget.h" +#include "screenwidget.h" +#include "viewer.h" + +/* + Constructor: initializes a default value for the brightness, creates + the main menu entries, and constructs a central widget that contains + enough space for images to be displayed. +*/ + +Viewer::Viewer() +{ + setWindowTitle(tr("QImage Color Separations")); + + brightness = 255; + + createMenus(); + setCentralWidget(createCentralWidget()); +} + +/* + Creates a main menu with two entries: a File menu, to allow the image + to be selected, and a Brightness menu to allow the brightness of the + separations to be changed. + + Initially, the Brightness menu items are disabled, but the first entry in + the menu is checked to reflect the default brightness. +*/ + +void Viewer::createMenus() +{ + fileMenu = new QMenu(tr("&File"), this); + brightnessMenu = new QMenu(tr("&Brightness"), this); + + QAction *openAction = fileMenu->addAction(tr("&Open...")); + openAction->setShortcut(QKeySequence("Ctrl+O")); + saveAction = fileMenu->addAction(tr("&Save...")); + saveAction->setShortcut(QKeySequence("Ctrl+S")); + saveAction->setEnabled(false); + QAction *quitAction = fileMenu->addAction(tr("E&xit")); + quitAction->setShortcut(QKeySequence("Ctrl+Q")); + + QAction *noBrightness = brightnessMenu->addAction(tr("&0%")); + noBrightness->setCheckable(true); + QAction *quarterBrightness = brightnessMenu->addAction(tr("&25%")); + quarterBrightness->setCheckable(true); + QAction *halfBrightness = brightnessMenu->addAction(tr("&50%")); + halfBrightness->setCheckable(true); + QAction *threeQuartersBrightness = brightnessMenu->addAction(tr("&75%")); + threeQuartersBrightness->setCheckable(true); + QAction *fullBrightness = brightnessMenu->addAction(tr("&100%")); + fullBrightness->setCheckable(true); + + menuMap[noBrightness] = None; + menuMap[quarterBrightness] = Quarter; + menuMap[halfBrightness] = Half; + menuMap[threeQuartersBrightness] = ThreeQuarters; + menuMap[fullBrightness] = Full; + + currentBrightness = fullBrightness; + currentBrightness->setChecked(true); + brightnessMenu->setEnabled(false); + + menuBar()->addMenu(fileMenu); + menuBar()->addMenu(brightnessMenu); + + connect(openAction, SIGNAL(triggered()), this, SLOT(chooseFile())); + connect(saveAction, SIGNAL(triggered()), this, SLOT(saveImage())); + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(brightnessMenu, SIGNAL(triggered(QAction *)), this, + SLOT(setBrightness(QAction *))); +} + +/* + Constructs a central widget for the window consisting of a two-by-two + grid of labels, each of which will contain an image. We restrict the + size of the labels to 256 pixels, and ensure that the window cannot + be resized. +*/ + +QFrame* Viewer::createCentralWidget() +{ + QFrame* frame = new QFrame(this); + grid = new QGridLayout(frame); + grid->setSpacing(8); + grid->setMargin(4); + + layout()->setSizeConstraint(QLayout::SetFixedSize); + + QSize labelSize(256, 256); + + finalWidget = new FinalWidget(frame, tr("Final image"), labelSize); + + cyanWidget = new ScreenWidget(frame, Qt::cyan, tr("Cyan"), + ScreenWidget::Cyan, labelSize); + magentaWidget = new ScreenWidget(frame, Qt::magenta, tr("Magenta"), + ScreenWidget::Magenta, labelSize); + yellowWidget = new ScreenWidget(frame, Qt::yellow, tr("Yellow"), + ScreenWidget::Yellow, labelSize); + + connect(cyanWidget, SIGNAL(imageChanged()), this, SLOT(createImage())); + connect(magentaWidget, SIGNAL(imageChanged()), this, SLOT(createImage())); + connect(yellowWidget, SIGNAL(imageChanged()), this, SLOT(createImage())); + + grid->addWidget(finalWidget, 0, 0, Qt::AlignTop | Qt::AlignHCenter); + grid->addWidget(cyanWidget, 0, 1, Qt::AlignTop | Qt::AlignHCenter); + grid->addWidget(magentaWidget, 1, 0, Qt::AlignTop | Qt::AlignHCenter); + grid->addWidget(yellowWidget, 1, 1, Qt::AlignTop | Qt::AlignHCenter); + + return frame; +} + +/* + Provides a dialog window to allow the user to specify an image file. + If a file is selected, the appropriate function is called to process + and display it. +*/ + +void Viewer::chooseFile() +{ + QString imageFile = QFileDialog::getOpenFileName(this, + tr("Choose an image file to open"), path, tr("Images (*.*)")); + + if (!imageFile.isEmpty()) { + openImageFile(imageFile); + path = imageFile; + } +} + +/* + Changes the value of the brightness according to the entry selected in the + Brightness menu. The selected entry is checked, and the previously selected + entry is unchecked. + + The color separations are updated to use the new value for the brightness. +*/ + +void Viewer::setBrightness(QAction *action) +{ + if (!menuMap.contains(action) || scaledImage.isNull()) + return; + + Brightness amount = menuMap[action]; + + switch (amount) { + case None: + brightness = 0; break; + case Quarter: + brightness = 64; break; + case Half: + brightness = 128; break; + case ThreeQuarters: + brightness = 191; break; + case Full: + brightness = 255; break; + default: return; + } + + currentBrightness->setChecked(false); + currentBrightness = action; + currentBrightness->setChecked(true); + + createImage(); +} + +/* + Load the image from the file given, and create four pixmaps based + on the original image. + + The window caption is set, and the Brightness menu enabled if the image file + can be loaded. +*/ + +void Viewer::openImageFile(QString &imageFile) +{ + QImage originalImage; + + if (originalImage.load(imageFile)) { + setWindowTitle(imageFile); + //menuBar()->setItemEnabled(brightnessMenuId, true); + saveAction->setEnabled(true); + brightnessMenu->setEnabled(true); + + /* Note: the ScaleMin value may be different for Qt 4. */ + scaledImage = originalImage.scaled(256, 256, Qt::KeepAspectRatio); + + cyanWidget->setImage(scaledImage); + magentaWidget->setImage(scaledImage); + yellowWidget->setImage(scaledImage); + createImage(); + } + else + (void) QMessageBox::warning(this, tr("Cannot open file"), + tr("The selected file could not be opened."), + QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton); +} + +/* + Creates an image by combining the contents of the three screens + to present a page preview. + + The image associated with each screen is separated into cyan, + magenta, and yellow components. We add up the values for each + component from the three screen images, and subtract the totals + from the maximum value for each corresponding primary color. +*/ + +void Viewer::createImage() +{ + QImage newImage = scaledImage.copy(); + + QImage *image1 = cyanWidget->image(); + QImage *image2 = magentaWidget->image(); + QImage *image3 = yellowWidget->image(); + int darkness = 255 - brightness; + + for (int y = 0; y < newImage.height(); ++y) { + for (int x = 0; x < newImage.width(); ++x) { + + // Create three screens, using the quantities of the source + // CMY components to determine how much of each of the + // inks are to be put on each screen. + QRgb p1(image1->pixel(x, y)); + float cyan1 = 255 - qRed(p1); + float magenta1 = 255 - qGreen(p1); + float yellow1 = 255 - qBlue(p1); + + QRgb p2(image2->pixel(x, y)); + float cyan2 = 255 - qRed(p2); + float magenta2 = 255 - qGreen(p2); + float yellow2 = 255 - qBlue(p2); + + QRgb p3(image3->pixel(x, y)); + float cyan3 = 255 - qRed(p3); + float magenta3 = 255 - qGreen(p3); + float yellow3 = 255 - qBlue(p3); + + QColor newColor( + qMax(255 - int(cyan1+cyan2+cyan3) - darkness, 0), + qMax(255 - int(magenta1+magenta2+magenta3) - darkness, 0), + qMax(255 - int(yellow1+yellow2+yellow3) - darkness, 0)); + + newImage.setPixel(x, y, newColor.rgb()); + } + } + + finalWidget->setPixmap(QPixmap::fromImage(newImage)); +} + +/* + Provides a dialog window to allow the user to save the image file. +*/ + +void Viewer::saveImage() +{ + QString imageFile = QFileDialog::getSaveFileName(this, + tr("Choose a filename to save the image"), "", tr("Images (*.png)")); + + QFileInfo info(imageFile); + + if (!info.baseName().isEmpty()) { + QString newImageFile = QFileInfo(info.absoluteDir(), + info.baseName() + ".png").absoluteFilePath(); + + if (!finalWidget->pixmap()->save(newImageFile, "PNG")) + (void) QMessageBox::warning(this, tr("Cannot save file"), + tr("The file could not be saved."), + QMessageBox::Cancel, QMessageBox::NoButton, + QMessageBox::NoButton); + } + else + (void) QMessageBox::warning(this, tr("Cannot save file"), + tr("Please enter a valid filename."), + QMessageBox::Cancel, QMessageBox::NoButton, + QMessageBox::NoButton); +} diff --git a/src/gui/doc/snippets/separations/viewer.h b/src/gui/doc/snippets/separations/viewer.h new file mode 100644 index 0000000000..c1e3725895 --- /dev/null +++ b/src/gui/doc/snippets/separations/viewer.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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 Digia Plc and its Subsidiary(-ies) 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 VIEWER_H +#define VIEWER_H + +#include <QImage> +#include <QMainWindow> +#include <QMap> + +class QAction; +class QFrame; +class QGridLayout; +class QLabel; +class QMenu; +class FinalWidget; +class ScreenWidget; + +class Viewer : public QMainWindow +{ + Q_OBJECT +public: + enum Brightness { None, Quarter, Half, ThreeQuarters, Full }; + Viewer(); + +public slots: + void chooseFile(); + void setBrightness(QAction *action); + void createImage(); + void saveImage(); + +private: + void createMenus(); + QFrame *createCentralWidget(); + void openImageFile(QString &filePath); + + FinalWidget *finalWidget; + int brightness; + QAction *currentBrightness; + QAction *saveAction; + QGridLayout *grid; + QImage scaledImage; + QMap <QAction*,Brightness> menuMap; + QMenu *brightnessMenu; + QMenu *fileMenu; + QString path; + ScreenWidget *cyanWidget; + ScreenWidget *magentaWidget; + ScreenWidget *yellowWidget; +}; + +#endif diff --git a/src/gui/doc/src/dnd.qdoc b/src/gui/doc/src/dnd.qdoc new file mode 100644 index 0000000000..a4eb77469b --- /dev/null +++ b/src/gui/doc/src/dnd.qdoc @@ -0,0 +1,401 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page dnd.html + \title Drag and Drop + \brief An overview of the drag and drop system provided by Qt. + + \ingroup qt-gui-concepts + + Drag and drop provides a simple visual mechanism which users can use + to transfer information between and within applications. (In the + literature this is referred to as a "direct manipulation model".) Drag + and drop is similar in function to the clipboard's cut and paste + mechanism. + + \tableofcontents + + This document describes the basic drag and drop mechanism and + outlines the approach used to enable it in custom widgets. Drag + and drop operations are also supported by Qt's item views and by + the graphics view framework. More information is available in + \l{Using drag and drop with item views} and \l{Graphics View + Framework}. + + \section1 Drag and Drop Classes + + These classes deal with drag and drop and the necessary mime type + encoding and decoding. + + \annotatedlist draganddrop + + \section1 Configuration + + The QApplication object provides some properties that are related + to drag and drop operations: + + \list + \li \l{QApplication::startDragTime} describes the amount of time in + milliseconds that the user must hold down a mouse button over an + object before a drag will begin. + \li \l{QApplication::startDragDistance} indicates how far the user has to + move the mouse while holding down a mouse button before the movement + will be interpreted as dragging. Use of high values for this quantity + prevents accidental dragging when the user only meant to click on an + object. + \endlist + + These quantities provide sensible default values for you to use if you + provide drag and drop support in your widgets. + + \section1 Dragging + + To start a drag, create a QDrag object, and call its + exec() function. In most applications, it is a good idea to begin a drag + and drop operation only after a mouse button has been pressed and the + cursor has been moved a certain distance. However, the simplest way to + enable dragging from a widget is to reimplement the widget's + \l{QWidget::mousePressEvent()}{mousePressEvent()} and start a drag + and drop operation: + + \snippet dragging/mainwindow.cpp 0 + \dots 8 + \snippet dragging/mainwindow.cpp 2 + + Although the user may take some time to complete the dragging operation, + as far as the application is concerned the exec() function is a blocking + function that returns with \l{Qt::DropActions}{one of several values}. + These indicate how the operation ended, and are described in more detail + below. + + Note that the exec() function does not block the main event loop. + + For widgets that need to distinguish between mouse clicks and drags, it + is useful to reimplement the widget's + \l{QWidget::mousePressEvent()}{mousePressEvent()} function to record to + start position of the drag: + + \snippet draganddrop/dragwidget.cpp 6 + + Later, in \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()}, we can determine + whether a drag should begin, and construct a drag object to handle the + operation: + + \snippet draganddrop/dragwidget.cpp 7 + \dots + \snippet draganddrop/dragwidget.cpp 8 + + This particular approach uses the \l QPoint::manhattanLength() function + to get a rough estimate of the distance between where the mouse click + occurred and the current cursor position. This function trades accuracy + for speed, and is usually suitable for this purpose. + + \section1 Dropping + + To be able to receive media dropped on a widget, call + \l{QWidget::setAcceptDrops()}{setAcceptDrops(true)} for the widget, + and reimplement the \l{QWidget::dragEnterEvent()}{dragEnterEvent()} and + \l{QWidget::dropEvent()}{dropEvent()} event handler functions. + + For example, the following code enables drop events in the constructor of + a QWidget subclass, making it possible to usefully implement drop event + handlers: + + \snippet dropevents/window.cpp 0 + \dots + \snippet dropevents/window.cpp 1 + \snippet dropevents/window.cpp 2 + + The dragEnterEvent() function is typically used to inform Qt about the + types of data that the widget accepts. + You must reimplement this function if you want to receive either + QDragMoveEvent or QDropEvent in your reimplementations of + \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and + \l{QWidget::dropEvent()}{dropEvent()}. + + The following code shows how \l{QWidget::dragEnterEvent()}{dragEnterEvent()} + can be reimplemented to + tell the drag and drop system that we can only handle plain text: + + \snippet dropevents/window.cpp 3 + + The \l{QWidget::dropEvent()}{dropEvent()} is used to unpack dropped data + and handle it in way that is suitable for your application. + + In the following code, the text supplied in the event is passed to a + QTextBrowser and a QComboBox is filled with the list of MIME types that + are used to describe the data: + + \snippet dropevents/window.cpp 4 + + In this case, we accept the proposed action without checking what it is. + In a real world application, it may be necessary to return from the + \l{QWidget::dropEvent()}{dropEvent()} function without accepting the + proposed action or handling + the data if the action is not relevant. For example, we may choose to + ignore Qt::LinkAction actions if we do not support + links to external sources in our application. + + \section2 Overriding Proposed Actions + + We may also ignore the proposed action, and perform some other action on + the data. To do this, we would call the event object's + \l{QDropEvent::setDropAction()}{setDropAction()} with the preferred + action from Qt::DropAction before calling \l{QEvent::}{accept()}. + This ensures that the replacement drop action is used instead of the + proposed action. + + For more sophisticated applications, reimplementing + \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and + \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()} will let you make + certain parts of your widgets sensitive to drop events, and give you more + control over drag and drop in your application. + + \section2 Subclassing Complex Widgets + + Certain standard Qt widgets provide their own support for drag and drop. + When subclassing these widgets, it may be necessary to reimplement + \l{QWidget::dragMoveEvent()}{dragMoveEvent()} in addition to + \l{QWidget::dragEnterEvent()}{dragEnterEvent()} and + \l{QWidget::dropEvent()}{dropEvent()} to prevent the base class from + providing default drag and drop handling, and to handle any special + cases you are interested in. + + \section1 Drag and Drop Actions + + In the simplest case, the target of a drag and drop action receives a + copy of the data being dragged, and the source decides whether to + delete the original. This is described by the \c CopyAction action. + The target may also choose to handle other actions, specifically the + \c MoveAction and \c LinkAction actions. If the source calls + QDrag::exec(), and it returns \c MoveAction, the source is responsible + for deleting any original data if it chooses to do so. The QMimeData + and QDrag objects created by the source widget \e{should not be deleted} + - they will be destroyed by Qt. The target is responsible for taking + ownership of the data sent in the drag and drop operation; this is + usually done by keeping references to the data. + + If the target understands the \c LinkAction action, it should + store its own reference to the original information; the source + does not need to perform any further processing on the data. The + most common use of drag and drop actions is when performing a + Move within the same widget; see the section on \l{Drop Actions} + for more information about this feature. + + The other major use of drag actions is when using a reference type + such as text/uri-list, where the dragged data are actually references + to files or objects. + + \section1 Adding New Drag and Drop Types + + Drag and drop is not limited to text and images. Any type of information + can be transferred in a drag and drop operation. To drag information + between applications, the applications must be able to indicate to each + other which data formats they can accept and which they can produce. + This is achieved using + \l{http://www.rfc-editor.org/rfc/rfc1341.txt}{MIME types}. The QDrag + object constructed by the source contains a list of MIME types that it + uses to represent the data (ordered from most appropriate to least + appropriate), and the drop target uses one of these to access the data. + For common data types, the convenience functions handle the MIME types + used transparently but, for custom data types, it is necessary to + state them explicitly. + + To implement drag and drop actions for a type of information that is + not covered by the QDrag convenience functions, the first and most + important step is to look for existing formats that are appropriate: + The Internet Assigned Numbers Authority (\l{http://www.iana.org}{IANA}) + provides a + \l{http://www.iana.org/assignments/media-types/}{hierarchical + list of MIME media types} at the Information Sciences Institute + (\l{http://www.isi.edu}{ISI}). + Using standard MIME types maximizes the interoperability of + your application with other software now and in the future. + + To support an additional media type, simply set the data in the QMimeData + object with the \l{QMimeData::setData()}{setData()} function, supplying + the full MIME type and a QByteArray containing the data in the appropriate + format. The following code takes a pixmap from a label and stores it + as a Portable Network Graphics (PNG) file in a QMimeData object: + + \snippet separations/finalwidget.cpp 0 + + Of course, for this case we could have simply used + \l{QMimeData::setImageData()}{setImageData()} instead to supply image data + in a variety of formats: + + \snippet separations/finalwidget.cpp 1 + + The QByteArray approach is still useful in this case because it provides + greater control over the amount of data stored in the QMimeData object. + + Note that custom datatypes used in item views must be declared as + \l{QMetaObject}{meta objects} and that stream operators for them + must be implemented. + + \section1 Drop Actions + + In the clipboard model, the user can \e cut or \e copy the source + information, then later paste it. Similarly in the drag and drop + model, the user can drag a \e copy of the information or they can drag + the information itself to a new place (\e moving it). The + drag and drop model has an additional complication for the programmer: + The program doesn't know whether the user wants to cut or copy the + information until the operation is complete. This often makes no + difference when dragging information between applications, but within + an application it is important to check which drop action was used. + + We can reimplement the mouseMoveEvent() for a widget, and start a drag + and drop operation with a combination of possible drop actions. For + example, we may want to ensure that dragging always moves objects in + the widget: + + \snippet draganddrop/dragwidget.cpp 7 + \dots + \snippet draganddrop/dragwidget.cpp 8 + + The action returned by the exec() function may default to a + \c CopyAction if the information is dropped into another application + but, if it is dropped in another widget in the same application, we + may obtain a different drop action. + + The proposed drop actions can be filtered in a widget's dragMoveEvent() + function. However, it is possible to accept all proposed actions in + the dragEnterEvent() and let the user decide which they want to accept + later: + + \snippet draganddrop/dragwidget.cpp 0 + + When a drop occurs in the widget, the dropEvent() handler function is + called, and we can deal with each possible action in turn. First, we + deal with drag and drop operations within the same widget: + + \snippet draganddrop/dragwidget.cpp 1 + + In this case, we refuse to deal with move operations. Each type of drop + action that we accept is checked and dealt with accordingly: + + \snippet draganddrop/dragwidget.cpp 2 + \snippet draganddrop/dragwidget.cpp 3 + \snippet draganddrop/dragwidget.cpp 4 + \dots + \snippet draganddrop/dragwidget.cpp 5 + + Note that we checked for individual drop actions in the above code. + As mentioned above in the section on + \l{#Overriding Proposed Actions}{Overriding Proposed Actions}, it is + sometimes necessary to override the proposed drop action and choose a + different one from the selection of possible drop actions. + To do this, you need to check for the presence of each action in the value + supplied by the event's \l{QDropEvent::}{possibleActions()}, set the drop + action with \l{QDropEvent::}{setDropAction()}, and call + \l{QEvent::}{accept()}. + + \section1 Drop Rectangles + + The widget's dragMoveEvent() can be used to restrict drops to certain parts + of the widget by only accepting the proposed drop actions when the cursor + is within those areas. For example, the following code accepts any proposed + drop actions when the cursor is over a child widget (\c dropFrame): + + \snippet droprectangle/window.cpp 0 + + The dragMoveEvent() can also be used if you need to give visual + feedback during a drag and drop operation, to scroll the window, or + whatever is appropriate. + + \section1 The Clipboard + + Applications can also communicate with each other by putting data on + the clipboard. To access this, you need to obtain a QClipboard object + from the QApplication object: + + \snippet widgets/charactermap/mainwindow.cpp 3 + + The QMimeData class is used to represent data that is transferred to and + from the clipboard. To put data on the clipboard, you can use the + setText(), setImage(), and setPixmap() convenience functions for common + data types. These functions are similar to those found in the QMimeData + class, except that they also take an additional argument that controls + where the data is stored: If \l{QClipboard::Mode}{Clipboard} is + specified, the data is placed on the clipboard; if + \l{QClipboard::Mode}{Selection} is specified, the data is placed in the + mouse selection (on X11 only). By default, data is put on the clipboard. + + For example, we can copy the contents of a QLineEdit to the clipboard + with the following code: + + \snippet widgets/charactermap/mainwindow.cpp 11 + + Data with different MIME types can also be put on the clipboard. + Construct a QMimeData object and set data with setData() function in + the way described in the previous section; this object can then be + put on the clipboard with the + \l{QClipboard::setMimeData()}{setMimeData()} function. + + The QClipboard class can notify the application about changes to the + data it contains via its \l{QClipboard::dataChanged()}{dataChanged()} + signal. For example, we can monitor the clipboard by connecting this + signal to a slot in a widget: + + \snippet clipboard/clipwindow.cpp 0 + + The slot connected to this signal can read the data on the clipboard + using one of the MIME types that can be used to represent it: + + \snippet clipboard/clipwindow.cpp 1 + \dots + \snippet clipboard/clipwindow.cpp 2 + + The \l{QClipboard::selectionChanged()}{selectionChanged()} signal can + be used on X11 to monitor the mouse selection. + + \section1 Examples + + \list + \li \l{draganddrop/draggableicons}{Draggable Icons} + \li \l{draganddrop/draggabletext}{Draggable Text} + \li \l{draganddrop/dropsite}{Drop Site} + \li \l{draganddrop/fridgemagnets}{Fridge Magnets} + \li \l{draganddrop/puzzle}{Drag and Drop Puzzle} + \endlist + + \section1 Interoperating with Other Applications + + On X11, the public \l{http://www.newplanetsoftware.com/xdnd/}{XDND + protocol} is used, while on Windows Qt uses the OLE standard, and + Qt for Mac OS X uses the Cocoa Drag Manager. On X11, XDND uses MIME, + so no translation is necessary. The Qt API is the same regardless of + the platform. On Windows, MIME-aware applications can communicate by + using clipboard format names that are MIME types. Already some + Windows applications use MIME naming conventions for their + clipboard formats. Internally, Qt uses QWindowsMime and + QMacPasteboardMime for translating proprietary clipboard formats + to and from MIME types. + +*/ diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc index c08ee657bb..f68ccbb6a8 100644 --- a/src/gui/doc/src/qtgui.qdoc +++ b/src/gui/doc/src/qtgui.qdoc @@ -158,7 +158,9 @@ QtGui now contains only a small set of enablers, which are generally useful for all graphical applications. + \section1 Drag and Drop + More info in \l{Drag and Drop} \section1 Reference \list diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 8b7bb13a26..301d704e2e 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -1,5 +1,3 @@ -load(qt_build_config) - TARGET = QtGui QT = core-private MODULE_CONFIG = opengl diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index a67917ca3b..64d2f8001f 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1211,6 +1211,12 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv QGuiApplicationPrivate::processFileOpenEvent( static_cast<QWindowSystemInterfacePrivate::FileOpenEvent *>(e)); break; +#ifndef QT_NO_CONTEXTMENU + case QWindowSystemInterfacePrivate::ContextMenu: + QGuiApplicationPrivate::processContextMenuEvent( + static_cast<QWindowSystemInterfacePrivate::ContextMenuEvent *>(e)); + break; +#endif default: qWarning() << "Unknown user input event type:" << e->type; break; @@ -1639,6 +1645,19 @@ void QGuiApplicationPrivate::processPlatformPanelEvent(QWindowSystemInterfacePri QGuiApplication::sendSpontaneousEvent(e->window.data(), &ev); } +#ifndef QT_NO_CONTEXTMENU +void QGuiApplicationPrivate::processContextMenuEvent(QWindowSystemInterfacePrivate::ContextMenuEvent *e) +{ + // Widgets do not care about mouse triggered context menu events. Also, do not forward event + // to a window blocked by a modal window. + if (!e->window || e->mouseTriggered || e->window->d_func()->blockedByModalWindow) + return; + + QContextMenuEvent ev(QContextMenuEvent::Keyboard, e->pos, e->globalPos, e->modifiers); + QGuiApplication::sendSpontaneousEvent(e->window.data(), &ev); +} +#endif + Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k) { return qHash(k.device) + k.touchPointId; diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 0c81d78f86..44a9275688 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -138,6 +138,9 @@ public: static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e); static void processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e); +#ifndef QT_NO_CONTEXTMENU + static void processContextMenuEvent(QWindowSystemInterfacePrivate::ContextMenuEvent *e); +#endif #ifndef QT_NO_DRAGANDDROP static QPlatformDragQtResponse processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions); diff --git a/src/gui/kernel/qinputmethod.h b/src/gui/kernel/qinputmethod.h index 25b133ec0a..d038542dc3 100644 --- a/src/gui/kernel/qinputmethod.h +++ b/src/gui/kernel/qinputmethod.h @@ -48,8 +48,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Gui) - class QInputMethodPrivate; class QWindow; class QRectF; diff --git a/src/gui/kernel/qplatformscreen_p.h b/src/gui/kernel/qplatformscreen_p.h index 8aaa8192c8..a63f8298ec 100644 --- a/src/gui/kernel/qplatformscreen_p.h +++ b/src/gui/kernel/qplatformscreen_p.h @@ -57,8 +57,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Gui) - class QScreen; class QPlatformScreenPrivate diff --git a/src/gui/kernel/qplatformsharedgraphicscache.h b/src/gui/kernel/qplatformsharedgraphicscache.h index 9c07b0e03c..707e862fbc 100644 --- a/src/gui/kernel/qplatformsharedgraphicscache.h +++ b/src/gui/kernel/qplatformsharedgraphicscache.h @@ -58,8 +58,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Gui) - class Q_GUI_EXPORT QPlatformSharedGraphicsCache: public QObject { Q_OBJECT diff --git a/src/gui/kernel/qplatformwindow_p.h b/src/gui/kernel/qplatformwindow_p.h index f4bb8ed388..ac9abfa10b 100644 --- a/src/gui/kernel/qplatformwindow_p.h +++ b/src/gui/kernel/qplatformwindow_p.h @@ -59,8 +59,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Gui) - class QPlatformWindowPrivate { public: diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h index 0bd63ca57b..f3b6082c15 100644 --- a/src/gui/kernel/qscreen_p.h +++ b/src/gui/kernel/qscreen_p.h @@ -51,8 +51,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Gui) - class QScreenPrivate : public QObjectPrivate { public: diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index d05dc8cbdc..6fb10b6c75 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -89,6 +89,26 @@ void QWindowSystemInterface::handleLeaveEvent(QWindow *tlw) QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } +/*! + This method can be used to ensure leave and enter events are both in queue when moving from + one QWindow to another. This allows QWindow subclasses to check for a queued enter event + when handling the leave event (\c QWindowSystemInterfacePrivate::peekWindowSystemEvent) to + determine where mouse went and act accordingly. E.g. QWidgetWindow needs to know if mouse + cursor moves between windows in same window hierarchy. +*/ +void QWindowSystemInterface::handleEnterLeaveEvent(QWindow *enter, QWindow *leave) +{ + bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents; + if (wasSynchronous) + setSynchronousWindowsSystemEvents(false); + handleLeaveEvent(leave); + handleEnterEvent(enter); + if (wasSynchronous) { + flushWindowSystemEvents(); + setSynchronousWindowsSystemEvents(true); + } +} + void QWindowSystemInterface::handleWindowActivated(QWindow *tlw) { QWindowSystemInterfacePrivate::ActivatedWindowEvent *e = new QWindowSystemInterfacePrivate::ActivatedWindowEvent(tlw); @@ -324,6 +344,16 @@ QWindowSystemInterfacePrivate::WindowSystemEvent * QWindowSystemInterfacePrivate return windowSystemEventQueue.takeFirstOrReturnNull(); } +QWindowSystemInterfacePrivate::WindowSystemEvent *QWindowSystemInterfacePrivate::peekWindowSystemEvent(EventType t) +{ + return windowSystemEventQueue.peekAtFirstOfType(t); +} + +void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *event) +{ + windowSystemEventQueue.remove(event); +} + void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev) { if (synchronousWindowsSystemEvents) { @@ -600,6 +630,18 @@ void QWindowSystemInterface::handlePlatformPanelEvent(QWindow *w) QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } +#ifndef QT_NO_CONTEXTMENU +void QWindowSystemInterface::handleContextMenuEvent(QWindow *w, bool mouseTriggered, + const QPoint &pos, const QPoint &globalPos, + Qt::KeyboardModifiers modifiers) +{ + QWindowSystemInterfacePrivate::ContextMenuEvent *e = + new QWindowSystemInterfacePrivate::ContextMenuEvent(w, mouseTriggered, pos, + globalPos, modifiers); + QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); +} +#endif + Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier) { QWindowSystemInterface::handleMouseEvent(w, local, global, b, mods); } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index cf5d22edbd..b4b2e845fc 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -136,6 +136,7 @@ public: static void handleCloseEvent(QWindow *w); static void handleEnterEvent(QWindow *w); static void handleLeaveEvent(QWindow *w); + static void handleEnterLeaveEvent(QWindow *enter, QWindow *leave); static void handleWindowActivated(QWindow *w); static void handleWindowStateChanged(QWindow *w, Qt::WindowState newState); @@ -174,6 +175,11 @@ public: static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid); static void handlePlatformPanelEvent(QWindow *w); +#ifndef QT_NO_CONTEXTMENU + static void handleContextMenuEvent(QWindow *w, bool mouseTriggered, + const QPoint &pos, const QPoint &globalPos, + Qt::KeyboardModifiers modifiers); +#endif // For event dispatcher implementations static bool sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index e9d2fadc84..1b5351db71 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -52,7 +52,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QWindowSystemInterfacePrivate { +class Q_GUI_EXPORT QWindowSystemInterfacePrivate { public: enum EventType { Close, @@ -77,7 +77,8 @@ public: Tablet, TabletEnterProximity, TabletLeaveProximity, - PlatformPanel + PlatformPanel, + ContextMenu }; class WindowSystemEvent { @@ -333,6 +334,21 @@ public: QPointer<QWindow> window; }; +#ifndef QT_NO_CONTEXTMENU + class ContextMenuEvent : public WindowSystemEvent { + public: + explicit ContextMenuEvent(QWindow *w, bool mouseTriggered, const QPoint &pos, + const QPoint &globalPos, Qt::KeyboardModifiers modifiers) + : WindowSystemEvent(ContextMenu), window(w), mouseTriggered(mouseTriggered), pos(pos), + globalPos(globalPos), modifiers(modifiers) { } + QPointer<QWindow> window; + bool mouseTriggered; + QPoint pos; // Only valid if triggered by mouse + QPoint globalPos; // Only valid if triggered by mouse + Qt::KeyboardModifiers modifiers; + }; +#endif + class WindowSystemEventList { QList<WindowSystemEvent *> impl; mutable QMutex mutex; @@ -349,6 +365,25 @@ public: { const QMutexLocker locker(&mutex); impl.append(e); } int count() const { const QMutexLocker locker(&mutex); return impl.count(); } + WindowSystemEvent *peekAtFirstOfType(EventType t) const + { + const QMutexLocker locker(&mutex); + for (int i = 0; i < impl.size(); ++i) { + if (impl.at(i)->type == t) + return impl.at(i); + } + return 0; + } + void remove(const WindowSystemEvent *e) + { + const QMutexLocker locker(&mutex); + for (int i = 0; i < impl.size(); ++i) { + if (impl.at(i) == e) { + impl.removeAt(i); + break; + } + } + } private: Q_DISABLE_COPY(WindowSystemEventList); }; @@ -356,7 +391,9 @@ public: static WindowSystemEventList windowSystemEventQueue; static int windowSystemEventsQueued(); - static WindowSystemEvent * getWindowSystemEvent(); + static WindowSystemEvent *getWindowSystemEvent(); + static WindowSystemEvent *peekWindowSystemEvent(EventType t); + static void removeWindowSystemEvent(WindowSystemEvent *event); static void handleWindowSystemEvent(WindowSystemEvent *ev); static QElapsedTimer eventTime; diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index e0f1fe50a6..624eeaffd9 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -1194,7 +1194,7 @@ void QOpenGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) return; QOpenGL2PaintEngineState *s = state(); - if (pen.isCosmetic() && !qt_scaleForTransform(s->transform(), 0)) { + if (qt_pen_is_cosmetic(pen, state()->renderHints) && !qt_scaleForTransform(s->transform(), 0)) { // QTriangulatingStroker class is not meant to support cosmetically sheared strokes. QPaintEngineEx::stroke(path, pen); return; @@ -1229,15 +1229,16 @@ void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &p : QRectF(0, 0, width, height)); if (penStyle == Qt::SolidLine) { - stroker.process(path, pen, clip); + stroker.process(path, pen, clip, s->renderHints); } else { // Some sort of dash - dasher.process(path, pen, clip); + dasher.process(path, pen, clip, s->renderHints); QVectorPath dashStroke(dasher.points(), dasher.elementCount(), - dasher.elementTypes()); - stroker.process(dashStroke, pen, clip); + dasher.elementTypes(), + s->renderHints); + stroker.process(dashStroke, pen, clip, s->renderHints); } if (!stroker.vertexCount()) @@ -1261,7 +1262,7 @@ void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &p ? qMax(pen.miterLimit() * width, width) : width; - if (pen.isCosmetic()) + if (qt_pen_is_cosmetic(pen, q->state()->renderHints)) extra = extra * inverseScale; QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra); @@ -1637,7 +1638,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type continue; int x = qFloor(staticTextItem->glyphPositions[i].x) + c.baseLineX - margin; - int y = qFloor(staticTextItem->glyphPositions[i].y) - c.baseLineY - margin; + int y = qRound(staticTextItem->glyphPositions[i].y) - c.baseLineY - margin; vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h)); textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy)); diff --git a/src/gui/opengl/qtriangulatingstroker.cpp b/src/gui/opengl/qtriangulatingstroker.cpp index 0be6e12721..6c8ab7d607 100644 --- a/src/gui/opengl/qtriangulatingstroker.cpp +++ b/src/gui/opengl/qtriangulatingstroker.cpp @@ -81,7 +81,7 @@ static inline void skipDuplicatePoints(const qreal **pts, const qreal *endPts) } } -void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &) +void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &, QPainter::RenderHints hints) { const qreal *pts = path.points(); const QPainterPath::ElementType *types = path.elements(); @@ -95,7 +95,7 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, co m_width = realWidth / 2; - bool cosmetic = pen.isCosmetic(); + bool cosmetic = qt_pen_is_cosmetic(pen, hints); if (cosmetic) { m_width = m_width * m_inv_scale; } @@ -519,14 +519,14 @@ QDashedStrokeProcessor::QDashedStrokeProcessor() m_dash_stroker.setCubicToHook(qdashprocessor_cubicTo); } -void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip) +void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip, QPainter::RenderHints hints) { const qreal *pts = path.points(); const QPainterPath::ElementType *types = path.elements(); int count = path.elementCount(); - bool cosmetic = pen.isCosmetic(); + bool cosmetic = qt_pen_is_cosmetic(pen, hints); m_points.reset(); m_types.reset(); diff --git a/src/gui/opengl/qtriangulatingstroker_p.h b/src/gui/opengl/qtriangulatingstroker_p.h index 295ddbab5a..98b12b0fb3 100644 --- a/src/gui/opengl/qtriangulatingstroker_p.h +++ b/src/gui/opengl/qtriangulatingstroker_p.h @@ -54,8 +54,11 @@ QT_BEGIN_NAMESPACE class Q_GUI_EXPORT QTriangulatingStroker { public: - QTriangulatingStroker() : m_vertices(0) {} - void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); + QTriangulatingStroker() : m_vertices(0), m_cx(0), m_cy(0), m_nvx(0), m_nvy(0), m_width(1), m_miter_limit(2), + m_roundness(0), m_sin_theta(0), m_cos_theta(0), m_inv_scale(1), m_curvyness_mul(1), m_curvyness_add(0), + m_join_style(Qt::BevelJoin), m_cap_style(Qt::SquareCap) {} + + void process(const QVectorPath &path, const QPen &pen, const QRectF &clip, QPainter::RenderHints hints); inline int vertexCount() const { return m_vertices.size(); } inline const float *vertices() const { return m_vertices.data(); } @@ -97,7 +100,7 @@ class Q_GUI_EXPORT QDashedStrokeProcessor public: QDashedStrokeProcessor(); - void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); + void process(const QVectorPath &path, const QPen &pen, const QRectF &clip, QPainter::RenderHints hints); inline void addElement(QPainterPath::ElementType type, qreal x, qreal y) { m_points.add(x); diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp index 2eab7b25c5..7fcab1f087 100644 --- a/src/gui/painting/qcosmeticstroker.cpp +++ b/src/gui/painting/qcosmeticstroker.cpp @@ -275,7 +275,7 @@ void QCosmeticStroker::setup() qreal width = state->lastPen.widthF(); if (width == 0) opacity = 256; - else if (state->lastPen.isCosmetic()) + else if (qt_pen_is_cosmetic(state->lastPen, state->renderHints)) opacity = (int) 256*width; else opacity = (int) 256*width*state->txscale; diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index e72b9ba968..a29d2037db 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -535,7 +535,8 @@ public: static inline Int32x4 v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); } // pre-VS 2008 doesn't have cast intrinsics, whereas 2008 and later requires it -#if defined(Q_CC_MSVC) && _MSC_VER < 1500 + // (same deal with gcc prior to 4.0) +#if (defined(Q_CC_MSVC) && _MSC_VER < 1500) || (defined(Q_CC_GNU) && __GNUC__ < 4) static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { union Convert { Int32x4 vi; Float32x4 vf; } convert; diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index 1e5a00e835..d7b16114b8 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -680,7 +680,7 @@ void QPaintBufferEngine::penChanged() } else { qreal penWidth = (pen.widthF() == 0) ? 1 : pen.widthF(); QPointF transformedWidth(penWidth, penWidth); - if (!pen.isCosmetic()) + if (!qt_pen_is_cosmetic(pen, state()->renderHints)) transformedWidth = painter()->transform().map(transformedWidth); buffer->penWidthAdjustment = transformedWidth.x() / 2.0; } diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index 09b1f0a8e4..339421f5e2 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -445,7 +445,7 @@ void QPaintEngine::drawPoints(const QPointF *points, int pointCount) p->save(); QTransform transform; - if (p->pen().isCosmetic()) { + if (qt_pen_is_cosmetic(p->pen(), p->renderHints())) { transform = p->transform(); p->setTransform(QTransform()); } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index e0eab8dc73..fec01afdee 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -771,7 +771,7 @@ void QRasterPaintEngine::updatePen(const QPen &pen) } else if (pen_style != Qt::NoPen) { if (!d->dashStroker) d->dashStroker.reset(new QDashStroker(&d->basicStroker)); - if (pen.isCosmetic()) { + if (qt_pen_is_cosmetic(pen, s->renderHints)) { d->dashStroker->setClipRect(d->deviceRect); } else { // ### I've seen this inverted devrect multiple places now... @@ -786,10 +786,11 @@ void QRasterPaintEngine::updatePen(const QPen &pen) } ensureRasterState(); // needed because of tx_noshear... + bool cosmetic = qt_pen_is_cosmetic(pen, s->renderHints); s->flags.fast_pen = pen_style > Qt::NoPen && s->penData.blend - && ((pen.isCosmetic() && penWidth <= 1) - || (!pen.isCosmetic() && s->flags.tx_noshear && penWidth * s->txscale <= 1)); + && ((cosmetic && penWidth <= 1) + || (!cosmetic && s->flags.tx_noshear && penWidth * s->txscale <= 1)); s->flags.non_complex_pen = qpen_capStyle(s->lastPen) <= Qt::SquareCap && s->flags.tx_noshear; @@ -1610,7 +1611,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding); stroker.drawPath(path); } else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) { - qreal width = s->lastPen.isCosmetic() + qreal width = qt_pen_is_cosmetic(s->lastPen, s->renderHints) ? (qpen_widthf(s->lastPen) == 0 ? 1 : qpen_widthf(s->lastPen)) : qpen_widthf(s->lastPen) * s->txscale; int dashIndex = 0; @@ -2786,7 +2787,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, alphaPenBlt(alphaMap->bits(), alphaMap->bytesPerLine(), alphaMap->depth(), qFloor(positions[i].x) + offset.x(), - qFloor(positions[i].y) + offset.y(), + qRound(positions[i].y) + offset.y(), alphaMap->width(), alphaMap->height()); fontEngine->unlockAlphaMapForGlyph(); @@ -2817,7 +2818,6 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, rightShift = 3; // divide by 8 int margin = fontEngine->glyphMargin(glyphType); - const QFixed offs = s->flags.legacy_rounding ? QFixed::fromReal(aliasedCoordinateDelta) : QFixed(); const uchar *bits = image.bits(); for (int i=0; i<numGlyphs; ++i) { @@ -2828,7 +2828,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, continue; int x = qFloor(positions[i].x) + c.baseLineX - margin; - int y = qFloor(positions[i].y + offs) - c.baseLineY - margin; + int y = qRound(positions[i].y) - c.baseLineY - margin; // printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n", // c.x, c.y, diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index dd93a58635..113cbd8a8e 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -435,7 +435,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) } if (pen.style() > Qt::SolidLine) { - if (pen.isCosmetic()) { + if (qt_pen_is_cosmetic(pen, state()->renderHints)){ d->activeStroker->setClipRect(d->exDeviceRect); } else { QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect)); @@ -462,7 +462,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) flags |= QVectorPath::CurvedShapeMask; // ### Perspective Xforms are currently not supported... - if (!pen.isCosmetic()) { + if (!qt_pen_is_cosmetic(pen, state()->renderHints)) { // We include cosmetic pens in this case to avoid having to // change the current transform. Normal transformed, // non-cosmetic pens will be transformed as part of fill diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 69267b259b..7070e5732d 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -897,26 +897,8 @@ void QPainterPrivate::updateState(QPainterState *newState) if (!newState) { engine->state = newState; - } else if (newState->state() || engine->state!=newState) { - bool setNonCosmeticPen = (newState->renderHints & QPainter::NonCosmeticDefaultPen) - && newState->pen.widthF() == 0; - if (setNonCosmeticPen) { - // Override the default pen's cosmetic state if the - // NonCosmeticDefaultPen render hint is used. - QPen oldPen = newState->pen; - newState->pen.setWidth(1); - newState->pen.setCosmetic(false); - newState->dirtyFlags |= QPaintEngine::DirtyPen; - - updateStateImpl(newState); - - // Restore the state pen back to its default to preserve visible - // state. - newState->pen = oldPen; - } else { - updateStateImpl(newState); - } + updateStateImpl(newState); } } @@ -1417,14 +1399,13 @@ void QPainterPrivate::updateState(QPainterState *newState) indicating that the engine should use fragment programs and offscreen rendering for antialiasing. - \value NonCosmeticDefaultPen The engine should interpret pens with a width - of 0 (which otherwise enables QPen::isCosmetic()) as being a non-cosmetic - pen with a width of 1. + \value NonCosmeticDefaultPen This value is obsolete, the default for QPen + is now non-cosmetic. \value Qt4CompatiblePainting Compatibility hint telling the engine to use the same X11 based fill rules as in Qt 4, where aliased rendering is offset - by slightly less than half a pixel. Potentially useful when porting a - Qt 4 application to Qt 5. + by slightly less than half a pixel. Also will treat default constructed pens + as cosmetic. Potentially useful when porting a Qt 4 application to Qt 5. \sa renderHints(), setRenderHint(), {QPainter#Rendering Quality}{Rendering Quality}, {Concentric Circles Example} @@ -3849,13 +3830,10 @@ void QPainter::setPen(const QColor &color) return; } - if (d->state->pen.style() == Qt::SolidLine - && d->state->pen.widthF() == 0 - && d->state->pen.isSolid() - && d->state->pen.color() == color) - return; + QPen pen(color.isValid() ? color : QColor(Qt::black)); - QPen pen(color.isValid() ? color : QColor(Qt::black), 0, Qt::SolidLine); + if (d->state->pen == pen) + return; d->state->pen = pen; if (d->extended) @@ -3904,7 +3882,7 @@ void QPainter::setPen(const QPen &pen) /*! \overload - Sets the painter's pen to have the given \a style, width 0 and + Sets the painter's pen to have the given \a style, width 1 and black color. */ @@ -3916,15 +3894,12 @@ void QPainter::setPen(Qt::PenStyle style) return; } - if (d->state->pen.style() == style - && (style == Qt::NoPen || (d->state->pen.widthF() == 0 - && d->state->pen.isSolid() - && d->state->pen.color() == QColor(Qt::black)))) + QPen pen = QPen(style); + + if (d->state->pen == pen) return; - // QPen(Qt::NoPen) is to avoid creating QPenData, including its brush (from the color) - // Note that this works well as long as QPen(Qt::NoPen) returns a black, zero-width pen - d->state->pen = (style == Qt::NoPen) ? QPen(Qt::NoPen) : QPen(Qt::black, 0, style); + d->state->pen = pen; if (d->extended) d->extended->penChanged(); @@ -6207,10 +6182,16 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QLineF line(pos.x(), pos.y(), pos.x() + qFloor(width), pos.y()); + bool wasCompatiblePainting = painter->renderHints() + & QPainter::Qt4CompatiblePainting; + + if (wasCompatiblePainting) + painter->setRenderHint(QPainter::Qt4CompatiblePainting, false); + const qreal underlineOffset = fe->underlinePosition().toReal(); // deliberately ceil the offset to avoid the underline coming too close to // the text above it. - const qreal underlinePos = pos.y() + qCeil(underlineOffset); + const qreal underlinePos = pos.y() + qCeil(underlineOffset) + 0.5; if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); @@ -6272,6 +6253,9 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setPen(oldPen); painter->setBrush(oldBrush); + + if (wasCompatiblePainting) + painter->setRenderHint(QPainter::Qt4CompatiblePainting); } Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray, @@ -7525,36 +7509,16 @@ start_lengthVariant: qreal yoff = 0; qreal xoff = 0; - if (tf & Qt::AlignBottom) { + if (tf & Qt::AlignBottom) yoff = r.height() - height; - } else if (tf & Qt::AlignVCenter) { + else if (tf & Qt::AlignVCenter) yoff = (r.height() - height)/2; - if (painter) { - QTransform::TransformationType type = painter->transform().type(); - if (type <= QTransform::TxScale) { - // do the rounding manually to work around inconsistencies - // in the paint engines when drawing on floating point offsets - const qreal scale = painter->transform().m22(); - if (scale != 0) - yoff = -qRound(-yoff * scale) / scale; - } - } - } - if (tf & Qt::AlignRight) { + + if (tf & Qt::AlignRight) xoff = r.width() - width; - } else if (tf & Qt::AlignHCenter) { + else if (tf & Qt::AlignHCenter) xoff = (r.width() - width)/2; - if (painter) { - QTransform::TransformationType type = painter->transform().type(); - if (type <= QTransform::TxScale) { - // do the rounding manually to work around inconsistencies - // in the paint engines when drawing on floating point offsets - const qreal scale = painter->transform().m11(); - if (scale != 0) - xoff = qRound(xoff * scale) / scale; - } - } - } + QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) { diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h index 6ad1cb07cc..0e46cee4b5 100644 --- a/src/gui/painting/qpainter_p.h +++ b/src/gui/painting/qpainter_p.h @@ -241,10 +241,6 @@ public: void updateMatrix(); void updateInvMatrix(); - int rectSubtraction() const { - return state->pen.style() != Qt::NoPen && state->pen.width() == 0 ? 1 : 0; - } - void checkEmulation(); static QPainterPrivate *get(QPainter *painter) @@ -269,6 +265,11 @@ Q_GUI_EXPORT void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, Q QString qt_generate_brush_key(const QBrush &brush); +inline bool qt_pen_is_cosmetic(const QPen &pen, QPainter::RenderHints hints) +{ + return pen.isCosmetic() || (const_cast<QPen &>(pen).data_ptr()->defaultWidth && (hints & QPainter::Qt4CompatiblePainting)); +} + QT_END_NAMESPACE #endif // QPAINTER_P_H diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index d2aa938aed..1d07d44dd8 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -44,6 +44,7 @@ #include <qfile.h> #include <qtemporaryfile.h> #include <private/qmath_p.h> +#include <private/qpainter_p.h> #include <qnumeric.h> #include "private/qfont_p.h" #include <qimagewriter.h> @@ -784,7 +785,7 @@ QPdf::Stroker::Stroker() basicStroker.setStrokeWidth(.1); } -void QPdf::Stroker::setPen(const QPen &pen) +void QPdf::Stroker::setPen(const QPen &pen, QPainter::RenderHints hints) { if (pen.style() == Qt::NoPen) { stroker = 0; @@ -792,7 +793,7 @@ void QPdf::Stroker::setPen(const QPen &pen) } qreal w = pen.widthF(); bool zeroWidth = w < 0.0001; - cosmeticPen = pen.isCosmetic(); + cosmeticPen = qt_pen_is_cosmetic(pen, hints); if (zeroWidth) w = .1; @@ -1198,12 +1199,14 @@ void QPdfEngine::updateState(const QPaintEngineState &state) if (flags & DirtyPen) { d->pen = state.pen(); d->hasPen = d->pen.style() != Qt::NoPen; - d->stroker.setPen(d->pen); + d->stroker.setPen(d->pen, state.renderHints()); QBrush penBrush = d->pen.brush(); bool oldSimple = d->simplePen; d->simplePen = (d->hasPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque()); if (oldSimple != d->simplePen) flags |= DirtyTransform; + } else if (flags & DirtyHints) { + d->stroker.setPen(d->pen, state.renderHints()); } if (flags & DirtyBrush) { d->brush = state.brush(); diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index ba86803288..735c5d13e0 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -124,7 +124,7 @@ namespace QPdf { struct Stroker { Stroker(); - void setPen(const QPen &pen); + void setPen(const QPen &pen, QPainter::RenderHints hints); void strokePath(const QPainterPath &path); ByteStream *stream; bool first; diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp index d86a5f0392..6b71c3818f 100644 --- a/src/gui/painting/qpen.cpp +++ b/src/gui/painting/qpen.cpp @@ -86,7 +86,7 @@ typedef QPenPrivate QPenData; \snippet code/src_gui_painting_qpen.cpp 1 - The default pen is a solid black brush with 0 width, square + The default pen is a solid black brush with 1 width, square cap style (Qt::SquareCap), and bevel join style (Qt::BevelJoin). In addition QPen provides the color() and setColor() @@ -230,9 +230,9 @@ typedef QPenPrivate QPenData; \internal */ inline QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle, - Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle) + Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle, bool _defaultWidth) : ref(1), dashOffset(0), miterLimit(2), - cosmetic(false) + cosmetic(false), defaultWidth(_defaultWidth) { width = _width; brush = _brush; @@ -261,12 +261,12 @@ public: }; Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, defaultPenInstance, - (Qt::black, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join)) + (Qt::black, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join)) Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance, - (Qt::black, 0, Qt::NoPen, qpen_default_cap, qpen_default_join)) + (Qt::black, 1, Qt::NoPen, qpen_default_cap, qpen_default_join)) /*! - Constructs a default black solid line pen with 0 width. + Constructs a default black solid line pen with 1 width. */ QPen::QPen() @@ -276,7 +276,7 @@ QPen::QPen() } /*! - Constructs a black pen with 0 width and the given \a style. + Constructs a black pen with 1 width and the given \a style. \sa setStyle() */ @@ -287,20 +287,20 @@ QPen::QPen(Qt::PenStyle style) d = nullPenInstance()->pen; d->ref.ref(); } else { - d = new QPenData(Qt::black, 0, style, qpen_default_cap, qpen_default_join); + d = new QPenData(Qt::black, 1, style, qpen_default_cap, qpen_default_join); } } /*! - Constructs a solid line pen with 0 width and the given \a color. + Constructs a solid line pen with 1 width and the given \a color. \sa setBrush(), setColor() */ QPen::QPen(const QColor &color) { - d = new QPenData(color, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join); + d = new QPenData(color, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join); } @@ -315,7 +315,7 @@ QPen::QPen(const QColor &color) QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j) { - d = new QPenData(brush, width, s, c, j); + d = new QPenData(brush, width, s, c, j, false); } /*! @@ -655,12 +655,15 @@ void QPen::setWidth(int width) void QPen::setWidthF(qreal width) { - if (width < 0.f) + if (width < 0.f) { qWarning("QPen::setWidthF: Setting a pen width with a negative value is not defined"); + return; + } if (qAbs(d->width - width) < 0.00000001f) return; detach(); d->width = width; + d->defaultWidth = false; } @@ -785,8 +788,7 @@ bool QPen::isSolid() const used with. Drawing a shape with a cosmetic pen ensures that its outline will have the same thickness at different scale factors. - A zero width pen is cosmetic by default; pens with a non-zero width - are non-cosmetic. + A zero width pen is cosmetic by default. \sa setCosmetic(), widthF() */ @@ -848,7 +850,8 @@ bool QPen::operator==(const QPen &p) const || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) && pdd->dashPattern == dd->dashPattern)) && p.d->brush == d->brush - && pdd->cosmetic == dd->cosmetic); + && pdd->cosmetic == dd->cosmetic + && pdd->defaultWidth == dd->defaultWidth); } @@ -910,6 +913,8 @@ QDataStream &operator<<(QDataStream &s, const QPen &p) } if (s.version() >= 9) s << double(p.dashOffset()); + if (s.version() >= QDataStream::Qt_5_0) + s << bool(dd->defaultWidth); } return s; } @@ -935,6 +940,7 @@ QDataStream &operator>>(QDataStream &s, QPen &p) QVector<qreal> dashPattern; double dashOffset = 0; bool cosmetic = false; + bool defaultWidth = false; if (s.version() < QDataStream::Qt_4_3) { quint8 style8; s >> style8; @@ -967,6 +973,13 @@ QDataStream &operator>>(QDataStream &s, QPen &p) s >> dashOffset; } + if (s.version() >= QDataStream::Qt_5_0) { + s >> defaultWidth; + } else { + // best we can do for legacy pens + defaultWidth = qFuzzyIsNull(width); + } + p.detach(); QPenData *dd = static_cast<QPenData *>(p.d); dd->width = width; @@ -978,6 +991,7 @@ QDataStream &operator>>(QDataStream &s, QPen &p) dd->miterLimit = miterLimit; dd->dashOffset = dashOffset; dd->cosmetic = cosmetic; + dd->defaultWidth = defaultWidth; return s; } diff --git a/src/gui/painting/qpen_p.h b/src/gui/painting/qpen_p.h index 93f2532e63..4b2fcaa71d 100644 --- a/src/gui/painting/qpen_p.h +++ b/src/gui/painting/qpen_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class QPenPrivate { public: QPenPrivate(const QBrush &brush, qreal width, Qt::PenStyle, Qt::PenCapStyle, - Qt::PenJoinStyle _joinStyle); + Qt::PenJoinStyle _joinStyle, bool defaultWidth = true); QAtomicInt ref; qreal width; QBrush brush; @@ -71,6 +71,7 @@ public: qreal dashOffset; qreal miterLimit; uint cosmetic : 1; + uint defaultWidth : 1; // default-constructed width? used for cosmetic pen compatibility }; QT_END_NAMESPACE diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 995d48d450..2bc63cbd10 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -649,6 +649,24 @@ void QFont::detach() } /*! + \internal + Detaches the font object from common font attributes data. + Call this instead of QFont::detach() if the only font attributes data + has been changed (underline, letterSpacing, kerning, etc.). +*/ +void QFontPrivate::detachButKeepEngineData(QFont *font) +{ + if (font->d->ref.load() == 1) + return; + + QFontEngineData *engineData = font->d->engineData; + if (engineData) + engineData->ref.ref(); + font->d.detach(); + font->d->engineData = engineData; +} + +/*! Constructs a font object that uses the application's default font. \sa QGuiApplication::setFont(), QGuiApplication::font() @@ -1149,7 +1167,7 @@ void QFont::setUnderline(bool enable) if ((resolve_mask & QFont::UnderlineResolved) && d->underline == enable) return; - detach(); + QFontPrivate::detachButKeepEngineData(this); d->underline = enable; resolve_mask |= QFont::UnderlineResolved; @@ -1175,7 +1193,7 @@ void QFont::setOverline(bool enable) if ((resolve_mask & QFont::OverlineResolved) && d->overline == enable) return; - detach(); + QFontPrivate::detachButKeepEngineData(this); d->overline = enable; resolve_mask |= QFont::OverlineResolved; @@ -1202,7 +1220,7 @@ void QFont::setStrikeOut(bool enable) if ((resolve_mask & QFont::StrikeOutResolved) && d->strikeOut == enable) return; - detach(); + QFontPrivate::detachButKeepEngineData(this); d->strikeOut = enable; resolve_mask |= QFont::StrikeOutResolved; @@ -1262,7 +1280,7 @@ void QFont::setKerning(bool enable) if ((resolve_mask & QFont::KerningResolved) && d->kerning == enable) return; - detach(); + QFontPrivate::detachButKeepEngineData(this); d->kerning = enable; resolve_mask |= QFont::KerningResolved; @@ -1512,7 +1530,7 @@ void QFont::setLetterSpacing(SpacingType type, qreal spacing) d->letterSpacing == newSpacing) return; - detach(); + QFontPrivate::detachButKeepEngineData(this); d->letterSpacing = newSpacing; d->letterSpacingIsAbsolute = absoluteSpacing; @@ -1562,7 +1580,7 @@ void QFont::setWordSpacing(qreal spacing) d->wordSpacing == newSpacing) return; - detach(); + QFontPrivate::detachButKeepEngineData(this); d->wordSpacing = newSpacing; resolve_mask |= QFont::WordSpacingResolved; @@ -1596,7 +1614,7 @@ void QFont::setCapitalization(Capitalization caps) capitalization() == caps) return; - detach(); + QFontPrivate::detachButKeepEngineData(this); d->capital = caps; resolve_mask |= QFont::CapitalizationResolved; @@ -1635,6 +1653,7 @@ void QFont::setRawMode(bool enable) { if ((bool) d->rawMode == enable) return; + // might change behavior, thus destroy engine data detach(); d->rawMode = enable; diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index f32b6e72a4..2a37b56d87 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -185,6 +185,9 @@ public: } void resolve(uint mask, const QFontPrivate *other); + + static void detachButKeepEngineData(QFont *font); + private: QFontPrivate &operator=(const QFontPrivate &) { return *this; } }; diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp index 37195d5f61..c6e8a53284 100644 --- a/src/gui/text/qfontengine_qpa.cpp +++ b/src/gui/text/qfontengine_qpa.cpp @@ -726,6 +726,7 @@ void QFontEngineMultiQPA::setFallbackFamiliesList(const QStringList &fallbacks) // Turns out we lied about having any fallback at all. fallbackFamilies << fe->fontDef.family; engines[1] = fe; + fe->ref.ref(); } fallbacksQueried = true; } diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 38fe2f8140..82cff6a043 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1015,10 +1015,22 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const casedString.resize(entire_shaper_item.item.length); HB_UChar16 *uc = casedString.data(); for (uint i = 0; i < entire_shaper_item.item.length; ++i) { - if(si.analysis.flags == QScriptAnalysis::Lowercase) - uc[i] = QChar::toLower(entire_shaper_item.string[si.position + i]); - else - uc[i] = QChar::toUpper(entire_shaper_item.string[si.position + i]); + uint ucs4 = entire_shaper_item.string[si.position + i]; + if (QChar::isHighSurrogate(ucs4)) { + uc[i] = ucs4; // high part never changes in simple casing + if (i + 1 < entire_shaper_item.item.length) { + ushort low = entire_shaper_item.string[si.position + i + 1]; + if (QChar::isLowSurrogate(low)) { + ucs4 = QChar::surrogateToUcs4(ucs4, low); + ucs4 = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4) + : QChar::toUpper(ucs4); + uc[++i] = QChar::lowSurrogate(ucs4); + } + } + } else { + uc[i] = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4) + : QChar::toUpper(ucs4); + } } entire_shaper_item.item.pos = 0; entire_shaper_item.string = uc; @@ -3060,8 +3072,7 @@ void QTextEngine::drawItemDecorationList(QPainter *painter, const ItemDecoration foreach (const ItemDecoration &decoration, decorationList) { painter->setPen(decoration.pen); - QLineF line(decoration.x1, decoration.y, decoration.x2, decoration.y); - painter->drawLine(line); + painter->drawLine(QLineF(decoration.x1, decoration.y, decoration.x2, decoration.y)); } } @@ -3069,13 +3080,23 @@ void QTextEngine::drawDecorations(QPainter *painter) { QPen oldPen = painter->pen(); + bool wasCompatiblePainting = painter->renderHints() + & QPainter::Qt4CompatiblePainting; + + if (wasCompatiblePainting) + painter->setRenderHint(QPainter::Qt4CompatiblePainting, false); + adjustUnderlines(); drawItemDecorationList(painter, underlineList); drawItemDecorationList(painter, strikeOutList); drawItemDecorationList(painter, overlineList); - painter->setPen(oldPen); clearDecorations(); + + if (wasCompatiblePainting) + painter->setRenderHint(QPainter::Qt4CompatiblePainting); + + painter->setPen(oldPen); } void QTextEngine::clearDecorations() diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index bef461f448..aff5e1cb7f 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -390,7 +390,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine mutable uint gridfitted : 1; uint hasTrailingSpaces : 1; uint leadingIncluded : 1; - QFixed height() const { return (ascent + descent).ceil() + QFixed height() const { return ascent + descent + (leadingIncluded? qMax(QFixed(),leading) : QFixed()); } QFixed base() const { return ascent + (leadingIncluded ? qMax(QFixed(),leading) : QFixed()); } @@ -540,24 +540,14 @@ public: int findItem(int strPos) const; inline QTextFormatCollection *formats() const { -#ifdef QT_BUILD_COMPAT_LIB - return 0; // Compat should never reference this symbol -#else if (block.docHandle()) return block.docHandle()->formatCollection(); - else if (specialData) - return specialData->formats.data(); - - return 0; -#endif + return specialData ? specialData->formats.data() : 0; } QTextCharFormat format(const QScriptItem *si) const; inline QAbstractTextDocumentLayout *docLayout() const { -#ifdef QT_BUILD_COMPAT_LIB - return 0; // Compat should never reference this symbol -#else + Q_ASSERT(block.docHandle()); return block.docHandle()->document()->documentLayout(); -#endif } int formatIndex(const QScriptItem *si) const; diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp index 49945ae5b0..6231a097d3 100644 --- a/src/gui/util/qvalidator.cpp +++ b/src/gui/util/qvalidator.cpp @@ -862,7 +862,8 @@ QRegExpValidator::~QRegExpValidator() partially (i.e. could be a valid match if additional valid characters are added), and \l Invalid if \a input is not matched. - The \a pos parameter is set to the length of the \a input parameter. + Additionally, if \a input is not matched, the \a pos parameter is set to + the length of the \a input parameter. For example, if the regular expression is \b{\\w\\d\\d} (word-character, digit, digit) then "A57" is \l Acceptable, |