feat(gui): add document-origin tracking and display in window title (#16)
Some checks failed
Build and Test / build (push) Has been cancelled

- Add originForDocument(), setDocumentOrigin(), clearDocumentOrigin()
  methods to OriginManager
- Add signalDocumentOriginChanged signal for UI updates
- Add document-to-origin tracking map in OriginManager
- Update MDIView::buildWindowTitle() to append origin suffix for
  non-local origins (e.g., 'Part001 [Silo]')

This implements Issue #16: Document origin tracking and display
This commit is contained in:
2026-02-05 14:53:45 -06:00
parent db85277f26
commit 015df38328
3 changed files with 92 additions and 0 deletions

View File

@@ -44,7 +44,9 @@
#include "Application.h"
#include "Document.h"
#include "FileDialog.h"
#include "FileOrigin.h"
#include "MainWindow.h"
#include "OriginManager.h"
#include "ViewProviderDocumentObject.h"
@@ -522,6 +524,13 @@ QString MDIView::buildWindowTitle() const
QString windowTitle;
if (auto document = getAppDocument()) {
windowTitle.append(QString::fromStdString(document->Label.getStrValue()));
// Append origin suffix for non-local origins
FileOrigin* origin = OriginManager::instance()->originForDocument(document);
if (origin && origin->type() != OriginType::Local) {
windowTitle.append(QStringLiteral(" [%1]")
.arg(QString::fromStdString(origin->nickname())));
}
}
return windowTitle;

View File

@@ -231,6 +231,63 @@ FileOrigin* OriginManager::findOwningOrigin(App::Document* doc) const
return nullptr;
}
FileOrigin* OriginManager::originForDocument(App::Document* doc) const
{
if (!doc) {
return nullptr;
}
// Check explicit association first
auto it = _documentOrigins.find(doc);
if (it != _documentOrigins.end()) {
FileOrigin* origin = getOrigin(it->second);
if (origin) {
return origin;
}
// Origin was unregistered, clear stale association
_documentOrigins.erase(it);
}
// Fall back to ownership detection
FileOrigin* owner = findOwningOrigin(doc);
if (owner) {
// Cache the result
_documentOrigins[doc] = owner->id();
return owner;
}
return nullptr;
}
void OriginManager::setDocumentOrigin(App::Document* doc, FileOrigin* origin)
{
if (!doc) {
return;
}
std::string originId = origin ? origin->id() : "";
if (origin) {
_documentOrigins[doc] = originId;
} else {
_documentOrigins.erase(doc);
}
signalDocumentOriginChanged(doc, originId);
}
void OriginManager::clearDocumentOrigin(App::Document* doc)
{
if (!doc) {
return;
}
auto it = _documentOrigins.find(doc);
if (it != _documentOrigins.end()) {
_documentOrigins.erase(it);
}
}
FileOrigin* OriginManager::originForNewDocument() const
{
return currentOrigin();

View File

@@ -121,6 +121,27 @@ public:
*/
FileOrigin* findOwningOrigin(App::Document* doc) const;
/**
* Get the origin associated with a document.
* First checks explicit association, then uses findOwningOrigin().
* @param doc The document to check
* @return The document's origin or nullptr if unknown
*/
FileOrigin* originForDocument(App::Document* doc) const;
/**
* Associate a document with an origin.
* @param doc The document
* @param origin The origin to associate (nullptr to clear)
*/
void setDocumentOrigin(App::Document* doc, FileOrigin* origin);
/**
* Clear document origin association (called when document closes).
* @param doc The document being closed
*/
void clearDocumentOrigin(App::Document* doc);
/**
* Get the appropriate origin for a new document.
* Returns the current origin.
@@ -137,6 +158,8 @@ public:
fastsignals::signal<void(const std::string&)> signalOriginUnregistered;
/** Emitted when current origin changes */
fastsignals::signal<void(const std::string&)> signalCurrentOriginChanged;
/** Emitted when a document's origin association changes */
fastsignals::signal<void(App::Document*, const std::string&)> signalDocumentOriginChanged;
//@}
protected:
@@ -151,6 +174,9 @@ private:
static OriginManager* _instance;
std::map<std::string, std::unique_ptr<FileOrigin>> _origins;
std::string _currentOriginId;
// Document-to-origin associations (doc -> origin ID)
mutable std::map<App::Document*, std::string> _documentOrigins;
};
} // namespace Gui