mirror of
https://github.com/leozide/leocad.git
synced 2026-10-27 06:20:55 +00:00
HTML export saved its transparency option without passing it to image rendering. Select a transparent clear background when enabled and preserve the configured background with fully opaque pixels when disabled. Keep the existing background behavior for other step-image and Save Image callers. Add tooltips, contextual overviews, and Help/F1 support to HTML Export, Submodels, and all three Render modes. Link field labels to matching help and explain export scope, file output, model management, and render controls. Refresh catalog keys and locations while preserving existing translations and review status. Leave the 56 new strings untranslated for the later translation pass. Validation: Qt 6.10 debug build; 16 actual PNG exports covering two steps, solid/gradient backgrounds, transparency on/off, tiled rendering, background colors, retained geometry, and unchanged Save Image behavior; dialog Help/F1, Escape, label-buddy and visual layout checks; catalog coverage for 2,170 active source messages; git diff --check.
302 lines
8.9 KiB
C++
302 lines
8.9 KiB
C++
#include "lc_global.h"
|
|
#include "lc_qutils.h"
|
|
#include "lc_modellistdialog.h"
|
|
#include "ui_lc_modellistdialog.h"
|
|
#include "project.h"
|
|
#include "lc_profile.h"
|
|
#include "lc_model.h"
|
|
|
|
enum class lcModelListRole
|
|
{
|
|
ExistingModel = Qt::UserRole,
|
|
DuplicateModel
|
|
};
|
|
|
|
lcModelListDialog::lcModelListDialog(QWidget* Parent, const std::vector<std::unique_ptr<lcModel>>& Models)
|
|
: QDialog(Parent), ui(new Ui::lcModelListDialog)
|
|
{
|
|
mActiveModelItem = nullptr;
|
|
|
|
ui->setupUi(this);
|
|
lcSetupDialogHelp(this, ui->buttonBox);
|
|
|
|
connect(ui->NewModel, &QPushButton::clicked, this, &lcModelListDialog::NewModelClicked);
|
|
connect(ui->DeleteModel, &QPushButton::clicked, this, &lcModelListDialog::DeleteModelClicked);
|
|
connect(ui->RenameModel, &QPushButton::clicked, this, &lcModelListDialog::RenameModelClicked);
|
|
connect(ui->ExportModel, &QPushButton::clicked, this, &lcModelListDialog::ExportModelClicked);
|
|
connect(ui->DuplicateModel, &QPushButton::clicked, this, &lcModelListDialog::DuplicateModelClicked);
|
|
connect(ui->ModelList, &QListWidget::itemDoubleClicked, this, &lcModelListDialog::ModelListItemDoubleClicked);
|
|
connect(ui->ModelList, &QListWidget::itemSelectionChanged, this, &lcModelListDialog::ModelListItemSelectionChanged);
|
|
|
|
ui->ModelList->setDefaultDropAction(Qt::DropAction::MoveAction);
|
|
ui->ModelList->setDragDropMode(QAbstractItemView::DragDropMode::InternalMove);
|
|
|
|
lcModel* ActiveModel = lcGetActiveProject()->GetActiveModel();
|
|
int ActiveModelIndex = -1;
|
|
|
|
for (const std::unique_ptr<lcModel>& Model : Models)
|
|
{
|
|
QListWidgetItem* Item = new QListWidgetItem(Model->GetProperties().mFileName);
|
|
Item->setData(static_cast<int>(lcModelListRole::ExistingModel), QVariant::fromValue<uintptr_t>((uintptr_t)Model.get()));
|
|
ui->ModelList->addItem(Item);
|
|
|
|
if (Model.get() == ActiveModel)
|
|
ActiveModelIndex = ui->ModelList->count() - 1;
|
|
}
|
|
|
|
if (ActiveModelIndex != -1)
|
|
ui->ModelList->setCurrentRow(ActiveModelIndex);
|
|
|
|
QSettings Settings;
|
|
ui->SetActiveModel->setChecked(Settings.value("Settings/ModelListSetActive", true).toBool());
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
lcModelListDialog::~lcModelListDialog()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
int lcModelListDialog::GetActiveModelIndex() const
|
|
{
|
|
return ui->ModelList->row(mActiveModelItem);
|
|
}
|
|
|
|
std::vector<lcModelListDialogEntry> lcModelListDialog::GetResults() const
|
|
{
|
|
std::vector<lcModelListDialogEntry> Models;
|
|
Models.reserve(ui->ModelList->count());
|
|
|
|
for (int ItemIdx = 0; ItemIdx < ui->ModelList->count(); ItemIdx++)
|
|
{
|
|
QListWidgetItem* Item = ui->ModelList->item(ItemIdx);
|
|
|
|
lcModelListDialogEntry Entry;
|
|
|
|
Entry.Name = Item->text();
|
|
Entry.ExistingModel = reinterpret_cast<lcModel*>(Item->data(static_cast<int>(lcModelListRole::ExistingModel)).value<uintptr_t>());
|
|
Entry.DuplicateSource = reinterpret_cast<lcModel*>(Item->data(static_cast<int>(lcModelListRole::DuplicateModel)).value<uintptr_t>());
|
|
|
|
Models.emplace_back(Entry);
|
|
}
|
|
|
|
return Models;
|
|
}
|
|
|
|
void lcModelListDialog::UpdateButtons()
|
|
{
|
|
int ModelCount = ui->ModelList->count();
|
|
|
|
ui->DeleteModel->setEnabled(ModelCount > 1);
|
|
ui->SetActiveModel->setEnabled(ui->ModelList->currentItem() != nullptr);
|
|
}
|
|
|
|
void lcModelListDialog::accept()
|
|
{
|
|
if (ui->SetActiveModel->isChecked())
|
|
mActiveModelItem = ui->ModelList->currentItem();
|
|
|
|
QSettings Settings;
|
|
Settings.setValue("Settings/ModelListSetActive", ui->SetActiveModel->isChecked());
|
|
|
|
QDialog::accept();
|
|
}
|
|
|
|
void lcModelListDialog::NewModelClicked()
|
|
{
|
|
QStringList ModelNames;
|
|
|
|
for (int ItemIdx = 0; ItemIdx < ui->ModelList->count(); ItemIdx++)
|
|
ModelNames.append(ui->ModelList->item(ItemIdx)->text());
|
|
|
|
QString Name = lcGetActiveProject()->GetNewModelName(this, tr("New Submodel"), QString(), ModelNames);
|
|
|
|
if (Name.isEmpty())
|
|
return;
|
|
|
|
QListWidgetItem* Item = new QListWidgetItem(Name);
|
|
ui->ModelList->addItem(Item);
|
|
UpdateButtons();
|
|
}
|
|
|
|
void lcModelListDialog::DeleteModelClicked()
|
|
{
|
|
if (ui->ModelList->count() == 1)
|
|
{
|
|
QMessageBox::information(this, tr("Delete Submodel"), tr("The model cannot be empty."));
|
|
return;
|
|
}
|
|
|
|
const QList<QListWidgetItem*> SelectedItems = ui->ModelList->selectedItems();
|
|
|
|
if (SelectedItems.isEmpty())
|
|
{
|
|
QMessageBox::information(this, tr("Delete Submodel"), tr("No submodel selected."));
|
|
return;
|
|
}
|
|
|
|
QString Prompt;
|
|
if (SelectedItems.size() == 1)
|
|
Prompt = tr("Are you sure you want to delete the submodel '%1'?").arg(SelectedItems[0]->text());
|
|
else
|
|
Prompt = tr("Are you sure you want to delete %n submodels?", nullptr, static_cast<int>(SelectedItems.size()));
|
|
|
|
if (QMessageBox::question(this, tr("Delete Submodel"), Prompt, QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
|
|
return;
|
|
|
|
for (QListWidgetItem* SelectedItem : SelectedItems)
|
|
{
|
|
if (mActiveModelItem == SelectedItem)
|
|
mActiveModelItem = nullptr;
|
|
|
|
delete SelectedItem;
|
|
}
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
void lcModelListDialog::RenameModelClicked()
|
|
{
|
|
const QList<QListWidgetItem*> SelectedItems = ui->ModelList->selectedItems();
|
|
|
|
if (SelectedItems.isEmpty())
|
|
{
|
|
QMessageBox::information(this, tr("Rename Submodel"), tr("No submodel selected."));
|
|
return;
|
|
}
|
|
|
|
for (QListWidgetItem* CurrentItem : SelectedItems)
|
|
{
|
|
QStringList ModelNames;
|
|
|
|
for (int ItemIdx = 0; ItemIdx < ui->ModelList->count(); ItemIdx++)
|
|
ModelNames.append(ui->ModelList->item(ItemIdx)->text());
|
|
|
|
QString Name = lcGetActiveProject()->GetNewModelName(this, tr("Rename Submodel"), CurrentItem->text(), ModelNames);
|
|
|
|
if (!Name.isEmpty())
|
|
CurrentItem->setText(Name);
|
|
}
|
|
}
|
|
|
|
void lcModelListDialog::ExportModelClicked()
|
|
{
|
|
const QList<QListWidgetItem*> SelectedItems = ui->ModelList->selectedItems();
|
|
|
|
if (SelectedItems.isEmpty())
|
|
{
|
|
QMessageBox::information(this, tr("Export Submodel"), tr("No submodel selected."));
|
|
return;
|
|
}
|
|
|
|
if (SelectedItems.size() == 1)
|
|
{
|
|
QListWidgetItem* CurrentItem = SelectedItems[0];
|
|
lcModel* Model = (lcModel*)CurrentItem->data(static_cast<int>(lcModelListRole::ExistingModel)).value<uintptr_t>();
|
|
|
|
if (!Model)
|
|
{
|
|
Model = (lcModel*)CurrentItem->data(static_cast<int>(lcModelListRole::DuplicateModel)).value<uintptr_t>();
|
|
|
|
if (!Model)
|
|
{
|
|
QMessageBox::information(this, tr("Export Submodel"), tr("Nothing to export."));
|
|
return;
|
|
}
|
|
}
|
|
|
|
QString SaveFileName = QFileInfo(QDir(lcGetProfileString(LC_PROFILE_PROJECTS_PATH)), CurrentItem->text()).absoluteFilePath();
|
|
|
|
SaveFileName = QFileDialog::getSaveFileName(this, tr("Export Model"), SaveFileName, tr("Supported Files (*.ldr *.dat);;All Files (*.*)"));
|
|
|
|
if (SaveFileName.isEmpty())
|
|
return;
|
|
|
|
lcResult<void> ExportResult = lcGetActiveProject()->ExportModel(SaveFileName, Model);
|
|
|
|
if (!ExportResult && !ExportResult.error().isEmpty())
|
|
QMessageBox::warning(this, tr("Export Submodel"), ExportResult.error());
|
|
|
|
lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(SaveFileName).absolutePath());
|
|
}
|
|
else
|
|
{
|
|
QString Folder = QFileDialog::getExistingDirectory(this, tr("Select Export Folder"), lcGetProfileString(LC_PROFILE_PROJECTS_PATH));
|
|
|
|
for (QListWidgetItem* CurrentItem : SelectedItems)
|
|
{
|
|
lcModel* Model = (lcModel*)CurrentItem->data(static_cast<int>(lcModelListRole::ExistingModel)).value<uintptr_t>();
|
|
|
|
if (!Model)
|
|
Model = (lcModel*)CurrentItem->data(static_cast<int>(lcModelListRole::DuplicateModel)).value<uintptr_t>();
|
|
|
|
if (Model)
|
|
{
|
|
QString SaveFileName = QFileInfo(QDir(Folder), CurrentItem->text()).absoluteFilePath();
|
|
lcResult<void> ExportResult = lcGetActiveProject()->ExportModel(SaveFileName, Model);
|
|
|
|
if (!ExportResult && !ExportResult.error().isEmpty())
|
|
{
|
|
QMessageBox::warning(this, tr("Export Submodel"), ExportResult.error());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
lcSetProfileString(LC_PROFILE_PROJECTS_PATH, Folder);
|
|
}
|
|
}
|
|
|
|
void lcModelListDialog::DuplicateModelClicked()
|
|
{
|
|
const QList<QListWidgetItem*> SelectedItems = ui->ModelList->selectedItems();
|
|
|
|
if (SelectedItems.isEmpty())
|
|
{
|
|
QMessageBox::information(this, tr("Duplicate Submodel"), tr("No submodel selected."));
|
|
return;
|
|
}
|
|
|
|
for (QListWidgetItem* CurrentItem : SelectedItems)
|
|
{
|
|
QStringList ModelNames;
|
|
|
|
for (int ItemIdx = 0; ItemIdx < ui->ModelList->count(); ItemIdx++)
|
|
ModelNames.append(ui->ModelList->item(ItemIdx)->text());
|
|
|
|
QString Name = CurrentItem->text();
|
|
|
|
do
|
|
{
|
|
Name = tr("Copy of ") + Name;
|
|
} while (ModelNames.contains(Name, Qt::CaseInsensitive));
|
|
|
|
Name = lcGetActiveProject()->GetNewModelName(this, tr("Duplicate Submodel"), Name, ModelNames);
|
|
|
|
if (Name.isEmpty())
|
|
continue;
|
|
|
|
QListWidgetItem* Item = new QListWidgetItem(Name);
|
|
uintptr_t ExistingModel = CurrentItem->data(static_cast<int>(lcModelListRole::ExistingModel)).value<uintptr_t>();
|
|
if (!ExistingModel)
|
|
ExistingModel = CurrentItem->data(static_cast<int>(lcModelListRole::DuplicateModel)).value<uintptr_t>();
|
|
Item->setData(static_cast<int>(lcModelListRole::DuplicateModel), QVariant::fromValue<uintptr_t>(ExistingModel));
|
|
ui->ModelList->addItem(Item);
|
|
}
|
|
|
|
UpdateButtons();
|
|
}
|
|
|
|
void lcModelListDialog::ModelListItemDoubleClicked(QListWidgetItem* Item)
|
|
{
|
|
mActiveModelItem = Item;
|
|
|
|
accept();
|
|
}
|
|
|
|
void lcModelListDialog::ModelListItemSelectionChanged()
|
|
{
|
|
UpdateButtons();
|
|
}
|