/**

    @page doc_project Project Documentation
    
    @tableofcontents

    This is the documentation of a LibrePCB project. Such a project is represented by an
    instance of the class project#Project.


    @section doc_project_filestructure The File Structure of a Project

        TODO


    @section doc_project_compatibility Compatibility between different application versions

        We need a system which ensures that a project with all its files can be loaded and
        saved with different application versions without corrupting the project.

        For this purpose, each XML file of a project has the attribute "version" in the root
        node. This attribute contains the major version number (uint) of the application
        which is able to load this file. So if the root node contains the attribute
        version="3", this file can be loaded only with application versions >= 3.0.0.

        @see #XmlDomDocument, #SmartXmlFile
        

    @section doc_project_lock Avoid opening a project multiple times (File Lock)

        Opening a project multiple times simultaneously can be dangerous. Even if
        the application's design does not allow to open a project multiple times, it's
        still possible to save a project in a shared folder and open it from different
        computers at the same time (for example). This could demage the project files.

        To avoid such problems, the project#Project's constructor will try to lock the project
        file (*.lpp) with a #FileLock object (project#Project#mFileLock). If the project
        file is already locked by another application instance, the project cannot be
        opened (the project#Project's constructor throws an exception). If the lock file exists
        because the application was crashed while the project was open, the user gets a
        message box to ask whether the last automatic backup should be restored or not
        (see also @ref doc_project_save). The lock will be released automatically when
        the project#Project object is destroyed (RAII, see #FileLock documentation).

        @see #FileLock, project#Project#Project(), project#Project#mFileLock
        
     
    @section doc_project_save Saving Procedere / Automatic Periodically Saving

        It's important to keep all files of a project valid and consistent. If the
        application crashes, the project files must not be demaged. Also a crash while
        saving the project should not demage the project.

        Additionally, an automatic backup/restore system is useful to avoid the loose of
        all the changes made in a project after the last saving. If the application
        crashes with unsaved changes, it should be possible to restore (some of) these
        changes while opening that project the next time. To indicate a crash, the
        #FileLock class is used (see @ref doc_project_lock)

        <b>To try to reach these goals, we use temporary copies of the project files while a
        project is open. This means:</b>
            -# The project is automatically saved to temporary files periodically (autosave).
               Temporary files are indicated by the '~' at the end of the filename. For
               example the class project#Circuit saves its content to "core/circuit.xml~"
               instead of "core/circuit.xml".
            -# If the user wants to save the project, all changes will be saved to the
               temporary files first. Only after ALL changes to the whole project were
               saved SUCCESSFULLY to these files, the changes can be written to the
               original files. The temporary files will still exist. If saving to the 
               temporary files was not successful, you must NOT begin saving the changes 
               to the original files. This way, the original files will stay valid even 
               if there is an error in the save algorithm.
            -# On closing a project, all temporary files will be removed from the harddisc.
            -# If the application crashes while unsaved changes are made in a project, the
               temporary files won't be removed (and also the file lock still exist). On opening
               this project the next time, the user can choose whether to restore the last backup
               or not. If not, the normal, original files will be loaded (as if there was no
               crash). But if the backup should be restored, the backup files will be loaded
               instead. For this purpose, the constructor of classes like project#Project, 
               project#Circuit and so on needs a parameter "bool restore" (or similar).


        <b>Details of #2 of the list above:</b><br>
        To save a project, all related classes need a method with this signature:
        @code bool save(int version, bool toOriginal, QStringList& errors) noexcept; @endcode

        This method will be called to save all the changes of the corresponding object
        <b>and all its child objects</b>. So, the class project#Project provides such a
        method to save <b>the whole project with all its content</b> (circuit, schematics
        and so on). If the parameter "toOriginal" is false, all changes will be saved to
        the temporary files. Otherwise they are saved to the original files. Error
        messages must be appended the QStringList "errors" (after translation). All
        entries in the list will be printet out in a message box. The return value is true
        if the saving proccess was successful, and false if there was an error. These
        methods should never throw an exception (keyword "noexcept").

        If an error occurs while saving the project, you should not abort the saving
        proccess. "Save all what you can" is the name of the game :-) Simply add the
        error message to the error list and return "false" after the job is finished.

        The class project#ProjectEditor provides the public slot project#ProjectEditor#saveProject().
        This method will try to save the whole project to the temporary files. <b>Only if 
        this call has returned "true" (project successfully saved to temporary files), it 
        will also save the project to the original files.</b>


    @section doc_project_undostack The undo/redo system (Command Design Pattern)

        It's very important to have undo and a redo commands for the whole project
        (and maybe also for independent parts of the project). For this purpose we use
        the "Command Design Pattern". Our common classes #UndoCommand and #UndoStack
        implement this design pattern. Look at their documentation for more details.

        @note The documentation "Overview of Qt's Undo Framework" (http://qt-project.org/doc/qt-5/qundo.html)
        and/or other documentations about the Command Design Pattern may be useful to
        understand the whole undo/redo system. Our own undo classes are quite similar to
        Qt's classes QUndoCommand and QUndoStack, but provide some additional functionality.
        
        All #UndoCommand subclasses which are used to modify a project#Project are located
        in the static library "librepcbproject". But the #UndoStack is only used in the
        library "librepcbprojecteditor", so it is located there: project#ProjectEditor#mUndoStack.
        
        All important changes to the project which should appear in the undo stack
        needs to be implemented as a subclass of #UndoCommand and must be appended to
        project#ProjectEditor#mUndoStack. Changes which do not need an undo action (like
        changing the color of a layer) can be done without the use of the undo/redo
        system. These changes then cannot be undone. Basically, all changes to the
        circuit/schematics/boards and so on must have an undo action. If you are unsure
        if you should use the project's undo/redo system, try to answer the question
        "do the user wants to undo/redo this action with the undo/redo buttons in the
        schematic- or board-editor?".

        It's possible to use seperate #UndoStack objects for independent parts of the
        project. For example, changing the project settings could be done by using an
        undo/redo system to provide an undo command. But these undo stacks need their
        own undo/redo buttons. The undo/redo buttons in the schematic editor and in the
        board editor are only connected to the stack project#ProjectEditor#mUndoStack.

        #UndoCommand objects can also have an unlimited amount of child objects.
        This is very useful to group actions together. For example, if multiple symbols
        are selected in the schematic and the user wants to remove them all, multiple
        #UndoCommand objects will be created (one for each symbol). But if the user
        now wants to undo the deletion, the undo command (Ctrl+Z) will only bring back
        the last symbol, so the user needs to press the undo command multiple times. This
        is not good. So we use the parent/child mechanism of #UndoCommand. This means,
        we will still create a #UndoCommand for each removed symbol. But we will also
        create a parent #UndoCommand for all these child commands. Only the parent command
        will be added to the undo stack (for example project#ProjectEditor#mUndoStack).
        Now, if the user wants to undo the deletion, he only needs to press undo (Ctrl+Z)
        once. And with pressing redo (Ctrl+Y) once, all symbols will be restored.

        @see #UndoCommand, #UndoStack, project#ProjectEditor#mUndoStack
        @see http://qt-project.org/doc/qt-5/qundo.html (Overview of Qt's Undo Framework)

*/
