From bc2dabf8ff9b7867945bfac68942ab98d79432ea Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 21 Aug 2015 10:17:58 +0200 Subject: Extend the image viewer example. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add: - Save As - Copy - Paste from clipboard into new image Change-Id: Ibbc308e9bbd2ce407119cd9358874f5c22a6bb83 Reviewed-by: Topi Reiniƶ --- .../widgets/widgets/imageviewer/imageviewer.cpp | 128 ++++++++++++++++++--- examples/widgets/widgets/imageviewer/imageviewer.h | 9 ++ 2 files changed, 120 insertions(+), 17 deletions(-) (limited to 'examples/widgets/widgets') diff --git a/examples/widgets/widgets/imageviewer/imageviewer.cpp b/examples/widgets/widgets/imageviewer/imageviewer.cpp index 2c36491b50..a4b37060f6 100644 --- a/examples/widgets/widgets/imageviewer/imageviewer.cpp +++ b/examples/widgets/widgets/imageviewer/imageviewer.cpp @@ -72,16 +72,30 @@ bool ImageViewer::loadFile(const QString &fileName) { QImageReader reader(fileName); reader.setAutoTransform(true); - const QImage image = reader.read(); - if (image.isNull()) { + const QImage newImage = reader.read(); + if (newImage.isNull()) { QMessageBox::information(this, QGuiApplication::applicationDisplayName(), tr("Cannot load %1: %2") .arg(QDir::toNativeSeparators(fileName)), reader.errorString()); return false; } -//! [2] //! [3] +//! [2] + + setImage(newImage); + + setWindowFilePath(fileName); + + const QString message = tr("Opened \"%1\", %2x%3, Depth: %4") + .arg(QDir::toNativeSeparators(fileName)).arg(image.width()).arg(image.height()).arg(image.depth()); + statusBar()->showMessage(message); + return true; +} + +void ImageViewer::setImage(const QImage &newImage) +{ + image = newImage; imageLabel->setPixmap(QPixmap::fromImage(image)); -//! [3] //! [4] +//! [4] scaleFactor = 1.0; scrollArea->setVisible(true); @@ -91,37 +105,66 @@ bool ImageViewer::loadFile(const QString &fileName) if (!fitToWindowAct->isChecked()) imageLabel->adjustSize(); +} - setWindowFilePath(fileName); +//! [4] - const QString message = tr("Opened \"%1\", %2x%3, Depth: %4") - .arg(QDir::toNativeSeparators(fileName)).arg(image.width()).arg(image.height()).arg(image.depth()); +bool ImageViewer::saveFile(const QString &fileName) +{ + QImageWriter writer(fileName); + + if (!writer.write(image)) { + QMessageBox::information(this, QGuiApplication::applicationDisplayName(), + tr("Cannot write %1: %2") + .arg(QDir::toNativeSeparators(fileName)), writer.errorString()); + return false; + } + const QString message = tr("Wrote \"%1\"").arg(QDir::toNativeSeparators(fileName)); statusBar()->showMessage(message); return true; } -//! [4] - -//! [2] - //! [1] -void ImageViewer::open() + +static void initializeImageFileDialog(QFileDialog &dialog, QFileDialog::AcceptMode acceptMode) { + static bool firstDialog = true; + + if (firstDialog) { + firstDialog = false; + const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); + dialog.setDirectory(picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.last()); + } + QStringList mimeTypeFilters; - foreach (const QByteArray &mimeTypeName, QImageReader::supportedMimeTypes()) + const QByteArrayList supportedMimeTypes = acceptMode == QFileDialog::AcceptOpen + ? QImageReader::supportedMimeTypes() : QImageWriter::supportedMimeTypes(); + foreach (const QByteArray &mimeTypeName, supportedMimeTypes) mimeTypeFilters.append(mimeTypeName); mimeTypeFilters.sort(); - const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); - QFileDialog dialog(this, tr("Open File"), - picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.last()); - dialog.setAcceptMode(QFileDialog::AcceptOpen); dialog.setMimeTypeFilters(mimeTypeFilters); dialog.selectMimeTypeFilter("image/jpeg"); + if (acceptMode == QFileDialog::AcceptSave) + dialog.setDefaultSuffix("jpg"); +} + +void ImageViewer::open() +{ + QFileDialog dialog(this, tr("Open File")); + initializeImageFileDialog(dialog, QFileDialog::AcceptOpen); while (dialog.exec() == QDialog::Accepted && !loadFile(dialog.selectedFiles().first())) {} } //! [1] +void ImageViewer::saveAs() +{ + QFileDialog dialog(this, tr("Save File As")); + initializeImageFileDialog(dialog, QFileDialog::AcceptSave); + + while (dialog.exec() == QDialog::Accepted && !saveFile(dialog.selectedFiles().first())) {} +} + //! [5] void ImageViewer::print() //! [5] //! [6] @@ -144,6 +187,43 @@ void ImageViewer::print() } //! [8] +void ImageViewer::copy() +{ +#ifndef QT_NO_CLIPBOARD + QGuiApplication::clipboard()->setImage(image); +#endif // !QT_NO_CLIPBOARD +} + +#ifndef QT_NO_CLIPBOARD +static QImage clipboardImage() +{ + if (const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData()) { + if (mimeData->hasImage()) { + const QImage image = qvariant_cast(mimeData->imageData()); + if (!image.isNull()) + return image; + } + } + return QImage(); +} +#endif // !QT_NO_CLIPBOARD + +void ImageViewer::paste() +{ +#ifndef QT_NO_CLIPBOARD + const QImage newImage = clipboardImage(); + if (newImage.isNull()) { + statusBar()->showMessage(tr("No image in clipboard")); + } else { + setImage(newImage); + setWindowFilePath(QString()); + const QString message = tr("Obtained image from clipboard, %1x%2, Depth: %3") + .arg(newImage.width()).arg(newImage.height()).arg(newImage.depth()); + statusBar()->showMessage(message); + } +#endif // !QT_NO_CLIPBOARD +} + //! [9] void ImageViewer::zoomIn() //! [9] //! [10] @@ -207,6 +287,9 @@ void ImageViewer::createActions() QAction *openAct = fileMenu->addAction(tr("&Open..."), this, &ImageViewer::open); openAct->setShortcut(QKeySequence::Open); + saveAsAct = fileMenu->addAction(tr("&Save As..."), this, &ImageViewer::saveAs); + saveAsAct->setEnabled(false); + printAct = fileMenu->addAction(tr("&Print..."), this, &ImageViewer::print); printAct->setShortcut(QKeySequence::Print); printAct->setEnabled(false); @@ -216,6 +299,15 @@ void ImageViewer::createActions() QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close); exitAct->setShortcut(tr("Ctrl+Q")); + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + + copyAct = editMenu->addAction(tr("&Copy"), this, &ImageViewer::copy); + copyAct->setShortcut(QKeySequence::Copy); + copyAct->setEnabled(false); + + QAction *pasteAct = editMenu->addAction(tr("&Paste"), this, &ImageViewer::paste); + pasteAct->setShortcut(QKeySequence::Paste); + QMenu *viewMenu = menuBar()->addMenu(tr("&View")); zoomInAct = viewMenu->addAction(tr("Zoom &In (25%)"), this, &ImageViewer::zoomIn); @@ -248,6 +340,8 @@ void ImageViewer::createActions() void ImageViewer::updateActions() //! [21] //! [22] { + saveAsAct->setEnabled(!image.isNull()); + copyAct->setEnabled(!image.isNull()); zoomInAct->setEnabled(!fitToWindowAct->isChecked()); zoomOutAct->setEnabled(!fitToWindowAct->isChecked()); normalSizeAct->setEnabled(!fitToWindowAct->isChecked()); diff --git a/examples/widgets/widgets/imageviewer/imageviewer.h b/examples/widgets/widgets/imageviewer/imageviewer.h index 6443428baf..7084bf98d1 100644 --- a/examples/widgets/widgets/imageviewer/imageviewer.h +++ b/examples/widgets/widgets/imageviewer/imageviewer.h @@ -42,6 +42,7 @@ #define IMAGEVIEWER_H #include +#include #ifndef QT_NO_PRINTER #include #endif @@ -65,7 +66,10 @@ public: private slots: void open(); + void saveAs(); void print(); + void copy(); + void paste(); void zoomIn(); void zoomOut(); void normalSize(); @@ -76,9 +80,12 @@ private: void createActions(); void createMenus(); void updateActions(); + bool saveFile(const QString &fileName); + void setImage(const QImage &newImage); void scaleImage(double factor); void adjustScrollBar(QScrollBar *scrollBar, double factor); + QImage image; QLabel *imageLabel; QScrollArea *scrollArea; double scaleFactor; @@ -87,7 +94,9 @@ private: QPrinter printer; #endif + QAction *saveAsAct; QAction *printAct; + QAction *copyAct; QAction *zoomInAct; QAction *zoomOutAct; QAction *normalSizeAct; -- cgit v1.2.3