File indexing completed on 2024-04-21 04:41:39

0001 /*
0002  * SPDX-FileCopyrightText: (C) 2020 Carl Schwan <carl@carlschwan.eu>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-or-later
0005  */
0006 
0007 #include "imagedocument.h"
0008 
0009 #include "commands/cropcommand.h"
0010 #include "commands/mirrorcommand.h"
0011 #include "commands/resizecommand.h"
0012 #include "commands/rotatecommand.h"
0013 #include "commands/undocommand.h"
0014 
0015 #include <QDebug>
0016 #include <QFile>
0017 #include <QImage>
0018 #include <QString>
0019 #include <QUrl>
0020 
0021 ImageDocument::ImageDocument(QObject *parent)
0022     : QObject(parent)
0023 {
0024     connect(this, &ImageDocument::pathChanged, this, [this](const QUrl &url) {
0025         m_image = QImage(url.isLocalFile() ? url.toLocalFile() : url.toString());
0026         m_edited = false;
0027         Q_EMIT editedChanged();
0028         Q_EMIT imageChanged();
0029     });
0030 }
0031 
0032 void ImageDocument::cancel()
0033 {
0034     while (!m_undos.empty()) {
0035         const auto command = m_undos.pop();
0036         m_image = command->undo(m_image);
0037         delete command;
0038     }
0039     setEdited(false);
0040     Q_EMIT imageChanged();
0041 }
0042 
0043 QImage ImageDocument::image() const
0044 {
0045     return m_image;
0046 }
0047 
0048 bool ImageDocument::edited() const
0049 {
0050     return m_edited;
0051 }
0052 
0053 void ImageDocument::undo()
0054 {
0055     Q_ASSERT(!m_undos.empty());
0056     const auto command = m_undos.pop();
0057     m_image = command->undo(m_image);
0058     delete command;
0059     Q_EMIT imageChanged();
0060     if (m_undos.empty()) {
0061         setEdited(false);
0062     }
0063 }
0064 
0065 void ImageDocument::crop(int x, int y, int width, int height)
0066 {
0067     const auto command = new CropCommand(QRect(x, y, width, height));
0068     m_image = command->redo(m_image);
0069     m_undos.append(command);
0070     setEdited(true);
0071     Q_EMIT imageChanged();
0072 }
0073 
0074 void ImageDocument::resize(int width, int height)
0075 {
0076     const auto command = new ResizeCommand(QSize(width, height));
0077     m_image = command->redo(m_image);
0078     m_undos.append(command);
0079     setEdited(true);
0080     Q_EMIT imageChanged();
0081 }
0082 
0083 void ImageDocument::mirror(bool horizontal, bool vertical)
0084 {
0085     const auto command = new MirrorCommand(horizontal, vertical);
0086     m_image = command->redo(m_image);
0087     m_undos.append(command);
0088     setEdited(true);
0089     Q_EMIT imageChanged();
0090 }
0091 
0092 void ImageDocument::rotate(int angle)
0093 {
0094     QTransform transform;
0095     transform.rotate(angle);
0096     const auto command = new RotateCommand(transform);
0097     m_image = command->redo(m_image);
0098     m_undos.append(command);
0099     setEdited(true);
0100     Q_EMIT imageChanged();
0101 }
0102 
0103 void ImageDocument::setEdited(bool value)
0104 {
0105     if (m_edited == value) {
0106         return;
0107     }
0108 
0109     m_edited = value;
0110     Q_EMIT editedChanged();
0111 }
0112 
0113 bool ImageDocument::save()
0114 {
0115     return m_image.save(m_path.isLocalFile() ? m_path.toLocalFile() : m_path.toString());
0116 }
0117 
0118 bool ImageDocument::saveAs(const QUrl &location)
0119 {
0120     return m_image.save(location.isLocalFile() ? location.toLocalFile() : location.toString());
0121 }
0122 
0123 QUrl ImageDocument::path() const
0124 {
0125     return m_path;
0126 }
0127 
0128 void ImageDocument::setPath(const QUrl &path)
0129 {
0130     m_path = path;
0131     Q_EMIT pathChanged(path);
0132 }
0133 
0134 #include "moc_imagedocument.cpp"