mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-10 06:04:12 +02:00
Drop picture files on a folio to add them
Picture files (png, jpg, bmp, svg) dragged from the file manager onto a folio are added there: the first centred on the drop point, the others cascaded from it, and one undo step removes them all. A picture larger than the visible part of the folio is scaled down to fit it. Files that cannot be used are listed once after the others have been placed, and a drop holding only other files (a .qet project) still reaches the main window, which opens it. The checks a picture must pass before it is embedded in the project move into ImageDrop::load and are now shared by the drop, the add image dialog and the script API: a regular file of at most 10 MB, and at most 64 megapixels, read from the header before any pixel is allocated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "imagedrop.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QImageReader>
|
||||
#include <QMimeData>
|
||||
#include <QUrl>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool isImageFile(const QUrl &url)
|
||||
{
|
||||
if (!url.isLocalFile())
|
||||
return false;
|
||||
const QString suffix = QFileInfo(url.toLocalFile()).suffix().toLower();
|
||||
return ImageDrop::supportedSuffixes().contains(suffix);
|
||||
}
|
||||
|
||||
QString tr(const char *text)
|
||||
{
|
||||
return QCoreApplication::translate("ImageDrop", text);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList ImageDrop::supportedSuffixes()
|
||||
{
|
||||
return {QStringLiteral("png"), QStringLiteral("jpg"), QStringLiteral("jpeg"),
|
||||
QStringLiteral("bmp"), QStringLiteral("svg")};
|
||||
}
|
||||
|
||||
QStringList ImageDrop::imageFiles(const QMimeData *mime)
|
||||
{
|
||||
QStringList files;
|
||||
if (!mime || !mime->hasUrls())
|
||||
return files;
|
||||
for (const QUrl &url : mime->urls())
|
||||
if (isImageFile(url))
|
||||
files << url.toLocalFile();
|
||||
return files;
|
||||
}
|
||||
|
||||
bool ImageDrop::hasOnlyOtherUrls(const QMimeData *mime)
|
||||
{
|
||||
return mime && mime->hasUrls() && imageFiles(mime).isEmpty();
|
||||
}
|
||||
|
||||
QImage ImageDrop::load(const QString &path, QString *error)
|
||||
{
|
||||
auto fail = [error](const QString &message) {
|
||||
if (error)
|
||||
*error = message;
|
||||
return QImage();
|
||||
};
|
||||
|
||||
const QFileInfo info(path);
|
||||
if (!info.isFile())
|
||||
return fail(tr("not a file"));
|
||||
if (info.size() > maxFileBytes)
|
||||
return fail(tr("the file is larger than 10 MB"));
|
||||
|
||||
QImageReader reader(path);
|
||||
const QSize size = reader.size();
|
||||
if (size.isValid() && qint64(size.width()) * size.height() > maxPixels)
|
||||
return fail(tr("the image has too many pixels"));
|
||||
|
||||
const QImage image = reader.read();
|
||||
if (image.isNull())
|
||||
return fail(tr("unable to read the image"));
|
||||
return image;
|
||||
}
|
||||
|
||||
qreal ImageDrop::fitScale(const QSizeF &size, const QSizeF &available)
|
||||
{
|
||||
if (size.isEmpty() || available.isEmpty())
|
||||
return 1.0;
|
||||
const qreal scale = std::min(available.width() * fitMargin / size.width(),
|
||||
available.height() * fitMargin / size.height());
|
||||
return std::min(1.0, scale);
|
||||
}
|
||||
|
||||
QPointF ImageDrop::cascadeOffset(int index)
|
||||
{
|
||||
return QPointF(cascadeStep * index, cascadeStep * index);
|
||||
}
|
||||
Reference in New Issue
Block a user