Files
create/src/Gui/FileOrigin.h
forbes 87a0af0b0f phase 1: copy Kindred-only files onto upstream/main (FreeCAD 1.2.0-dev)
Wholesale copy of all Kindred Create additions that don't conflict with
upstream FreeCAD code:

- kindred-icons/ (1444 Catppuccin Mocha SVG icon overrides)
- src/Mod/Create/ (Kindred Create workbench)
- src/Gui/ Kindred source files (FileOrigin, OriginManager,
  OriginSelectorWidget, CommandOrigin, BreadcrumbToolBar, EditingContext)
- src/Gui/Icons/ (Kindred branding and silo icons)
- src/Gui/PreferencePacks/KindredCreate/
- src/Gui/Stylesheets/ (KindredCreate.qss, images_dark-light/)
- package/ (rattler-build recipe)
- docs/ (architecture, guides, specifications)
- .gitea/ (CI workflows, issue templates)
- mods/silo, mods/ztools submodules
- .gitmodules (Kindred submodule URLs)
- resources/ (kindred-create.desktop, kindred-create.xml)
- banner-logo-light.png, CONTRIBUTING.md
2026-02-13 14:03:58 -06:00

277 lines
10 KiB
C++

/***************************************************************************
* Copyright (c) 2025 Kindred Systems *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_FILEORIGIN_H
#define GUI_FILEORIGIN_H
#include <string>
#include <QIcon>
#include <FCGlobal.h>
#include <fastsignals/signal.h>
namespace App {
class Document;
}
namespace Gui {
/**
* @brief Classification of origin types
*/
enum class OriginType {
Local, ///< Local filesystem storage
PLM, ///< Product Lifecycle Management system (e.g., Silo)
Cloud, ///< Generic cloud storage
Custom ///< User-defined origin type
};
/**
* @brief Connection state for origins that require network access
*/
enum class ConnectionState {
Disconnected, ///< Not connected
Connecting, ///< Connection in progress
Connected, ///< Successfully connected
Error ///< Connection error occurred
};
/**
* @brief Abstract base class for document origin handlers
*
* FileOrigin provides an interface for different storage backends
* that can handle FreeCAD documents. Each origin defines workflows
* for creating, opening, saving, and managing documents.
*
* Key insight: Origins don't change where files are stored - all documents
* are always saved locally. Origins change the workflow and identity model:
* - Local: Document identity = file path, no external tracking
* - PLM: Document identity = database UUID, syncs with external system
*/
class GuiExport FileOrigin
{
public:
virtual ~FileOrigin() = default;
///@name Identity Methods
//@{
/** Unique identifier for this origin instance */
virtual std::string id() const = 0;
/** Display name for UI */
virtual std::string name() const = 0;
/** Short nickname for compact UI elements (e.g., toolbar) */
virtual std::string nickname() const = 0;
/** Icon for UI representation */
virtual QIcon icon() const = 0;
/** Origin type classification */
virtual OriginType type() const = 0;
//@}
///@name Workflow Characteristics
//@{
/** Whether this origin tracks documents externally (e.g., in a database) */
virtual bool tracksExternally() const = 0;
/** Whether this origin requires user authentication */
virtual bool requiresAuthentication() const = 0;
//@}
///@name Capability Queries
//@{
/** Whether this origin supports revision history */
virtual bool supportsRevisions() const { return false; }
/** Whether this origin supports Bill of Materials */
virtual bool supportsBOM() const { return false; }
/** Whether this origin supports part numbers */
virtual bool supportsPartNumbers() const { return false; }
/** Whether this origin supports assemblies natively */
virtual bool supportsAssemblies() const { return false; }
//@}
///@name Connection State
//@{
/** Get current connection state */
virtual ConnectionState connectionState() const { return ConnectionState::Connected; }
/** Attempt to connect/authenticate */
virtual bool connect() { return true; }
/** Disconnect from origin */
virtual void disconnect() {}
/** Signal emitted when connection state changes */
fastsignals::signal<void(ConnectionState)> signalConnectionStateChanged;
//@}
///@name Document Identity
//@{
/**
* Get document identity string (path for local, UUID for PLM)
* This is the immutable tracking key for the document.
* @param doc The App document to get identity for
* @return Identity string or empty if not owned by this origin
*/
virtual std::string documentIdentity(App::Document* doc) const = 0;
/**
* Get human-readable document identity (path for local, part number for PLM)
* This is for display purposes in the UI.
* @param doc The App document
* @return Display identity string or empty if not owned
*/
virtual std::string documentDisplayId(App::Document* doc) const = 0;
/**
* Check if this origin owns the given document.
* Ownership is determined by document properties, not file path.
* @param doc The document to check
* @return true if this origin owns the document
*/
virtual bool ownsDocument(App::Document* doc) const = 0;
//@}
///@name Property Synchronization
//@{
/**
* Sync document properties to the origin backend.
* For local origin this is a no-op. For PLM origins this pushes
* property changes to the database.
* @param doc The document to sync
* @return true if sync succeeded
*/
virtual bool syncProperties(App::Document* doc) { (void)doc; return true; }
//@}
///@name Core Document Operations
//@{
/**
* Create a new document managed by this origin.
* Local: Creates empty document
* PLM: Shows part creation form
* @param name Optional document name
* @return The created document or nullptr on failure
*/
virtual App::Document* newDocument(const std::string& name = "") = 0;
/**
* Open a document by identity (non-interactive).
* Local: Opens file at path
* PLM: Opens document by UUID (downloads if needed)
* @param identity Document identity (path or UUID)
* @return The opened document or nullptr on failure
*/
virtual App::Document* openDocument(const std::string& identity) = 0;
/**
* Open a document interactively (shows dialog).
* Local: Shows file picker dialog
* PLM: Shows search/browse dialog
* @return The opened document or nullptr if cancelled/failed
*/
virtual App::Document* openDocumentInteractive() = 0;
/**
* Save the document.
* Local: Saves to disk (if path known)
* PLM: Saves to disk and syncs with external system
* @param doc The document to save
* @return true if save succeeded
*/
virtual bool saveDocument(App::Document* doc) = 0;
/**
* Save document with new identity (non-interactive).
* @param doc The document to save
* @param newIdentity New identity (path or part number)
* @return true if save succeeded
*/
virtual bool saveDocumentAs(App::Document* doc, const std::string& newIdentity) = 0;
/**
* Save document interactively (shows dialog).
* Local: Shows file picker for new path
* PLM: Shows migration or copy workflow dialog
* @param doc The document to save
* @return true if save succeeded
*/
virtual bool saveDocumentAsInteractive(App::Document* doc) = 0;
//@}
///@name Extended Operations (PLM-specific, default to no-op)
//@{
/** Commit document changes to external system */
virtual bool commitDocument(App::Document* doc) { (void)doc; return false; }
/** Pull latest changes from external system */
virtual bool pullDocument(App::Document* doc) { (void)doc; return false; }
/** Push local changes to external system */
virtual bool pushDocument(App::Document* doc) { (void)doc; return false; }
/** Show document info dialog */
virtual void showInfo(App::Document* doc) { (void)doc; }
/** Show Bill of Materials dialog */
virtual void showBOM(App::Document* doc) { (void)doc; }
//@}
protected:
FileOrigin() = default;
// Non-copyable
FileOrigin(const FileOrigin&) = delete;
FileOrigin& operator=(const FileOrigin&) = delete;
};
/**
* @brief Local filesystem origin - default origin for local files
*
* This is the default origin that handles documents stored on the
* local filesystem without any external tracking or synchronization.
*/
class GuiExport LocalFileOrigin : public FileOrigin
{
public:
LocalFileOrigin();
~LocalFileOrigin() override = default;
// Identity
std::string id() const override { return "local"; }
std::string name() const override { return "Local Files"; }
std::string nickname() const override { return "Local"; }
QIcon icon() const override;
OriginType type() const override { return OriginType::Local; }
// Characteristics
bool tracksExternally() const override { return false; }
bool requiresAuthentication() const override { return false; }
// Document identity
std::string documentIdentity(App::Document* doc) const override;
std::string documentDisplayId(App::Document* doc) const override;
bool ownsDocument(App::Document* doc) const override;
// Document operations
App::Document* newDocument(const std::string& name = "") override;
App::Document* openDocument(const std::string& identity) override;
App::Document* openDocumentInteractive() override;
bool saveDocument(App::Document* doc) override;
bool saveDocumentAs(App::Document* doc, const std::string& newIdentity) override;
bool saveDocumentAsInteractive(App::Document* doc) override;
};
} // namespace Gui
#endif // GUI_FILEORIGIN_H