ores.cpp.qt.detail_dialog_header
Table of Contents
Detail dialog declarations. 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.
Extension points
<<paste:UUID>> markers in this template are paste-block injection
points — see paste blocks: injecting custom code into generated files
for the full mechanism. This header defines one:
F55CB64E-165A-4E15-A50A-5723C0320E97— inprivate:, after the generated method declarations. Pairs with the implementation seam of the same purpose in ores.cpp.qt.detail_dialog_impl (EC97923E-BC8D-4A50-9970-CBC5CBD4B732) — an entity declares any extra private methods here that block implements.9C3E6A1D-4B8F-4D2C-8A5E-3F1B7C9D2E6A— after the generated includes, before theUiforward declaration. Use for any type used by aF55CB64Emember/method declaration that isn't already visible (e.g. a hand-written helper class's header) — a forward declaration alone is not enough for by-value orunique_ptr<T>members, so most entities will need a real#includehere.EC19A4EE-363D-4D41-A33A-D5F85A139C80— in the dialog's ownsignals:, after the generatedSaved=/=Deleted=/(optional) =revertRequestedsignals. Declares a custom dialog signal, e.g. for a toolbar action the dialog can't act on itself. Pair with the controller-side seam that relays it upward (DF72DFCF-FD65-4FE5-98BA-CB8168CE0FDFin ores.cpp.qt.controller_impl, via the controller header's ownsignals:seam66E078FB-D6A6-4DF6-814B-65995D948090in ores.cpp.qt.controller_header).
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.hpp.mustache.
{{! GENERATED FILE — tangled from projects/ores.codegen/library/templates/cpp_qt.org. Edit the org source. }}
{{! Template to generate Qt detail dialog header for domain entities }}
{{{cpp_license}}}
#ifndef ORES_QT_{{domain_entity.entity_upper}}_DETAIL_DIALOG_HPP
#define ORES_QT_{{domain_entity.entity_upper}}_DETAIL_DIALOG_HPP
#include <vector>
#include "ores.qt/ClientManager.hpp"
#include "ores.qt/DetailDialogBase.hpp"
#include "ores.logging/make_logger.hpp"
#include "{{domain_entity.qt.domain_include}}"
{{#domain_entity.qt.has_setting_gated_actions}}
#include "ores.qt/SettingGatedActionController.hpp"
#include <QAction>
{{/domain_entity.qt.has_setting_gated_actions}}
{{#domain_entity.qt.has_version_navigation}}
#include <vector>
{{/domain_entity.qt.has_version_navigation}}
{{#domain_entity.qt.has_generate_action}}
#include "ores.{{domain_entity.component_include}}/{{domain_entity.generator_facet_name}}/{{domain_entity.entity_singular}}_generator.hpp"
#include "ores.utility/generation/generation_context.hpp"
{{/domain_entity.qt.has_generate_action}}
{{#domain_entity.qt.has_toolbar}}
#include "ores.qt/IconUtils.hpp"
#include <QAction>
#include <QToolBar>
{{/domain_entity.qt.has_toolbar}}
{{#domain_entity.qt.detail_fields}}{{#is_dynamic_combo}}
{{^combo_fetch_fn}}
#include "{{combo_include}}"
{{/combo_fetch_fn}}
{{#combo_fetch_fn}}
#include "{{combo_fetch_include}}"
{{/combo_fetch_fn}}
{{/is_dynamic_combo}}{{/domain_entity.qt.detail_fields}}
{{#domain_entity.qt.has_flagged_combo_fields}}
#include "ores.qt/FlagIconHelper.hpp"
#include "ores.qt/LookupFetcher.hpp"
{{/domain_entity.qt.has_flagged_combo_fields}}
{{#domain_entity.qt.has_colour_fields}}
#include "ores.qt/ColourSwatchHelper.hpp"
#include <QPushButton>
{{/domain_entity.qt.has_colour_fields}}
<<paste:9C3E6A1D-4B8F-4D2C-8A5E-3F1B7C9D2E6A>>
namespace Ui {
class {{domain_entity.entity_pascal}}DetailDialog;
}
namespace ores::qt {
/**
* @brief Detail dialog for viewing and editing {{domain_entity.entity_singular_words}} records.
*
* This dialog allows viewing, creating, and editing {{domain_entity.entity_plural_words}}.
* It supports both create mode (for new records) and edit mode (for
* existing records).
*/
class {{domain_entity.entity_pascal}}DetailDialog final : public DetailDialogBase {
Q_OBJECT
private:
inline static std::string_view logger_name =
"ores.qt.{{domain_entity.entity_snake}}_detail_dialog";
[[nodiscard]] static auto& lg() {
using namespace ores::logging;
static auto instance = make_logger(logger_name);
return instance;
}
public:
explicit {{domain_entity.entity_pascal}}DetailDialog(QWidget* parent = nullptr);
~{{domain_entity.entity_pascal}}DetailDialog() override;
void setClientManager(ClientManager* clientManager);
void setUsername(const std::string& username);
void set{{domain_entity.entity_pascal_short}}(const {{domain_entity.qt.domain_class}}& {{domain_entity.qt.item_var}});
void setCreateMode(bool createMode);
{{^domain_entity.qt.has_version_navigation}}
void setReadOnly(bool readOnly);
{{/domain_entity.qt.has_version_navigation}}
{{#domain_entity.qt.has_version_navigation}}
void setReadOnly(bool readOnly, int versionNumber = 0);
/**
* @brief Sets the history for version navigation.
*
* Shows a navigation toolbar allowing the user to navigate between
* versions (first/prev/next/last); the flag is grayed out for
* non-latest versions.
*
* @param history All versions ordered newest-first (index 0 is latest)
* @param versionNumber The version number to initially display
*/
void setHistory(const std::vector<{{domain_entity.qt.domain_class}}>& history, int versionNumber);
{{/domain_entity.qt.has_version_navigation}}
/**
* @brief Force the dialog into the unsaved-changes state.
*
* Used when values are loaded programmatically and must be savable
* immediately even though the user typed nothing — e.g. a revert, where
* the act of loading a past version's values is itself the change.
*/
void markDirty();
{{#domain_entity.qt.detail_fields}}{{#is_dynamic_combo}}{{^combo_fetch_fn}}
void {{combo_setter}}(const std::vector<{{combo_type}}>& items);
{{/combo_fetch_fn}}{{/is_dynamic_combo}}{{/domain_entity.qt.detail_fields}}
signals:
void {{domain_entity.qt.item_var}}Saved(const QString& code);
void {{domain_entity.qt.item_var}}Deleted(const QString& code);
{{#domain_entity.qt.has_version_navigation}}
/**
* @brief Emitted when user requests to revert to the displayed historical version.
* @param {{domain_entity.qt.item_var}} The {{domain_entity.entity_singular_words}} data to revert to.
*/
void revertRequested(const {{domain_entity.qt.domain_class}}& {{domain_entity.qt.item_var}});
{{/domain_entity.qt.has_version_navigation}}
<<paste:EC19A4EE-363D-4D41-A33A-D5F85A139C80>>
private slots:
void onSaveClicked();
void onDeleteClicked();
{{#domain_entity.qt.has_line_edit_key}}
void onCodeChanged(const QString& text);
{{/domain_entity.qt.has_line_edit_key}}
void onFieldChanged();
{{#domain_entity.qt.has_version_navigation}}
void onRevertClicked();
void onFirstVersionClicked();
void onPrevVersionClicked();
void onNextVersionClicked();
void onLastVersionClicked();
{{/domain_entity.qt.has_version_navigation}}
{{#domain_entity.qt.has_generate_action}}
void onGenerateClicked();
{{/domain_entity.qt.has_generate_action}}
protected:
QTabWidget* tabWidget() const override;
QWidget* provenanceTab() const override;
ProvenanceWidget* provenanceWidget() const override;
bool hasUnsavedChanges() const override { return hasChanges_; }
QString code() const override;
{{#domain_entity.qt.has_flag_icon}}
std::optional<boost::uuids::uuid> entityImageId() const override;
{{/domain_entity.qt.has_flag_icon}}
{{#domain_entity.qt.has_key_flag_icon}}
QLineEdit* keyFlagField() const override;
QIcon keyFlagIcon(const std::string& key) const override;
{{#domain_entity.qt.key_flag_is_pair}}
QSize keyFlagIconSize() const override;
{{/domain_entity.qt.key_flag_is_pair}}
{{/domain_entity.qt.has_key_flag_icon}}
private:
void setupUi();
void setupConnections();
{{#domain_entity.qt.has_combo_fields}}
void setupCombos();
{{/domain_entity.qt.has_combo_fields}}
void updateUiFrom{{domain_entity.entity_pascal_short}}();
void update{{domain_entity.entity_pascal_short}}FromUi();
void updateSaveButtonState();
bool validateInput();
{{#domain_entity.qt.detail_fields}}{{#is_dynamic_combo}}
void populate{{combo_setter_pascal}}();
{{/is_dynamic_combo}}{{/domain_entity.qt.detail_fields}}
{{#domain_entity.qt.detail_fields}}{{#is_flagged_combo}}
void populate{{field_pascal}}Combo();
{{/is_flagged_combo}}{{/domain_entity.qt.detail_fields}}
{{#domain_entity.qt.has_version_navigation}}
void displayCurrentVersion();
void updateVersionNavButtonStates();
void showVersionNavActions(bool visible);
{{/domain_entity.qt.has_version_navigation}}
{{#domain_entity.qt.has_generate_action}}
void setupGenerateAction();
{{/domain_entity.qt.has_generate_action}}
{{! see * Extension points above }}
<<paste:F55CB64E-165A-4E15-A50A-5723C0320E97>>
Ui::{{domain_entity.entity_pascal}}DetailDialog* ui_;
ClientManager* clientManager_;
std::string username_;
{{domain_entity.qt.domain_class}} {{domain_entity.qt.item_var}}_;
bool createMode_{true};
bool readOnly_{false};
bool hasChanges_{false};
{{#domain_entity.qt.detail_fields}}{{#is_dynamic_combo}}{{^combo_fetch_fn}}
std::vector<{{combo_type}}> {{combo_items_member}}_;
{{/combo_fetch_fn}}{{/is_dynamic_combo}}{{/domain_entity.qt.detail_fields}}
{{#domain_entity.qt.has_setting_gated_actions}}
{{#domain_entity.qt.setting_gated_actions}}
QAction* {{action}}_;
{{/domain_entity.qt.setting_gated_actions}}
SettingGatedActionController* settingGatedActions_{nullptr};
{{/domain_entity.qt.has_setting_gated_actions}}
{{#domain_entity.qt.has_toolbar}}
QToolBar* toolBar_{nullptr};
{{/domain_entity.qt.has_toolbar}}
{{#domain_entity.qt.has_version_navigation}}
QAction* revertAction_{nullptr};
QAction* firstVersionAction_{nullptr};
QAction* prevVersionAction_{nullptr};
QAction* nextVersionAction_{nullptr};
QAction* lastVersionAction_{nullptr};
std::vector<{{domain_entity.qt.domain_class}}> history_;
int currentHistoryIndex_{0};
int historicalVersion_{0};
{{/domain_entity.qt.has_version_navigation}}
};
}
#endif
See also
- Parent facet: ores.cpp.qt
- Template variable reference