changeset 560:e3b23d706816 annotations

rename
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 01 Sep 2026 16:25:38 +0200
parents d90ff66a934b
children a802aa368b0a
files ViewerPlugin/Annotations/AnnotationsRestApi.cpp ViewerPlugin/WebApplication/viewer.html ViewerPlugin/WebApplication/viewer.js
diffstat 3 files changed, 81 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/ViewerPlugin/Annotations/AnnotationsRestApi.cpp	Tue Sep 01 16:05:46 2026 +0200
+++ b/ViewerPlugin/Annotations/AnnotationsRestApi.cpp	Tue Sep 01 16:25:38 2026 +0200
@@ -42,7 +42,7 @@
 
 namespace OrthancWSI
 {
-  class AnnotationsManagerId
+  class AnnotationsWorkspaceId
   {
   private:
     std::string            projectId_;
@@ -51,10 +51,10 @@
     unsigned int           frameNumber_;
 
   public:
-    AnnotationsManagerId(const std::string& projectId,
-                         Orthanc::ResourceType level,
-                         const std::string& resourceId,
-                         unsigned int frameNumber) :
+    AnnotationsWorkspaceId(const std::string& projectId,
+                           Orthanc::ResourceType level,
+                           const std::string& resourceId,
+                           unsigned int frameNumber) :
       projectId_(projectId),
       level_(level),
       resourceId_(resourceId),
@@ -398,20 +398,20 @@
   }
 
 
-  static std::string GetInfoKey(const AnnotationsManagerId& annotations)
+  static std::string GetInfoKey(const AnnotationsWorkspaceId& annotations)
   {
     return annotations.GetKey() + "|info";
   }
 
 
-  static std::string GetLayersKey(const AnnotationsManagerId& annotations,
+  static std::string GetLayersKey(const AnnotationsWorkspaceId& annotations,
                                   const UserId& user)
   {
     return annotations.GetKey() + "|layers|" + user.GetKey();
   }
 
 
-  static std::string GetFeaturesKey(const AnnotationsManagerId& annotations,
+  static std::string GetFeaturesKey(const AnnotationsWorkspaceId& annotations,
                                     const UserId& user)
   {
     return annotations.GetKey() + "|features|" + user.GetKey();
@@ -829,7 +829,7 @@
   };
 
 
-  class AnnotationsManager : public Orthanc::IDynamicObject
+  class AnnotationsWorkspace : public Orthanc::IDynamicObject
   {
   private:
     class Info : public ISerializable
@@ -937,13 +937,13 @@
 
     typedef std::map<UserId, UserAnnotationsSettings*>   Content;
 
-    Orthanc::ReaderWriterLock         mutex_;
-    AnnotationsManagerId              id_;
-    std::unique_ptr<Info>  info_;
-    Content                           content_;
+    Orthanc::ReaderWriterLock  mutex_;
+    AnnotationsWorkspaceId     id_;
+    std::unique_ptr<Info>      info_;
+    Content                    content_;
 
   public:
-    AnnotationsManager(const AnnotationsManagerId& id) :
+    AnnotationsWorkspace(const AnnotationsWorkspaceId& id) :
       id_(id)
     {
       const std::string key = GetInfoKey(id);
@@ -976,7 +976,7 @@
       }
     }
 
-    ~AnnotationsManager()
+    ~AnnotationsWorkspace()
     {
       for (Content::iterator it = content_.begin(); it != content_.end(); ++it)
       {
@@ -1013,6 +1013,7 @@
 
       target.clear();
 
+      // Loop over the users
       for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it)
       {
         assert(it->second != NULL);
@@ -1034,7 +1035,7 @@
       const UserAnnotationsSettings*      userSettings_;
 
     public:
-      UserReader(AnnotationsManager& that,
+      UserReader(AnnotationsWorkspace& that,
                  const UserId& userId) :
         lock_(that.mutex_),
         info_(*that.info_),
@@ -1118,7 +1119,7 @@
     {
     private:
       Orthanc::ReaderWriterLock::WriteLock  lock_;
-      AnnotationsManager&                   that_;
+      AnnotationsWorkspace&                 that_;
       UserId                                userId_;
       UserAnnotationsSettings*              userSettings_;
 
@@ -1128,7 +1129,7 @@
       }
 
     public:
-      UserWriter(AnnotationsManager& that,
+      UserWriter(AnnotationsWorkspace& that,
                  const UserId& userId) :
         lock_(that.mutex_),
         that_(that),
@@ -1226,7 +1227,7 @@
   };
 
 
-  class CachedAnnotationsManager : public boost::noncopyable
+  class CachedAnnotationsWorkspace : public boost::noncopyable
   {
   private:
     boost::shared_ptr<Orthanc::IDynamicObject>  cached_;
@@ -1249,7 +1250,7 @@
     }
 
   public:
-    CachedAnnotationsManager(const AnnotationsManagerId& id)
+    CachedAnnotationsWorkspace(const AnnotationsWorkspaceId& id)
     {
       const std::string key = id.GetKey();
 
@@ -1257,14 +1258,14 @@
 
       if (cached_.get() == NULL)
       {
-        cached_.reset(new AnnotationsManager(id));
+        cached_.reset(new AnnotationsWorkspace(id));
         GetCache().Store(key, cached_, 1);
       }
     }
 
-    AnnotationsManager& GetContent() const
+    AnnotationsWorkspace& GetContent() const
     {
-      return dynamic_cast<AnnotationsManager&>(*cached_);
+      return dynamic_cast<AnnotationsWorkspace&>(*cached_);
     }
   };
 
@@ -1272,10 +1273,10 @@
   class AnnotationsCommandContext : public boost::noncopyable
   {
   private:
-    std::unique_ptr<IAuthenticatedUser>        user_;
-    Json::Value                                body_;
-    std::unique_ptr<AnnotationsManagerId>      managerId_;
-    std::unique_ptr<CachedAnnotationsManager>  manager_;
+    std::unique_ptr<IAuthenticatedUser>          user_;
+    Json::Value                                  body_;
+    std::unique_ptr<AnnotationsWorkspaceId>      workspaceId_;
+    std::unique_ptr<CachedAnnotationsWorkspace>  workspace_;
 
   public:
     AnnotationsCommandContext(const OrthancPluginHttpRequest* request)
@@ -1298,18 +1299,18 @@
       const std::string resourceId = Orthanc::SerializationToolbox::ReadString(body_, "resource");
       unsigned int frameNumber = Orthanc::SerializationToolbox::ReadUnsignedInteger(body_, "frame", 0 /* default frame */);
 
-      managerId_.reset(new AnnotationsManagerId(projectId, Orthanc::StringToResourceType(level.c_str()), resourceId, frameNumber));
+      workspaceId_.reset(new AnnotationsWorkspaceId(projectId, Orthanc::StringToResourceType(level.c_str()), resourceId, frameNumber));
 
-      IAuthenticatedUser::ProjectRole role = user_->GetRoleInProject(managerId_->GetProjectId());
+      IAuthenticatedUser::ProjectRole role = user_->GetRoleInProject(workspaceId_->GetProjectId());
 
       if (role != IAuthenticatedUser::ProjectRole_Instructor &&
           role != IAuthenticatedUser::ProjectRole_Learner)
       {
         throw Orthanc::OrthancException(Orthanc::ErrorCode_ForbiddenAccess, "User \"" + user_->Format() +
-                                        "\" is not instructor or learner of project \"" + managerId_->GetProjectId() + "\"");
+                                        "\" is not instructor or learner of project \"" + workspaceId_->GetProjectId() + "\"");
       }
 
-      manager_.reset(new CachedAnnotationsManager(*managerId_));
+      workspace_.reset(new CachedAnnotationsWorkspace(*workspaceId_));
     }
 
     const IAuthenticatedUser& GetUser() const
@@ -1318,10 +1319,10 @@
       return *user_;
     }
 
-    const AnnotationsManagerId& GetAnnotationsId() const
+    const AnnotationsWorkspaceId& GetWorkspaceId() const
     {
-      assert(managerId_.get() != NULL);
-      return *managerId_;
+      assert(workspaceId_.get() != NULL);
+      return *workspaceId_;
     }
 
     std::string GetBodyString(const char* field) const
@@ -1341,10 +1342,10 @@
       }
     }
 
-    AnnotationsManager& GetAnnotations()
+    AnnotationsWorkspace& GetWorkspace()
     {
-      assert(manager_.get() != NULL);
-      return manager_->GetContent();
+      assert(workspace_.get() != NULL);
+      return workspace_->GetContent();
     }
   };
 
