29constexpr int kSuggestionDanger = 0;
30constexpr int kSuggestionWarning = 1;
31constexpr int kSuggestionSuccess = 2;
37 contractAllocatableMode_(
payload::contract_allocatable_mode::kMixed) {}
40 if (importWorkflow_ == value) {
43 bindImportWorkflow(value);
44 if (importWorkflow_) {
45 importWorkflow_->setWorkspaceRoles(commands_, selectors_);
47 syncTransactionDraftFromWorkflow();
48 updateManualPathFromWorkflow();
49 applyDefaultImportSelection();
54 if (settings_ == value) {
58 applyDefaultImportSelection();
63 if (actions_ == value) {
71 if (navigation_ == value) {
79 if (status_ == value) {
90 if (store_ == store && commands_ == commands && selection_ == selection &&
91 selectors_ == selectors) {
94 bindWorkspaceRoles(store, commands, selection, selectors);
95 if (importWorkflow_) {
96 importWorkflow_->setWorkspaceRoles(commands_, selectors_);
98 applyDefaultImportSelection();
103 if (importWorkflow_) {
104 disconnect(importWorkflow_,
nullptr,
this,
nullptr);
106 importWorkflow_ = value;
107 if (!importWorkflow_) {
111 updateManualPathFromWorkflow();
112 syncTransactionDraftFromWorkflow();
116 setStatusText(tr(
"Import canceled"));
119 setStatusText(tr(
"Import finished"));
122 [
this](
const QString& error) {
123 setStatusText(error.isEmpty() ? tr(
"Import failed") : error);
127void ImportViewModel::bindSettings(
Settings* value) {
129 disconnect(settings_,
nullptr,
this,
nullptr);
134 applyDefaultImportSelection();
140void ImportViewModel::bindActions(
Actions* value) {
142 disconnect(actions_,
nullptr,
this,
nullptr);
149 [
this](
const QString& path) {
150 manualPathText_ = path;
151 setSelectedImportFiles(QStringList{path});
154 [
this](
const QStringList& paths) {
155 manualPathText_ = paths.isEmpty() ? QString{} : paths.front();
156 setSelectedImportFiles(paths);
159 [
this](
const QString& path) {
160 queueImportFiles(QStringList{path});
163 [
this](
const QStringList& paths) {
164 queueImportFiles(paths);
173 disconnect(store_,
nullptr,
this,
nullptr);
176 commands_ = commands;
177 selection_ = selection;
178 selectors_ = selectors;
181 applyDefaultImportSelection();
182 reloadCurrentTransactionView();
189 if (manualPathText_ == value) {
192 manualPathText_ = value;
193 selectedImportFiles_.clear();
199 if (!importWorkflow_) {
202 if (!importWorkflow_->selectedFile().isEmpty()) {
203 files.push_back(importWorkflow_->selectedFile());
205 files.append(importWorkflow_->queuedFiles());
211 if (files.isEmpty()) {
216 names.reserve(files.size());
217 for (
const QString& file : files) {
218 const QString name = QFileInfo(file).fileName();
219 names.push_back(name.isEmpty() ? file : name);
221 return tr(
"Selected: %1").arg(names.join(QStringLiteral(
", ")));
225 applyDefaultImportSelection();
228void ImportViewModel::applyDefaultImportSelection() {
229 if (!importWorkflow_ || !settings_ || importWorkflow_->
isRunning()) {
235 const QString currentFile = importWorkflow_->selectedFile();
236 const QString defaultPath = settings_->importDefaultPath();
237 const bool canReplaceSelection =
238 currentFile.isEmpty() || currentFile == appliedDefaultImportPath_;
239 if (!canReplaceSelection || currentFile == defaultPath) {
242 importWorkflow_->setSelectedFile(defaultPath);
243 appliedDefaultImportPath_ = defaultPath;
244 updateManualPathFromWorkflow();
250 actions_->browseImportPdf();
255 QStringList files = selectedImportFiles_;
256 if (files.isEmpty() && !manualPathText_.trimmed().isEmpty()) {
257 files.push_back(manualPathText_);
259 queueImportFiles(files);
260 if (!files.isEmpty()) {
261 manualPathText_.clear();
262 selectedImportFiles_.clear();
267void ImportViewModel::queueImportFiles(
const QStringList& paths) {
268 if (!importWorkflow_) {
271 const QStringList supported = supportedImportFiles(paths);
272 if (supported.isEmpty()) {
276 "ImportViewModel::queueImportFiles",
"Import files queued",
279 importWorkflow_->addFiles(supported);
280 selectedImportFiles_.clear();
284void ImportViewModel::updateManualPathFromWorkflow() {
285 if (!importWorkflow_ || !selectedImportFiles_.isEmpty()) {
288 const QString selectedFile = importWorkflow_->selectedFile();
289 if (manualPathText_ != selectedFile) {
290 manualPathText_ = selectedFile;
294void ImportViewModel::setSelectedImportFiles(
const QStringList& paths) {
295 selectedImportFiles_ = paths;
300ImportViewModel::supportedImportFiles(
const QStringList& paths)
const {
301 QStringList supported;
302 for (
const QString& path : paths) {
303 const QString trimmed = path.trimmed();
304 if (trimmed.isEmpty()) {
307 if (QFileInfo(trimmed).suffix().compare(QStringLiteral(
"pdf"),
308 Qt::CaseInsensitive) == 0) {
309 supported.push_back(trimmed);
320 return importWorkflow_ !=
nullptr;
324 return importWorkflow_ && importWorkflow_->hasDraft();
328 return selectors_ && !selectors_->attachedImportDraftIds().isEmpty();
332 return importWorkflow_ && !importWorkflow_->isRunning();
336 return importWorkflow_ && importWorkflow_->isRunning();
340 return importWorkflow_ && importWorkflow_->isRunning();
344 if (!importWorkflow_ || importWorkflow_->isRunning()) {
347 return !importWorkflow_->selectedFile().isEmpty() ||
348 importWorkflow_->queuedCount() > 0;
352 return importWorkflow_ && importWorkflow_->isRunning();
356 return importWorkflow_ && importWorkflow_->isPaused();
360 return importWorkflow_ && importWorkflow_->isPaused() ? tr(
"Resume")
365 if (!importWorkflow_) {
368 if (!importWorkflow_->error().isEmpty()) {
369 return importWorkflow_->error();
371 return importWorkflow_->phase().isEmpty() ? tr(
"Ready")
372 : importWorkflow_->phase();
376 return importWorkflow_ && !importWorkflow_->error().isEmpty();
380 return importWorkflow_ ? importWorkflow_->progress() : 0.0;
384 return importWorkflow_ ? importWorkflow_->queuedCount() : 0;
388 return selectors_ ? selectors_->importLogRows() : QVariantList{};
392 return importWorkflow_ ? importWorkflow_->currentDraftId() : QString();
400 return {tr(
"Commerzbank26")};
404 manualPathText_.clear();
405 selectedImportFiles_.clear();
406 appliedDefaultImportPath_.clear();
407 if (importWorkflow_) {
408 importWorkflow_->resetStatus();
414 if (importWorkflow_) {
415 importWorkflow_->cancelImport();
420 if (importWorkflow_) {
421 importWorkflow_->cancelQueuedImports();
426 if (importWorkflow_ && importWorkflow_->isRunning() &&
427 !importWorkflow_->isPaused()) {
428 importWorkflow_->pauseImport();
433 if (importWorkflow_ && importWorkflow_->isRunning() &&
434 importWorkflow_->isPaused()) {
435 importWorkflow_->resumeImport();
440 if (importWorkflow_) {
441 importWorkflow_->startStatementImport();
445int ImportViewModel::activeDraftStackIndex()
const {
446 if (!importWorkflow_ || !selectors_) {
450 if (ids.isEmpty() || !importWorkflow_->
hasDraft() ||
454 return ids.indexOf(importWorkflow_->currentDraftId());
457bool ImportViewModel::openDraftAtStackIndex(
int index) {
458 if (!importWorkflow_ || !selectors_) {
461 const auto ids = selectors_->attachedImportDraftIds();
462 if (index < 0 || index >= ids.size()) {
465 return importWorkflow_->openStoredDraft(ids.at(index));
469 if (!importWorkflow_ || !selectors_) {
472 const auto ids = selectors_->attachedImportDraftIds();
476 const int index = activeDraftStackIndex();
477 if (index < 0 || index >= ids.size()) {
478 openDraftAtStackIndex(ids.size() - 1);
482 importWorkflow_->clearDraft();
486 openDraftAtStackIndex((index + ids.size() - 1) % ids.size());
491 if (!importWorkflow_ || !selectors_) {
494 const auto ids = selectors_->attachedImportDraftIds();
498 const int index = activeDraftStackIndex();
499 if (index < 0 || index >= ids.size()) {
500 openDraftAtStackIndex(0);
503 if (index == ids.size() - 1) {
504 importWorkflow_->clearDraft();
508 openDraftAtStackIndex((index + 1) % ids.size());
513 const QString& statementId,
514 const QString& draftId) {
515 if (!importWorkflow_) {
519 const QString targetDraftId = !draftId.isEmpty() ? draftId : logId;
521 "Import draft log opened",
522 {{
"logId", logId.toStdString()},
523 {
"draftId", targetDraftId.toStdString()}});
524 const QString currentDraftId = importWorkflow_->currentDraftId();
525 if (targetDraftId != currentDraftId) {
526 importWorkflow_->openStoredDraft(targetDraftId);
534 if (statementId.isEmpty() || !selection_) {
537 selection_->selectTransaction(statementId, {});
539 "Import statement log opened",
540 {{
"logId", logId.toStdString()},
541 {
"statementId", statementId.toStdString()}});
548 const QString& draftId) {
549 if (importWorkflow_) {
550 importWorkflow_->removeAttachedImportLog(logId, draftAttached, draftId);
551 }
else if (commands_ && !logId.isEmpty()) {
552 commands_->deleteImportLog(logId);
556void ImportViewModel::setStatusText(
const QString&
text) {
564 return importWorkflow_ ? importWorkflow_->currentStatementName() : QString();
571 if (importWorkflow_->renameCurrentStatementDraft(value)) {
580 return importWorkflow_->currentTransactionIndex() + 1;
584 return importWorkflow_ ? importWorkflow_->transactionCount() : 0;
588 return importWorkflow_ && importWorkflow_->transactionCount() > 1;
592 return importWorkflow_ && importWorkflow_->currentTransactionIndex() > 0;
596 return importWorkflow_ && importWorkflow_->currentTransactionIndex() <
597 importWorkflow_->transactionCount() - 1;
601 if (!importWorkflow_) {
604 importWorkflow_->pauseActiveDraft();
609 if (!importWorkflow_) {
612 importWorkflow_->discardActiveDraft();
617 if (!
hasDraft() || !importWorkflow_) {
620 if (importWorkflow_->insertTransactionAfterCurrent() >= 0) {
629 if (importWorkflow_->removeCurrentTransaction() >= 0) {
635 if (!importWorkflow_) {
638 importWorkflow_->finalizeActiveDraft();
646 importWorkflow_->setCurrentTransactionIndex(
647 importWorkflow_->currentTransactionIndex() - 1);
654 importWorkflow_->setCurrentTransactionIndex(
655 importWorkflow_->currentTransactionIndex() + 1);
658void ImportViewModel::syncTransactionDraftFromWorkflow() {
659 const QString previousId = lastTransactionId_;
660 reloadCurrentTransactionView();
661 const QString
id = currentTransactionView_.
id;
662 if (!
id.isEmpty() &&
id == previousId) {
665 lastTransactionId_ = id;
666 resetTransactionDraftFields();
669void ImportViewModel::resetTransactionDraftFields() {
670 nameText_ = currentTransactionView_.name;
671 bookingDateText_ = currentTransactionView_.bookingDate;
672 valutaText_ = currentTransactionView_.valuta;
673 amountText_ = currentTransactionView_.amountText;
675 contractName_.clear();
676 contractType_.clear();
678 propertyName_.clear();
681void ImportViewModel::reloadCurrentTransactionView() {
682 currentTransactionView_ = {};
683 if (!importWorkflow_) {
686 currentTransactionView_ = importWorkflow_->currentTransactionView();
690 if (nameText_ == value) {
698 if (bookingDateText_ == value) {
701 bookingDateText_ = value;
706 if (valutaText_ == value) {
714 if (amountText_ == value) {
735 return currentTransactionView_.metadata;
739 return currentTransactionView_.proofSource;
743 return currentTransactionView_.effectiveAllocatable;
747 if (!importWorkflow_ || nameText_ == currentTransactionView_.name) {
750 importWorkflow_->commitCurrentTransactionName(nameText_);
754 if (!importWorkflow_ ||
755 bookingDateText_ == currentTransactionView_.bookingDate) {
758 importWorkflow_->commitCurrentTransactionBookingDate(bookingDateText_);
762 if (!importWorkflow_ || valutaText_ == currentTransactionView_.valuta) {
765 importWorkflow_->commitCurrentTransactionValuta(valutaText_);
769 if (!importWorkflow_) {
772 importWorkflow_->applyCurrentTransactionAmountText(amountText_);
776 if (!importWorkflow_) {
779 importWorkflow_->setCurrentTransactionStatus(
784 if (!importWorkflow_) {
791 return selectors_ ? selectors_->actorDropdownRows() : QVariantList{};
796 currentTransactionActorId());
800 if (actorName_ == value) {
809 selectors_->actorIdByName(actorName_).isEmpty();
813 if (!importWorkflow_) {
819 importWorkflow_->clearCurrentTransactionActor();
821 importWorkflow_->selectCurrentTransactionActor(
id);
829 importWorkflow_->createActorForCurrentTransaction(actorName_);
833 return selectors_ ? selectors_->propertyDropdownRows() : QVariantList{};
837 if (propertyName_ == value) {
840 propertyName_ = value;
846 selectors_->propertyIdByName(propertyName_).isEmpty();
850 return currentTransactionPropertyIds().contains(propertyId);
855 if (importWorkflow_) {
856 importWorkflow_->setCurrentTransactionPropertySelected(propertyId,
865 if (importWorkflow_->createPropertyForCurrentTransaction(propertyName_)) {
866 propertyName_.clear();
872 return selectors_ ? selectors_->contractDropdownRows() : QVariantList{};
877 currentTransactionView_.contractId);
886 if (!importWorkflow_) {
892 importWorkflow_->clearCurrentTransactionContract();
894 importWorkflow_->selectCurrentTransactionContract(
id);
899 if (contractName_ == value) {
902 contractName_ = value;
907 if (contractType_ == value) {
910 contractType_ = value;
916 return selectors_->nextContractName();
918 return tr(
"Contract 1");
923 tr(
"Mixed"), tr(
"All allocatable"), tr(
"Never allocatable"));
934 if (contractAllocatableMode_ == mode) {
937 contractAllocatableMode_ = mode;
945 const QString actorId = currentTransactionActorId();
946 QStringList actorIds;
947 if (!actorId.trimmed().isEmpty()) {
948 actorIds.push_back(actorId.trimmed());
950 const QString effectiveName = contractName_.trimmed().isEmpty()
951 ? selectors_->nextContractName()
952 : contractName_.trimmed();
954 ->contractIdBySignature(effectiveName, contractType_, actorIds,
955 currentTransactionPropertyIds())
963 if (importWorkflow_->createOrSelectContractForCurrentTransaction(
964 contractName_, contractType_, contractAllocatableMode_)) {
969QString ImportViewModel::displaySuggestionSummary(
const QString& value)
const {
970 return value.isEmpty() ? tr(
"0% Confidence - No suggestion") : value;
973QString ImportViewModel::currentTransactionId()
const {
974 return currentTransactionView_.
id;
977QStringList ImportViewModel::currentTransactionPropertyIds()
const {
978 return currentTransactionView_.propertyIds;
981QString ImportViewModel::currentTransactionActorId()
const {
982 return currentTransactionView_.actorId;
986 if (confidence >= 0.9) {
987 return kSuggestionSuccess;
989 if (confidence >= 0.4) {
990 return kSuggestionWarning;
992 return kSuggestionDanger;
996 return currentTransactionView_.actorSuggestionConfidence;
1000 return displaySuggestionSummary(
1001 currentTransactionView_.actorSuggestionSummary);
1005 return currentTransactionView_.propertySuggestionConfidence;
1009 return displaySuggestionSummary(
1010 currentTransactionView_.propertySuggestionSummary);
1014 return currentTransactionView_.contractSuggestionConfidence;
1018 return displaySuggestionSummary(
1019 currentTransactionView_.contractSuggestionSummary);
1023 return currentTransactionView_.allocatableSuggestionConfidence;
1027 return displaySuggestionSummary(
1028 currentTransactionView_.allocatableSuggestionSummary);
Declares QAction wrappers exposed to the UI layer and QML.
Declares the QML API for import overview and draft review.
Coordinates asynchronous statement imports and in-memory draft sessions.
Declarations for the UI Navigation component.
Declarations for the UI Origins component.
Declarations for the UI payload mapper helpers.
Declares the centralized UI settings view model exposed to QML.
Declarations for the UI Status component.
Declares lightweight conversions between common Qt string types and standard strings.
Provides translated C++ UI strings for shell, workflow, adapter and view model code.
Declarations for the UI Trace component.
Declares the workspace selection state synchronized with the store.
Declares read-only workspace selectors for QML payloads.
Declares the UI workspace snapshot store.
Owns the main window actions and exposes them to QML.
void importFileSelected(const QString &path)
Emitted after a single import file was selected by the user.
void importFileDropped(const QString &path)
Emitted when a file was dropped onto an import target in QML.
void importFilesSelected(const QStringList &paths)
Emitted after multiple import files were selected by the user.
void importFilesDropped(const QStringList &paths)
Emitted when multiple files were dropped onto an import target in QML.
Q_INVOKABLE void initializeImportView()
Initializes import view state when the view is opened.
void setSettings(Settings *value)
Sets settings used for import defaults.
Q_INVOKABLE void commitAmountText()
Commits the amount field to the workflow draft.
Q_INVOKABLE void startImport()
Starts importing the selected files.
Q_INVOKABLE void finalize()
Finalizes the active statement draft through the import workflow.
void setImportWorkflow(ImportWorkflow *value)
Sets the import workflow used for import runs and draft review.
void setAmountText(const QString &value)
Updates the amount field.
QStringList importSourceLabels
QString selectedContractType
Q_INVOKABLE void discard()
Discards the active statement draft.
void setWorkspaceRoles(WorkspaceStore *store, WorkspaceCommands *commands, WorkspaceSelection *selection, WorkspaceSelectors *selectors)
Sets workspace roles used for import logs, catalog and selection.
QVariantList actorOptions
Q_INVOKABLE void selectStatusAtIndex(int index)
Selects a transaction status option.
Q_INVOKABLE void toggleAllocatable()
Toggles the current draft allocatable state.
Q_INVOKABLE void selectContractAtIndex(int index)
Selects a contract option.
Q_INVOKABLE void deleteImportLog(const QString &logId, bool draftAttached, const QString &draftId)
Deletes an import log and attached draft state when requested.
Q_INVOKABLE void selectNextDraft()
Selects the next statement draft.
Q_INVOKABLE void addContract()
Creates and selects a contract for the current draft.
QString contractNamePlaceholder
QVariantList statusOptions
bool canDeleteTransaction
void setStatementName(const QString &value)
Updates the active statement draft name field.
Q_INVOKABLE void addProperty()
Creates and selects a property for the current draft.
Q_INVOKABLE void commitValutaText()
Commits the valuta field to the workflow draft.
Q_INVOKABLE void returnToImport()
Returns from draft review to the import overview.
Q_INVOKABLE void pauseImport()
Pauses the current import job.
ImportViewModel(QObject *parent=nullptr)
Creates the import view model.
Q_INVOKABLE void selectPreviousTransactionDraft()
Selects the previous transaction draft.
QString allocatableSuggestionText
Q_INVOKABLE void cancelCurrentImport()
Cancels the current import job.
Q_INVOKABLE void commitBookingDateText()
Commits the booking date field to the workflow draft.
void setStatus(Status *value)
Sets shell status output used by import actions.
QString propertySuggestionSummary
Q_INVOKABLE void openImportLog(const QString &logId, bool draftAttached, const QString &statementId, const QString &draftId)
Opens an import log from the sidebar.
Q_INVOKABLE void setPropertySelected(const QString &propertyId, bool selected)
Updates whether a property is selected for the current draft.
bool effectiveAllocatable
double actorSuggestionConfidence
int contractAllocatableModeIndex
int currentTransactionNumber
Q_INVOKABLE int suggestionTone(double confidence) const
Maps suggestion confidence to a presentation tone.
void setContractType(const QString &value)
Updates the quick-create contract type field.
int selectedContractOptionIndex
Q_INVOKABLE void addActor()
Creates and selects an actor for the current draft.
QVariantList contractAllocatableModes
Q_INVOKABLE void resumeImport()
Resumes a paused import job.
QString importFileSummary
Q_INVOKABLE void browseImportPdf()
Opens a file browser for import PDFs.
void setNameText(const QString &value)
Updates the transaction name field.
Q_INVOKABLE void commitNameText()
Commits the transaction name field to the workflow draft.
QString contractSuggestionSummary
void setPropertyName(const QString &value)
Updates the quick-create property name field.
bool canSelectPreviousTransactionDraft READ canSelectPreviousTransactionDraft
void changed()
Emitted when import view model state changed.
Q_INVOKABLE void addTransactionAfterCurrent()
Adds a transaction draft after the current one.
QVariantList propertyOptions
void setManualPathText(const QString &value)
Updates the manual import path field.
Q_INVOKABLE bool isPropertySelected(const QString &propertyId) const
Returns whether a property is selected for the current draft.
Q_INVOKABLE void selectNextTransactionDraft()
Selects the next transaction draft.
double propertySuggestionConfidence READ propertySuggestionConfidence
Q_INVOKABLE void selectPreviousDraft()
Selects the previous statement draft.
QStringList statementStrategyLabels
Q_INVOKABLE void addSelectedImportFiles()
Adds the manual path field to the selected import files.
double contractSuggestionConfidence READ contractSuggestionConfidence
double allocatableSuggestionConfidence READ allocatableSuggestionConfidence
Q_INVOKABLE void deleteCurrentTransaction()
Deletes the current transaction draft.
int selectedActorOptionIndex
void setNavigation(Navigation *value)
Sets shell navigation used by import transitions.
void setContractName(const QString &value)
Updates the quick-create contract name field.
bool canSelectNextTransactionDraft READ canSelectNextTransactionDraft
QString actorSuggestionSummary
void setBookingDateText(const QString &value)
Updates the booking date field.
Q_INVOKABLE void cancelQueuedImports()
Cancels queued import jobs.
void setValutaText(const QString &value)
Updates the valuta field.
Q_INVOKABLE void clearImport()
Clears the local import selection and progress display.
Q_INVOKABLE void selectActorAtIndex(int index)
Selects an actor option.
void setContractAllocatableModeIndex(int index)
Updates selected contract allocatable mode index.
QVariantList contractOptions
void setActorName(const QString &value)
Updates the quick-create actor name field.
void setActions(Actions *value)
Sets shell actions used for browsing files.
Runs PDF imports and holds the active in-memory statement draft session.
QString currentDraftId() const
Returns the active draft id.
void importFailed(const QString &error)
Emitted when an import failed.
bool isRunning() const noexcept
Reports whether an import is running.
bool hasDraft() const noexcept
Reports whether an active statement draft exists.
int queuedCount() const noexcept
Returns queued import file count.
void stateChanged()
Emitted when import workflow state changed.
void importFinished()
Emitted when an import reached a finished state.
void importCanceled()
Emitted when an import was canceled.
Stores the active top-level shell section and settings sub-section.
Stores and exposes globally persisted UI settings for settings-related views.
void importDefaultPathChanged()
Exposes the shell status text shown by the main window.
void setText(const QString &value)
Updates the current status text.
Maps UI intent to core workspace writer commands.
Tracks the currently selected workspace entities.
Projects workspace store data into QML-facing read models.
QStringList attachedImportDraftIds() const
Returns ids of import logs that have attached statement drafts.
Owns the current UI-side workspace snapshot and revision lifecycle.
void dataRevisionChanged()
constexpr auto kFirstFile
constexpr auto kQueuedCount
void traceViewModel(const char *origin, std::string message, core::errors::ErrorContext context={})
Emits a view model trace event.
QVariantList options(const QString &mixed, const QString &allocatable, const QString &nonAllocatable)
Builds contract allocatable mode options.
QString modeAt(const QVariantList &options, int index)
Reads the allocatable mode at an option index.
int indexForMode(const QVariantList &options, const QString &mode)
Finds the option index for an allocatable mode.
QVariantMap mapAt(const QVariantList &rows, int index)
Returns a map at an index in a row list.
int indexById(const QVariantList &rows, const QString &id)
Finds the index of a row id.
QString rowType(const QVariantMap &row)
Reads a row type.
QString rowId(const QVariantMap &row)
Reads a row id.
QVariantList options(const QString &neutral, const QString &unverified, const QString &verified, const QString &completed)
Builds transaction status options.
int indexForStatus(const QVariantList &options, int status)
Finds the option index for a transaction status.
int statusAt(const QVariantList &options, int index)
Reads the status value at an option index.
QString normalizedText(const QString &value)
Normalizes text for case-insensitive UI comparisons.
QString verified()
Label for verified transaction status.
QString neutral()
Label for neutral transaction status.
QString unverified()
Label for unverified transaction status.
QString completed()
Label for completed transaction status.
Declares UI-side workspace command submission.