示例#1
0
        public IHttpActionResult PutNoteTag(int id, NoteTag noteTag)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            if (id != noteTag.Id)
            {
                return(BadRequest());
            }

            db.Entry(noteTag).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!NoteTagExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(StatusCode(HttpStatusCode.NoContent));
        }
示例#2
0
 public AddNoteWindow(VideoNote note, NoteTag tag)
 {
     Note       = note;
     Location   = tag.Location;
     TagContent = tag.Content;
     InitializeComponent();
 }
示例#3
0
 public IActionResult Edit(NoteVM noteVM)
 {
     if (noteVM.Note == null)
     {
         return(NotFound());
     }
     if (ModelState.IsValid)
     {
         Note newNote = noteVM.Note;
         _db.Note.Remove(_db.Note.Find(newNote.Id));
         _db.RemoveRange(_db.NoteTag.Where(i => i.NotesId == newNote.Id));
         if (noteVM.NoteTags != null)
         {
             foreach (var t in _db.Tag)
             {
                 if (noteVM.NoteTags.Contains(t.Id))
                 {
                     NoteTag noteTag = new NoteTag {
                         NotesId = newNote.Id, TagsId = t.Id
                     };
                     newNote.NoteTags.Add(noteTag);
                 }
             }
         }
         _db.Add(newNote);
         _db.SaveChanges();
         return(RedirectToAction("Index"));
     }
     return(View(noteVM));
 }
示例#4
0
        public IActionResult Create(NoteVM noteVM)
        {
            if (ModelState.IsValid)
            {
                Note newNote = noteVM.Note;

                if (noteVM.NoteTags != null)
                {
                    foreach (var t in _db.Tag)
                    {
                        if (noteVM.NoteTags.Contains(t.Id))
                        {
                            NoteTag noteTag = new NoteTag {
                                NotesId = newNote.Id, TagsId = t.Id
                            };
                            newNote.NoteTags.Add(noteTag);
                        }
                    }
                }
                _db.Note.Add(newNote);
                _db.SaveChanges();
                return(RedirectToAction("Index"));
            }
            return(View(noteVM));
        }
示例#5
0
        public static void Run()
        {
            // ExStart:GetTagDetails
            // The path to the documents directory.
            string dataDir = RunExamples.GetDataDir_Tags();

            // Load the document into Aspose.Note.
            Document oneFile = new Document(dataDir + "TagFile.one");

            // Get all RichText nodes
            IList <RichText> nodes = oneFile.GetChildNodes <RichText>();

            // Iterate through each node
            foreach (RichText richText in nodes)
            {
                foreach (var tag in richText.Tags)
                {
                    if (tag is NoteTag)
                    {
                        NoteTag noteTag = (NoteTag)tag;
                        // Retrieve properties
                        Console.WriteLine("Completed Time: " + noteTag.CompletedTime);
                        Console.WriteLine("Create Time: " + noteTag.CreationTime);
                        Console.WriteLine("Font Color: " + noteTag.FontColor);
                        Console.WriteLine("Status: " + noteTag.Status);
                        Console.WriteLine("Label: " + noteTag.Label);
                        Console.WriteLine("Icon: " + noteTag.Icon);
                        Console.WriteLine("High Light: " + noteTag.Highlight);
                    }
                }
            }

            // ExEnd:GetTagDetails
        }
示例#6
0
        // 删除标签, 供API调用
        public bool DeleteTagApi(long?userId, string tag, int usn, out int toUsn, out string msg)
        {
            NoteTag noteTag = GetTag(userId, tag);

            if (noteTag == null)
            {
                toUsn = 0;
                msg   = "notExists";
                return(false);
            }
            if (noteTag.Usn > usn)
            {
                toUsn = noteTag.Usn;
                msg   = "conflict";
                return(false);
            }

            var result = dataContext.NoteTag
                         .Where(b => b.UserId == userId && b.Tag.Equals(tag
                                                                        )).FirstOrDefault();

            result.IsDeleted = true;
            toUsn            = UserService.IncrUsn(userId);
            //todo:这里应该进行事务控制,失败的话应该回滚事务
            msg = "success";
            return(dataContext.SaveChanges() > 0);
        }
    public async Task <ApiResponse <object> > UpdateTagAsync([FromForm] NoteTag tag)
    {
        var response = new ApiResponse <object>();

        try
        {
            _request.Tag = tag;
            var blogResponse = await _noteGrpcService.UpdateNoteTagAsync(_request);

            if (blogResponse.IsOk)
            {
                response.RedirectTo = "/note/tag";
            }
            else
            {
                response.IsOk    = false;
                response.Message = blogResponse.Message;
            }
        }
        catch (Exception ex)
        {
            response.IsOk    = false;
            response.Message = ex.Message;
            _logger.LogError(ex, $"Update tag failed. {JsonUtil.Serialize(tag)}");
        }

        return(response);
    }
