feat: action for save image as new file with different format

This commit is contained in:
2026-01-18 12:02:30 +08:00
parent 4948ea7445
commit 5b2255e903
4 changed files with 76 additions and 0 deletions

View File

@@ -55,6 +55,7 @@ void ActionManager::setupAction(MainWindow *mainWindow)
CREATE_NEW_ACTION(mainWindow, actionAnimationNextFrame);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionOpen, document-open);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionSaveAs, document-save-as);
CREATE_NEW_ACTION(mainWindow, actionHorizontalFlip);
CREATE_NEW_ACTION(mainWindow, actionFitInView);
CREATE_NEW_ACTION(mainWindow, actionFitByWidth);
@@ -84,6 +85,7 @@ void ActionManager::retranslateUi(MainWindow *mainWindow)
Q_UNUSED(mainWindow);
actionOpen->setText(QCoreApplication::translate("MainWindow", "&Open...", nullptr));
actionSaveAs->setText(QCoreApplication::translate("MainWindow", "Save &As...", nullptr));
actionActualSize->setText(QCoreApplication::translate("MainWindow", "Actual size", nullptr));
actionToggleMaximize->setText(QCoreApplication::translate("MainWindow", "Toggle maximize", nullptr));
@@ -129,6 +131,7 @@ void ActionManager::retranslateUi(MainWindow *mainWindow)
void ActionManager::setupShortcuts()
{
actionOpen->setShortcut(QKeySequence::Open);
actionSaveAs->setShortcut(QKeySequence::SaveAs);
actionActualSize->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
actionZoomIn->setShortcut(QKeySequence::ZoomIn);
actionZoomOut->setShortcut(QKeySequence::ZoomOut);

View File

@@ -23,6 +23,7 @@ public:
public:
QAction *actionOpen;
QAction *actionSaveAs;
QAction *actionActualSize;
QAction *actionToggleMaximize;

View File

@@ -38,6 +38,7 @@
#include <QProcess>
#include <QDesktopServices>
#include <QMessageBox>
#include <QImageWriter>
#ifdef HAVE_QTDBUS
#include <QDBusInterface>
@@ -504,6 +505,12 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event)
menu->addAction(paste);
}
#if 0
if (currentFileUrl.isValid()) {
menu->addAction(m_am->actionSaveAs);
}
#endif // 0
menu->addSeparator();
menu->addAction(m_am->actionHorizontalFlip);
@@ -696,6 +703,70 @@ void MainWindow::on_actionOpen_triggered()
}
}
void MainWindow::on_actionSaveAs_triggered()
{
QUrl currentFileUrl = currentImageFileUrl();
if (!currentFileUrl.isValid()) {
QMessageBox::warning(this, tr("Save As"), tr("No image is currently open."));
return;
}
QStringList supportedFormats;
QStringList nameFilters;
const QList<QByteArray> imageFormats = QImageWriter::supportedImageFormats();
for (const QByteArray &format : imageFormats) {
QString formatStr = QString::fromLatin1(format).toLower();
if (!formatStr.isEmpty()) {
supportedFormats << formatStr;
nameFilters << tr("%1 Image (*.%2)").arg(formatStr.toUpper(), formatStr);
}
}
if (imageFormats.isEmpty()) {
QMessageBox::warning(this, tr("Save As"),
tr("No supported image formats are available."));
return;
}
QString selectedFilter;
QString saveFilePath = QFileDialog::getSaveFileName(this,
tr("Save As"),
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation),
nameFilters.join(";;"),
&selectedFilter);
if (saveFilePath.isEmpty()) {
return; // User cancelled
}
// Ensure the file has the correct extension
QString expectedExtension;
const int filterIndex = nameFilters.indexOf(selectedFilter);
if (filterIndex != -1) {
expectedExtension = supportedFormats.at(filterIndex);
}
if (!expectedExtension.isEmpty() && !saveFilePath.endsWith('.' + expectedExtension, Qt::CaseInsensitive)) {
saveFilePath += '.' + expectedExtension;
}
// Save the image
QImageReader imageReader(currentFileUrl.toLocalFile());
imageReader.setAutoTransform(true);
imageReader.setDecideFormatFromContent(true);
imageReader.setAllocationLimit(0);
QImage img(imageReader.read());
QImageWriter writer(saveFilePath);
writer.setFormat(expectedExtension.toLatin1());
if (!writer.write(img)) {
QMessageBox::warning(this, tr("Save As"),
tr("Failed to save image: %1").arg(writer.errorString()));
return;
}
}
void MainWindow::on_actionActualSize_triggered()
{
m_graphicsView->resetScale();

View File

@@ -75,6 +75,7 @@ protected:
private slots:
void on_actionOpen_triggered();
void on_actionSaveAs_triggered();
void on_actionActualSize_triggered();
void on_actionToggleMaximize_triggered();