1 /* 2 * LibrePCB - Professional EDA for everyone! 3 * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors. 4 * https://librepcb.org/ 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef LIBREPCB_WORKSPACE_H 21 #define LIBREPCB_WORKSPACE_H 22 23 /******************************************************************************* 24 * Includes 25 ******************************************************************************/ 26 #include <librepcb/common/fileio/directorylock.h> 27 #include <librepcb/common/version.h> 28 29 #include <QtCore> 30 31 /******************************************************************************* 32 * Namespace / Forward Declarations 33 ******************************************************************************/ 34 namespace librepcb { 35 36 namespace library { 37 class Library; 38 } 39 40 namespace project { 41 class Project; 42 } 43 44 namespace workspace { 45 46 class ProjectTreeModel; 47 class RecentProjectsModel; 48 class FavoriteProjectsModel; 49 class WorkspaceSettings; 50 class WorkspaceLibraryDb; 51 52 /******************************************************************************* 53 * Class Workspace 54 ******************************************************************************/ 55 56 /** 57 * @brief The Workspace class represents a workspace with all its data (library, 58 * projects, settings, ...) 59 * 60 * To access the settings of the workspace, use the method #getSettings(). 61 */ 62 class Workspace final : public QObject { 63 Q_OBJECT 64 65 public: 66 // Constructors / Destructor 67 Workspace() = delete; 68 Workspace(const Workspace& other) = delete; 69 70 /** 71 * @brief Constructor to open an existing workspace 72 * 73 * @param wsPath The filepath to the workspace directory 74 * @param lockCallback A callback which gets called if the workspace 75 * directory is locked, to decide what to do in this 76 * case. 77 * 78 * @throw Exception If the workspace could not be opened, this constructor 79 * throws an exception. 80 */ 81 explicit Workspace(const FilePath& wsPath, 82 DirectoryLock::LockHandlerCallback lockCallback = nullptr); 83 84 /** 85 * The destructor 86 */ 87 ~Workspace() noexcept; 88 89 // Getters 90 91 /** 92 * @brief Get the filepath to the workspace directory 93 */ getPath()94 const FilePath& getPath() const { return mPath; } 95 96 /** 97 * @brief Get the filepath to the "projects" directory in the workspace 98 */ getProjectsPath()99 const FilePath& getProjectsPath() const { return mProjectsPath; } 100 101 /** 102 * @brief Get the filepath to the version directory (v#) in the workspace 103 */ getMetadataPath()104 const FilePath& getMetadataPath() const { return mMetadataPath; } 105 106 /** 107 * @brief Get the filepath to the "v#/libraries" directory in the workspace 108 */ getLibrariesPath()109 const FilePath& getLibrariesPath() const { return mLibrariesPath; } 110 111 /** 112 * @brief Get the filepath to the "v#/libraries/local" directory 113 */ getLocalLibrariesPath()114 FilePath getLocalLibrariesPath() const { 115 return mLibrariesPath.getPathTo("local"); 116 } 117 118 /** 119 * @brief Get the filepath to the "v#/libraries/remote" directory 120 */ getRemoteLibrariesPath()121 FilePath getRemoteLibrariesPath() const { 122 return mLibrariesPath.getPathTo("remote"); 123 } 124 125 ProjectTreeModel& getProjectTreeModel() const noexcept; 126 RecentProjectsModel& getRecentProjectsModel() const noexcept; 127 FavoriteProjectsModel& getFavoriteProjectsModel() const noexcept; 128 129 /** 130 * @brief Get the workspace settings 131 */ getSettings()132 WorkspaceSettings& getSettings() const { return *mWorkspaceSettings; } 133 134 // Library Management 135 136 /** 137 * @brief Get the workspace library database 138 */ getLibraryDb()139 WorkspaceLibraryDb& getLibraryDb() const { return *mLibraryDb; } 140 141 // Project Management 142 143 /** 144 * @brief setLastRecentlyUsedProject 145 * @param filepath 146 */ 147 void setLastRecentlyUsedProject(const FilePath& filepath) noexcept; 148 149 /** 150 * @brief Check whether a project is in the favorite project list or not 151 * 152 * @param filepath The filepath to a *.lpp project file 153 * 154 * @return True if the specified project is in the favorites list, false 155 * otherwise 156 */ 157 bool isFavoriteProject(const FilePath& filepath) const noexcept; 158 159 /** 160 * @brief Add a project to the favorite projects list 161 * 162 * @param filepath The filepath to a *.lpp project file 163 */ 164 void addFavoriteProject(const FilePath& filepath) noexcept; 165 166 /** 167 * @brief Remove a project from the favorite projects list 168 * 169 * @param filepath The filepath to a *.lpp project file 170 */ 171 void removeFavoriteProject(const FilePath& filepath) noexcept; 172 173 // Operator Overloadings 174 Workspace& operator=(const Workspace& rhs) = delete; 175 176 // Static Methods 177 178 /** 179 * @brief Check whether a filepath points to a valid workspace directory or 180 * not 181 * 182 * @param path A path to a directory 183 * 184 * @return True if the path is a valid workspace directory, false otherwise 185 */ 186 static bool isValidWorkspacePath(const FilePath& path) noexcept; 187 188 /** 189 * @brief getFileFormatVersionsOfWorkspace 190 * @param path 191 * @return 192 */ 193 static QList<Version> getFileFormatVersionsOfWorkspace( 194 const FilePath& path) noexcept; 195 196 /** 197 * @brief getHighestFileFormatVersionOfWorkspace 198 * @param path 199 * @return 200 */ 201 static tl::optional<Version> getHighestFileFormatVersionOfWorkspace( 202 const FilePath& path) noexcept; 203 204 /** 205 * @brief Create a new workspace 206 * 207 * @param path A path to a directory where to create the new workspace 208 * 209 * @throws Exception on error. 210 */ 211 static void createNewWorkspace(const FilePath& path); 212 213 /** 214 * @brief Get the most recently used workspace path 215 * 216 * @return The filepath to the last recently used workspace (may be invalid) 217 */ 218 static FilePath getMostRecentlyUsedWorkspacePath() noexcept; 219 220 /** 221 * @brief Set the most recently used workspace path 222 * 223 * @param path The filepath to the workspace directory 224 */ 225 static void setMostRecentlyUsedWorkspacePath(const FilePath& path) noexcept; 226 227 /** 228 * @brief Current workspace file format version (constant) 229 * 230 * @warning Don't change this value unless you know exactly what you're doing! 231 * 232 * @return File format version 233 */ FILE_FORMAT_VERSION()234 static Version FILE_FORMAT_VERSION() noexcept { 235 return Version::fromString("0.1"); 236 } 237 238 private: // Data 239 /// a FilePath object which represents the workspace directory 240 FilePath mPath; 241 242 /// the directory "projects" 243 FilePath mProjectsPath; 244 245 /// the subdirectory of the current file format version 246 FilePath mMetadataPath; 247 248 /// the directory "v#/libraries" 249 FilePath mLibrariesPath; 250 251 /// to lock the version directory (#mMetadataPath) 252 DirectoryLock mLock; 253 254 /// the WorkspaceSettings object 255 QScopedPointer<WorkspaceSettings> mWorkspaceSettings; 256 257 /// the library database 258 QScopedPointer<WorkspaceLibraryDb> mLibraryDb; 259 260 /// a tree model for the whole projects directory 261 QScopedPointer<ProjectTreeModel> mProjectTreeModel; 262 263 /// a list model of all recent projects 264 QScopedPointer<RecentProjectsModel> mRecentProjectsModel; 265 266 /// a list model of all favorite projects 267 QScopedPointer<FavoriteProjectsModel> mFavoriteProjectsModel; 268 }; 269 270 /******************************************************************************* 271 * End of File 272 ******************************************************************************/ 273 274 } // namespace workspace 275 } // namespace librepcb 276 277 #endif // LIBREPCB_WORKSPACE_H 278