示例#8
0
 public bool TryGetNoteTag(Note note, Tag tag, out NoteTag noteTag)
 {
     noteTag = NoteTags.FirstOrDefault(nt => nt.NoteKey == note.Key && nt.TagKey == tag.Key)
               ?? new NoteTag()
     {
         Note = note, Tag = tag
     };
     return(noteTag != null);
 }
示例#9
0
        void OnMenuItemActivated(object sender, EventArgs args)
        {
            NoteTag broken_link_tag = Note.TagTable.BrokenLinkTag;

            Gtk.TextIter note_start, note_end;

            // We get the whole note as a range
            // and then just remove the "broken link" tag from it
            Note.Buffer.GetBounds(out note_start, out note_end);

            // Sweep 'em & recreate WikiWord broken links (depending on Preferences),
            Buffer.RemoveTag(broken_link_tag, note_start, note_end);

            // HACK: The below is copied from Watchers.cs->ApplyWikiwordToBlock()
            // It turns WikiWords back into broken links after sweeping all broken links,
            // but only in case WikiWords are enabled.
            // Most probably there's more elegant way of doing this.

            if ((bool)Preferences.Get(Preferences.ENABLE_WIKIWORDS))
            {
                const string WIKIWORD_REGEX = @"\b((\p{Lu}+[\p{Ll}0-9]+){2}([\p{Lu}\p{Ll}0-9])*)\b";

                Regex regex = new Regex(WIKIWORD_REGEX, RegexOptions.Compiled);

                NoteBuffer.GetBlockExtents(ref note_start,
                                           ref note_end,
                                           80 /* max wiki name */,
                                           broken_link_tag);

                //Buffer.RemoveTag (broken_link_tag, start, end);

                for (Match match = regex.Match(note_start.GetText(note_end));
                     match.Success;
                     match = match.NextMatch())
                {
                    System.Text.RegularExpressions.Group group = match.Groups [1];

                    Logger.Debug("Highlighting back wikiword: '{0}' at offset {1}",
                                 group,
                                 group.Index);

                    Gtk.TextIter start_cpy = note_start;
                    start_cpy.ForwardChars(group.Index);

                    note_end = start_cpy;
                    note_end.ForwardChars(group.Length);

                    if (Manager.Find(group.ToString()) == null)
                    {
                        Buffer.ApplyTag(broken_link_tag, start_cpy, note_end);
                    }
                }
            }
            /// End of hack
        }
示例#10
0
        public IHttpActionResult GetNoteTag(int id)
        {
            NoteTag noteTag = db.NoteTags.Find(id);

            if (noteTag == null)
            {
                return(NotFound());
            }

            return(Ok(noteTag));
        }
示例#11
0
        /// <summary>
        /// Method used when user clicks on tag. Synchronusly starts DecryptPassAsync().
        /// </summary>
        /// <param name="tag"> NoteTag which was clicked. </param>
        /// <param name="editor"> NoteEditor in which NoteTag was clicked. </param>
        /// <param name="start"> TextIter pointiong to beginning of tag. </param>
        /// <param name="end"> TextIter pointiong to end of tag. </param>
        /// <returns> Returns true if password contained in tag is not empty string. </returns>
        protected bool PassEncryptTag_Activated(NoteTag tag, NoteEditor editor, Gtk.TextIter start, Gtk.TextIter end)
        {
            string encPass = (tag as PassEncryptTag).Attributes[AtrName];

            if (string.IsNullOrWhiteSpace(encPass))
            {
                return(false);
            }
            DecryptPassAsync(encPass);
            return(true);
        }
    private NoteTagRuntime GetNoteTagRuntime(NoteTag tag, bool extractRuntime, List <Note> notes)
    {
        var runtime = new NoteTagRuntime(tag);

        if (extractRuntime)
        {
            runtime.ExtractRuntime(notes);
        }

        return(runtime);
    }
