#include "fiko/ui/komut.hpp" #include #include #include #include "fiko/ui/fiko_universal_arama.hpp" // FikoUniversalArama/FikoAramaOgesi tam-tip namespace fiko { namespace { std::string kucult(const std::string& s) { std::string r = s; std::transform(r.begin(), r.end(), r.begin(), [](unsigned char c) { return (char)std::tolower(c); }); return r; } } int bulanikSkor(const std::string& sorgu, const std::string& hedef) { const std::string s = kucult(sorgu); const std::string h = kucult(hedef); if (s.empty()) return 0; if (h.empty()) return -1; int skor = 0; int ardisik = 0; // ardisik eslesme zinciri uzunlugu std::size_t hi = 0; for (char c : s) { bool bulundu = false; for (; hi < h.size(); ++hi) { if (h[hi] == c) { skor += 1; if (hi == 0) { skor += 8; // en bas eslesmesi } else if (!std::isalnum((unsigned char)h[hi - 1])) { skor += 6; // kelime siniri (bosluk/ayrac sonrasi) } skor += ardisik * 3; // ardisik eslesme bonusu ++ardisik; ++hi; bulundu = true; break; } ardisik = 0; // atlanan karakter zinciri kirar } if (!bulundu) return -1; // sorgu karakteri hedefte kalmadi } skor += std::max(0, 20 - (int)h.size()); // kisa/spesifik hedef bonusu return skor; } std::vector bulanikEslesmePozisyonlari(const std::string& sorgu, const std::string& hedef) { const std::string s = kucult(sorgu); const std::string h = kucult(hedef); std::vector pozlar; if (s.empty() || h.empty()) return pozlar; std::size_t hi = 0; for (char c : s) { bool bulundu = false; for (; hi < h.size(); ++hi) if (h[hi] == c) { pozlar.push_back((int)hi); ++hi; bulundu = true; break; } if (!bulundu) return {}; // eşleşmezse boş (bulanikSkor -1 ile tutarlı) } return pozlar; } std::vector KomutKaydi::ara(const std::string& sorgu) const { std::vector sonuc; if (sorgu.empty()) { // Bos sorgu: once son-kullanilanlar (MRU sirasi), sonra kalanlar kayit sirasinda. sonuc.reserve(komutlar_.size()); for (const std::string& ad : sonKullanilanlar_) { for (const auto& k : komutlar_) { if (k.ad == ad) { sonuc.push_back(&k); break; } } } for (const auto& k : komutlar_) { if (mruSira(k.ad) < 0) sonuc.push_back(&k); } return sonuc; } std::vector> skorlu; for (const auto& k : komutlar_) { const int sAd = bulanikSkor(sorgu, k.ad); const int sKat = bulanikSkor(sorgu, k.kategori); // Kategori eslesmesi ada gore daha zayif agirlikli. int s = std::max(sAd, sKat >= 0 ? sKat / 2 : -1); if (s < 0) continue; // MRU tiebreak bonusu: son-kullanilan komutlar esit fuzzy skorda one gecer. const int mru = mruSira(k.ad); if (mru >= 0) s += (12 - mru); skorlu.push_back({s, &k}); } std::stable_sort(skorlu.begin(), skorlu.end(), [](const auto& a, const auto& b) { return a.first > b.first; }); sonuc.reserve(skorlu.size()); for (const auto& [s, k] : skorlu) sonuc.push_back(k); return sonuc; } // ── KomutPaleti out-of-line (uSonuc_ = FikoAramaOgesi tam-tip burada) ───────── KomutPaleti::KomutPaleti() : uSonuc_(std::make_unique>()) {} KomutPaleti::~KomutPaleti() = default; KomutPaleti::KomutPaleti(KomutPaleti&&) noexcept = default; KomutPaleti& KomutPaleti::operator=(KomutPaleti&&) noexcept = default; const std::vector& KomutPaleti::universalSonuclar() const { return *uSonuc_; } int KomutPaleti::sonucSayisi() const { return universal_ ? (int)uSonuc_->size() : (int)sonuclar_.size(); } void KomutPaleti::ac() { acik_ = true; sorgu_.clear(); secili_ = 0; if (universal_) universal_->topla(); // kaynakları önbelleğe topla (açılışta bir kez) yenile(); } void KomutPaleti::yenile() { if (universal_) { *uSonuc_ = universal_->ara(sorgu_); sonuclar_.clear(); } else { sonuclar_ = kayit_ ? kayit_->ara(sorgu_) : std::vector{}; uSonuc_->clear(); } const int n = sonucSayisi(); if (secili_ >= n) secili_ = n - 1; if (secili_ < 0) secili_ = 0; } bool KomutPaleti::onayla() { if (universal_) { if (secili_ < 0 || secili_ >= (int)uSonuc_->size()) return false; const ui::FikoAramaOgesi& o = (*uSonuc_)[secili_]; if (o.calistir) o.calistir(); if (ogeCalisti) ogeCalisti(o.ad); // makro/plugin/olay gözlemi kapat(); return true; } const Komut* k = seciliKomut(); if (!k || !kayit_) return false; const std::string ad = k->ad; // calistir MRU'yu değiştirebilir → ad'ı önce al kayit_->calistir(*k); if (ogeCalisti) ogeCalisti(ad); // makro/plugin/olay gözlemi kapat(); return true; } }