mirror of
https://github.com/riuson/lcd-image-converter.git
synced 2026-03-06 16:17:00 +01:00
495 lines
15 KiB
C++
495 lines
15 KiB
C++
/*
|
|
* LCD Image Converter. Converts images and fonts for embedded applications.
|
|
* Copyright (C) 2012 riuson
|
|
* mailto: riuson@gmail.com
|
|
*
|
|
* This program 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/
|
|
*/
|
|
|
|
#include "actionfilehandlers.h"
|
|
|
|
#include <QDir>
|
|
#include <QFileDialog>
|
|
#include <QFileInfo>
|
|
#include <QInputDialog>
|
|
#include <QLineEdit>
|
|
#include <QMap>
|
|
#include <QStringList>
|
|
#include <QTextStream>
|
|
|
|
#include "datacontainer.h"
|
|
#include "dialogfontselect.h"
|
|
#include "editortabfont.h"
|
|
#include "editortabimage.h"
|
|
#include "filedialogoptions.h"
|
|
#include "fontparameters.h"
|
|
#include "idocument.h"
|
|
#include "imainwindow.h"
|
|
#include "parser.h"
|
|
#include "preset.h"
|
|
#include "widgetbitmapeditor.h"
|
|
|
|
namespace AppUI
|
|
{
|
|
namespace MenuHandlers
|
|
{
|
|
|
|
ActionFileHandlers::ActionFileHandlers(QObject* parent) : ActionHandlersBase(parent) {}
|
|
|
|
void ActionFileHandlers::newImage_triggered()
|
|
{
|
|
bool ok;
|
|
QString name = QInputDialog::getText(this->mMainWindow->parentWidget(), tr("Enter image name"), tr("Image name:"),
|
|
QLineEdit::Normal, QString("Image"), &ok);
|
|
|
|
if (ok) {
|
|
AppUI::Images::EditorTabImage* ed = new AppUI::Images::EditorTabImage(this->mMainWindow->parentWidget());
|
|
this->connect(ed, SIGNAL(documentChanged()), SLOT(documentChanged()));
|
|
|
|
emit this->tabCreated(ed);
|
|
|
|
name = this->mMainWindow->findAvailableName(name);
|
|
ed->document()->setDocumentName(name);
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::newFont_triggered()
|
|
{
|
|
bool ok;
|
|
QString name = QInputDialog::getText(this->mMainWindow->parentWidget(), tr("Enter font name"), tr("Font name:"),
|
|
QLineEdit::Normal, QString("Font"), &ok);
|
|
|
|
if (ok) {
|
|
AppUI::Fonts::DialogFontSelect dialog(this->mMainWindow->parentWidget());
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
AppUI::Fonts::EditorTabFont* ed = new AppUI::Fonts::EditorTabFont(this->mMainWindow->parentWidget());
|
|
this->connect(ed, SIGNAL(documentChanged()), SLOT(documentChanged()));
|
|
|
|
ed->document()->beginChanges();
|
|
|
|
QString chars = dialog.characters();
|
|
Data::Containers::FontParameters parameters;
|
|
dialog.getFontParameters(¶meters);
|
|
|
|
ed->setFontCharacters(chars, parameters);
|
|
|
|
emit this->tabCreated(ed);
|
|
|
|
name = this->mMainWindow->findAvailableName(name);
|
|
ed->document()->setDocumentName(name);
|
|
|
|
ed->document()->endChanges(true);
|
|
ed->document()->dataContainer()->historyInit();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::open_triggered()
|
|
{
|
|
QFileDialog dialog(this->mMainWindow->parentWidget());
|
|
dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
|
dialog.setDirectory(Settings::FileDialogOptions::directory(Settings::FileDialogOptions::Dialogs::OpenDocument));
|
|
dialog.setFileMode(QFileDialog::ExistingFiles);
|
|
dialog.setWindowTitle(tr("Open xml or image file"));
|
|
|
|
QStringList filters;
|
|
filters << tr("XML Files (*.xml)")
|
|
<< tr("Images (*.bmp *.gif *.jpg *.jpeg *.png *.pbm *.pgm *.ppm *.tiff *.xbm *.xpm)");
|
|
dialog.setNameFilters(filters);
|
|
dialog.selectNameFilter(filters.at(
|
|
Settings::FileDialogOptions::filterIndex(Settings::FileDialogOptions::Dialogs::OpenDocument) < filters.count()
|
|
? Settings::FileDialogOptions::filterIndex(Settings::FileDialogOptions::Dialogs::OpenDocument)
|
|
: 0));
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
QStringList filenames = dialog.selectedFiles();
|
|
Settings::FileDialogOptions::setDirectory(Settings::FileDialogOptions::Dialogs::OpenDocument,
|
|
dialog.directory().absolutePath());
|
|
Settings::FileDialogOptions::setFilterIndex(Settings::FileDialogOptions::Dialogs::OpenDocument,
|
|
filters.indexOf(dialog.selectedNameFilter()));
|
|
|
|
this->openFiles(filenames);
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::rename_triggered()
|
|
{
|
|
bool ok;
|
|
IEditor* editor = this->editor();
|
|
|
|
if (editor != nullptr) {
|
|
QString name = QInputDialog::getText(this->mMainWindow->parentWidget(), tr("Rename"), tr("New name:"),
|
|
QLineEdit::Normal, editor->document()->documentName(), &ok);
|
|
|
|
if (ok) {
|
|
editor->document()->setDocumentName(name);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::save_triggered()
|
|
{
|
|
IEditor* editor = this->editor();
|
|
|
|
if (editor != nullptr) {
|
|
if (QFile::exists(editor->document()->documentFilename())) {
|
|
editor->document()->save(editor->document()->documentFilename());
|
|
} else {
|
|
this->saveAs_triggered();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::saveAs_triggered()
|
|
{
|
|
IEditor* editor = this->editor();
|
|
|
|
if (editor != nullptr) {
|
|
QFileDialog dialog(this->mMainWindow->parentWidget());
|
|
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
|
dialog.setFileMode(QFileDialog::AnyFile);
|
|
dialog.setNameFilter(tr("XML Files (*.xml)"));
|
|
dialog.setDefaultSuffix(QString("xml"));
|
|
dialog.setWindowTitle(tr("Save file as"));
|
|
|
|
QFileInfo outputFile(editor->document()->documentFilename());
|
|
|
|
if (outputFile.exists()) {
|
|
dialog.setDirectory(outputFile.dir());
|
|
} else {
|
|
dialog.setDirectory(Settings::FileDialogOptions::directory(Settings::FileDialogOptions::Dialogs::SaveDocument));
|
|
}
|
|
|
|
if (editor->document()->documentFilename().isEmpty()) {
|
|
dialog.selectFile(editor->document()->documentName());
|
|
} else {
|
|
dialog.selectFile(editor->document()->documentFilename());
|
|
}
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
Settings::FileDialogOptions::setDirectory(Settings::FileDialogOptions::Dialogs::SaveDocument,
|
|
dialog.directory().absolutePath());
|
|
QString filename = dialog.selectedFiles().at(0);
|
|
editor->document()->save(filename);
|
|
|
|
emit this->rememberFilename(filename);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::close_triggered() { emit closeRequest(this->mMainWindow->currentTab()); }
|
|
|
|
void ActionFileHandlers::closeAll_triggered()
|
|
{
|
|
QList<QWidget*> list;
|
|
|
|
this->mMainWindow->tabsList(&list);
|
|
|
|
for (int i = 0; i < list.count(); i++) {
|
|
emit closeRequest(list.at(i));
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::convert_triggered()
|
|
{
|
|
IEditor* editor = this->mMainWindow->currentEditor();
|
|
|
|
if (editor != nullptr) {
|
|
this->convertDocument(editor->document(), true);
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::convertAll_triggered()
|
|
{
|
|
QList<QWidget*> list;
|
|
|
|
this->mMainWindow->tabsList(&list);
|
|
|
|
for (int i = 0; i < list.count(); i++) {
|
|
IEditor* editor = dynamic_cast<IEditor*>(list.at(i));
|
|
|
|
if (editor != nullptr) {
|
|
this->convertDocument(editor->document(), false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::openFiles(const QStringList& filenames)
|
|
{
|
|
QList<QWidget*> existingTabs;
|
|
this->mMainWindow->tabsList(&existingTabs);
|
|
QMap<QString, QWidget*> existingFilesInEditors;
|
|
QString lastExistingFile;
|
|
|
|
for (int i = 0; i < existingTabs.count(); i++) {
|
|
IEditor* editor = dynamic_cast<IEditor*>(existingTabs.at(i));
|
|
|
|
if (editor != nullptr) {
|
|
existingFilesInEditors.insert(editor->document()->documentFilename(), existingTabs.at(i));
|
|
}
|
|
}
|
|
|
|
// binary image
|
|
QStringList filesBinaryImage;
|
|
{
|
|
QStringList imageExtensions;
|
|
imageExtensions << "bmp" << "gif" << "jpg" << "jpeg" << "png" << "pbm" << "pgm" << "ppm" << "tiff" << "xbm"
|
|
<< "xpm";
|
|
|
|
foreach (const QString& filename, filenames) {
|
|
QFileInfo info(filename);
|
|
|
|
if (info.exists() && imageExtensions.contains(info.suffix().toLower())) {
|
|
filesBinaryImage << filename;
|
|
}
|
|
}
|
|
}
|
|
|
|
// document image
|
|
QStringList filesDocumentImage;
|
|
{
|
|
foreach (const QString& filename, filenames) {
|
|
QFileInfo info(filename);
|
|
|
|
if (info.exists() && info.suffix().toLower() == "xml" && !existingFilesInEditors.contains(filename)) {
|
|
QFile file(filename);
|
|
|
|
if (file.open(QIODevice::ReadWrite)) {
|
|
QTextStream stream(&file);
|
|
QRegExp regImage("<data.+type=\"image\"", Qt::CaseInsensitive);
|
|
|
|
while (!stream.atEnd()) {
|
|
QString readedLine = stream.readLine();
|
|
|
|
if (readedLine.contains(regImage)) {
|
|
filesDocumentImage << filename;
|
|
break;
|
|
}
|
|
}
|
|
|
|
file.close();
|
|
}
|
|
} else if (existingFilesInEditors.keys().contains(filename)) {
|
|
lastExistingFile = filename;
|
|
}
|
|
}
|
|
}
|
|
|
|
// document font
|
|
QStringList filesDocumentFont;
|
|
{
|
|
foreach (const QString& filename, filenames) {
|
|
QFileInfo info(filename);
|
|
|
|
if (info.exists() && info.suffix().toLower() == "xml" && !existingFilesInEditors.contains(filename)) {
|
|
QFile file(filename);
|
|
|
|
if (file.open(QIODevice::ReadWrite)) {
|
|
QTextStream stream(&file);
|
|
QRegExp regFont("<data.+type=\"font\"", Qt::CaseInsensitive);
|
|
|
|
while (!stream.atEnd()) {
|
|
QString readedLine = stream.readLine();
|
|
|
|
if (readedLine.contains(regFont)) {
|
|
filesDocumentFont << filename;
|
|
break;
|
|
}
|
|
}
|
|
|
|
file.close();
|
|
}
|
|
} else if (existingFilesInEditors.keys().contains(filename)) {
|
|
lastExistingFile = filename;
|
|
}
|
|
}
|
|
}
|
|
|
|
this->openBinaryImage(filesBinaryImage);
|
|
this->openImage(filesDocumentImage);
|
|
this->openFont(filesDocumentFont);
|
|
|
|
if (existingFilesInEditors.contains(lastExistingFile)) {
|
|
this->tabSelect(existingFilesInEditors.value(lastExistingFile));
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::openFile(const QString& filename)
|
|
{
|
|
QStringList files = QStringList() << filename;
|
|
this->openFiles(files);
|
|
}
|
|
|
|
void ActionFileHandlers::openImage(QImage* image, const QString& documentName)
|
|
{
|
|
AppUI::Images::EditorTabImage* ed = new AppUI::Images::EditorTabImage(this->mMainWindow->parentWidget());
|
|
this->connect(ed, SIGNAL(documentChanged()), SLOT(documentChanged()));
|
|
|
|
QString name = this->mMainWindow->findAvailableName(documentName);
|
|
|
|
// assign image
|
|
{
|
|
QStringList keys = ed->selectedKeys();
|
|
|
|
QStringListIterator iterator(keys);
|
|
|
|
while (iterator.hasNext()) {
|
|
QString key = iterator.next();
|
|
ed->document()->dataContainer()->setImage(key, image);
|
|
}
|
|
}
|
|
|
|
ed->document()->setDocumentName(name);
|
|
|
|
emit this->tabCreated(ed);
|
|
}
|
|
|
|
void ActionFileHandlers::openBinaryImage(const QStringList& filenames)
|
|
{
|
|
foreach (const QString& filename, filenames) {
|
|
QFileInfo info(filename);
|
|
|
|
QImage imageLoaded;
|
|
|
|
if (info.exists() && imageLoaded.load(filename)) {
|
|
QImage imageConverted = imageLoaded.convertToFormat(QImage::Format_ARGB32);
|
|
|
|
AppUI::Images::EditorTabImage* ed = new AppUI::Images::EditorTabImage(this->mMainWindow->parentWidget());
|
|
this->connect(ed, SIGNAL(documentChanged()), SLOT(documentChanged()));
|
|
|
|
QString name = this->mMainWindow->findAvailableName(info.baseName());
|
|
|
|
// assign image
|
|
{
|
|
QStringList keys = ed->selectedKeys();
|
|
|
|
QStringListIterator iterator(keys);
|
|
|
|
while (iterator.hasNext()) {
|
|
QString key = iterator.next();
|
|
ed->document()->dataContainer()->setImage(key, &imageConverted);
|
|
}
|
|
}
|
|
|
|
emit this->tabCreated(ed);
|
|
ed->document()->setDocumentName(name);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::openImage(const QStringList& filenames)
|
|
{
|
|
foreach (const QString& filename, filenames) {
|
|
AppUI::Images::EditorTabImage* ed = new AppUI::Images::EditorTabImage(this->mMainWindow->parentWidget());
|
|
this->connect(ed, SIGNAL(documentChanged()), SLOT(documentChanged()));
|
|
|
|
emit this->tabCreated(ed);
|
|
ed->document()->load(filename);
|
|
emit this->rememberFilename(filename);
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::openFont(const QStringList& filenames)
|
|
{
|
|
foreach (const QString& filename, filenames) {
|
|
AppUI::Fonts::EditorTabFont* ed = new AppUI::Fonts::EditorTabFont(this->mMainWindow->parentWidget());
|
|
this->connect(ed, SIGNAL(documentChanged()), SLOT(documentChanged()));
|
|
|
|
emit this->tabCreated(ed);
|
|
ed->document()->load(filename);
|
|
emit this->rememberFilename(filename);
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::convertDocument(Data::Containers::IDocument* document, bool request)
|
|
{
|
|
// converter output file name
|
|
QString outputFileName = document->outputFilename();
|
|
|
|
// document file name
|
|
QString documentFileName = document->documentFilename();
|
|
|
|
// if file name not specified, show dialog
|
|
bool outputFilenameNotSpecified = outputFileName.isEmpty();
|
|
|
|
// if document not saved, do not save output file name
|
|
bool documentFilenameNotSpecified = documentFileName.isEmpty();
|
|
|
|
// show dialog
|
|
if (request || outputFilenameNotSpecified) {
|
|
QFileDialog dialog(qobject_cast<QWidget*>(this->parent()));
|
|
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
|
dialog.selectFile(outputFileName);
|
|
dialog.setDirectory(Settings::FileDialogOptions::directory(Settings::FileDialogOptions::Dialogs::ConvertDocument));
|
|
dialog.setFileMode(QFileDialog::AnyFile);
|
|
dialog.setDefaultSuffix(QString("c"));
|
|
dialog.setWindowTitle(tr("Save result file as"));
|
|
|
|
QStringList filters;
|
|
filters << tr("C source code (*.c)") << tr("C++ source code (*.cpp)") << tr("C/C++ headers (*.h)")
|
|
<< tr("C/C++ files (*.c *.cpp *.h)") << tr("All Files (*.*)");
|
|
dialog.setNameFilters(filters);
|
|
dialog.selectNameFilter(
|
|
filters.at(Settings::FileDialogOptions::filterIndex(Settings::FileDialogOptions::Dialogs::ConvertDocument) <
|
|
filters.count()
|
|
? Settings::FileDialogOptions::filterIndex(Settings::FileDialogOptions::Dialogs::ConvertDocument)
|
|
: 0));
|
|
|
|
if (outputFilenameNotSpecified) {
|
|
dialog.selectFile(document->documentName());
|
|
} else {
|
|
dialog.selectFile(outputFileName);
|
|
}
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
outputFileName = dialog.selectedFiles().at(0);
|
|
Settings::FileDialogOptions::setDirectory(Settings::FileDialogOptions::Dialogs::ConvertDocument,
|
|
dialog.directory().absolutePath());
|
|
Settings::FileDialogOptions::setFilterIndex(Settings::FileDialogOptions::Dialogs::ConvertDocument,
|
|
filters.indexOf(dialog.selectedNameFilter()));
|
|
} else {
|
|
outputFileName = "";
|
|
}
|
|
}
|
|
|
|
// if file name specified, save result
|
|
if (!outputFileName.isEmpty()) {
|
|
QFile file(outputFileName);
|
|
|
|
if (file.open(QFile::WriteOnly)) {
|
|
Settings::Presets::Preset preset;
|
|
preset.load(Settings::Presets::Preset::selectedName());
|
|
|
|
QString result = document->convert(&preset);
|
|
|
|
file.write(result.toUtf8());
|
|
file.close();
|
|
|
|
if ((document->outputFilename() != outputFileName) && !documentFilenameNotSpecified) {
|
|
document->setOutputFilename(outputFileName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ActionFileHandlers::documentChanged()
|
|
{
|
|
QWidget* w = qobject_cast<QWidget*>(sender());
|
|
emit this->tabChanged(w);
|
|
}
|
|
|
|
} // namespace MenuHandlers
|
|
} // namespace AppUI
|