示例#13
0
        public bool AddNoteTag(NoteTag noteTag)
        {
            if (noteTag.TagId == 0)
            {
                noteTag.TagId = idGenerator.NextId();
            }

            var result = dataContext.NoteTag.Add(noteTag);

            return(dataContext.SaveChanges() > 0);
        }
示例#14
0
        public IHttpActionResult PostNoteTag(NoteTag noteTag)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            db.NoteTags.Add(noteTag);
            db.SaveChanges();

            return(CreatedAtRoute("DefaultApi", new { id = noteTag.Id }, noteTag));
        }
示例#15
0
        public static void Run()
        {
            // ExStart:AddTextNodeWithTag
            // ExFor:NoteTag
            // ExFor:RichText
            // ExFor:RichText.Text
            // ExFor:RichText.ParagraphStyle
            // ExSummary:Shows how to add new paragraph with tag.

            // The path to the documents directory.
            string dataDir = RunExamples.GetDataDir_Tags();

            // Create an object of the Document class
            Document doc = new Document();

            // Initialize Page class object
            Aspose.Note.Page page = new Aspose.Note.Page(doc);

            // Initialize Outline class object
            Outline outline = new Outline(doc);

            // Initialize OutlineElement class object
            OutlineElement outlineElem = new OutlineElement(doc);
            ParagraphStyle textStyle   = new ParagraphStyle {
                FontColor = Color.Black, FontName = "Arial", FontSize = 10
            };
            RichText text = new RichText(doc)
            {
                Text = "OneNote text.", ParagraphStyle = textStyle
            };

            text.Tags.Add(NoteTag.CreateYellowStar());

            // Add text node
            outlineElem.AppendChildLast(text);

            // Add outline element node
            outline.AppendChildLast(outlineElem);

            // Add outline node
            page.AppendChildLast(outline);

            // Add page node
            doc.AppendChildLast(page);

            // Save OneNote document
            dataDir = dataDir + "AddTextNodeWithTag_out.one";
            doc.Save(dataDir);

            // ExEnd:AddTextNodeWithTag

            Console.WriteLine("\nText node with tag added successfully.\nFile saved at " + dataDir);
        }
示例#16
0
 public static bool AddNoteTag(NoteTag noteTag)
 {
     if (noteTag.TagId == 0)
     {
         noteTag.TagId = SnowFlake_Net.GenerateSnowFlakeID();
     }
     using (var db = new DataContext())
     {
         var result = db.NoteTag.Add(noteTag);
         return(db.SaveChanges() > 0);
     }
 }
示例#17
0
        public bool UpdateByIdAndUserId(long?tagId, long?userId, NoteTag noteTag)
        {
            var noteT = dataContext.NoteTag
                        .Where(b => b.TagId == tagId &&
                               b.UserId == userId).FirstOrDefault();

            noteT.Tag         = noteTag.Tag;
            noteT.Usn         = noteTag.Usn;
            noteT.Count       = noteTag.Count;
            noteT.UpdatedTime = noteTag.UpdatedTime;
            noteT.IsDeleted   = noteTag.IsDeleted;
            return(dataContext.SaveChanges() > 0);
        }
示例#18
0
        public override void Initialize()
        {
            bold_tag          = (NoteTag)Note.TagTable.Lookup("bold");
            italic_tag        = (NoteTag)Note.TagTable.Lookup("italic");
            highlight_tag     = (NoteTag)Note.TagTable.Lookup("highlight");
            underline_tag     = (NoteTag)Note.TagTable.Lookup("underline");
            strikethrough_tag = (NoteTag)Note.TagTable.Lookup("strikethrough");

            /*
             * url_tag = (NoteTag) Note.TagTable.Lookup ("link:url");
             * link_tag = (NoteTag) Note.TagTable.Lookup ("link:internal");
             * broken_link_tag = (NoteTag) Note.TagTable.Lookup ("link:broken");
             */
        }
