Example #1
0
        /// <summary>
        /// Execute a search request and callback for every incoming items and when the search is completed.
        /// The user is responsible for disposing of the search context.
        /// </summary>
        public static void Request(SearchContext context,
                                   Action <SearchContext, IEnumerable <SearchItem> > onIncomingItems,
                                   Action <SearchContext> onSearchCompleted,
                                   SearchFlags options = SearchFlags.None)
        {
            var requestId = Guid.NewGuid().ToString("N");

            if (options.HasAny(SearchFlags.Debug))
            {
                Debug.Log($"{requestId} Request started {context.searchText} ({options | context.options})");
            }
            var sessionCount       = 0;
            var firstBatchResolved = false;
            var completed          = false;
            var batchCount         = 1;

            void ReceiveItems(SearchContext c, IEnumerable <SearchItem> items)
            {
                if (options.HasAny(SearchFlags.Debug))
                {
                    Debug.Log($"{requestId} #{batchCount++} Request incoming batch {context.searchText}");
                }
                onIncomingItems?.Invoke(c, items.Where(e => e != null));
            }

            void OnSessionStarted(SearchContext c)
            {
                if (options.HasAny(SearchFlags.Debug))
                {
                    Debug.Log($"{requestId} Request session begin {context.searchText}");
                }
                ++sessionCount;
            }

            void OnSessionEnded(SearchContext c)
            {
                if (options.HasAny(SearchFlags.Debug))
                {
                    Debug.Log($"{requestId} Request session ended {context.searchText}");
                }
                --sessionCount;
                if (sessionCount == 0 && firstBatchResolved)
                {
                    if (options.HasAny(SearchFlags.Debug))
                    {
                        Debug.Log($"{requestId} Request async ended {context.searchText}");
                    }
                    context.asyncItemReceived -= ReceiveItems;
                    context.sessionStarted    -= OnSessionStarted;
                    context.sessionEnded      -= OnSessionEnded;
                    onSearchCompleted?.Invoke(c);
                    completed = true;
                }
            }

            context.asyncItemReceived += ReceiveItems;
            context.sessionStarted    += OnSessionStarted;
            context.sessionEnded      += OnSessionEnded;
            GetItems(context, options | SearchFlags.FirstBatchAsync);
            firstBatchResolved = true;
            if (sessionCount == 0 && !completed)
            {
                if (options.HasAny(SearchFlags.Debug))
                {
                    Debug.Log($"{requestId} Request sync ended {context.searchText}");
                }
                context.asyncItemReceived -= ReceiveItems;
                context.sessionStarted    -= OnSessionStarted;
                context.sessionEnded      -= OnSessionEnded;
                onSearchCompleted?.Invoke(context);
            }
        }
 public SearchExpressionParserArgs(SearchContext context, SearchExpressionParserFlags options = SearchExpressionParserFlags.Default)
     : this(new StringView(context.searchText), context, options)
 {
 }
 /// <summary>
 /// Create a Search item that will be bound to the SeaechProvider.
 /// </summary>
 /// <param name="context">Search context from the query that generates this item.</param>
 /// <param name="id">Unique id of the search item. This is used to remove duplicates to the user view.</param>
 /// <param name="label">The search item label is displayed on the first line of the search item UI widget.</param>
 /// <param name="description">The search item description is displayed on the second line of the search item UI widget.</param>
 /// <param name="thumbnail">The search item thumbnail is displayed left to the item label and description as a preview.</param>
 /// <param name="data">User data used to recover more information about a search item. Generally used in fetchLabel, fetchDescription, etc.</param>
 /// <returns>New SearchItem</returns>
 public SearchItem CreateItem(SearchContext context, string id, string label, string description, Texture2D thumbnail, object data)
 {
     return(CreateItem(context, id, 0, label, description, thumbnail, data));
 }
