diff --git a/app/src/qt/main_menu_presenter.cpp b/app/src/qt/main_menu_presenter.cpp index 3b2e0927..3d059e5c 100644 --- a/app/src/qt/main_menu_presenter.cpp +++ b/app/src/qt/main_menu_presenter.cpp @@ -116,6 +116,7 @@ MainMenuPresenter::MainMenuPresenter(MainWindowPresenter* mwp) QObject::connect(view->actionLibraryAdd, SIGNAL(triggered()), mwp, SLOT(doActionLibraryNew())); QObject::connect(view->actionLibrarySync, SIGNAL(triggered()), mwp, SLOT(doActionLibrarySync())); QObject::connect(view->actionLibraryOrphans, SIGNAL(triggered()), mwp, SLOT(doActionLibraryOrphans())); + QObject::connect(view->actionLibraryDeprecateOrphanOs, SIGNAL(triggered()), mwp, SLOT(doActionLibraryDeprecateOrphanOs())); QObject::connect(view->actionLibraryDeprecate, SIGNAL(triggered()), mwp, SLOT(doActionLibraryRm())); // menu: Organizer diff --git a/app/src/qt/main_menu_view.cpp b/app/src/qt/main_menu_view.cpp index 76074cbd..3194ad29 100644 --- a/app/src/qt/main_menu_view.cpp +++ b/app/src/qt/main_menu_view.cpp @@ -147,7 +147,14 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView) mainWindow); actionLibrarySync->setStatusTip( tr("Find library Notebooks which reference non-existent documents...")); - // library: deprecate + // library: deprecate orphan Os + actionLibraryDeprecateOrphanOs = new QAction( + QIcon(":/menu-icons/delete.svg"), + tr("Deprecate &orphans"), + mainWindow); + actionLibraryDeprecateOrphanOs->setStatusTip( + tr("Deprecate library Notebooks that has tag which indicates reference of non-existent document...")); + // library: delete actionLibraryDeprecate = new QAction( QIcon(":/menu-icons/delete.svg"), tr("&Delete library"), mainWindow); actionLibraryDeprecate->setStatusTip(tr( @@ -156,6 +163,7 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView) submenuMindLibrary->addAction(actionLibraryAdd); submenuMindLibrary->addAction(actionLibrarySync); submenuMindLibrary->addAction(actionLibraryOrphans); + submenuMindLibrary->addAction(actionLibraryDeprecateOrphanOs); submenuMindLibrary->addAction(actionLibraryDeprecate); // dream ... sanity, integrity, detox, inference, assoc discovery, ... diff --git a/app/src/qt/main_menu_view.h b/app/src/qt/main_menu_view.h index 5a7e2065..5f039026 100644 --- a/app/src/qt/main_menu_view.h +++ b/app/src/qt/main_menu_view.h @@ -86,6 +86,7 @@ class MainMenuView : public QObject QAction* actionLibraryAdd; QAction* actionLibrarySync; QAction* actionLibraryOrphans; + QAction* actionLibraryDeprecateOrphanOs; QAction* actionLibraryDeprecate; QAction* actionMindPreferences; QMenu* submenuMindExport; diff --git a/app/src/qt/main_window_presenter.cpp b/app/src/qt/main_window_presenter.cpp index 91521567..41b4690c 100644 --- a/app/src/qt/main_window_presenter.cpp +++ b/app/src/qt/main_window_presenter.cpp @@ -3466,7 +3466,56 @@ void MainWindowPresenter::handleSyncLibrary() void MainWindowPresenter::doActionLibraryOrphans() { - mind->findLibraryOrphanOs(); + int orphans = mind->findLibraryOrphanOs(); + if(orphans) { + doActionViewOutlines(); + + QMessageBox::information( + &view, + tr("Library Orphans"), + tr( + "Found %1 library Notebooks with orphaned documents. " + "Notebooks were tagged with 'library-orphan-document' tag. " + "Use scopes to filter them out." + ).arg(orphans) + ); + } else { + QMessageBox::information( + &view, + tr("Library Orphans"), + tr("No Notebooks with orphaned documents found.") + ); + } +} + +void MainWindowPresenter::doActionLibraryDeprecateOrphanOs() +{ + vector tags{}; + tags.push_back( + mind->getOntology().findOrCreateTag( + MarkdownDocumentRepresentation::TAG_LIB_DOC_ORPHAN)); + vector os{}; + mind->findOutlinesByTags(tags, os); + + if(os.size()) { + for(Outline* o:os) { + mind->outlineForget(o->getKey()); + } + + QMessageBox::information( + &view, + tr("Library Orphans"), + tr("%1 Notebooks tagged as library orphans were deprecated.").arg(os.size()) + ); + + doActionViewOutlines(); + } else { + QMessageBox::information( + &view, + tr("Library Orphans"), + tr("No Notebooks with library orphan tag found.") + ); + } } void MainWindowPresenter::doActionLibraryRm() diff --git a/app/src/qt/main_window_presenter.h b/app/src/qt/main_window_presenter.h index 1e843c68..8396e802 100644 --- a/app/src/qt/main_window_presenter.h +++ b/app/src/qt/main_window_presenter.h @@ -241,6 +241,7 @@ public slots: void handleNewLibrary(); void doActionLibrarySync(); void doActionLibraryOrphans(); + void doActionLibraryDeprecateOrphanOs(); void handleSyncLibrary(); void doActionLibraryRm(); void handleRmLibrary(); diff --git a/lib/src/mind/mind.cpp b/lib/src/mind/mind.cpp index 9fc392ed..4407e7e2 100644 --- a/lib/src/mind/mind.cpp +++ b/lib/src/mind/mind.cpp @@ -702,7 +702,7 @@ vector* Mind::getNotesOfType(const NoteType& type, const Outline& outline return nullptr; } -void Mind::findOutlinesByTags(const std::vector& tags, std::vector& result) const +void Mind::findOutlinesByTags(const vector& tags, vector& result) const { for(Outline* o:memory.getOutlines()) { bool allMatched = true; @@ -1502,7 +1502,7 @@ void Mind::initWingman() wingmanLlmProvider = WingmanLlmProviders::WINGMAN_PROVIDER_NONE; } -void Mind::findLibraryOrphanOs() +int Mind::findLibraryOrphanOs() { vector orphanOutlines{}; const vector& outlines = memory.getOutlines(); @@ -1539,14 +1539,32 @@ void Mind::findLibraryOrphanOs() MF_DEBUG(" '" << documentPath << "'" << endl); if(!isFile(documentPath.c_str())) { MF_DEBUG(" ORPHAN" << endl); - // TODO - detect whether the file exists + orphanOutlines.push_back(outline); + + // tag O as orphan + const Tag* orphanTag = memory.getOntology().findOrCreateTag( + MarkdownDocumentRepresentation::TAG_LIB_DOC_ORPHAN); + if(!outline->hasTag(orphanTag)) { + outline->addTag(orphanTag); + memory.remember(outline); + } } } } } } } + + if(orphanOutlines.size()) { + MF_DEBUG("ORPHAN library outlines found:" << endl); + for(Outline* o:orphanOutlines) { + MF_DEBUG(" " << o->getName() << endl); + } + } else { + MF_DEBUG("NO ORPHAN library outlines found." << endl); + } + + return orphanOutlines.size(); } Wingman* Mind::getWingman() diff --git a/lib/src/mind/mind.h b/lib/src/mind/mind.h index 39854594..dc12d650 100644 --- a/lib/src/mind/mind.h +++ b/lib/src/mind/mind.h @@ -693,7 +693,7 @@ class Mind : public OntologyProvider /** * @brief Find Os which reference non-existent documents. */ - void findLibraryOrphanOs(); + int findLibraryOrphanOs(); /* * WINGMAN diff --git a/lib/src/representations/markdown/markdown_document_representation.h b/lib/src/representations/markdown/markdown_document_representation.h index 93116abb..e5255229 100644 --- a/lib/src/representations/markdown/markdown_document_representation.h +++ b/lib/src/representations/markdown/markdown_document_representation.h @@ -32,6 +32,7 @@ class MarkdownDocumentRepresentation public: static constexpr const auto TAG_LIB_DOC = "library-document"; + static constexpr const auto TAG_LIB_DOC_ORPHAN = "library-orphan-document"; static constexpr const auto PREFIX_1ST_LINE = "This is a notebook for the document: ";