示例#19
0
        public IHttpActionResult DeleteNoteTag(int id)
        {
            NoteTag noteTag = db.NoteTags.Find(id);

            if (noteTag == null)
            {
                return(NotFound());
            }

            db.NoteTags.Remove(noteTag);
            db.SaveChanges();

            return(Ok(noteTag));
        }
        public static void Run()
        {
            // ExStart:AddImageNodeWithTag
            // ExFor:Image
            // ExFor:Image.Tags
            // ExFor:NoteTag
            // ExFor:Page
            // ExFor:Outline
            // ExFor:OutlineElement
            // ExSummary:Shows how to add new image with tag.

            // The path to the documents directory.
            string dataDir = RunExamples.GetDataDir_Tags();

            // Create an object of the Document class
            Document doc = new Document();

            // Initialize Page class object
            Aspose.Note.Page page = new Aspose.Note.Page(doc);

            // Initialize Outline class object
            Outline outline = new Outline(doc);

            // Initialize OutlineElement class object
            OutlineElement outlineElem = new OutlineElement(doc);

            // Load an image
            Aspose.Note.Image image = new Aspose.Note.Image(doc, dataDir + "icon.jpg");

            // Insert image in the document node
            outlineElem.AppendChildLast(image);
            image.Tags.Add(NoteTag.CreateYellowStar());

            // Add outline element node
            outline.AppendChildLast(outlineElem);

            // Add outline node
            page.AppendChildLast(outline);

            // Add page node
            doc.AppendChildLast(page);

            // Save OneNote document
            dataDir = dataDir + "AddImageNodeWithTag_out.one";
            doc.Save(dataDir);

            // ExEnd:AddImageNodeWithTag

            Console.WriteLine("\nImage node with tag added successfully.\nFile saved at " + dataDir);
        }
示例#21
0
        public void RemoveBrokenLinkTag(Note note)
        {
            NoteTag broken_link_tag = note.TagTable.BrokenLinkTag;

            Gtk.TextIter note_start, note_end;

            // We get the whole note as a range
            // and then just remove the "broken link" tag from it
            note.Buffer.GetBounds(out note_start, out note_end);

            // Sweep 'em
            note.Buffer.RemoveTag(broken_link_tag, note_start, note_end);

            Logger.Debug("Removed broken links from a note: " + note.Title);
        }
示例#22
0
        public JsonResult AddTag(string token, string tag)
        {
            NoteTag noteTag = tagService.AddOrUpdateTag(GetUserIdByToken(token), tag);

            if (noteTag == null)
            {
                return(Json(new ApiRe()
                {
                    Ok = false, Msg = "添加标签失败"
                }, MyJsonConvert.GetLeanoteOptions()));
            }
            else
            {
                return(Json(noteTag, MyJsonConvert.GetLeanoteOptions()));
            }
        }
        public void Update(int noteId, string name, string description, NoteTag tag, int userId)
        {
            var note = _noteRepository.Table.FirstOrDefault(x =>
                                                            x.NoteIdPk == noteId && x.NoteCreatedByIdFk == userId);

            if (note == null)
            {
                throw new NoteNotFoundException();
            }

            note.NoteName        = name;
            note.NoteDescription = description;
            note.NoteTag         = tag;
            note.NoteIsEdited    = true;

            _noteRepository.SaveAll();
        }
