Skip to content

Commit

Permalink
Rework export dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
peterspackman committed Aug 27, 2024
1 parent 27a44a7 commit 68fc7f8
Show file tree
Hide file tree
Showing 7 changed files with 446 additions and 25 deletions.
61 changes: 36 additions & 25 deletions src/crystalx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "crystalx.h"
#include "dialoghtml.h"
#include "elementdata.h"
#include "exportdialog.h"
#include "infodocuments.h"
#include "isosurface_calculator.h"
#include "mathconstants.h"
Expand Down Expand Up @@ -877,10 +878,8 @@ void Crystalx::loadExternalFileData(QString filename) {
showStatusMessage(
QString("Loading crystal clear output from %1").arg(filename));
project->loadCrystalClearJson(filename);
}
else if(filename.endsWith("surface.json")) {
showStatusMessage(
QString("Loading crystal surface from %1").arg(filename));
} else if (filename.endsWith("surface.json")) {
showStatusMessage(QString("Loading crystal surface from %1").arg(filename));
project->loadCrystalClearSurfaceJson(filename);
} else if (extension == CIF_EXTENSION || extension == CIF2_EXTENSION) {
processCif(filename);
Expand Down Expand Up @@ -1441,29 +1440,38 @@ void Crystalx::exportAs() {
if (!project->currentScene())
return;

QString filter = "Portable Network Graphics (*.png);;POV-ray (*.pov)";
QFileInfo fi(project->currentScene()->title());
QString suggestedFilename = fi.baseName() + ".png";
QString filename = QFileDialog::getSaveFileName(0, tr("Export graphics"),
suggestedFilename, filter);

bool success = false;
if (filename.isEmpty())
return;
ExportDialog dialog(this);
QImage previewImage = glWindow->renderToImage(1);
dialog.updateImage(previewImage);
dialog.updateFilePath(suggestedFilename);
dialog.updateBackgroundColor(glWindow->backgroundColor());

if (filename.toLower().endsWith(".png")) {
QImage img = glWindow->renderToImage(1);
success = img.save(filename);
} else {
QFile outputFile(filename);
outputFile.open(QIODevice::WriteOnly);
if (outputFile.isOpen()) {
QTextStream outStream(&outputFile);
success = glWindow->renderToPovRay(outStream);
QString filename{""};
bool success = false;
if (dialog.exec() == QDialog::Accepted) {
// The user clicked OK
filename = dialog.currentFilePath();
int scaleFactor = dialog.currentResolutionScale();
QColor backgroundColor = dialog.currentBackgroundColor();

if (filename.toLower().endsWith(".png")) {
QImage img = glWindow->exportToImage(scaleFactor, backgroundColor);
qDebug() << "Exporting image with scale factor" << scaleFactor << "resolution" << img.size();
success = img.save(filename);
} else {
QFile outputFile(filename);
outputFile.open(QIODevice::WriteOnly);
if (outputFile.isOpen()) {
QTextStream outStream(&outputFile);
success = glWindow->renderToPovRay(outStream);
}
}
}

if (success) {
if (!filename.isEmpty()) {
showStatusMessage("Saved current graphics state to " + filename);
}
}
Expand Down Expand Up @@ -1970,11 +1978,14 @@ void Crystalx::showEnergyFrameworkDialog() {
Scene *scene = project->currentScene();
if (!scene)
return;
auto * structure = scene->chemicalStructure();
if(!structure) return;
auto * interactions = structure->pairInteractions();
if(!interactions) return;
if(!interactions->haveInteractions()) return;
auto *structure = scene->chemicalStructure();
if (!structure)
return;
auto *interactions = structure->pairInteractions();
if (!interactions)
return;
if (!interactions->haveInteractions())
return;

if (childPropertyController) {
childPropertyController->setCurrentPairInteractions(interactions);
Expand Down
2 changes: 2 additions & 0 deletions src/dialogs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ qt_wrap_ui(DIALOG_UI_HEADERS
"${CMAKE_CURRENT_SOURCE_DIR}/closecontactsdialog.ui"
"${CMAKE_CURRENT_SOURCE_DIR}/depthfadingandclippingdialog.ui"
"${CMAKE_CURRENT_SOURCE_DIR}/elementeditor.ui"
"${CMAKE_CURRENT_SOURCE_DIR}/exportdialog.ui"
"${CMAKE_CURRENT_SOURCE_DIR}/energycalculationdialog.ui"
"${CMAKE_CURRENT_SOURCE_DIR}/fingerprintoptions.ui"
"${CMAKE_CURRENT_SOURCE_DIR}/fileeditor.ui"
Expand All @@ -27,6 +28,7 @@ qt_add_library(cx_dialogs STATIC
"${CMAKE_CURRENT_SOURCE_DIR}/depthfadingandclippingdialog.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/elementeditor.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/energycalculationdialog.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/exportdialog.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/fingerprintoptions.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/fingerprintplot.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/fingerprintwindow.cpp"
Expand Down
158 changes: 158 additions & 0 deletions src/dialogs/exportdialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#include "exportdialog.h"
#include "ui_exportdialog.h"
#include <QColorDialog>
#include <QFileDialog>
#include <QMessageBox>
#include <QPainter>
#include <QResizeEvent>

ExportDialog::ExportDialog(QWidget *parent)
: QDialog(parent), ui(new Ui::ExportDialog) {
ui->setupUi(this);
QStringList resolutionOptions{"1x", "2x", "3x", "4x"};
ui->resolutionScaleComboBox->addItems(resolutionOptions);
ui->resolutionScaleComboBox->setCurrentText("1x");
initConnections();
}

ExportDialog::~ExportDialog() { delete ui; }

void ExportDialog::initConnections() {
connect(ui->destinationBrowseButton, &QPushButton::clicked, this,
&ExportDialog::selectFile);
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(ui->resolutionScaleComboBox, &QComboBox::currentIndexChanged, this,
&ExportDialog::updateResolutionLabel);
connect(ui->backgroundColorToolButton, &QAbstractButton::clicked, [&]() {
QColor color = QColorDialog::getColor(currentBackgroundColor(), this,
"Set Background Color for Export",
QColorDialog::ShowAlphaChannel);
if (color.isValid()) {
updateBackgroundColor(color);
}
});
}

int ExportDialog::currentResolutionScale() const {
QString currentText = ui->resolutionScaleComboBox->currentText();
// Remove the 'x' at the end of the string
currentText = currentText.remove(currentText.length() - 1, 1);
bool conversionOk{false};
int scale = currentText.toInt(&conversionOk);

if (!conversionOk) {
qWarning() << "Failed to convert resolution scale text to float: "
<< currentText;
return 1; // Default to 1x if conversion fails
}
return scale;
}

void ExportDialog::updateResolutionLabel() {
int scale = currentResolutionScale();
if (m_currentPixmap.isNull()) {
ui->resolutionLabel->setText("N/A");
return;
}
QSize originalSize = m_currentPixmap.size();

int newWidth = originalSize.width() * scale;
int newHeight = originalSize.height() * scale;

QString resolutionText = QString("%1 x %2 px").arg(newWidth).arg(newHeight);

ui->resolutionLabel->setText(resolutionText);
}

void ExportDialog::updateFilePath(QString path) {
m_currentFilePath = path;
ui->destinationLineEdit->setText(path);
}

QColor ExportDialog::currentBackgroundColor() const {
return m_currentBackgroundColor;
}

void ExportDialog::updateBackgroundColor(const QColor &color) {
m_currentBackgroundColor = color;
auto *button = ui->backgroundColorToolButton;
QPixmap pixmap = QPixmap(button->iconSize());
pixmap.fill(color);
button->setIcon(QIcon(pixmap));
}

void ExportDialog::selectFile() {
QString filter = "Portable Network Graphics (*.png);; POV-ray (*.pov)";
QString filePath = QFileDialog::getSaveFileName(this, tr("Export graphics"),
m_currentFilePath, filter);

if (!filePath.isEmpty()) {
m_currentFilePath = filePath;
updateFilePath(filePath);
updatePreview();
}
}

void ExportDialog::updateImage(const QImage &image) {
bool success = m_currentPixmap.convertFromImage(image);
qDebug() << "Loaded pixmap from image";
updatePreview();
}

void ExportDialog::resizeEvent(QResizeEvent *event) {
QDialog::resizeEvent(event);
qDebug() << "Dialog resized to:" << event->size();
updatePreview();
}

void ExportDialog::updatePreview() {
auto *label = ui->pixmapDisplayLabel;

qDebug() << "Dialog size:" << this->size();
qDebug() << "Label size:" << label->size();
qDebug() << "Label minimum size:" << label->minimumSize();
qDebug() << "Label maximum size:" << label->maximumSize();
qDebug() << "Label size policy:" << label->sizePolicy().horizontalPolicy()
<< label->sizePolicy().verticalPolicy();

if (m_currentPixmap.isNull()) {
qDebug() << "Current pixmap is null";
label->setText("No image to preview");
return;
}

QSize labelSize = label->size();
QPixmap scaledPixmap = m_currentPixmap.scaled(labelSize, Qt::KeepAspectRatio,
Qt::SmoothTransformation);

QPixmap background(labelSize);
background.fill(QColor::fromRgb(255, 255, 255, 0));

// Create a painter to draw on the background
QPainter painter(&background);

// Calculate position to center the scaled pixmap
int x = (labelSize.width() - scaledPixmap.width()) / 2;
int y = (labelSize.height() - scaledPixmap.height()) / 2;

// Draw the scaled pixmap onto the background
painter.drawPixmap(x, y, scaledPixmap);

// Set the final composited pixmap to the label
label->setPixmap(background);
qDebug() << "Original pixmap size:" << m_currentPixmap.size();
qDebug() << "Scaled pixmap size:" << scaledPixmap.size();
updateResolutionLabel();
}

void ExportDialog::accept() {
if (m_currentFilePath.isEmpty()) {
QMessageBox::warning(this, "Warning", "Please select a destination file.");
return; // Don't accept yet
}

QDialog::accept();
}

void ExportDialog::reject() { QDialog::reject(); }
42 changes: 42 additions & 0 deletions src/dialogs/exportdialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once
#include <QDialog>
#include <QImage>

namespace Ui {
class ExportDialog;
}

class ExportDialog : public QDialog {
Q_OBJECT

public:
explicit ExportDialog(QWidget *parent = nullptr);
~ExportDialog();

QString currentFilePath() const { return m_currentFilePath; }
int currentResolutionScale() const;
QColor currentBackgroundColor() const;

public slots:
void updateImage(const QImage &);
void updateFilePath(QString);
void updateBackgroundColor(const QColor &);

void accept() override;
void reject() override;

private slots:
void updateResolutionLabel();
void selectFile();
void updatePreview();

protected:
void resizeEvent(QResizeEvent *event) override;

private:
QString m_currentFilePath{"destination.png"};
QPixmap m_currentPixmap;
QColor m_currentBackgroundColor{Qt::white};
void initConnections();
Ui::ExportDialog *ui;
};
Loading

0 comments on commit 68fc7f8

Please sign in to comment.