@@ -1364,9 +1365,9 @@
   }
 
 
-  void GetAnnotationsInfo(OrthancPluginRestOutput* output,
-                          const char* url,
-                          const OrthancPluginHttpRequest* request)
+  void GetWorkspaceInfo(OrthancPluginRestOutput* output,
+                        const char* url,
+                        const OrthancPluginHttpRequest* request)
   {
     if (ProtectPostRequest(output, request))
     {
@@ -1375,7 +1376,7 @@
       Json::Value answer;
 
       {
-        AnnotationsManager::UserReader reader(context.GetAnnotations(), context.GetUser().GetAnnotatingId());
+        AnnotationsWorkspace::UserReader reader(context.GetWorkspace(), context.GetUser().GetAnnotatingId());
         answer["description"] = reader.GetProjectDescription();
         answer["name"] = reader.GetProjectName();
       }
@@ -1407,7 +1408,7 @@
       Json::Value answer;
 
       {
-        AnnotationsManager::UserReader reader(context.GetAnnotations(), context.GetUser().GetAnnotatingId());
+        AnnotationsWorkspace::UserReader reader(context.GetWorkspace(), context.GetUser().GetAnnotatingId());
         reader.ListLayers(answer);
       }
 
@@ -1427,7 +1428,7 @@
       Json::Value answer;
 
       {
-        AnnotationsManager::UserWriter writer(context.GetAnnotations(), context.GetUser().GetAnnotatingId());
+        AnnotationsWorkspace::UserWriter writer(context.GetWorkspace(), context.GetUser().GetAnnotatingId());
         writer.CreateUserLayer(answer);
       }
 
@@ -1447,7 +1448,7 @@
       UserLayer updated(context.GetBodyField("layer"));
 
       {
-        AnnotationsManager::UserWriter writer(context.GetAnnotations(), context.GetUser().GetAnnotatingId());
+        AnnotationsWorkspace::UserWriter writer(context.GetWorkspace(), context.GetUser().GetAnnotatingId());
         writer.UpdateUserLayer(updated);
       }
 
@@ -1467,7 +1468,7 @@
       const std::string layerId = context.GetBodyString("layer-id");
 
       {
-        AnnotationsManager::UserWriter writer(context.GetAnnotations(), context.GetUser().GetAnnotatingId());
+        AnnotationsWorkspace::UserWriter writer(context.GetWorkspace(), context.GetUser().GetAnnotatingId());
         writer.DeleteUserLayer(layerId);
       }
 
@@ -1584,7 +1585,7 @@
     }
 
   public:
-    CachedUserFeatures(const AnnotationsManagerId& annotations,
+    CachedUserFeatures(const AnnotationsWorkspaceId& annotations,
                        const UserId& user)
     {
       const std::string key = GetFeaturesKey(annotations, user);
@@ -1620,7 +1621,7 @@
       Json::Value answer;
 
       {
-        CachedUserFeatures cached(context.GetAnnotationsId(), context.GetUser().GetAnnotatingId());
+        CachedUserFeatures cached(context.GetWorkspaceId(), context.GetUser().GetAnnotatingId());
         cached.GetFeatures().GetContent(answer[KEY_FEATURES]);
       }
 
@@ -1642,7 +1643,7 @@
       AnnotationsCommandContext context(request);
 
       {
-        CachedUserFeatures cached(context.GetAnnotationsId(), context.GetUser().GetAnnotatingId());
+        CachedUserFeatures cached(context.GetWorkspaceId(), context.GetUser().GetAnnotatingId());
         cached.GetFeatures().SetContent(context.GetBodyField(KEY_FEATURES));
       }
 
@@ -1667,7 +1668,7 @@
       const std::string query = context.GetBodyString("query");
 
       std::set<UserId> users;
-      context.GetAnnotations().SearchActiveUsers(users, query);
+      context.GetWorkspace().SearchActiveUsers(users, query);
 
       Json::Value answer = Json::arrayValue;
 
@@ -1706,7 +1707,7 @@
       AnnotationsCommandContext context(request);
 
       std::set<UserId> users;
-      context.GetAnnotations().ListUsersSharingLayerWith(users, context.GetUser().GetAnnotatingId());
+      context.GetWorkspace().ListUsersSharingLayerWith(users, context.GetUser().GetAnnotatingId());
 
       Json::Value answer = Json::arrayValue;
 
@@ -1738,7 +1739,7 @@
       Json::Value answer;
 
       {
-        AnnotationsManager::UserReader reader(context.GetAnnotations(), user);
+        AnnotationsWorkspace::UserReader reader(context.GetWorkspace(), user);
         reader.ListLayersSharedWith(answer, context.GetUser().GetAnnotatingId());
       }
 
@@ -1763,7 +1764,7 @@
       const std::string layerId = context.GetBodyString("layer");
 
       {
-        AnnotationsManager::UserWriter writer(context.GetAnnotations(), context.GetUser().GetAnnotatingId());
+        AnnotationsWorkspace::UserWriter writer(context.GetWorkspace(), context.GetUser().GetAnnotatingId());
         writer.ImportSharedLayer(author, layerId);
       }
 
@@ -1787,7 +1788,7 @@
       const std::string layerId = context.GetBodyString("layer");
 
       {
-        AnnotationsManager::UserWriter writer(context.GetAnnotations(), context.GetUser().GetAnnotatingId());
+        AnnotationsWorkspace::UserWriter writer(context.GetWorkspace(), context.GetUser().GetAnnotatingId());
         writer.RemoveSharedLayer(layerId);
       }
 
@@ -1807,7 +1808,7 @@
       SharedLayer updated(context.GetBodyField("layer"));
 
       {
-        AnnotationsManager::UserWriter writer(context.GetAnnotations(), context.GetUser().GetAnnotatingId());
+        AnnotationsWorkspace::UserWriter writer(context.GetWorkspace(), context.GetUser().GetAnnotatingId());
         writer.UpdateSharedLayer(updated);
       }
 
@@ -1845,7 +1846,7 @@
       std::list<SharedLayerId> layers;
 
       {
-        AnnotationsManager::UserReader reader(context.GetAnnotations(), context.GetUser().GetAnnotatingId());
+        AnnotationsWorkspace::UserReader reader(context.GetWorkspace(), context.GetUser().GetAnnotatingId());
         reader.ListSharedLayers(layers);
       }
 
@@ -1863,7 +1864,7 @@
 
 void RegisterAnnotationsRestApi()
 {
-  OrthancPlugins::RegisterRestCallback<OrthancWSI::GetAnnotationsInfo>("/wsi/api/annotations-info", true);
+  OrthancPlugins::RegisterRestCallback<OrthancWSI::GetWorkspaceInfo>("/wsi/api/workspace-info", true);
 
   if (OrthancWSI::ViewerConfiguration::GetInstance().AreAnnotationsEnabled())
   {
--- a/ViewerPlugin/WebApplication/viewer.html	Tue Sep 01 16:05:46 2026 +0200
+++ b/ViewerPlugin/WebApplication/viewer.html	Tue Sep 01 16:25:38 2026 +0200
@@ -141,7 +141,7 @@
     <div id="app">
       <div id="map" :style="{ background: mapBackground }">
         <div id="toolbar-top" style="display:none" v-show="toolbarsVisible">
-          <div class="btn-group" role="group" v-if="annotationsInfo.enabled">
+          <div class="btn-group" role="group" v-if="workspaceInfo.enabled">
             <button type="button" class="btn btn-outline-secondary icon-btn"
                     :class="{ active: activeDrawTool === 'select' }"
                     data-bs-toggle="tooltip" data-bs-placement="bottom" title="Select annotation"
@@ -206,7 +206,7 @@
             </button>
           </div>
 
-          <div class="btn-group" role="group" v-if="annotationsInfo.enabled">
+          <div class="btn-group" role="group" v-if="workspaceInfo.enabled">
             <button type="button" class="btn btn-outline-secondary icon-btn"
                     :class="{ active: activeDrawTool === 'move' }"
                     data-bs-toggle="tooltip" data-bs-placement="bottom" title="Move annotation"
@@ -230,7 +230,7 @@
           </div>
 
           <div class="alert alert-danger alert-dismissible d-inline-block py-0" role="alert"
-               v-if="annotationsInfo.enabled && !annotationsInfo.persistent">
+               v-if="workspaceInfo.enabled && !workspaceInfo.persistent">
             Your annotations will not be saved
             <button type="button" class="btn-close top-50 translate-middle-y" data-bs-dismiss="alert" aria-label="Close"></button>
           </div>
@@ -289,21 +289,21 @@
       </div>
 
       <div class="offcanvas offcanvas-end" data-bs-backdrop="false" data-bs-scroll="true"
-           tabindex="-1" id="right-panel" v-show="annotationsInfo.enabled">
+           tabindex="-1" id="right-panel" v-show="workspaceInfo.enabled">
         <div class="offcanvas-header">
           <h5 class="offcanvas-title">Annotations</h5>
           <button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
         </div>
         <div class="offcanvas-body p-2">
-          <h5 v-if="annotationsInfo.name !== ''">{{ annotationsInfo.name }}</h5>
+          <h5 v-if="workspaceInfo.name !== ''">{{ workspaceInfo.name }}</h5>
 
-          <p v-if="annotationsInfo.description !== ''">
-            <small>{{ annotationsInfo.description }}</small>
+          <p v-if="workspaceInfo.description !== ''">
+            <small>{{ workspaceInfo.description }}</small>
           </p>
 
-          <p v-if="annotationsInfo.user !== ''">
+          <p v-if="workspaceInfo.user !== ''">
             <small>Logged as:</small>
-            <span class="badge bg-secondary">{{ annotationsInfo.user }}</span>
+            <span class="badge bg-secondary">{{ workspaceInfo.user }}</span>
           </p>
 
           <div class="d-flex align-items-center mb-1">
@@ -322,7 +322,7 @@
                 <th class="p-0 text-center fw-normal" title="Color">C</th>
                 <th class="px-1 py-0 fw-normal">Name</th>
                 <th class="p-0 text-center fw-normal" title="Share layer with other users"
-                    v-if="annotationsInfo.sharing">S</th>
+                    v-if="workspaceInfo.sharing">S</th>
                 <th class="p-0"></th>
               </tr>
             </thead>
@@ -352,7 +352,7 @@
                          v-model:value="layer.name"
                          v-on:change="SaveUserLayer(layer)">
                 </td>
-                <td class="text-center align-middle p-0" v-if="annotationsInfo.sharing">
+                <td class="text-center align-middle p-0" v-if="workspaceInfo.sharing">
                   <button type="button" class="btn btn-link p-1"
                           v-on:click="ShowShareUserLayerModal(layer)">
                     <i class="bi bi-share"></i>
@@ -372,7 +372,7 @@
 
           <hr class="my-4">
 
-          <div class="d-flex align-items-center mb-1" v-if="annotationsInfo.sharing">
+          <div class="d-flex align-items-center mb-1" v-if="workspaceInfo.sharing">
             <h5>Shared layers</h5>
             <button type="button" class="btn btn-primary btn-sm ms-auto"
                     v-on:click="ShowImportSharedLayerModal()">
@@ -381,7 +381,7 @@
             </button>
           </div>
 
-          <table class="table table-sm table-borderless mb-3 align-middle" v-if="annotationsInfo.sharing">
+          <table class="table table-sm table-borderless mb-3 align-middle" v-if="workspaceInfo.sharing">
             <thead class="small text-muted">
               <tr>
                 <th class="p-0 text-center fw-normal" title="Visible">V</th>
@@ -420,11 +420,11 @@
           </table>
 
           <button class="btn btn-sm btn-primary w-100 mb-2" v-on:click="ReloadSharedLayersContent()"
-                  v-if="annotationsInfo.sharing && sharedLayers.length > 0">
+                  v-if="workspaceInfo.sharing && sharedLayers.length > 0">
             <i class="bi bi-arrow-clockwise me-2 align-middle"></i> Reload shared content
           </button>
 
-          <hr class="my-4" v-if="annotationsInfo.sharing">
+          <hr class="my-4" v-if="workspaceInfo.sharing">
 
           <div v-show="selectedFeature !== null" class="mb-3">
             <h5>Current selection</h5>
@@ -458,7 +458,7 @@
       </div>
 
       <button id="right-panel-toggle" type="button" class="btn btn-secondary"
-              style="display:none" v-show="annotationsInfo.enabled && toolbarsVisible"
+              style="display:none" v-show="workspaceInfo.enabled && toolbarsVisible"
               data-bs-toggle="offcanvas" data-bs-target="#right-panel">
         <i class="bi" :class="panelOpen ? 'bi-chevron-compact-right' : 'bi-chevron-compact-left'"></i>
       </button>
--- a/ViewerPlugin/WebApplication/viewer.js	Tue Sep 01 16:05:46 2026 +0200
+++ b/ViewerPlugin/WebApplication/viewer.js	Tue Sep 01 16:25:38 2026 +0200
@@ -38,7 +38,7 @@
       // hue: 0,        // Degrees, in the range between [-180,180]
 
       // Main state for annotations
-      annotationsInfo: {},
+      workspaceInfo: {},
       imageDescription: '',
       userLayers: [],
       sharedLayers: [],
@@ -217,9 +217,9 @@
 
     LoadUserFeatures: function() {
       console.assert(this.drawSource !== null);  // InitializeAnnotations() must have been invoked
-      console.assert(this.annotationsInfo.enabled !== undefined);  // LoadLayers() must have been invoked
+      console.assert(this.workspaceInfo.enabled !== undefined);  // LoadLayers() must have been invoked
 
-      if (!this.annotationsInfo.enabled) {
+      if (!this.workspaceInfo.enabled) {
         return;
       }
 
@@ -384,12 +384,12 @@
 
     LoadAnnotationsInfo: function() {
       var that = this;
-      axios.post('../api/annotations-info',
+      axios.post('../api/workspace-info',
                  this.CreatePostPayload({}))
         .then(function(response) {
-          that.annotationsInfo = response.data;
+          that.workspaceInfo = response.data;
 
-          if (that.annotationsInfo.enabled) {
+          if (that.workspaceInfo.enabled) {
             that.LoadLayers();
           }
         })
@@ -1242,9 +1242,9 @@
 
     ReloadSharedLayersContent: function() {
       console.assert(this.drawSharedSource !== null);  // InitializeAnnotations() must have been invoked
-      console.assert(this.annotationsInfo.enabled !== undefined);  // LoadLayers() must have been invoked
+      console.assert(this.workspaceInfo.enabled !== undefined);  // LoadLayers() must have been invoked
 
-      if (!this.annotationsInfo.sharing) {
+      if (!this.workspaceInfo.sharing) {
         return;
       }