// ------------------------------
        // private
        // ------------------------------
        private void ShowPreview(Link link, Point loc)
        {
            if (link != null && UriUtil.IsMemoUri(link.Uri))
            {
                var info = UriUtil.GetMemoInfo(link.Uri);

                if (info != null)
                {
                    var bmp = default(Bitmap);
                    if (_app.IsLoadedMemo(info))
                    {
                        /// Loadされていればそのcanvasからbitmapを作る
                        var content = _app.FindPageContent(info);
                        bmp = MemoOutlineUtil.CreateOutline(content.EditorCanvas);
                    }
                    else
                    {
                        bmp = MemoOutlineUtil.LoadOrSaveAndLoadOutline(info);
                    }

                    DisposePreviewPopup();

                    var canvas  = Host.Site.EditorCanvas;
                    var bounds  = _Figure.Bounds;
                    var screen  = Screen.FromRectangle(bounds);
                    var outline = new OutlinePreviewControl(screen, info.Title, bmp, 1f);
                    _previewPopup = new Popup(outline);
                    /// AutoClose = falseにしておかないとPopupにフォーカスを取られてしまう
                    _previewPopup.AutoClose = false;
                    _previewPopup.Tag       = bmp;

                    var locDelta      = 20;
                    var locOnScreen   = canvas.PointToScreen(canvas.TranslateToControlPoint(loc));
                    var preferredSize = outline.GetPreferredSize(new Size(int.MaxValue, int.MaxValue));

                    var isEnoughLowerSpace = preferredSize.Height < screen.WorkingArea.Height - (locOnScreen.Y + locDelta) - 2;
                    var isLocUpper         = locOnScreen.Y <= screen.WorkingArea.Height / 2;
                    var y = 0;
                    if (isEnoughLowerSpace || isLocUpper)
                    {
                        outline.MaxHeight = screen.WorkingArea.Height - (locOnScreen.Y + locDelta) - 2;
                        y = locOnScreen.Y + locDelta;
                    }
                    else
                    {
                        outline.MaxHeight = locOnScreen.Y - locDelta - 2;
                        y = locOnScreen.Y - locDelta - Math.Min(preferredSize.Height, outline.MaxHeight);
                    }

                    var isEnoughRighterSpace = preferredSize.Width < screen.WorkingArea.Width - (locOnScreen.X + locDelta) - 2;
                    var isLocLefter          = locOnScreen.X <= screen.WorkingArea.Width / 2;
                    var x = 0;
                    if (isEnoughRighterSpace || isLocLefter)
                    {
                        outline.MaxWidth = screen.WorkingArea.Width - (locOnScreen.X + locDelta) - 2;
                        x = locOnScreen.X + locDelta;
                    }
                    else
                    {
                        outline.MaxWidth = locOnScreen.X - locDelta - 2;
                        x = locOnScreen.X - locDelta - Math.Min(preferredSize.Width, outline.MaxWidth);
                    }

                    _previewPopup.Show(new Point(x, y));
                }
            }
        }