示例#24
0
        public void HighlightWikiWords(Note note)
        {
            NoteTag broken_link_tag = note.TagTable.BrokenLinkTag;

            Gtk.TextIter note_start, note_end;

            note.Buffer.GetBounds(out note_start, out note_end);

            // HACK: The below is copied from Watchers.cs->ApplyWikiwordToBlock()
            // It turns WikiWords back into broken links after sweeping all broken links,
            // but only in case WikiWords are enabled.
            // Most probably there's more elegant way of doing this.

            const string WIKIWORD_REGEX = @"\b((\p{Lu}+[\p{Ll}0-9]+){2}([\p{Lu}\p{Ll}0-9])*)\b";

            Regex regex = new Regex(WIKIWORD_REGEX, RegexOptions.Compiled);

            NoteBuffer.GetBlockExtents(ref note_start,
                                       ref note_end,
                                       80 /* max wiki name */,
                                       broken_link_tag);

            for (Match match = regex.Match(note_start.GetText(note_end));
                 match.Success;
                 match = match.NextMatch())
            {
                System.Text.RegularExpressions.Group group = match.Groups [1];

                Logger.Debug("Highlighting back wikiword: '{0}' at offset {1}",
                             group,
                             group.Index);

                Gtk.TextIter start_cpy = note_start;
                start_cpy.ForwardChars(group.Index);

                note_end = start_cpy;
                note_end.ForwardChars(group.Length);

                if (note.Manager.Find(group.ToString()) == null)
                {
                    note.Buffer.ApplyTag(broken_link_tag, start_cpy, note_end);
                }
            }
            /// End of hack
        }
示例#25
0
        private void RemoveTagButton_Click(object sender, RoutedEventArgs e)
        {
            NoteTag noteTag = null;

            if (!string.IsNullOrWhiteSpace(NewTagNameBox.Text))
            {
                noteTag = currentSelectedNote.NoteTags.FirstOrDefault(nt =>
                                                                      nt.Tag.Name.ToLower() == NewTagNameBox.Text.ToLower());
                currentSelectedNote.NoteTags.Remove(noteTag);
                context.TryUpdateManyToMany(currentSelectedNote.NoteTags, currentSelectedNote.NoteTags, x => x.TagKey);
                context.SaveChanges();
                TagList.ItemsSource = currentSelectedNote.NoteTags.Select(nt => nt.Tag);
                CollectionViewSource.GetDefaultView(TagList.ItemsSource).Refresh();
                NewTagNameBox.Text = "";
                if (!context.NoteTags.Any(nt => nt.Tag == noteTag.Tag))
                {
                    context.Remove(noteTag.Tag);
                    context.SaveChanges();
                }
                NewTagNameBox.Focus();
                return;
            }
            if (TagList.SelectedIndex == -1)
            {
                NewTagNameBox.Focus();
                return;
            }

            noteTag = currentSelectedNote.NoteTags.FirstOrDefault(nt => nt.Tag == (TagList.SelectedItem as Tag));
            currentSelectedNote.NoteTags.Remove(noteTag);
            context.TryUpdateManyToMany(currentSelectedNote.NoteTags, currentSelectedNote.NoteTags, x => x.TagKey);
            context.SaveChanges();
            TagList.ItemsSource = currentSelectedNote.NoteTags.Select(nt => nt.Tag);
            CollectionViewSource.GetDefaultView(TagList.ItemsSource).Refresh();
            NewTagNameBox.Text = "";
            if (!context.NoteTags.Any(nt => nt.Tag == noteTag.Tag))
            {
                context.Remove(noteTag.Tag);
                context.SaveChanges();
            }
            NewTagNameBox.Focus();
        }