Example #4
0
 public SearchQueryError(QueryError error, SearchContext context, SearchProvider provider, bool fromSearchQuery = true)
     : this(error.index, error.length, error.reason, context, provider, fromSearchQuery, error.type)
 {
 }
Example #5
0
 public IEnumerable <object> EvaluateArgs(SearchContext context, bool reevaluateLiterals = false)
 {
     return(args.SelectMany(qma => qma.Evaluate(context, reevaluateLiterals)));
 }
Example #6
0
 private void OnProviderAsyncItemReceived(SearchContext context, IEnumerable <SearchItem> items)
 {
     asyncItemReceived?.Invoke(context, items);
 }
 public SearchApiSession(params SearchProvider[] providers)
 {
     context = new SearchContext(providers);
 }
 public static object SelectValue(SearchItem item, SearchContext context, string selectorName)
 {
     return(SelectValue(item, context, selectorName, out var _));
 }
        public static object SelectValue(SearchItem item, SearchContext context, string selectorName, out string suggestedSelectorName)
        {
            suggestedSelectorName = selectorName;
            if (item.TryGetValue(selectorName, context, out var field))
            {
                return(field.value);
            }

            if (string.IsNullOrEmpty(selectorName))
            {
                return(null);
            }

            #if USE_PROPERTY_DATABASE
            using (var view = SearchMonitor.GetView())
            #endif
            {
                #if USE_PROPERTY_DATABASE
                if (view.TryLoadProperty(item.key, selectorName, out var recordKey, out var cv, out suggestedSelectorName))
                {
                    return(cv);
                }
                #endif

                string localSuggestedSelectorName = null;
                string providerType = item.provider.type;
                var    itemValue    = TaskEvaluatorManager.EvaluateMainThread(() =>
                {
                    foreach (var m in Match(selectorName, providerType))
                    {
                        var selectorArgs  = new SearchSelectorArgs(m, item);
                        var selectedValue = m.selector.select(selectorArgs);
                        if (selectedValue != null)
                        {
                            if (selectorArgs.name != null)
                            {
                                localSuggestedSelectorName = selectorArgs.name;
                            }
                            return(selectedValue);
                        }
                    }

                    return(null);
                });

                if (itemValue == null)
                {
                    return(null);
                }

                if (!string.IsNullOrEmpty(localSuggestedSelectorName))
                {
                    suggestedSelectorName = localSuggestedSelectorName;
                }

                #if USE_PROPERTY_DATABASE
                view.StoreProperty(recordKey, itemValue, suggestedSelectorName);
                #endif

                return(itemValue);
            }
        }
Example #10
0
 public static SearchReport Create(SearchContext context, SearchTable table, IEnumerable <SearchItem> items)
 {
     return(Create(context, table.columns, items));
 }
Example #11
0
 public static string Export(SearchContext context, IEnumerable <SearchColumn> columns, IEnumerable <SearchItem> items)
 {
     return(Create(context, columns, items).Export());
 }
Example #12
0
 public static SearchReport Create(SearchContext context, SearchTable table)
 {
     return(Create(context, table.columns, null));
 }
Example #13
0
 public static new SearchItem CreateItem(SearchContext context, string id, int score, string label, string description, Texture2D thumbnail, object @ref)
 {
     return(s_Provider.CreateItem(context, id, score, label, description, thumbnail, @ref));
 }
Example #14
0
 private static void OnSearchEnded(SearchContext context)
 {
     context.searchFinishTime = DateTime.Now.Ticks;
 }
Example #15
0
 public SearchSession(SearchContext context)
 {
     m_Context = context;
 }
 public static IEnumerable <SearchItem> SelectValues(SearchContext context, IEnumerable <SearchItem> items, string selector, string setFieldName)
 {
     return(EvaluatorUtils.ProcessValues(items, setFieldName, item => SelectValue(item, context, selector)?.ToString()));
 }
