private async void Filter_MenuItem_Click(object sender, RoutedEventArgs e) { try { if (ContextTagsSource == null) { return; } MenuItem itm = sender as MenuItem; TagContext filter = (TagContext)Enum.Parse(typeof(TagContext), itm.Tag.ToString()); IEnumerable <TagPageSet> tags = await GetContextTagsAsync(filter); Tags = from t in tags select t.TagName; if (string.IsNullOrEmpty(tagInput.Text)) { filterPopup.IsOpen = true; } } catch (Exception ex) { TraceLogger.Log(TraceCategory.Error(), "Applying preset filter failed {0}", ex); TraceLogger.ShowGenericErrorBox(Properties.Resources.TagEditor_Filter_Error, ex); } finally { e.Handled = true; } }
private void TagInputBox_Input(object sender, TagInputEventArgs e) { suggestedTags.Notification = String.Empty; try { if (tagInput.IsEmpty) { suggestedTags.Highlighter = new TextSplitter(); } else { IEnumerable <string> tags = tagInput.Tags; if (e.TagInputComplete) { _model.PageTags.AddAll(from t in tags where !_model.PageTags.ContainsKey(t) select new SimpleTagButtonModel(t)); tagInput.Clear(); } suggestedTags.Highlighter = new TextSplitter(tagInput.Tags); } } catch (Exception ex) { TraceLogger.Log(TraceCategory.Error(), "Processing Tag input failed with {0}", ex); TraceLogger.ShowGenericErrorBox(Properties.Resources.TagEditor_Input_Error, ex); } e.Handled = true; }
private void Hyperlink_Click(object sender, RoutedEventArgs e) { try { HitHighlightedPageLink l = sender as HitHighlightedPageLink; if (l != null) { HitHighlightedPageLinkModel model = l.DataContext as HitHighlightedPageLinkModel; _model.NavigateTo(model.PageID); if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) { int ndx = foundPagesList.SelectedItems.IndexOf(model); if (ndx >= 0) { foundPagesList.SelectedItems.RemoveAt(ndx); } else { foundPagesList.SelectedItems.Add(model); } } else { // select the link foundPagesList.SelectedItem = model; } e.Handled = true; } } catch (System.Exception ex) { TraceLogger.Log(TraceCategory.Error(), "Navigation to OneNote page failed: {0}", ex); TraceLogger.ShowGenericErrorBox(Properties.Resources.TagSearch_Error_PageNavigation, ex); } }
private void _model_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e == FindTaggedPagesModel.PAGE_COUNT) { foundPagesList.UnselectAll(); } else if (e == FindTaggedPagesModel.CURRENT_TAGS) { // update query if necessary string thisScopID; switch (scopeSelect.SelectedScope) { case SearchScope.Notebook: thisScopID = ViewModel.OneNoteApp.CurrentNotebookID; break; case SearchScope.SectionGroup: thisScopID = ViewModel.OneNoteApp.CurrentSectionGroupID; break; case SearchScope.Section: thisScopID = ViewModel.OneNoteApp.CurrentSectionID; break; default: thisScopID = string.Empty; break; } if (!thisScopID.Equals(ViewModel.LastScopeID)) { // rerun the query for the current scope try { pBar.Visibility = System.Windows.Visibility.Visible; string query = searchComboBox.Text; _model.FindPagesAsync(query, scopeSelect.SelectedScope).Wait(); tagInput.Tags = ViewModel.CurrentTags; pBar.Visibility = System.Windows.Visibility.Hidden; searchComboBox.SelectedValue = query; } catch (System.Exception ex) { TraceLogger.Log(TraceCategory.Error(), "Changing search scope failed: {0}", ex); TraceLogger.ShowGenericErrorBox(Properties.Resources.TagSearch_Error_ScopeChange, ex); } } else { tagInput.Tags = ViewModel.CurrentTags; } } }
private async void SearchButton_Click(object sender, RoutedEventArgs e) { string query = searchComboBox.Text; try { pBar.Visibility = System.Windows.Visibility.Visible; await _model.FindPagesAsync(query, scopeSelect.SelectedScope); searchComboBox.SelectedValue = query; pBar.Visibility = System.Windows.Visibility.Hidden; } catch (System.Exception ex) { TraceLogger.Log(TraceCategory.Error(), "search for '{0}' failed: {1}", query, ex); TraceLogger.ShowGenericErrorBox(Properties.Resources.TagSearch_Error_Find, ex); } e.Handled = true; }
/// <summary> /// Extract tags from page descriptors. /// </summary> /// <param name="pageDescriptors"> /// XML document describing pages in the OneNote hierarchy or search result. /// </param> /// <param name="selectedPagesOnly">true to process only pages selected by user</param> /// <param name="omitUntaggedPages">drip untagged pages</param> internal void ExtractTags(XDocument pageDescriptors, bool selectedPagesOnly, bool omitUntaggedPages = false) { // parse the search results _tags.Clear(); _pages.Clear(); try { XNamespace one = pageDescriptors.Root.GetNamespaceOfPrefix("one"); Dictionary <string, TagPageSet> tags = new Dictionary <string, TagPageSet>(); foreach (XElement page in pageDescriptors.Descendants(one.GetName("Page"))) { TaggedPage tp = new TaggedPage(page); if (selectedPagesOnly && !tp.IsSelected) { continue; } // assign Tags int tagcount = 0; foreach (string tagname in tp.TagNames) { tagcount++; TagPageSet t; if (!tags.TryGetValue(tagname, out t)) { t = new TagPageSet(tagname); tags.Add(tagname, t); } t.AddPage(tp); tp.Tags.Add(t); } if (!omitUntaggedPages || tagcount > 0) { _pages.Add(tp.Key, tp); } } // bulk update for performance reasons _tags.UnionWith(tags.Values); TraceLogger.Log(TraceCategory.Info(), "Extracted {0} tags from {1} pages.", _tags.Count, _pages.Count); } catch (Exception ex) { TraceLogger.Log(TraceCategory.Error(), "Parsing Hierarchy data failed: {0}", ex); TraceLogger.Flush(); } }
private void ScopeSelector_ScopeChanged(object sender, ScopeChangedEventArgs e) { try { pBar.Visibility = System.Windows.Visibility.Visible; string query = searchComboBox.Text; // using ContinueWith until I've discovered how to do implement async // events properly _model.FindPagesAsync(query, scopeSelect.SelectedScope).ContinueWith(tsk => Dispatcher.Invoke(() => { pBar.Visibility = System.Windows.Visibility.Hidden; searchComboBox.SelectedValue = query; })); } catch (System.Exception ex) { TraceLogger.Log(TraceCategory.Error(), "Changing search scope failed: {0}", ex); TraceLogger.ShowGenericErrorBox(Properties.Resources.TagSearch_Error_ScopeChange, ex); } e.Handled = true; }
private void ApplyPageTags(TagOperation op) { tagInput.FocusInput(); try { TaggingScope scope = ((TaggingScopeDescriptor)taggingScope.SelectedItem).Scope; int pagesTagged = _model.EnqueuePagesForTagging(op, scope); taggingScope.SelectedIndex = 0; tagInput.Clear(); suggestedTags.Highlighter = new TextSplitter(); suggestedTags.Notification = pagesTagged == 0 ? Properties.Resources.TagEditor_Popup_NothingTagged : string.Format(Properties.Resources.TagEditor_Popup_TaggingInProgress, pagesTagged); } catch (Exception xe) { TraceLogger.Log(TraceCategory.Error(), "Applying tags to page failed: {0}", xe); TraceLogger.ShowGenericErrorBox(Properties.Resources.TagEditor_TagUpdate_Error, xe); } }
/// <summary> /// Add items to the sorted collection in batches. /// </summary> /// <remarks> /// Groups the given items into contiguous ranges of batches and adds each batch at /// once, firing one change notification per batch. /// </remarks> /// <param name="items">items to add</param> internal void AddAll(IEnumerable <TValue> items) { List <KeyValuePair <int, TValue> > toAdd = new List <KeyValuePair <int, TValue> >(); foreach (TValue item in items) { if (!_dictionary.ContainsKey(item.Key)) { // lookup insertion point int insertionPoint = _sortedList.BinarySearch(new KeyValuePair <TSort, TValue>(item.SortKey, item), _comparer); #if DEBUG Debug.Assert(insertionPoint < 0, string.Format("Item with key {0} already present in list at index {1}", item.Key, insertionPoint)); #endif if (insertionPoint < 0) { _dictionary.Add(item.Key, item); toAdd.Add(new KeyValuePair <int, TValue>(~insertionPoint, item)); } else { TraceLogger.Log(TraceCategory.Error(), "List is inconsistency! Attempting to recover"); TraceLogger.Flush(); _dictionary.Add(item.Key, item); } } } toAdd.Sort(_indexComparer); // process the sorted list of items to add in reverse order so that we do not // have to correct indices while (toAdd.Count > 0) { List <KeyValuePair <TSort, TValue> > batch = new List <KeyValuePair <TSort, TValue> >(); int lastItemIndex = toAdd.Count - 1; KeyValuePair <int, TValue> itemToAdd = toAdd[lastItemIndex]; // add the first item to the batch int insertionPoint = itemToAdd.Key; batch.Add(new KeyValuePair <TSort, TValue>(itemToAdd.Value.SortKey, itemToAdd.Value)); toAdd.RemoveAt(lastItemIndex); lastItemIndex = toAdd.Count - 1; while (lastItemIndex >= 0 && toAdd[lastItemIndex].Key == insertionPoint) { itemToAdd = toAdd[lastItemIndex]; batch.Add(new KeyValuePair <TSort, TValue>(itemToAdd.Value.SortKey, itemToAdd.Value)); toAdd.RemoveAt(lastItemIndex); lastItemIndex = toAdd.Count - 1; } batch.Sort(_comparer); _sortedList.InsertRange(insertionPoint, batch); if (CollectionChanged != null) { NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, (from b in batch select b.Value).ToList(), insertionPoint); CollectionChanged(this, args); } } }
private async void Page_MenuItem_Click(object sender, RoutedEventArgs e) { MenuItem item = sender as MenuItem; if (item != null) { switch (item.Tag.ToString()) { case "Refresh": string query = searchComboBox.Text; try { pBar.Visibility = System.Windows.Visibility.Visible; await _model.FindPagesAsync(query, scopeSelect.SelectedScope); searchComboBox.SelectedValue = query; pBar.Visibility = System.Windows.Visibility.Hidden; } catch (System.Exception ex) { TraceLogger.Log(TraceCategory.Error(), "search for '{0}' failed: {1}", query, ex); TraceLogger.ShowGenericErrorBox(Properties.Resources.TagSearch_Error_Find, ex); } break; case "ClearSelection": foundPagesList.UnselectAll(); break; case "SelectAll": foundPagesList.SelectAll(); break; case "MarkSelection": string[] marker = new string[] { "-✩-" }; int pagesTagged = 0; foreach (var mdl in _model.Pages.Where((p) => p.IsSelected)) { _model.OneNoteApp.TaggingService.Add(new Tagger.TaggingJob(mdl.PageID, marker, Tagger.TagOperation.UNITE)); pagesTagged++; } tagsPanel.Notification = pagesTagged == 0 ? Properties.Resources.TagEditor_Popup_NothingTagged : string.Format(Properties.Resources.TagEditor_Popup_TaggingInProgress, pagesTagged); break; case "CopyLinks": string header = @"Version:0.9 StartHTML:{0:D6} EndHTML:{1:D6} StartFragment:{2:D6} EndFragment:{3:D6} StartSelection:{4:D6} EndSelection:{5:D6}"; string htmlpre = @"<HTML> <BODY> <!--StartFragment-->"; StringBuilder links = new StringBuilder(); foreach (var mdl in _model.Pages.Where((p) => p.IsSelected)) { string pageTitle = mdl.LinkTitle; try { if (links.Length > 0) { links.Append("<br />"); } links.Append(@"<a href="""); links.Append(mdl.PageLink); links.Append(@""">"); links.Append(mdl.LinkTitle); links.Append("</a>"); } catch (Exception ex) { TraceLogger.Log(TraceCategory.Error(), "Link to page '{0}' could not be created: {1}", pageTitle, ex); TraceLogger.ShowGenericErrorBox(Properties.Resources.TagSearch_Error_CopyLink, ex); } } string htmlpost = @"<!--EndFragment--> </BODY> </HTML>"; string strLinks = links.ToString(); string clip = string.Format(header, header.Length, header.Length + htmlpre.Length + strLinks.Length + htmlpost.Length, header.Length + htmlpre.Length, header.Length + htmlpre.Length + strLinks.Length, header.Length + htmlpre.Length, header.Length + htmlpre.Length + strLinks.Length) + htmlpre + strLinks + htmlpost; Clipboard.SetText(clip, TextDataFormat.Html); break; } e.Handled = true; } }