示例#26
0
    public async Task UpdateNoteTagAsync(NoteTag tag, CancellationToken cancellationToken = default)
    {
        if (tag == null)
        {
            return;
        }

        if (string.IsNullOrEmpty(tag.Id))
        {
            throw new Exception("Empty tag id.");
        }

        var tags = await GetNoteTagsAsync(cancellationToken);

        var existingTag = tags.FirstOrDefault(x =>
                                              StringUtil.EqualsIgnoreCase(x.Link, tag.Link) && !StringUtil.EqualsIgnoreCase(x.Id, tag.Id));

        if (existingTag != null)
        {
            throw new Exception($"Tag with link({tag.Link}) already exists.");
        }

        existingTag = tags.FirstOrDefault(x =>
                                          StringUtil.EqualsIgnoreCase(x.DisplayName, tag.DisplayName) && !StringUtil.EqualsIgnoreCase(x.Id, tag.Id));
        if (existingTag != null)
        {
            throw new Exception($"Tag with display name({tag.DisplayName}) already exists.");
        }

        existingTag = tags.FirstOrDefault(x => StringUtil.EqualsIgnoreCase(x.Id, tag.Id));
        if (existingTag == null)
        {
            throw new Exception($"Tag with id({tag.Id}) does not exist.");
        }

        existingTag.LastUpdatedAt = DateTime.Now;
        existingTag.DisplayName   = tag.DisplayName;
        existingTag.Link          = tag.Link;
        existingTag.Description   = tag.Description;
        await _noteFileRepository.WriteAsync("tag.json", JsonUtil.Serialize(tags, true), cancellationToken);
    }
        public int Create(int lectureId, string name, string description, NoteTag tag, IFormFile document, int createdBy)
        {
            var fileName = _fileService.GenerateFileName(document, createdBy.ToString());

            _fileService.Save(document, DataConstants.NoteFilePath, fileName);

            var note = new NoteEntity
            {
                NoteName          = name,
                NoteDescription   = description,
                NoteTag           = tag,
                NoteLectureIdFk   = lectureId,
                NoteCreatedByIdFk = createdBy,
                NoteFileName      = fileName,
                NoteCreatedAt     = DateTime.Now
            };

            _noteRepository.Insert(note);
            _noteRepository.SaveAll();

            return(note.NoteIdPk);
        }
示例#28
0
        //---------------------------
        // v2
        // 第二版标签, 单独一张表, 每一个tag一条记录

        // 添加或更新标签, 先查下是否存在, 不存在则添加, 存在则更新
        // 都要统计下tag的note数
        // 什么时候调用? 笔记添加Tag, 删除Tag时
        // 删除note时, 都可以调用
        // 万能
        public NoteTag AddOrUpdateTag(long?userId, string tag)
        {
            NoteTag noteTag = GetTag(userId, tag);

            // 存在, 则更新之
            if (noteTag != null && noteTag.TagId != 0)
            {
                // 统计note数
                int count = NoteService.CountNoteByTag(userId, tag);
                noteTag.Count       = count;
                noteTag.UpdatedTime = DateTime.Now;
                // 之前删除过的, 现在要添加回来了
                if (noteTag.IsDeleted)
                {
                    noteTag.Usn       = UserService.IncrUsn(userId);
                    noteTag.IsDeleted = false;
                    UpdateByIdAndUserId(noteTag.TagId, userId, noteTag);
                }
                return(noteTag);
            }
            // 不存在, 则创建之
            var timeNow = DateTime.Now;

            noteTag = new NoteTag()
            {
                TagId       = idGenerator.NextId(),
                Count       = 1,
                Tag         = tag,
                UserId      = userId,
                CreatedTime = timeNow,
                UpdatedTime = timeNow,
                Usn         = UserService.IncrUsn(userId),
                IsDeleted   = false
            };
            AddNoteTag(noteTag);
            return(noteTag);
        }
示例#29
0
    public async Task AddNoteTagAsync(NoteTag tag, CancellationToken cancellationToken = default)
    {
        if (tag == null)
        {
            return;
        }

        if (string.IsNullOrEmpty(tag.Id))
        {
            tag.Id = StringUtil.GenerateRandom().ToLowerInvariant();
        }

        var tags = await GetNoteTagsAsync(cancellationToken);

        var existingTag = tags.FirstOrDefault(x => StringUtil.EqualsIgnoreCase(x.Id, tag.Id));

        if (existingTag != null)
        {
            throw new Exception($"Tag with id({tag.Id}) already exists.");
        }

        existingTag = tags.FirstOrDefault(x => StringUtil.EqualsIgnoreCase(x.Link, tag.Link));
        if (existingTag != null)
        {
            throw new Exception($"Tag with link({tag.Link}) already exists.");
        }

        existingTag = tags.FirstOrDefault(x => StringUtil.EqualsIgnoreCase(x.DisplayName, tag.DisplayName));
        if (existingTag != null)
        {
            throw new Exception($"Tag with display name({tag.DisplayName}) already exists.");
        }

        tag.LastUpdatedAt = DateTime.Now;
        tags.Add(tag);
        await _noteFileRepository.WriteAsync("tag.json", JsonUtil.Serialize(tags, true), cancellationToken);
    }