Example #17
0
 private void OnProviderAsyncSessionEnded(SearchContext context)
 {
     sessionEnded?.Invoke(context);
 }
Example #18
0
        public static GUIContent FormatDescription(SearchItem item, SearchContext context, float availableSpace, bool useColor = true)
        {
            var desc = item.GetDescription(context);

            if (desc != null && item.options.HasAny(SearchItemOptions.Compacted))
            {
                desc = desc.Replace("\n", " ");
            }
            if (String.IsNullOrEmpty(desc))
            {
                return(Styles.emptyContent);
            }
            var content = Take(desc);

            if (item.options == SearchItemOptions.None || Event.current.type != EventType.Repaint)
            {
                return(content);
            }

            var truncatedDesc = desc;
            var truncated     = false;

            if (useColor)
            {
                if (item.options.HasAny(SearchItemOptions.Ellipsis))
                {
                    int maxCharLength = Utils.GetNumCharactersThatFitWithinWidth(Styles.itemDescription, truncatedDesc + "...", availableSpace);
                    if (maxCharLength < 0)
                    {
                        maxCharLength = truncatedDesc.Length;
                    }
                    truncated = desc.Length > maxCharLength;
                    if (truncated)
                    {
                        if (item.options.HasAny(SearchItemOptions.RightToLeft))
                        {
                            truncatedDesc = "..." + desc.Replace("<b>", "").Replace("</b>", "");
                            truncatedDesc = truncatedDesc.Substring(Math.Max(0, truncatedDesc.Length - maxCharLength));
                        }
                        else
                        {
                            truncatedDesc = desc.Substring(0, Math.Min(maxCharLength, desc.Length)) + "...";
                        }
                    }
                }

                if (context != null)
                {
                    if (item.options.HasAny(SearchItemOptions.Highlight))
                    {
                        var parts = context.searchQuery.Split('*', ' ', '.').Where(p => p.Length > 2);
                        foreach (var p in parts)
                        {
                            truncatedDesc = Regex.Replace(truncatedDesc, Regex.Escape(p), string.Format(Styles.highlightedTextColorFormat, "$0"), RegexOptions.IgnoreCase);
                        }
                    }
                    else if (item.options.HasAny(SearchItemOptions.FuzzyHighlight))
                    {
                        long score   = 1;
                        var  matches = new List <int>();
                        var  sq      = Utils.CleanString(context.searchQuery.ToLowerInvariant());
                        if (FuzzySearch.FuzzyMatch(sq, Utils.CleanString(truncatedDesc), ref score, matches))
                        {
                            truncatedDesc = RichTextFormatter.FormatSuggestionTitle(truncatedDesc, matches);
                        }
                    }
                }
            }

            content.text = truncatedDesc;
            if (truncated)
            {
                content.tooltip = Utils.StripHTML(desc);
            }

            return(content);
        }
Example #19
0
 private void OnAsyncItemsReceived(SearchContext context, IEnumerable <SearchItem> items)
 {
     AddItems(items);
 }
Example #20
0
 internal static SortedSet <SearchProposition> Fetch(SearchContext context, in SearchPropositionOptions options)
 private void OnAsyncItemsReceived(SearchContext context, IEnumerable <SearchItem> items)
 {
     onAsyncItemsReceived?.Invoke(items.Select(item => item.id));
 }
 public SearchSessionContext(SearchContext context, StackTrace stackTrace)
 {
     this.searchContext = context;
     this.stackTrace    = stackTrace;
 }
Example #23
0
 public static string ReplaceMarkersWithEvaluatedValues(StringView text, SearchContext context)
 {
     return(ReplaceMarkersWithEvaluatedValues(text.ToString(), context));
 }
 public SearchSessionContext(SearchContext context)
     : this(context, new StackTrace(2, true))
 {
 }
 public SearchExpressionParserArgs(StringView text, SearchContext context = null, SearchExpressionParserFlags options = SearchExpressionParserFlags.Default)
 {
     this.text    = text.Trim();
     this.context = context;
     this.options = options;
 }