Example #2
0
        /// <summary>
        /// infos内からqueryに適合するものだけを返す。
        /// </summary>
        public IEnumerable <MemoInfo> Search(IEnumerable <MemoInfo> infos, MemoQuery query)
        {
            if (query == null || query.IsEmptyQuery)
            {
                return(new List <MemoInfo>());
            }

            var matched = infos;

            /// タイトル
            if (query.NarrowByTitle)
            {
                matched = matched.Where(
                    info => info.Title.IndexOf(query.Title, StringComparison.OrdinalIgnoreCase) > -1
                    );
            }

            /// タグ
            if (query.NarrowByTagIds)
            {
                var tags     = GetTags(query);
                var noTag    = query.NoTag;
                var compKind = query.TagCompoundKind;
                Func <MemoInfo, bool> tagFilter = info => {
                    var memo = _facade.Container.Find <Memo>(info.MemoId);
                    return
                        /// noTagかつ「allでタグを指定」を満たすことはあり得ないので,noTagは常にorでつなぐだけにしておく
                        ((noTag && !memo.Tags.Any()) ||
                         (compKind == MemoConditionCompoundKind.Any && memo.Tags.ContainsAny(tags)) ||
                         (compKind == MemoConditionCompoundKind.All && memo.Tags.ContainsAll(tags)));
                };
                matched = matched.Where(tagFilter);
            }

            /// 重要度
            if (query.NarrowByImportanceKind)
            {
                var importances = query.ImportanceKinds;
                Func <MemoInfo, bool> importanceFilter = info => {
                    var memo = _facade.Container.Find <Memo>(info.MemoId);
                    return(importances.Contains(memo.Importance));
                };
                matched = matched.Where(importanceFilter);
            }


            /// recent
            if (query.NarrowByRecentTimeSpan)
            {
                var recent = query.RecentTimeSpan;
                var filter = default(Func <MemoInfo, bool>);
                switch (recent.DateKind)
                {
                case MemoDateKind.Created: {
                    filter = info => {
                        var memo = _facade.Container.Find <Memo>(info.MemoId);
                        return
                            (memo.CreatedDate >= recent.FromDate &&
                             memo.CreatedDate < recent.ToDate);
                    };
                    break;
                }

                case MemoDateKind.Modified: {
                    filter = info => {
                        var memo = _facade.Container.Find <Memo>(info.MemoId);
                        return
                            (memo.ModifiedDate >= recent.FromDate &&
                             memo.ModifiedDate < recent.ToDate);
                    };
                    break;
                }

                case MemoDateKind.Accessed: {
                    filter = info => {
                        var memo = _facade.Container.Find <Memo>(info.MemoId);
                        return
                            (memo.AccessedDate >= recent.FromDate &&
                             memo.AccessedDate < recent.ToDate);
                    };
                    break;
                }
                }
                matched = matched.Where(filter);
            }

            /// 期間
            if (query.NarrowByTimeSpan)
            {
                var timeSpan = query.TimeSpan;
                var filter   = default(Func <MemoInfo, bool>);
                switch (timeSpan.DateKind)
                {
                case MemoDateKind.Created: {
                    filter = info => {
                        var memo = _facade.Container.Find <Memo>(info.MemoId);
                        return
                            (memo.CreatedDate >= timeSpan.FromDate &&
                             memo.CreatedDate < timeSpan.ToDate);
                    };
                    break;
                }

                case MemoDateKind.Modified: {
                    filter = info => {
                        var memo = _facade.Container.Find <Memo>(info.MemoId);
                        return
                            (memo.ModifiedDate >= timeSpan.FromDate &&
                             memo.ModifiedDate < timeSpan.ToDate);
                    };
                    break;
                }

                case MemoDateKind.Accessed: {
                    filter = info => {
                        var memo = _facade.Container.Find <Memo>(info.MemoId);
                        return
                            (memo.AccessedDate >= timeSpan.FromDate &&
                             memo.AccessedDate < timeSpan.ToDate);
                    };
                    break;
                }
                }
                matched = matched.Where(filter);
            }

            /// マーク
            if (query.NarrowByMarkKinds)
            {
                var noMarkKind = query.NoMarkKind;
                Func <MemoInfo, bool> markFilter = info => {
                    var memo   = _facade.Container.Find <Memo>(info.MemoId);
                    var opened = _facade.FindPageContent(info);

                    var markIds = default(IEnumerable <string>);
                    if (opened == null)
                    {
                        /// 開かれていなければキャッシュを見る
                        markIds = MemoMarkUtil.LoadMarkIdsCache(memo);
                        if (markIds == null)
                        {
                            markIds = MemoMarkUtil.GetMemoMarkIds(memo);
                            MemoMarkUtil.SaveMarkIdsCache(memo, markIds);
                        }
                    }
                    else
                    {
                        markIds = MemoMarkUtil.GetMemoMarkIds(memo);
                    }

                    if (noMarkKind && !markIds.Any())
                    {
                        return(true);
                    }
                    var marks     = MemoMarkUtil.GetMarks(markIds);
                    var markKinds = marks.Select(mark => mark.Kind).ToArray();
                    var compKind  = query.MarkCompoundKind;
                    return
                        ((compKind == MemoConditionCompoundKind.Any && query.MarkKinds.Any(kind => markKinds.Contains(kind))) ||
                         (compKind == MemoConditionCompoundKind.All && query.MarkKinds.All(kind => markKinds.Contains(kind))));
                };
                matched = matched.Where(markFilter);
            }


            /// 全文検索
            if (!query.NarrowByKeywords)
            {
                return(matched);
            }
            else
            {
                var ret = new List <MemoInfo>();

                var keywords = query.Condition.Split(' ');

                foreach (var info in matched.ToArray())
                {
                    /// MemoInfoのFullTextを取得
                    var fullText = default(string);
                    var opened   = _facade.FindPageContent(info);

                    if (opened == null)
                    {
                        fullText = _facade.Container.LoadExtendedTextData(typeof(Memo), info.MemoId, "FullText");

                        if (fullText == null)
                        {
                            /// 見つからなかった場合はノートをロードしてGetText()できるようにしておく
                            _facade.LoadMemo(info, true);
                            opened = _facade.FindPageContent(info);
                            if (opened != null)
                            {
                                var canvas = opened.EditorCanvas;
                                _facade.Container.SaveExtendedTextData(
                                    canvas.EditorContent, "FullText", canvas.GetFullText()
                                    );
                            }
                        }
                    }

                    if (opened != null && fullText == null)
                    {
                        var canvas = opened.EditorCanvas;
                        fullText = canvas.GetFullText();
                    }

                    if (fullText != null)
                    {
                        var matchFailed = false;
                        foreach (var keyword in keywords)
                        {
                            //if (Regex.IsMatch(fullText, keyword, RegexOptions.IgnoreCase | RegexOptions.Multiline)) {
                            if (keyword.StartsWith("-"))
                            {
                                /// "-"で始まる場合は除外キーワード
                                var realKeyword = keyword.Substring(1); /// "-"を除去
                                if (fullText.IndexOf(realKeyword, StringComparison.OrdinalIgnoreCase) > -1)
                                {
                                    matchFailed = true;
                                    break;
                                }
                            }
                            else
                            {
                                /// "-"で始まらなければ普通のキーワード
                                if (fullText.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) < 0)
                                {
                                    matchFailed = true;
                                    break;
                                }
                            }
                        }
                        if (!matchFailed)
                        {
                            ret.Add(info);
                        }
                    }
                }

                return(ret);
            }
        }