From 95d9a7f0f91707e974274b66ca17827aaa24cb16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Garramu=C3=B1o?= Date: Mon, 23 Sep 2024 04:06:53 -0300 Subject: [PATCH] Added Save/Annotations as JSON. --- src/docs/HISTORY.md | 2 ++ src/lib/mrvCore/mrvHotkey.cpp | 2 ++ src/lib/mrvCore/mrvHotkey.h | 1 + src/lib/mrvFl/mrvCallbacks.cpp | 27 +++++++++++++++++++++ src/lib/mrvFl/mrvCallbacks.h | 1 + src/lib/mrvFl/mrvFileRequester.cpp | 24 ++++++++++++++++++ src/lib/mrvFl/mrvFileRequester.h | 2 ++ src/lib/mrvGL/mrvTimelineViewportEvents.cpp | 3 ++- src/lib/mrvUI/mrvMenus.cpp | 16 +++++++++--- 9 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/docs/HISTORY.md b/src/docs/HISTORY.md index 70a0f0992..632ba1ef2 100644 --- a/src/docs/HISTORY.md +++ b/src/docs/HISTORY.md @@ -4,6 +4,8 @@ v1.2.9 - Handle **AV_DISPOSITION_ATTACHED_PIC** properly, instead of skipping it. - Added PNG decoder so attached png pictures in .wav files are decoded properly. +- Added a File->Save Annotations as JSON. This allows you to export the + annotations as a .json file. v1.2.8 ====== diff --git a/src/lib/mrvCore/mrvHotkey.cpp b/src/lib/mrvCore/mrvHotkey.cpp index dc73fc5dd..f4ae03234 100644 --- a/src/lib/mrvCore/mrvHotkey.cpp +++ b/src/lib/mrvCore/mrvHotkey.cpp @@ -28,6 +28,7 @@ namespace mrv Hotkey kSaveImage(false, false, false, false, 0); Hotkey kSaveImageToFolder(false, false, false, false, 0); Hotkey kSaveSequence(true, false, false, true, 's'); + Hotkey kSaveAnnotationsAsJson(false, false, false, false, 0); Hotkey kSaveOTIOEDL(false, false, false, false, 0); Hotkey kSavePDF(false, false, false, false, 0); Hotkey kSaveSession(true, false, false, false, 's'); @@ -368,6 +369,7 @@ namespace mrv HotkeyEntry(_("Save Movie or Sequence"), &kSaveSequence), HotkeyEntry(_("Save OTIO Timeline"), &kSaveOTIOEDL), + HotkeyEntry(_("Save Annotations as JSON"), &kSaveAnnotationsAsJson), HotkeyEntry(_("Save PDF Document"), &kSavePDF), HotkeyEntry(_("Save Session"), &kSaveSession), HotkeyEntry(_("Save Session As"), &kSaveSessionAs), diff --git a/src/lib/mrvCore/mrvHotkey.h b/src/lib/mrvCore/mrvHotkey.h index 2627d739b..e637eaf4a 100644 --- a/src/lib/mrvCore/mrvHotkey.h +++ b/src/lib/mrvCore/mrvHotkey.h @@ -96,6 +96,7 @@ namespace mrv extern Hotkey kSaveImageToFolder; extern Hotkey kSaveOTIOEDL; extern Hotkey kSaveSequence; + extern Hotkey kSaveAnnotationsAsJson; extern Hotkey kSavePDF; extern Hotkey kSaveSession; extern Hotkey kSaveSessionAs; diff --git a/src/lib/mrvFl/mrvCallbacks.cpp b/src/lib/mrvFl/mrvCallbacks.cpp index ffa9efcf6..5aaad81a3 100644 --- a/src/lib/mrvFl/mrvCallbacks.cpp +++ b/src/lib/mrvFl/mrvCallbacks.cpp @@ -664,6 +664,33 @@ namespace mrv #endif } + void save_annotations_as_json_cb(Fl_Menu_* w, ViewerUI* ui) + { + auto player = ui->uiView->getTimelinePlayer(); + if (!player) + return; + + const auto& annotations = player->getAllAnnotations(); + if (annotations.empty()) + return; + + const std::string& file = save_annotations(); + if (file.empty()) + return; + + Message j; + std::vector< draw::Annotation > flatAnnotations; + for (const auto& annotation : annotations) + { + flatAnnotations.push_back(*annotation.get()); + } + j["annotations"] = flatAnnotations; + + std::ofstream f(file); + f << j; + } + + void close_current_cb(Fl_Widget* w, ViewerUI* ui) { // Must come before model->close(). diff --git a/src/lib/mrvFl/mrvCallbacks.h b/src/lib/mrvFl/mrvCallbacks.h index 78891d048..dcae2adfb 100644 --- a/src/lib/mrvFl/mrvCallbacks.h +++ b/src/lib/mrvFl/mrvCallbacks.h @@ -49,6 +49,7 @@ namespace mrv void save_single_frame_to_folder_cb(Fl_Menu_* w, ViewerUI* ui); void save_single_frame_cb(Fl_Menu_* w, ViewerUI* ui); + void save_annotations_as_json_cb(Fl_Menu_* w, ViewerUI* ui); void save_movie_cb(Fl_Menu_* w, ViewerUI* ui); void save_pdf_cb(Fl_Menu_* w, ViewerUI* ui); diff --git a/src/lib/mrvFl/mrvFileRequester.cpp b/src/lib/mrvFl/mrvFileRequester.cpp index a54219565..187c67325 100644 --- a/src/lib/mrvFl/mrvFileRequester.cpp +++ b/src/lib/mrvFl/mrvFileRequester.cpp @@ -551,6 +551,30 @@ namespace mrv return file; } + std::string save_annotations(const char* startdir) + { + const std::string kJSON_PATTERN = _("Annotations (*.{json})"); + const std::string kALL_PATTERN = kJSON_PATTERN; + + std::string title = _("Save Annotations to JSON"); + + if (!startdir) + startdir = ""; + + std::string file = file_save_single_requester( + title.c_str(), kALL_PATTERN.c_str(), startdir, true); + + if (file.empty()) + return file; + + if (file.substr(file.size() - 5, file.size()) != ".json") + { + file += ".json"; + } + + return file; + } + std::string save_pdf(const char* startdir) { const std::string kPDF_PATTERN = _("Acrobat PDF (*.{pdf})"); diff --git a/src/lib/mrvFl/mrvFileRequester.h b/src/lib/mrvFl/mrvFileRequester.h index 07a671bb4..bd7ebbbec 100644 --- a/src/lib/mrvFl/mrvFileRequester.h +++ b/src/lib/mrvFl/mrvFileRequester.h @@ -85,6 +85,8 @@ namespace mrv std::string save_movie_or_sequence_file(const char* startfile = nullptr); + std::string save_annotations(const char* startdir = nullptr); + std::string save_pdf(const char* startdir = nullptr); std::string open_session_file(const char* startfile = nullptr); diff --git a/src/lib/mrvGL/mrvTimelineViewportEvents.cpp b/src/lib/mrvGL/mrvTimelineViewportEvents.cpp index 1d84b2377..d71c72475 100644 --- a/src/lib/mrvGL/mrvTimelineViewportEvents.cpp +++ b/src/lib/mrvGL/mrvTimelineViewportEvents.cpp @@ -1053,7 +1053,7 @@ namespace mrv std::shared_ptr< draw::Shape > s; if (annotation) s = annotation->lastShape(); - + p.lastEvent = 0; if (!s->laser) @@ -1070,6 +1070,7 @@ namespace mrv kLaserFadeTimeout, (Fl_Timeout_Handler)laserFade_cb, laserData); } + p.ui->uiMain->fill_menu(p.ui->uiMenuBar); _updateCursor(); return 1; } diff --git a/src/lib/mrvUI/mrvMenus.cpp b/src/lib/mrvUI/mrvMenus.cpp index f6c3c90a0..f02f08ce2 100644 --- a/src/lib/mrvUI/mrvMenus.cpp +++ b/src/lib/mrvUI/mrvMenus.cpp @@ -112,6 +112,19 @@ namespace mrv menu->add( _("File/Save/OTIO EDL Timeline"), kSaveOTIOEDL.hotkey(), (Fl_Callback*)save_timeline_to_disk_cb, ui, mode | FL_MENU_DIVIDER); + + auto player = ui->uiView->getTimelinePlayer(); + mode = 0; + if (!player || !player->hasAnnotations()) + mode = FL_MENU_INACTIVE; + + menu->add( + _("File/Save/Annotations as JSON"), kSaveAnnotationsAsJson.hotkey(), + (Fl_Callback*)save_annotations_as_json_cb, ui, mode | FL_MENU_DIVIDER); + + mode = 0; + if (numFiles == 0) + mode = FL_MENU_INACTIVE; menu->add( _("File/Save/PDF Document"), kSavePDF.hotkey(), (Fl_Callback*)save_pdf_cb, ui, FL_MENU_DIVIDER | mode); @@ -789,9 +802,6 @@ namespace mrv } timeline::Playback playback = timeline::Playback::Stop; - auto player = uiView->getTimelinePlayer(); - if (player) - playback = player->playback(); mode = FL_MENU_RADIO; if (numFiles == 0)