示例#30
0
        public void UpdateNoteTags(int noteId, IEnumerable <string> updatedTags)
        {
            Note note = Set.Find(noteId);

            if (note == null)
            {
                throw new ArgumentException($"No note with given id {noteId}", nameof(note));
            }

            updatedTags = updatedTags.ToArray();

            List <Tag>    availableTagEntities = Context.Set <Tag>().ToList();
            List <string> availableTags        = availableTagEntities.Select(t => t.Title).ToList();

            List <NoteTag> noteTags    = Context.Set <NoteTag>().Where(nt => nt.NoteId == noteId).ToList();
            List <string>  currentTags =
                (from tag in availableTagEntities join noteTag in noteTags on tag.Id equals noteTag.TagId select tag.Title).ToList();

            var newTags         = updatedTags.Except(availableTags).ToArray();
            var removedTags     = currentTags.Except(updatedTags).ToArray();
            var existingNewTags = updatedTags.Intersect(availableTags).ToArray();

            foreach (var newTag in newTags)
            {
                Tag tag = new Tag {
                    Title = newTag, Slug = Slug.Create(newTag)
                };
                NoteTag noteTag = new NoteTag {
                    NoteId = note.Id, TagId = tag.Id, Tag = tag, Note = note
                };

                Context.Set <Tag>().Add(tag);
                Context.Set <NoteTag>().Add(noteTag);
            }

            foreach (var removedTag in removedTags)
            {
                foreach (var noteTag in noteTags)
                {
                    if (noteTag.Tag.Title.Equals(removedTag, StringComparison.InvariantCultureIgnoreCase))
                    {
                        Context.Set <NoteTag>().Remove(noteTag);
                        break;
                    }
                }
            }

            foreach (var existingNewTag in existingNewTags)
            {
                foreach (var availableTag in availableTagEntities)
                {
                    if (existingNewTag.Equals(availableTag.Title, StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (currentTags.Any(existingTag => existingTag == existingNewTag))
                        {
                            break;
                        }

                        NoteTag noteTag = new NoteTag {
                            NoteId = note.Id, TagId = availableTag.Id, Note = note
                        };
                        note.NoteTags.Add(noteTag);
                        break;
                    }
                }
            }
        }
        public void InsertImage(TextIter iter, ImageInfo imageInfo, bool supportUndo)
        {
            Gdk.Pixbuf pixbuf = null;
            try {
                pixbuf = new Gdk.Pixbuf (imageInfo.FileContent);
            }
            catch {
                pixbuf = null;
            }
            if (pixbuf == null) {
                // TODO: Report the open image error.
                return;
            }

            if (imageInfo.DisplayWidth == 0) {
                imageInfo.DisplayWidth = pixbuf.Width;
                imageInfo.DisplayHeight = pixbuf.Height;
            }

            var imageWidget = new ImageWidget (pixbuf);
            imageWidget.ResizeImage (imageInfo.DisplayWidth, imageInfo.DisplayHeight);
            imageWidget.ShowAll ();
            InitImageWidgetContextMenu (imageWidget, imageInfo);
            imageWidget.Resized += imageWidget_Resized;

            if (supportUndo)
                Buffer.Undoer.FreezeUndo ();
            var anchorStart = iter;
            var anchor = Buffer.CreateChildAnchor (ref iter);

            var tag = new NoteTag ("dummy");
            tag.CanUndo = false;
            Buffer.ApplyTag (tag, anchorStart, iter);

            Window.Editor.AddChildAtAnchor (imageWidget, anchor);
            imageInfo.SetInBufferInfo (Buffer, anchor, imageWidget);

            //imageWidget.Destroyed += (o, e) =>
            //{
            //    if (!imageWidget.InsertUndone) {
            //        imageInfoList.Remove (imageInfo);
            //    }
            //};

            if (supportUndo) {
                Buffer.Undoer.ThawUndo ();
                var action = new InsertImageAction (this, imageInfo, imageInfoList);
                Buffer.Undoer.AddUndoAction (action);
            }
            imageInfoList.Add (imageInfo);
        }