App: Add class ProjectFile to access metadata and data files of a project
This commit is contained in:
204
src/App/ProjectFile.h
Normal file
204
src/App/ProjectFile.h
Normal file
@@ -0,0 +1,204 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef APP_PROJECTFILE_H
|
||||
#define APP_PROJECTFILE_H
|
||||
|
||||
#include <Base/Type.h>
|
||||
#include <zipios++/zipfile.h>
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <xercesc/util/XercesDefs.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
class DOMDocument;
|
||||
class DOMElement;
|
||||
class DOMNode;
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
namespace App
|
||||
{
|
||||
|
||||
class PropertyContainer;
|
||||
class Property;
|
||||
|
||||
/**
|
||||
* @code
|
||||
* ProjectFile proj(project.fcstd);
|
||||
* if (proj.loadDocument()) {
|
||||
* std::list<std::string> names = proj.getObjects();
|
||||
* std::list<std::string> files = proj.getInputFiles(names.front().name);
|
||||
* std::string meshFile = proj.extractInputFile(files.front());
|
||||
* std::ifstream str(meshFile.c_str(), std::ios::in | std::ios::binary);
|
||||
* Mesh::MeshObject mesh;
|
||||
* mesh.load(str);
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
class AppExport ProjectFile
|
||||
{
|
||||
public:
|
||||
struct Object
|
||||
{
|
||||
std::string name;
|
||||
Base::Type type;
|
||||
};
|
||||
struct PropertyFile
|
||||
{
|
||||
std::string file;
|
||||
std::string name;
|
||||
Base::Type type;
|
||||
};
|
||||
struct Metadata
|
||||
{
|
||||
std::string comment;
|
||||
std::string company;
|
||||
std::string createdBy;
|
||||
std::string creationDate;
|
||||
std::string label;
|
||||
std::string lastModifiedBy;
|
||||
std::string lastModifiedDate;
|
||||
std::string license;
|
||||
std::string licenseURL;
|
||||
std::string programVersion;
|
||||
std::string uuid;
|
||||
};
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
ProjectFile();
|
||||
/**
|
||||
* Creates an instance of ProjectFile pointing to a project file.
|
||||
* You have to call @ref loadDocument() afterwards.
|
||||
*/
|
||||
explicit ProjectFile(std::string zipArchive);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~ProjectFile();
|
||||
/**
|
||||
* Copy/move constructor & assignment
|
||||
*/
|
||||
ProjectFile(const ProjectFile&) = delete;
|
||||
ProjectFile(ProjectFile&&) = delete;
|
||||
ProjectFile& operator=(const ProjectFile&) = delete;
|
||||
ProjectFile& operator=(ProjectFile&&) = delete;
|
||||
/**
|
||||
* Assigns the file name of another project file. This clears any internal data, thus
|
||||
* @ref loadDocument() needs to be called afterwards.
|
||||
*/
|
||||
void setProjectFile(const std::string& zipArchive);
|
||||
/**
|
||||
* Loads the embedded document file of the project file. This is needed to query any information
|
||||
* about objects, their type ids or any referenced input files.
|
||||
*/
|
||||
bool loadDocument();
|
||||
/**
|
||||
* Return the meta data of the loaded document.
|
||||
*/
|
||||
Metadata getMetadata() const;
|
||||
/**
|
||||
* Returns a list of all object names with their type ids which are part of the project file.
|
||||
*/
|
||||
std::list<Object> getObjects() const;
|
||||
/**
|
||||
* Returns a list of object names of a given type id which are part of the project file.
|
||||
*/
|
||||
std::list<std::string> getObjectsOfType(const Base::Type&) const;
|
||||
/**
|
||||
* Restores the object identified by its @a name and loads all properties of @a prop
|
||||
* that match with the saved properties.
|
||||
*/
|
||||
bool restoreObject(const std::string& name, App::PropertyContainer*, bool verbose = true);
|
||||
/**
|
||||
* Retrieves the type id of a given object name.
|
||||
*/
|
||||
Base::Type getTypeId(const std::string& name) const;
|
||||
/**
|
||||
* Retrieves a list of input file names and their associated property names and type ids
|
||||
* to the given object name.
|
||||
* @see getInputFiles().
|
||||
*/
|
||||
std::list<PropertyFile> getPropertyFiles(const std::string& name) const;
|
||||
/**
|
||||
* Retrieves a list of input file names referenced to the given object name.
|
||||
* This method does the same as @ref getPropertyFiles() unless that it only
|
||||
* returns the file names.
|
||||
*/
|
||||
std::list<std::string> getInputFiles(const std::string& name) const;
|
||||
/**
|
||||
* Extracts an input file of @a name and saves it as file to the disk.
|
||||
* It's up to the client code to delete the file if needed.
|
||||
*/
|
||||
std::string extractInputFile(const std::string& name);
|
||||
/**
|
||||
* Extracts, via a temporary file the content of an input file of @a name.
|
||||
*/
|
||||
void readInputFile(const std::string& name, std::stringstream& str);
|
||||
/**
|
||||
* Directly extracts the content of an input file of @a name.
|
||||
*/
|
||||
void readInputFileDirect(const std::string& name, std::stringstream& str);
|
||||
/**
|
||||
* Replaces the input file @a name with the content of the given @a stream.
|
||||
* The method returns the file name of the newly created project file.
|
||||
*/
|
||||
std::string replaceInputFile(const std::string& name, std::istream& inp);
|
||||
/**
|
||||
* Replaces the input files with the streams of @a inp.
|
||||
* The method returns the file name of the newly created project file.
|
||||
* If you want to replace the original project file you must call the
|
||||
* method @ref replaceProjectFile() with the returned file name as argument.
|
||||
*/
|
||||
std::string replaceInputFiles(const std::map<std::string, std::istream*>& inp);
|
||||
/**
|
||||
* Replaces the property files with the content of the properties in @a props.
|
||||
* The method returns the file name of the newly created project file.
|
||||
* If you want to replace the original project file you must call the
|
||||
* method @ref replaceProjectFile() with the returned file name as argument.
|
||||
*/
|
||||
std::string replacePropertyFiles(const std::map<std::string, App::Property*>& props);
|
||||
/**
|
||||
* Replaces the project file with the given @a name. If @a keepfile is true
|
||||
* then the renamed original file won't be deleted.
|
||||
* Returns true if the replacement succeeded and false otherwise.
|
||||
* If you want to replace the original project file you must call the
|
||||
* method @ref replaceProjectFile() with the returned file name as argument.
|
||||
*/
|
||||
bool replaceProjectFile(const std::string& name, bool keepfile = false);
|
||||
|
||||
private:
|
||||
void findFiles(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode*, std::list<std::string>&) const;
|
||||
void findFiles(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode*, std::list<PropertyFile>&) const;
|
||||
|
||||
private:
|
||||
std::string stdFile;
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* xmlDocument;
|
||||
};
|
||||
|
||||
|
||||
} // namespace APP
|
||||
|
||||
#endif // APP_PROJECTFILE_H
|
||||
Reference in New Issue
Block a user