Archetype: cpp_qt_detail_dialog.cpp.mustache
Loads the generated .ui; field get/set per widget kind. Qt UI component: model/view class or dialog wired to the service layer via request/response messages.
See the Template variable reference for the complete list of available variables and their semantics.
Template
The full template source. Edit here and re-tangle with
compass build --direct tangle_codegen_templates to regenerate
library/templates/cpp_qt_detail_dialog.cpp.mustache.
{{! GENERATED FILE — tangled from projects/ores.codegen/library/templates/cpp_qt.org. Edit the org source. }}
{{! Template to generate Qt detail dialog source for domain entities }}
{{{cpp_license}}}
#include "ores.qt/{{domain_entity.entity_pascal}}DetailDialog.hpp"
#include <QMessageBox>
#include <QtConcurrent>
#include <QFutureWatcher>
{{#domain_entity.qt.has_text_edit_fields}}
#include <QPlainTextEdit>
{{/domain_entity.qt.has_text_edit_fields}}
{{#domain_entity.qt.has_combo_fields}}
#include <QComboBox>
{{/domain_entity.qt.has_combo_fields}}
{{#domain_entity.qt.has_uuid_primary_key}}
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
{{/domain_entity.qt.has_uuid_primary_key}}
{{^domain_entity.qt.has_uuid_primary_key}}
{{#domain_entity.qt.has_uuid_detail_fields}}
#include <boost/uuid/uuid_io.hpp>
{{/domain_entity.qt.has_uuid_detail_fields}}
{{/domain_entity.qt.has_uuid_primary_key}}
#include "ui_{{domain_entity.entity_pascal}}DetailDialog.h"
#include "ores.qt/ChangeReasonDialog.hpp"
#include "ores.qt/IconUtils.hpp"
#include "ores.qt/MessageBoxHelper.hpp"
#include "{{domain_entity.qt.protocol_include}}"
namespace ores::qt {
using namespace ores::logging;
{{domain_entity.entity_pascal}}DetailDialog::{{domain_entity.entity_pascal}}DetailDialog(QWidget* parent)
: DetailDialogBase(parent),
ui_(new Ui::{{domain_entity.entity_pascal}}DetailDialog),
clientManager_(nullptr) {
ui_->setupUi(this);
setupUi();
{{#domain_entity.qt.has_combo_fields}}
setupCombos();
{{/domain_entity.qt.has_combo_fields}}
setupConnections();
}
{{domain_entity.entity_pascal}}DetailDialog::~{{domain_entity.entity_pascal}}DetailDialog() {
delete ui_;
}
QTabWidget* {{domain_entity.entity_pascal}}DetailDialog::tabWidget() const {
return ui_->tabWidget;
}
QWidget* {{domain_entity.entity_pascal}}DetailDialog::provenanceTab() const {
return ui_->provenanceTab;
}
ProvenanceWidget* {{domain_entity.entity_pascal}}DetailDialog::provenanceWidget() const {
return ui_->provenanceWidget;
}
void {{domain_entity.entity_pascal}}DetailDialog::setupUi() {
ui_->saveButton->setIcon(
IconUtils::createRecoloredIcon(Icon::Save, IconUtils::DefaultIconColor));
ui_->saveButton->setEnabled(false);
ui_->deleteButton->setIcon(
IconUtils::createRecoloredIcon(Icon::Delete, IconUtils::DefaultIconColor));
ui_->closeButton->setIcon(
IconUtils::createRecoloredIcon(Icon::Dismiss, IconUtils::DefaultIconColor));
}
{{#domain_entity.qt.has_combo_fields}}
void {{domain_entity.entity_pascal}}DetailDialog::setupCombos() {
{{#domain_entity.qt.detail_fields}}
{{#is_static_combo}}
ui_->{{widget}}->clear();
{{#combo_values}}
ui_->{{widget}}->addItem(tr("{{label}}"), QString("{{value}}"));
{{/combo_values}}
{{/is_static_combo}}
{{/domain_entity.qt.detail_fields}}
}
{{/domain_entity.qt.has_combo_fields}}
void {{domain_entity.entity_pascal}}DetailDialog::setupConnections() {
connect(ui_->saveButton, &QPushButton::clicked, this,
&{{domain_entity.entity_pascal}}DetailDialog::onSaveClicked);
connect(ui_->deleteButton, &QPushButton::clicked, this,
&{{domain_entity.entity_pascal}}DetailDialog::onDeleteClicked);
connect(ui_->closeButton, &QPushButton::clicked, this,
&{{domain_entity.entity_pascal}}DetailDialog::onCloseClicked);
{{#domain_entity.qt.detail_fields}}
{{#is_key}}
{{#is_line_edit}}
connect(ui_->{{widget}}, &QLineEdit::textChanged, this,
&{{domain_entity.entity_pascal}}DetailDialog::onCodeChanged);
{{/is_line_edit}}
{{/is_key}}
{{^is_key}}
{{#is_line_edit}}
connect(ui_->{{widget}}, &QLineEdit::textChanged, this,
&{{domain_entity.entity_pascal}}DetailDialog::onFieldChanged);
{{/is_line_edit}}
{{#is_text_edit}}
connect(ui_->{{widget}}, &QPlainTextEdit::textChanged, this,
&{{domain_entity.entity_pascal}}DetailDialog::onFieldChanged);
{{/is_text_edit}}
{{#is_static_combo}}
connect(ui_->{{widget}}, &QComboBox::currentIndexChanged, this,
&{{domain_entity.entity_pascal}}DetailDialog::onFieldChanged);
{{/is_static_combo}}
{{#is_dynamic_combo}}
connect(ui_->{{widget}}, &QComboBox::currentIndexChanged, this,
&{{domain_entity.entity_pascal}}DetailDialog::onFieldChanged);
{{/is_dynamic_combo}}
{{/is_key}}
{{/domain_entity.qt.detail_fields}}
}
void {{domain_entity.entity_pascal}}DetailDialog::setClientManager(ClientManager* clientManager) {
clientManager_ = clientManager;
}
void {{domain_entity.entity_pascal}}DetailDialog::setUsername(const std::string& username) {
username_ = username;
}
void {{domain_entity.entity_pascal}}DetailDialog::set{{domain_entity.entity_pascal_short}}(
const {{domain_entity.qt.domain_class}}& {{domain_entity.qt.item_var}}) {
{{domain_entity.qt.item_var}}_ = {{domain_entity.qt.item_var}};
updateUiFrom{{domain_entity.entity_pascal_short}}();
}
void {{domain_entity.entity_pascal}}DetailDialog::setCreateMode(bool createMode) {
createMode_ = createMode;
ui_->{{domain_entity.qt.key_widget}}->setReadOnly(!createMode);
ui_->deleteButton->setVisible(!createMode);
setProvenanceEnabled(!createMode);
{{#domain_entity.qt.has_uuid_primary_key}}
if (createMode) {
{{domain_entity.qt.item_var}}_.{{#domain_entity.qt.id_access}}{{domain_entity.qt.id_access}}{{/domain_entity.qt.id_access}}{{^domain_entity.qt.id_access}}id{{/domain_entity.qt.id_access}} = boost::uuids::random_generator()();
}
{{/domain_entity.qt.has_uuid_primary_key}}
hasChanges_ = false;
updateSaveButtonState();
}
void {{domain_entity.entity_pascal}}DetailDialog::setReadOnly(bool readOnly) {
readOnly_ = readOnly;
{{#domain_entity.qt.detail_fields}}
{{#is_key}}
{{#is_line_edit}}
ui_->{{widget}}->setReadOnly(true);
{{/is_line_edit}}
{{#is_text_edit}}
ui_->{{widget}}->setReadOnly(true);
{{/is_text_edit}}
{{#is_static_combo}}
ui_->{{widget}}->setEnabled(false);
{{/is_static_combo}}
{{#is_dynamic_combo}}
ui_->{{widget}}->setEnabled(false);
{{/is_dynamic_combo}}
{{/is_key}}
{{^is_key}}
{{#is_line_edit}}
ui_->{{widget}}->setReadOnly(readOnly);
{{/is_line_edit}}
{{#is_text_edit}}
ui_->{{widget}}->setReadOnly(readOnly);
{{/is_text_edit}}
{{#is_static_combo}}
ui_->{{widget}}->setEnabled(!readOnly);
{{/is_static_combo}}
{{#is_dynamic_combo}}
ui_->{{widget}}->setEnabled(!readOnly);
{{/is_dynamic_combo}}
{{/is_key}}
{{/domain_entity.qt.detail_fields}}
ui_->saveButton->setVisible(!readOnly);
ui_->deleteButton->setVisible(!readOnly);
}
{{#domain_entity.qt.detail_fields}}
{{#is_dynamic_combo}}
void {{domain_entity.entity_pascal}}DetailDialog::{{combo_setter}}(
const std::vector<{{combo_type}}>& items) {
{{combo_items_member}}_ = items;
populate{{combo_setter_pascal}}();
}
void {{domain_entity.entity_pascal}}DetailDialog::populate{{combo_setter_pascal}}() {
const auto current = ui_->{{widget}}->currentData();
ui_->{{widget}}->clear();
{{#combo_is_optional}}
ui_->{{widget}}->addItem(tr("(None)"), QVariant{});
{{/combo_is_optional}}
for (const auto& item : {{combo_items_member}}_) {
ui_->{{widget}}->addItem(
QString::fromStdString(item.{{combo_display}}),
QString::fromStdString(item.{{combo_value}}));
}
if (current.isValid()) {
const int idx = ui_->{{widget}}->findData(current);
if (idx >= 0) ui_->{{widget}}->setCurrentIndex(idx);
}
}
{{/is_dynamic_combo}}
{{/domain_entity.qt.detail_fields}}
void {{domain_entity.entity_pascal}}DetailDialog::updateUiFrom{{domain_entity.entity_pascal_short}}() {
{{#domain_entity.qt.detail_fields}}
{{#is_line_edit}}
{{#is_optional_uuid}}
{
const auto& _opt = {{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}};
ui_->{{widget}}->setText(_opt
? QString::fromStdString(boost::uuids::to_string(*_opt))
: QString{});
}
{{/is_optional_uuid}}
{{^is_optional_uuid}}
{{#is_uuid}}
ui_->{{widget}}->setText(QString::fromStdString(
boost::uuids::to_string({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}})));
{{/is_uuid}}
{{^is_uuid}}
{{#is_optional_string}}
ui_->{{widget}}->setText({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}}
? QString::fromStdString(*{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}})
: QString{});
{{/is_optional_string}}
{{^is_optional_string}}
ui_->{{widget}}->setText(QString::fromStdString({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}}));
{{/is_optional_string}}
{{/is_uuid}}
{{/is_optional_uuid}}
{{/is_line_edit}}
{{#is_text_edit}}
{{#is_optional_string}}
ui_->{{widget}}->setPlainText({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}}
? QString::fromStdString(*{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}})
: QString{});
{{/is_optional_string}}
{{^is_optional_string}}
ui_->{{widget}}->setPlainText(QString::fromStdString({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}}));
{{/is_optional_string}}
{{/is_text_edit}}
{{#is_check_box}}
{{#is_tristate}}
ui_->{{widget}}->setCheckState({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}}
? (*{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} ? Qt::Checked : Qt::Unchecked)
: Qt::PartiallyChecked);
{{/is_tristate}}
{{^is_tristate}}
ui_->{{widget}}->setChecked({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}});
{{/is_tristate}}
{{/is_check_box}}
{{#is_spin_box}}
{{#is_nullable_int}}
ui_->{{widget}}->setValue({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}}.value_or(
ui_->{{widget}}->minimum()));
{{/is_nullable_int}}
{{^is_nullable_int}}
ui_->{{widget}}->setValue({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}});
{{/is_nullable_int}}
{{/is_spin_box}}
{{#is_static_combo}}
{
const int idx = ui_->{{widget}}->findData(
QString::fromStdString({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}}));
if (idx >= 0) ui_->{{widget}}->setCurrentIndex(idx);
}
{{/is_static_combo}}
{{#is_dynamic_combo}}
{
const auto val = QString::fromStdString({{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}});
const int idx = ui_->{{widget}}->findData(val);
if (idx >= 0) ui_->{{widget}}->setCurrentIndex(idx);
}
{{/is_dynamic_combo}}
{{/domain_entity.qt.detail_fields}}
populateProvenance({{domain_entity.qt.item_var}}_.{{#domain_entity.qt.version_access}}{{domain_entity.qt.version_access}}{{/domain_entity.qt.version_access}}{{^domain_entity.qt.version_access}}version{{/domain_entity.qt.version_access}},
{{domain_entity.qt.item_var}}_.{{#domain_entity.qt.modified_by_access}}{{domain_entity.qt.modified_by_access}}{{/domain_entity.qt.modified_by_access}}{{^domain_entity.qt.modified_by_access}}modified_by{{/domain_entity.qt.modified_by_access}},
{{domain_entity.qt.item_var}}_.{{#domain_entity.qt.performed_by_access}}{{domain_entity.qt.performed_by_access}}{{/domain_entity.qt.performed_by_access}}{{^domain_entity.qt.performed_by_access}}performed_by{{/domain_entity.qt.performed_by_access}},
{{domain_entity.qt.item_var}}_.{{#domain_entity.qt.recorded_at_access}}{{domain_entity.qt.recorded_at_access}}{{/domain_entity.qt.recorded_at_access}}{{^domain_entity.qt.recorded_at_access}}recorded_at{{/domain_entity.qt.recorded_at_access}},
{{domain_entity.qt.item_var}}_.{{#domain_entity.qt.change_reason_code_access}}{{domain_entity.qt.change_reason_code_access}}{{/domain_entity.qt.change_reason_code_access}}{{^domain_entity.qt.change_reason_code_access}}change_reason_code{{/domain_entity.qt.change_reason_code_access}},
{{domain_entity.qt.item_var}}_.{{#domain_entity.qt.change_commentary_access}}{{domain_entity.qt.change_commentary_access}}{{/domain_entity.qt.change_commentary_access}}{{^domain_entity.qt.change_commentary_access}}change_commentary{{/domain_entity.qt.change_commentary_access}});
hasChanges_ = false;
updateSaveButtonState();
}
void {{domain_entity.entity_pascal}}DetailDialog::update{{domain_entity.entity_pascal_short}}FromUi() {
{{#domain_entity.qt.detail_fields}}
{{#is_key}}
if (createMode_) {
{{#is_line_edit}}
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = ui_->{{widget}}->text().trimmed().toStdString();
{{/is_line_edit}}
{{#is_static_combo}}
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = ui_->{{widget}}->currentData().toString().trimmed().toStdString();
{{/is_static_combo}}
{{#is_dynamic_combo}}
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = ui_->{{widget}}->currentData().toString().trimmed().toStdString();
{{/is_dynamic_combo}}
}
{{/is_key}}
{{^is_key}}
{{#is_line_edit}}
{{^is_uuid}}
{{^is_optional_uuid}}
{{#is_optional_string}}
{
const auto {{field}}_str = ui_->{{widget}}->text().trimmed().toStdString();
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} =
{{field}}_str.empty() ? std::nullopt : std::optional<std::string>({{field}}_str);
}
{{/is_optional_string}}
{{^is_optional_string}}
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = ui_->{{widget}}->text().trimmed().toStdString();
{{/is_optional_string}}
{{/is_optional_uuid}}
{{/is_uuid}}
{{/is_line_edit}}
{{#is_text_edit}}
{{#is_optional_string}}
{
const auto {{field}}_str = ui_->{{widget}}->toPlainText().trimmed().toStdString();
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} =
{{field}}_str.empty() ? std::nullopt : std::optional<std::string>({{field}}_str);
}
{{/is_optional_string}}
{{^is_optional_string}}
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = ui_->{{widget}}->toPlainText().trimmed().toStdString();
{{/is_optional_string}}
{{/is_text_edit}}
{{#is_check_box}}
{{#is_tristate}}
switch (ui_->{{widget}}->checkState()) {
case Qt::Checked:
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = std::optional<bool>(true);
break;
case Qt::Unchecked:
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = std::optional<bool>(false);
break;
default:
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = std::nullopt;
break;
}
{{/is_tristate}}
{{^is_tristate}}
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = ui_->{{widget}}->isChecked();
{{/is_tristate}}
{{/is_check_box}}
{{#is_spin_box}}
{{#is_nullable_int}}
if (ui_->{{widget}}->value() == ui_->{{widget}}->minimum())
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = std::nullopt;
else
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = ui_->{{widget}}->value();
{{/is_nullable_int}}
{{^is_nullable_int}}
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} = ui_->{{widget}}->value();
{{/is_nullable_int}}
{{/is_spin_box}}
{{#is_static_combo}}
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} =
ui_->{{widget}}->currentData().toString().toStdString();
{{/is_static_combo}}
{{#is_dynamic_combo}}
{{domain_entity.qt.item_var}}_.{{#field_access}}{{field_access}}{{/field_access}}{{^field_access}}{{field}}{{/field_access}} =
ui_->{{widget}}->currentData().toString().toStdString();
{{/is_dynamic_combo}}
{{/is_key}}
{{/domain_entity.qt.detail_fields}}
{{domain_entity.qt.item_var}}_.{{#domain_entity.qt.modified_by_access}}{{domain_entity.qt.modified_by_access}}{{/domain_entity.qt.modified_by_access}}{{^domain_entity.qt.modified_by_access}}modified_by{{/domain_entity.qt.modified_by_access}} = username_;
}
void {{domain_entity.entity_pascal}}DetailDialog::onCodeChanged(const QString& /* text */) {
hasChanges_ = true;
updateSaveButtonState();
}
void {{domain_entity.entity_pascal}}DetailDialog::onFieldChanged() {
hasChanges_ = true;
updateSaveButtonState();
}
void {{domain_entity.entity_pascal}}DetailDialog::updateSaveButtonState() {
bool canSave = hasChanges_ && validateInput() && !readOnly_;
ui_->saveButton->setEnabled(canSave);
}
bool {{domain_entity.entity_pascal}}DetailDialog::validateInput() {
{{#domain_entity.qt.required_fields}}
const QString {{field}}_val = ui_->{{widget}}->text().trimmed();
{{/domain_entity.qt.required_fields}}
{{#domain_entity.qt.required_dynamic_combo_fields}}
const bool {{field}}_selected = ui_->{{widget}}->currentIndex() >= 0;
{{/domain_entity.qt.required_dynamic_combo_fields}}
return true
{{#domain_entity.qt.required_fields}}
&& !{{field}}_val.isEmpty()
{{/domain_entity.qt.required_fields}}
{{#domain_entity.qt.required_dynamic_combo_fields}}
&& {{field}}_selected
{{/domain_entity.qt.required_dynamic_combo_fields}}
;
}
void {{domain_entity.entity_pascal}}DetailDialog::onSaveClicked() {
if (!clientManager_ || !clientManager_->isConnected()) {
MessageBoxHelper::warning(this, "Disconnected",
"Cannot save {{domain_entity.entity_singular_words}} while disconnected from server.");
return;
}
if (!validateInput()) {
MessageBoxHelper::warning(this, "Invalid Input",
"Please fill in all required fields.");
return;
}
const auto crOpType = createMode_
? ChangeReasonDialog::OperationType::Create
: ChangeReasonDialog::OperationType::Amend;
const auto crSel = promptChangeReason(crOpType, hasChanges_,
createMode_ ? "system" : "common");
if (!crSel) return;
{{domain_entity.qt.item_var}}_.change_reason_code = crSel->reason_code;
{{domain_entity.qt.item_var}}_.change_commentary = crSel->commentary;
update{{domain_entity.entity_pascal_short}}FromUi();
BOOST_LOG_SEV(lg(), info) << "Saving {{domain_entity.entity_singular_words}}: "
<< {{domain_entity.qt.item_var}}_.{{#domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field_access}}{{/domain_entity.qt.key_field_access}}{{^domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field}}{{/domain_entity.qt.key_field_access}};
QPointer<{{domain_entity.entity_pascal}}DetailDialog> self = this;
struct SaveResult {
bool success;
std::string message;
};
auto task = [self, {{domain_entity.qt.item_var}} = {{domain_entity.qt.item_var}}_]() -> SaveResult {
if (!self || !self->clientManager_) {
return {false, "Dialog closed"};
}
{{domain_entity.qt.save_request_class}} request;
request.data = {{domain_entity.qt.item_var}};
auto response_result = self->clientManager_->
process_authenticated_request(std::move(request));
if (!response_result) {
return {false, "Failed to communicate with server"};
}
return {response_result->success, response_result->message};
};
auto* watcher = new QFutureWatcher<SaveResult>(self);
connect(watcher, &QFutureWatcher<SaveResult>::finished,
self, [self, watcher]() {
auto result = watcher->result();
watcher->deleteLater();
if (result.success) {
BOOST_LOG_SEV(lg(), info) << "{{domain_entity.entity_title}} saved successfully";
QString code = QString::fromStdString(
self->{{domain_entity.qt.item_var}}_.{{#domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field_access}}{{/domain_entity.qt.key_field_access}}{{^domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field}}{{/domain_entity.qt.key_field_access}});
self->hasChanges_ = false;
self->updateSaveButtonState();
emit self->{{domain_entity.qt.item_var}}Saved(code);
self->notifySaveSuccess(tr("{{domain_entity.entity_title}} '%1' saved").arg(code));
} else {
BOOST_LOG_SEV(lg(), error) << "Save failed: " << result.message;
QString errorMsg = QString::fromStdString(result.message);
emit self->errorMessage(errorMsg);
MessageBoxHelper::critical(self, "Save Failed", errorMsg);
}
});
QFuture<SaveResult> future = QtConcurrent::run(task);
watcher->setFuture(future);
}
void {{domain_entity.entity_pascal}}DetailDialog::onDeleteClicked() {
if (!clientManager_ || !clientManager_->isConnected()) {
MessageBoxHelper::warning(this, "Disconnected",
"Cannot delete {{domain_entity.entity_singular_words}} while disconnected from server.");
return;
}
QString code = QString::fromStdString(
{{domain_entity.qt.item_var}}_.{{#domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field_access}}{{/domain_entity.qt.key_field_access}}{{^domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field}}{{/domain_entity.qt.key_field_access}});
auto reply = MessageBoxHelper::question(this, "Delete {{domain_entity.entity_title}}",
QString("Are you sure you want to delete {{domain_entity.entity_singular_words}} '%1'?").arg(code),
QMessageBox::Yes | QMessageBox::No);
if (reply != QMessageBox::Yes) {
return;
}
const auto crSel = promptChangeReason(
ChangeReasonDialog::OperationType::Delete, false);
if (!crSel) return;
BOOST_LOG_SEV(lg(), info) << "Deleting {{domain_entity.entity_singular_words}}: "
<< {{domain_entity.qt.item_var}}_.{{#domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field_access}}{{/domain_entity.qt.key_field_access}}{{^domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field}}{{/domain_entity.qt.key_field_access}};
QPointer<{{domain_entity.entity_pascal}}DetailDialog> self = this;
struct DeleteResult {
bool success;
std::string message;
};
{{#domain_entity.qt.has_uuid_primary_key}}
auto task = [self, id_str = boost::uuids::to_string({{domain_entity.qt.item_var}}_.{{#domain_entity.qt.id_access}}{{domain_entity.qt.id_access}}{{/domain_entity.qt.id_access}}{{^domain_entity.qt.id_access}}id{{/domain_entity.qt.id_access}})]() -> DeleteResult {
if (!self || !self->clientManager_) {
return {false, "Dialog closed"};
}
{{domain_entity.qt.delete_request_class}} request;
{{#domain_entity.qt.delete_request_id_is_plural}}
request.{{domain_entity.qt.delete_request_id_field}} = {id_str};
{{/domain_entity.qt.delete_request_id_is_plural}}
{{^domain_entity.qt.delete_request_id_is_plural}}
request.{{domain_entity.qt.delete_request_id_field}} = id_str;
{{/domain_entity.qt.delete_request_id_is_plural}}
auto response_result = self->clientManager_->
process_authenticated_request(std::move(request));
if (!response_result) {
return {false, "Failed to communicate with server"};
}
return {response_result->success, response_result->message};
};
{{/domain_entity.qt.has_uuid_primary_key}}
{{^domain_entity.qt.has_uuid_primary_key}}
auto task = [self, code = {{domain_entity.qt.item_var}}_.{{#domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field_access}}{{/domain_entity.qt.key_field_access}}{{^domain_entity.qt.key_field_access}}{{domain_entity.qt.key_field}}{{/domain_entity.qt.key_field_access}}]() -> DeleteResult {
if (!self || !self->clientManager_) {
return {false, "Dialog closed"};
}
{{domain_entity.qt.delete_request_class}} request;
{{#domain_entity.qt.delete_request_id_field}}
{{#domain_entity.qt.delete_request_id_is_plural}}
request.{{domain_entity.qt.delete_request_id_field}} = {code};
{{/domain_entity.qt.delete_request_id_is_plural}}
{{^domain_entity.qt.delete_request_id_is_plural}}
request.{{domain_entity.qt.delete_request_id_field}} = code;
{{/domain_entity.qt.delete_request_id_is_plural}}
{{/domain_entity.qt.delete_request_id_field}}
{{^domain_entity.qt.delete_request_id_field}}
request.codes = {code};
{{/domain_entity.qt.delete_request_id_field}}
auto response_result = self->clientManager_->
process_authenticated_request(std::move(request));
if (!response_result) {
return {false, "Failed to communicate with server"};
}
return {response_result->success, response_result->message};
};
{{/domain_entity.qt.has_uuid_primary_key}}
auto* watcher = new QFutureWatcher<DeleteResult>(self);
connect(watcher, &QFutureWatcher<DeleteResult>::finished,
self, [self, code, watcher]() {
auto result = watcher->result();
watcher->deleteLater();
if (result.success) {
BOOST_LOG_SEV(lg(), info) << "{{domain_entity.entity_title}} deleted successfully";
emit self->statusMessage(
QString("{{domain_entity.entity_title}} '%1' deleted").arg(code));
emit self->{{domain_entity.qt.item_var}}Deleted(code);
self->requestClose();
} else {
BOOST_LOG_SEV(lg(), error) << "Delete failed: " << result.message;
QString errorMsg = QString::fromStdString(result.message);
emit self->errorMessage(errorMsg);
MessageBoxHelper::critical(self, "Delete Failed", errorMsg);
}
});
QFuture<DeleteResult> future = QtConcurrent::run(task);
watcher->setFuture(future);
}
}
See also
- Parent facet: C++ Qt templates
- Template variable reference