// TODO de werkwijze van het aanpassen van de autocomplete source veroorzaakt soms een access violation. Bijv. snel typen na opstarten. // TODO soms triggert de autoselect en wordt je tekst vanzelf geselecteerd, dat is irritant. // TODO er lijkt een memoryleak te zijn. Geheugengebruik loopt op als je snel wisselt tussen bijv. 'psalmen ' en 'psalmen 1'. Vermoedelijk de database. private void TriggerZoeklijstVeranderd() { _huidigZoekresultaat = _liturgieZoeker.VrijZoeken(textBoxZoek.Text, checkBoxAlsBijbeltekst.Checked, _huidigZoekresultaat); if (_huidigZoekresultaat.ZoeklijstAanpassing == VrijZoekresultaatAanpassingType.Geen) { return; } // We gaan kijken wat de verandering is. // Dit moet wat slimmer dan gewoon verwijderen/toevoegen omdat deze lijst zich instabiel gedraagt textBoxZoek.SuspendLayout(); lock (_dropdownLocker) // Lock om te voorkomen dat werk nog niet af is als we er nog een x in komen (lijkt namelijk te gebeuren) { if (_huidigZoekresultaat == null || _huidigZoekresultaat.ZoeklijstAanpassing == VrijZoekresultaatAanpassingType.Alles || _huidigZoekresultaat.DeltaMogelijkhedenVerwijderd.Count() > 50) { textBoxZoek.AutoCompleteCustomSource.Clear(); textBoxZoek.AutoCompleteCustomSource.AddRange(_huidigZoekresultaat.AlleMogelijkheden.Select(m => m.Weergave).ToArray()); } else if (_huidigZoekresultaat.ZoeklijstAanpassing == VrijZoekresultaatAanpassingType.Deel) { textBoxZoek.AutoCompleteCustomSource.AddRange(_huidigZoekresultaat.DeltaMogelijkhedenToegevoegd.Select(m => m.Weergave).ToArray()); foreach (var item in _huidigZoekresultaat.DeltaMogelijkhedenVerwijderd) { textBoxZoek.AutoCompleteCustomSource.Remove(item.Weergave); } } } textBoxZoek.ResumeLayout(); }
/// <summary> /// Dit maakt een lijst van resultaten die voldoen aan de zoektekst. Filteren gebeurd hier niet maar in de UI zelf. /// We helpen de UX beleving door de UI niet direct alle mogelijkheden meteen terug te geven, alleen te verdiepen waar de gebruiker /// echt naar zoekt. /// Verder wordt aangegeven welke zoekresultaten veranderd zijn zodat de UI de verwijderde of toegevoegde elementen kan animeren /// of iets dergelijks. /// </summary> public IVrijZoekresultaat VrijZoeken(string zoekTekst, bool alsBijbeltekst = false, IVrijZoekresultaat vorigResultaat = null) { var veiligeZoekTekst = (zoekTekst ?? "").TrimStart(); var veranderingGemaakt = vorigResultaat == null; var zoekRestricties = new ZoekRestricties(alsBijbeltekst); var aanname = vorigResultaat?.Aanname; var laatsteZoektekenIsFragmentWissel = veiligeZoekTekst.Length > 0 ? LiturgieInterpretator.LiturgieTekstNaarObject.BenamingDeelScheidingstekens.Contains(veiligeZoekTekst.Last()) : false; var onderdeelLijst = KrijgBasisDatabaseLijst(zoekRestricties, true); var fragmentLijst = Enumerable.Empty <IVrijZoekresultaatMogelijkheid>(); var vorigeZoektermSplit = _liturgieTekstNaarObject.VanTekstregel(vorigResultaat == null ? "" : vorigResultaat.ZoekTerm); var huidigeZoektermSplit = _liturgieTekstNaarObject.VanTekstregel(veiligeZoekTekst); // Wisselen tussen bijbeltekst vinkje of niet geeft natuurlijk grote wijziging if (vorigResultaat != null && vorigResultaat.AlsBijbeltekst != alsBijbeltekst) { veranderingGemaakt = true; } // Let op: Omdat de UI zelf filtert detecteren we hier alleen overgangen. // Kijk of er in de zoektekst een spatie is gebruikt, dan komt er nu een overgang aan if ((veiligeZoekTekst.Length > 0 && laatsteZoektekenIsFragmentWissel) || (string.IsNullOrWhiteSpace(vorigeZoektermSplit.Deel) && !string.IsNullOrWhiteSpace(huidigeZoektermSplit.Deel))) { // Fragment is er bij gekomen veranderingGemaakt = true; fragmentLijst = ZoekFragmenten(zoekRestricties, huidigeZoektermSplit.Benaming).Select(t => new ZoekresultaatItem() { Weergave = $"{huidigeZoektermSplit.Benaming} {t.Resultaat.Weergave}", UitDatabase = t.Database.Weergave, }).ToList(); // Geen aannames meer aanname = null; } // Zo gauw je de spatie weghaald is de overgang weer weg else if ((veiligeZoekTekst.Length == 0 || !laatsteZoektekenIsFragmentWissel) && string.IsNullOrWhiteSpace(huidigeZoektermSplit.Deel) && (vorigResultaat != null && vorigResultaat.ZoekTerm.Length > 0 && LiturgieInterpretator.LiturgieTekstNaarObject.BenamingDeelScheidingstekens.Contains(vorigResultaat.ZoekTerm.Last()))) { // Fragment is weer weg gehaald veranderingGemaakt = true; } // Bepaal het nieuwe zoekresultaat var nieuwResultaat = ZoekresultaatSamenstellen(veiligeZoekTekst, alsBijbeltekst, vorigResultaat, onderdeelLijst.Union(fragmentLijst), aanname, veranderingGemaakt); if (vorigResultaat == null) { return(nieuwResultaat); } // Het kan zijn dat bij het vorige zoekresultaat nog meerdere opties mogelijk waren, maar dat er nu nog maar 1 optie mogelijk is, // terwijl je nog wel een paar tekens moet typen. Dat kan handiger, we maken de aanname dat je deze ene optie bedoelt: if (!laatsteZoektekenIsFragmentWissel && vorigResultaat.Aanname == null && VoorspelZoekresultaat(vorigResultaat.AlleMogelijkheden, vorigResultaat.ZoekTerm).Count() > 1 && VoorspelZoekresultaat(nieuwResultaat.AlleMogelijkheden, nieuwResultaat.ZoekTerm).Count() == 1) { veranderingGemaakt = true; aanname = VoorspelZoekresultaat(nieuwResultaat.AlleMogelijkheden, nieuwResultaat.ZoekTerm).First().Weergave; // Fragment toevoegen op basis van aanname fragmentLijst = ZoekFragmenten(zoekRestricties, aanname).Select(t => new ZoekresultaatItem() { Weergave = $"{aanname} {t.Resultaat.Weergave}", UitDatabase = t.Database.Weergave, }).ToList(); nieuwResultaat = ZoekresultaatSamenstellen(veiligeZoekTekst, alsBijbeltekst, vorigResultaat, onderdeelLijst.Union(fragmentLijst), aanname, veranderingGemaakt); } // Als de aanname niet meer gemaakt kan worden else if (!string.IsNullOrEmpty(vorigResultaat.Aanname) && VoorspelZoekresultaat(nieuwResultaat.AlleMogelijkheden, nieuwResultaat.ZoekTerm).Count() > VoorspelZoekresultaat(vorigResultaat.AlleMogelijkheden, vorigResultaat.ZoekTerm).Count()) { veranderingGemaakt = true; aanname = null; nieuwResultaat = ZoekresultaatSamenstellen(veiligeZoekTekst, alsBijbeltekst, vorigResultaat, onderdeelLijst.Union(fragmentLijst), aanname, veranderingGemaakt); } return(nieuwResultaat); }
public string MaakTotTekst(string invoerTekst, LiturgieOptiesGebruiker opties, IVrijZoekresultaat zoekresultaat) { var tekstUitOpties = _liturgieTekstNaarObject.MaakTekstVanOpties(opties); var gebruiktZoekresultaat = zoekresultaat.AlleMogelijkheden .Where(w => invoerTekst.StartsWith(w.Weergave)) .OrderByDescending(w => w.Weergave.Length) .FirstOrDefault(); if (gebruiktZoekresultaat == null) { return($"{invoerTekst.Trim()} {tekstUitOpties.Trim()}".Trim()); } else { var resterend = invoerTekst.Substring(gebruiktZoekresultaat.Weergave.Length); return($"{gebruiktZoekresultaat.VeiligeNaam} {resterend.Trim()} {tekstUitOpties.Trim()}".Trim()); } }
public LiturgieOptiesGebruiker ZoekStandaardOptiesUitZoekresultaat(string invoerTekst, IVrijZoekresultaat zoekresultaat) { if (string.IsNullOrWhiteSpace(invoerTekst)) { return(null); } var databaseNaam = string.Empty; if (zoekresultaat != null) { var invoerTekstSplitsing = _liturgieTekstNaarObject.VanTekstregel(invoerTekst); var teZoekenTekst = $"{invoerTekstSplitsing.Benaming} {invoerTekstSplitsing.Deel}"; var itemInZoeklijst = zoekresultaat.AlleMogelijkheden.FirstOrDefault(z => z.Weergave == teZoekenTekst); if (itemInZoeklijst != null) { databaseNaam = itemInZoeklijst.UitDatabase; } if (string.IsNullOrWhiteSpace(databaseNaam)) { databaseNaam = zoekresultaat.VermoedelijkeDatabase; } } return(_liturgieTekstNaarObject.BepaalBasisOptiesTekstinvoer(invoerTekst, databaseNaam)); }
private Zoekresultaat ZoekresultaatSamenstellen(string zoekTekst, bool alsBijbeltekst, IVrijZoekresultaat vorigResultaat, IEnumerable <IVrijZoekresultaatMogelijkheid> lijst, string aanname, bool lijstIsGewijzigd) { var zoekLijst = Enumerable.Empty <IVrijZoekresultaatMogelijkheid>(); var zoekLijstDeltaToegevoegd = Enumerable.Empty <IVrijZoekresultaatMogelijkheid>(); var zoekLijstDeltaVerwijderd = Enumerable.Empty <IVrijZoekresultaatMogelijkheid>(); var aanpassing = VrijZoekresultaatAanpassingType.Alles; var vermoedelijkeDatabase = string.Empty; if (!lijstIsGewijzigd && vorigResultaat != null) { aanpassing = VrijZoekresultaatAanpassingType.Geen; zoekLijst = vorigResultaat.AlleMogelijkheden.ToList(); vermoedelijkeDatabase = vorigResultaat.VermoedelijkeDatabase; } else { zoekLijst = lijst.Distinct().OrderBy(z => z.Weergave).ToList(); if (aanpassing == VrijZoekresultaatAanpassingType.Alles && vorigResultaat != null) { zoekLijstDeltaToegevoegd = zoekLijst.Where(z => !vorigResultaat.AlleMogelijkheden.Contains(z)).ToList(); zoekLijstDeltaVerwijderd = vorigResultaat.AlleMogelijkheden.Where(z => !zoekLijst.Contains(z)).ToList(); if (zoekLijstDeltaVerwijderd.Count() != vorigResultaat.AlleMogelijkheden.Count()) { aanpassing = VrijZoekresultaatAanpassingType.Deel; } } var databases = zoekLijst.Select(z => z.UitDatabase).Distinct().ToList(); if (databases.Count == 1) { vermoedelijkeDatabase = databases.First(); } } return(new Zoekresultaat() { ZoekTerm = zoekTekst, AlsBijbeltekst = alsBijbeltekst, Aanname = aanname, VermoedelijkeDatabase = vermoedelijkeDatabase, AlleMogelijkheden = zoekLijst.ToList(), DeltaMogelijkhedenToegevoegd = zoekLijstDeltaToegevoegd, DeltaMogelijkhedenVerwijderd = zoekLijstDeltaVerwijderd, ZoeklijstAanpassing = aanpassing, }); }