1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using Odotocodot . OneNote . Linq ;
5+ using Odotocodot . OneNote . Linq . Abstractions ;
6+
7+ namespace Flow . Launcher . Plugin . OneNote . Search
8+ {
9+ public class NotebookExplorer : SearchBase
10+ {
11+ public override List < Result > GetResults ( string query )
12+ {
13+ if ( ValidateSearch ( query , out string ? search , out IOneNoteItem ? parent , out IEnumerable < IOneNoteItem > collection ) )
14+ return resultCreator . InvalidQuery ( false ) ;
15+
16+ List < Result > results = search switch
17+ {
18+ // Empty search so show all in collection
19+ string when string . IsNullOrWhiteSpace ( search ) => ShowAll ( parent , collection ) ,
20+
21+ // Search by title
22+ not null when search . StartsWith ( Keywords . TitleSearch ) && parent is not OneNotePage
23+ => TitleSearch . Filter ( search , parent , collection , context , settings , resultCreator ) ,
24+
25+ // Scoped search
26+ not null when search . StartsWith ( Keywords . ScopedSearch ) && parent is INotebookOrSectionGroup => ScopedSearch ( search , parent ) ,
27+
28+ // Default search
29+ _ => Explorer ( search , parent , collection ) ,
30+ } ;
31+
32+ if ( parent == null )
33+ return results ;
34+
35+ Result result = resultCreator . CreateOneNoteItemResult ( parent , false , score : Result . MaxScore ) ;
36+ result . Title = $ "Open \" { parent . Name } \" in OneNote";
37+ result . SubTitle = search switch
38+ {
39+ not null when search . StartsWith ( Keywords . TitleSearch ) => $ "Now searching by title in \" { parent . Name } \" ",
40+ not null when search . StartsWith ( Keywords . ScopedSearch ) => $ "Now searching all pages in \" { parent . Name } \" ",
41+ _ => $ "Use \' { Keywords . ScopedSearch } \' to search this item. Use \' { Keywords . TitleSearch } \' to search by title in this item",
42+ } ;
43+
44+ results . Add ( result ) ;
45+ return results ;
46+ }
47+
48+ private bool ValidateSearch ( string query , out string ? lastSearch , out IOneNoteItem ? parent , out IEnumerable < IOneNoteItem > collection )
49+ {
50+ lastSearch = null ;
51+ parent = null ;
52+ collection = OneNoteApplication . GetNotebooks ( ) ;
53+
54+ string search = query [ ( query . IndexOf ( Keywords . NotebookExplorer , StringComparison . Ordinal ) + Keywords . NotebookExplorer . Length ) ..] ;
55+
56+ const string separator = Keywords . NotebookExplorerSeparator ;
57+ var currIndex = search . IndexOf ( separator , StringComparison . Ordinal ) ;
58+ var prevIndex = 0 ;
59+
60+ while ( currIndex != - 1 )
61+ {
62+ var itemName = search [ prevIndex ..currIndex ] ;
63+ parent = collection . FirstOrDefault ( item => item . Name == itemName ) ;
64+ if ( parent == null )
65+ return false ;
66+
67+ collection = parent . Children ;
68+
69+ prevIndex = currIndex + 1 ;
70+ currIndex = search . IndexOf ( separator , currIndex + separator . Length , StringComparison . Ordinal ) ;
71+ }
72+
73+ lastSearch = search [ prevIndex ..] ;
74+ return true ;
75+ }
76+
77+ private List < Result > ShowAll ( IOneNoteItem ? parent , IEnumerable < IOneNoteItem > collection )
78+ {
79+ var results = collection . FilterBySettings ( settings )
80+ . Select ( item => resultCreator . CreateOneNoteItemResult ( item , true ) )
81+ . ToList ( ) ;
82+
83+ return results . Any ( ) ? results : resultCreator . NoItemsInCollection ( results , parent ) ;
84+ }
85+
86+ private List < Result > ScopedSearch ( string query , IOneNoteItem parent )
87+ {
88+ if ( query . Length == Keywords . ScopedSearch . Length )
89+ return new List < Result > ( 0 ) ;
90+
91+ if ( ! char . IsLetterOrDigit ( query [ Keywords . ScopedSearch . Length ] ) )
92+ return resultCreator . InvalidQuery ( ) ;
93+
94+ string currentSearch = query [ Keywords . TitleSearch . Length ..] ;
95+
96+ return OneNoteApplication . FindPages ( currentSearch , parent )
97+ . Select ( pg => resultCreator . CreatePageResult ( pg , currentSearch ) )
98+ . ToList ( ) ;
99+ }
100+
101+ private List < Result > Explorer ( string search , IOneNoteItem ? parent , IEnumerable < IOneNoteItem > collection )
102+ {
103+ var results = collection . FilterBySettings ( settings )
104+ . FuzzySearch ( search , context )
105+ . Select ( r => resultCreator . CreateOneNoteItemResult ( r . item , true , r . highlightData , r . score ) )
106+ . ToList ( ) ;
107+
108+ // If parent is a section, pages inside can have the same name
109+ if ( parent is not OneNoteSection && results . Any ( result => string . Equals ( search . Trim ( ) , result . Title , StringComparison . OrdinalIgnoreCase ) ) )
110+ return results ;
111+
112+ if ( parent ? . IsInRecycleBin ( ) == true )
113+ return results ;
114+
115+ //Add option to create new items
116+ switch ( parent )
117+ {
118+ case null :
119+ results . Add ( resultCreator . CreateNewNotebookResult ( search ) ) ;
120+ break ;
121+ case INotebookOrSectionGroup :
122+ results . Add ( resultCreator . CreateNewSectionResult ( search , parent ) ) ;
123+ results . Add ( resultCreator . CreateNewSectionGroupResult ( search , parent ) ) ;
124+ break ;
125+ case OneNoteSection section :
126+ if ( ! section . Locked )
127+ {
128+ results . Add ( resultCreator . CreateNewPageResult ( search , section ) ) ;
129+ }
130+ break ;
131+ }
132+
133+ return results ;
134+ }
135+ }
136+ }
0 commit comments