Mega Code Archive

 
Categories / C++ / Qt
 

Scribble area

/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file.  Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights.  These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file.  Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef SCRIBBLEAREA_H #define SCRIBBLEAREA_H #include <QColor> #include <QImage> #include <QPoint> #include <QWidget> class ScribbleArea : public QWidget {     Q_OBJECT public:     ScribbleArea(QWidget *parent = 0);     bool openImage(const QString &fileName);     bool saveImage(const QString &fileName, const char *fileFormat);     void setPenColor(const QColor &newColor);     void setPenWidth(int newWidth);     bool isModified() const { return modified; }     QColor penColor() const { return myPenColor; }     int penWidth() const { return myPenWidth; } public slots:     void clearImage();     void print(); protected:     void mousePressEvent(QMouseEvent *event);     void mouseMoveEvent(QMouseEvent *event);     void mouseReleaseEvent(QMouseEvent *event);     void paintEvent(QPaintEvent *event);     void resizeEvent(QResizeEvent *event); private:     void drawLineTo(const QPoint &endPoint);     void resizeImage(QImage *image, const QSize &newSize);     bool modified;     bool scribbling;     int myPenWidth;     QColor myPenColor;     QImage image;     QPoint lastPoint; }; #endif #include <QtGui> #include "scribblearea.h" ScribbleArea::ScribbleArea(QWidget *parent)     : QWidget(parent) {     setAttribute(Qt::WA_StaticContents);     modified = false;     scribbling = false;     myPenWidth = 1;     myPenColor = Qt::blue; } bool ScribbleArea::openImage(const QString &fileName)   {     QImage loadedImage;     if (!loadedImage.load(fileName))         return false;     QSize newSize = loadedImage.size().expandedTo(size());     resizeImage(&loadedImage, newSize);     image = loadedImage;     modified = false;     update();     return true; } bool ScribbleArea::saveImage(const QString &fileName, const char *fileFormat)   {     QImage visibleImage = image;     resizeImage(&visibleImage, size());     if (visibleImage.save(fileName, fileFormat)) {         modified = false;         return true;     } else {         return false;     } } void ScribbleArea::setPenColor(const QColor &newColor)   {     myPenColor = newColor; } void ScribbleArea::setPenWidth(int newWidth)   {     myPenWidth = newWidth; } void ScribbleArea::clearImage()   {     image.fill(qRgb(255, 255, 255));     modified = true;     update(); } void ScribbleArea::mousePressEvent(QMouseEvent *event)   {     if (event->button() == Qt::LeftButton) {         lastPoint = event->pos();         scribbling = true;     } } void ScribbleArea::mouseMoveEvent(QMouseEvent *event) {     if ((event->buttons() & Qt::LeftButton) && scribbling)         drawLineTo(event->pos()); } void ScribbleArea::mouseReleaseEvent(QMouseEvent *event) {     if (event->button() == Qt::LeftButton && scribbling) {         drawLineTo(event->pos());         scribbling = false;     } }   void ScribbleArea::paintEvent(QPaintEvent * /* event */)   {     QPainter painter(this);     painter.drawImage(QPoint(0, 0), image); } void ScribbleArea::resizeEvent(QResizeEvent *event)   {     if (width() > image.width() || height() > image.height()) {         int newWidth = qMax(width() + 128, image.width());         int newHeight = qMax(height() + 128, image.height());         resizeImage(&image, QSize(newWidth, newHeight));         update();     }     QWidget::resizeEvent(event); } void ScribbleArea::drawLineTo(const QPoint &endPoint)   {     QPainter painter(&image);     painter.setPen(QPen(myPenColor, myPenWidth, Qt::SolidLine, Qt::RoundCap,                         Qt::RoundJoin));     painter.drawLine(lastPoint, endPoint);     modified = true;     int rad = (myPenWidth / 2) + 2;     update(QRect(lastPoint, endPoint).normalized()                                      .adjusted(-rad, -rad, +rad, +rad));     lastPoint = endPoint; } void ScribbleArea::resizeImage(QImage *image, const QSize &newSize)   {     if (image->size() == newSize)         return;     QImage newImage(newSize, QImage::Format_RGB32);     newImage.fill(qRgb(255, 255, 255));     QPainter painter(&newImage);     painter.drawImage(QPoint(0, 0), *image);     *image = newImage; } void ScribbleArea::print() { #ifndef QT_NO_PRINTER     QPrinter printer(QPrinter::HighResolution);       QPrintDialog *printDialog = new QPrintDialog(&printer, this);       if (printDialog->exec() == QDialog::Accepted) {         QPainter painter(&printer);         QRect rect = painter.viewport();         QSize size = image.size();         size.scale(rect.size(), Qt::KeepAspectRatio);         painter.setViewport(rect.x(), rect.y(), size.width(), size.height());         painter.setWindow(image.rect());         painter.drawImage(0, 0, image);     } #endif // QT_NO_PRINTER } #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QList> #include <QMainWindow> class ScribbleArea; class MainWindow : public QMainWindow {     Q_OBJECT public:     MainWindow(); protected:     void closeEvent(QCloseEvent *event); private slots:     void open();     void save();     void penColor();     void penWidth();     void about(); private:     void createActions();     void createMenus();     bool maybeSave();     bool saveFile(const QByteArray &fileFormat);     ScribbleArea *scribbleArea;     QMenu *saveAsMenu;     QMenu *fileMenu;     QMenu *optionMenu;     QMenu *helpMenu;     QAction *openAct;     QList<QAction *> saveAsActs;     QAction *exitAct;     QAction *penColorAct;     QAction *penWidthAct;     QAction *printAct;     QAction *clearScreenAct;     QAction *aboutAct;     QAction *aboutQtAct; }; #endif #include <QtGui> #include "mainwindow.h" #include "scribblearea.h" MainWindow::MainWindow() {     scribbleArea = new ScribbleArea;     setCentralWidget(scribbleArea);     createActions();     createMenus();     setWindowTitle(tr("Scribble"));     resize(500, 500); } void MainWindow::closeEvent(QCloseEvent *event)   {     if (maybeSave()) {         event->accept();     } else {         event->ignore();     } } void MainWindow::open()   {     if (maybeSave()) {         QString fileName = QFileDialog::getOpenFileName(this,                                    tr("Open File"), QDir::currentPath());         if (!fileName.isEmpty())             scribbleArea->openImage(fileName);     } } void MainWindow::save()   {     QAction *action = qobject_cast<QAction *>(sender());     QByteArray fileFormat = action->data().toByteArray();     saveFile(fileFormat); } void MainWindow::penColor()   {     QColor newColor = QColorDialog::getColor(scribbleArea->penColor());     if (newColor.isValid())         scribbleArea->setPenColor(newColor); } void MainWindow::penWidth()   {     bool ok;     int newWidth = QInputDialog::getInteger(this, tr("Scribble"),                                             tr("Select pen width:"),                                             scribbleArea->penWidth(),                                             1, 50, 1, &ok);     if (ok)         scribbleArea->setPenWidth(newWidth); } void MainWindow::about()   {     QMessageBox::about(this, tr("About Scribble"),             tr("<p>The <b>Scribble</b> example shows how to use QMainWindow as the "                "base widget for an application, and how to reimplement some of "                "QWidget's event handlers to receive the events generated for "                "the application's widgets:</p><p> We reimplement the mouse event "                "handlers to facilitate drawing, the paint event handler to "                "update the application and the resize event handler to optimize "                "the application's appearance. In addition we reimplement the "                "close event handler to intercept the close events before "                "terminating the application.</p><p> The example also demonstrates "                "how to use QPainter to draw an image in real time, as well as "                "to repaint widgets.</p>")); } void MainWindow::createActions()   {     openAct = new QAction(tr("&Open..."), this);     openAct->setShortcut(tr("Ctrl+O"));     connect(openAct, SIGNAL(triggered()), this, SLOT(open()));     foreach (QByteArray format, QImageWriter::supportedImageFormats()) {         QString text = tr("%1...").arg(QString(format).toUpper());         QAction *action = new QAction(text, this);         action->setData(format);         connect(action, SIGNAL(triggered()), this, SLOT(save()));         saveAsActs.append(action);     }     printAct = new QAction(tr("&Print..."), this);     connect(printAct, SIGNAL(triggered()), scribbleArea, SLOT(print()));     exitAct = new QAction(tr("E&xit"), this);     exitAct->setShortcut(tr("Ctrl+Q"));     connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));     penColorAct = new QAction(tr("&Pen Color..."), this);     connect(penColorAct, SIGNAL(triggered()), this, SLOT(penColor()));     penWidthAct = new QAction(tr("Pen &Width..."), this);     connect(penWidthAct, SIGNAL(triggered()), this, SLOT(penWidth()));     clearScreenAct = new QAction(tr("&Clear Screen"), this);     clearScreenAct->setShortcut(tr("Ctrl+L"));     connect(clearScreenAct, SIGNAL(triggered()),             scribbleArea, SLOT(clearImage()));     aboutAct = new QAction(tr("&About"), this);     connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));     aboutQtAct = new QAction(tr("About &Qt"), this);     connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); } void MainWindow::createMenus()   {     saveAsMenu = new QMenu(tr("&Save As"), this);     foreach (QAction *action, saveAsActs)         saveAsMenu->addAction(action);     fileMenu = new QMenu(tr("&File"), this);     fileMenu->addAction(openAct);     fileMenu->addMenu(saveAsMenu);     fileMenu->addAction(printAct);     fileMenu->addSeparator();     fileMenu->addAction(exitAct);     optionMenu = new QMenu(tr("&Options"), this);     optionMenu->addAction(penColorAct);     optionMenu->addAction(penWidthAct);     optionMenu->addSeparator();     optionMenu->addAction(clearScreenAct);     helpMenu = new QMenu(tr("&Help"), this);     helpMenu->addAction(aboutAct);     helpMenu->addAction(aboutQtAct);     menuBar()->addMenu(fileMenu);     menuBar()->addMenu(optionMenu);     menuBar()->addMenu(helpMenu); } bool MainWindow::maybeSave()   {     if (scribbleArea->isModified()) {        QMessageBox::StandardButton ret;        ret = QMessageBox::warning(this, tr("Scribble"),                           tr("The image has been modified.\n"                              "Do you want to save your changes?"),                           QMessageBox::Save | QMessageBox::Discard         | QMessageBox::Cancel);         if (ret == QMessageBox::Save) {             return saveFile("png");         } else if (ret == QMessageBox::Cancel) {             return false;         }     }     return true; } bool MainWindow::saveFile(const QByteArray &fileFormat)   {     QString initialPath = QDir::currentPath() + "/untitled." + fileFormat;     QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"),                                initialPath,                                tr("%1 Files (*.%2);;All Files (*)")                                .arg(QString(fileFormat.toUpper()))                                .arg(QString(fileFormat)));     if (fileName.isEmpty()) {         return false;     } else {         return scribbleArea->saveImage(fileName, fileFormat);     } } #include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) {     QApplication app(argc, argv);     MainWindow window;     window.show();     return app.exec(); }