Exemplo n.º 1
0
        /// <summary>
        /// Searches the specified fields.
        /// </summary>
        /// <param name="fields">The fields.</param>
        /// <param name="filters">The filters.</param>
        public void Search(IEnumerable <SearchField> fields, IEnumerable <ICmObject> filters)
        {
            // If we abort this search (because the user typed), but somehow the system becomes idle before we complete a new
            // search, go ahead and complete the original one.
            m_pendingFields  = fields;
            m_pendingFilters = filters;
            m_mediator.IdleQueue.Add(IdleQueuePriority.High, DoPendingSearchWhenIdle);

            CreateSearchers();

            var       results        = new HashSet <ICmObject>();
            ITsString firstSearchStr = null;

            foreach (SearchField field in fields)
            {
                if (ShouldAbort())
                {
                    return;
                }
                if (firstSearchStr == null)
                {
                    firstSearchStr = field.String;
                }
                results.UnionWith(m_searcher.Search(field.Flid, field.String));
            }

            if (filters != null)
            {
                results.ExceptWith(filters);
            }

            if (ShouldAbort())
            {
                return;
            }
            // The following fixes LT-10293.
            RecordSorter sorter = null;

            if (firstSearchStr != null)
            {
                int  ws     = firstSearchStr.get_WritingSystemAt(0);
                bool isVern = m_cache.ServiceLocator.WritingSystems.VernacularWritingSystems.Contains(ws);
                sorter = m_bvMatches.CreateSorterForFirstColumn(isVern, ws);
            }
            if (sorter != null)
            {
                // Convert each ICmObject in results to a IManyOnePathSortItem, and sort
                // using the sorter.
                var records = new ArrayList(results.Count);
                foreach (ICmObject obj in results)
                {
                    records.Add(new ManyOnePathSortItem(obj));
                }
                sorter.Sort(records);
                var hvos = new int[records.Count];
                for (int i = 0; i < records.Count; ++i)
                {
                    hvos[i] = (((IManyOnePathSortItem)records[i]).KeyObject);
                }
                UpdateResults(hvos);
            }
            else
            {
                UpdateResults(results.Select(obj => obj.Hvo).ToArray());
            }
            // Completed successfully, don't want to do again.
            m_pendingFields = null;
            m_mediator.IdleQueue.Remove(DoPendingSearchWhenIdle);
        }
Exemplo n.º 2
0
        private void UpdateResults(SearchField firstField, IEnumerable <int> results)
        {
            ITsString firstSearchStr = firstField.String;
            // if the firstSearchStr is null we can't get its writing system
            RecordSorter sorter = null;

            if (firstSearchStr != null)
            {
                int ws = firstSearchStr.get_WritingSystemAt(0);
                sorter = CreateFindResultSorter(firstSearchStr, ws);
            }
            int[] hvos;
            if (sorter != null)
            {
                // Convert each ICmObject in results to a IManyOnePathSortItem, and sort
                // using the sorter.
                var records = new ArrayList();
                foreach (int hvo in results.Where(hvo => StartingObject == null || StartingObject.Hvo != hvo))
                {
                    records.Add(new ManyOnePathSortItem(hvo, null, null));
                }
                sorter.Sort(records);
                hvos = records.Cast <IManyOnePathSortItem>().Select(i => i.KeyObject).ToArray();
            }
            else
            {
                hvos = results.Where(hvo => StartingObject == null || StartingObject.Hvo != hvo).ToArray();
            }

            int count     = hvos.Length;
            int prevIndex = m_bvMatches.SelectedIndex;
            int prevHvo   = prevIndex == -1 ? 0 : m_bvMatches.AllItems[prevIndex];

            m_listPublisher.CacheVecProp(m_cache.LanguageProject.LexDbOA.Hvo, hvos);
            TabStop = count > 0;
            // Disable the list so that it doesn't steal the focus (LT-9481)
            m_bvMatches.Enabled = false;
            try
            {
                // LT-6366
                if (count == 0)
                {
                    if (m_bvMatches.BrowseView.IsHandleCreated)
                    {
                        m_bvMatches.SelectedIndex = -1;
                    }
                    m_selObject = null;
                }
                else
                {
                    int newIndex = 0;
                    var allItems = m_bvMatches.AllItems;                     // This is an important optimization; each call marshals the whole list!
                    for (int i = 0; i < allItems.Count; i++)
                    {
                        if (allItems[i] == prevHvo)
                        {
                            newIndex = i;
                            break;
                        }
                    }
                    if (m_bvMatches.BrowseView.IsHandleCreated)
                    {
                        m_bvMatches.SelectedIndex = newIndex;
                    }
                    m_selObject = m_cache.ServiceLocator.GetObject(allItems[newIndex]);
                    FireSelectionChanged();
                }
            }
            finally
            {
                m_bvMatches.Enabled = true;
            }

            if (!m_searchEngine.IsBusy && SearchCompleted != null)
            {
                SearchCompleted(this, new EventArgs());
            }
        }