Example #26
0
 private void OnAsyncItemsReceived(SearchContext context, IEnumerable <SearchItem> items)
 {
     m_Results.AddItems(items);
     Repaint();
 }
 /// <summary>
 /// Helper function to create a new search item for the current provider.
 /// </summary>
 /// <param name="context">Search context from the query that generates this item.</param>
 /// <param name="id">Unique id of the search item. This is used to remove duplicates to the user view.</param>
 /// <returns>The newly created search item attached to the current search provider.</returns>
 public SearchItem CreateItem(SearchContext context, string id)
 {
     return(CreateItem(context, id, 0, null, null, null, null));
 }
Example #28
0
        public void Draw(SearchContext context, float width)
        {
            var selection = context.searchView.selection;

            using (var scrollView = new EditorGUILayout.ScrollViewScope(m_ScrollPosition, Styles.panelBackgroundRight, GUILayout.Width(width), GUILayout.ExpandHeight(true)))
            {
                var selectionCount = selection.Count;

                var lastItem    = selection.Last();
                var showOptions = lastItem?.provider.showDetailsOptions ?? ShowDetailsOptions.None;

                if (Event.current.type == EventType.Layout)
                {
                    SetupEditors(selection, showOptions);
                }

                GUILayout.Label(Styles.previewInspectorContent, Styles.panelHeader);

                if (selectionCount == 0)
                {
                    return;
                }

                if (selectionCount > 1)
                {
                    // Do not render anything else if the selection is composed of items with different providers
                    if (selection.GroupBy(item => item.provider.id).Count() > 1)
                    {
                        GUILayout.Label($"Selected {selectionCount} items from different types.", Styles.panelHeader);
                        return;
                    }
                    else
                    {
                        GUILayout.Label($"Selected {selectionCount} items", Styles.panelHeader);
                    }
                }

                using (var s = new EditorGUILayout.VerticalScope(Styles.inspector))
                {
                    if (showOptions.HasAny(ShowDetailsOptions.Actions))
                    {
                        DrawActions(context);
                    }

                    if (selectionCount == 1)
                    {
                        if (showOptions.HasAny(ShowDetailsOptions.Preview) && lastItem != null)
                        {
                            DrawPreview(context, lastItem, width);
                        }

                        if (showOptions.HasAny(ShowDetailsOptions.Description) && lastItem != null)
                        {
                            DrawDescription(context, lastItem);
                        }
                    }

                    if (showOptions.HasAny(ShowDetailsOptions.Inspector))
                    {
                        DrawInspector(width);
                    }
                }

                m_ScrollPosition = scrollView.scrollPosition;
            }
        }
 public SearchContext(SearchContext context)
     : this(context.providers, context.searchText, context.options)
 {
 }
Example #30
0
 static void HandleItemsIteratorSession(object iterator, List <SearchItem> allItems, string id, SearchContext context, SearchFlags options)
 {
     if (iterator != null && options.HasAny(SearchFlags.Synchronous))
     {
         using (var stackedEnumerator = new SearchEnumerator <SearchItem>(iterator))
         {
             while (stackedEnumerator.MoveNext())
             {
                 if (stackedEnumerator.Current != null)
                 {
                     allItems.Add(stackedEnumerator.Current);
                 }
             }
         }
     }
     else
     {
         var session = context.sessions.GetProviderSession(context, id);
         session.Reset(context, iterator, k_MaxFetchTimeMs);
         session.Start();
         var sessionEnded = !session.FetchSome(allItems, k_MaxFetchTimeMs);
         if (options.HasAny(SearchFlags.FirstBatchAsync))
         {
             session.SendItems(context.subset != null ? allItems.Intersect(context.subset) : allItems);
             allItems.Clear();
         }
         if (sessionEnded)
         {
             session.Stop();
         }
     }
 }