Skip to content

Commit 376493c

Browse files
committed
db word search implemented in Ui for word manipulation.
1 parent 897efa7 commit 376493c

File tree

3 files changed

+88
-13
lines changed

3 files changed

+88
-13
lines changed

src/lekhika-trainer.cpp

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ class DbEditorTab : public QWidget
435435
explicit DbEditorTab(QWidget *parent = nullptr) : QWidget(parent)
436436
{
437437
auto *v = new QVBoxLayout(this);
438-
auto *h = new QHBoxLayout;
438+
auto *topControls = new QHBoxLayout;
439439

440440
reloadBtn = new QPushButton("Reload");
441441
newBtn = new QPushButton("New word");
@@ -444,12 +444,20 @@ class DbEditorTab : public QWidget
444444
editBtn = new QPushButton("Edit word");
445445
editBtn->setEnabled(false);
446446

447-
h->addWidget(reloadBtn);
448-
h->addWidget(newBtn);
449-
h->addWidget(delBtn);
450-
h->addWidget(editBtn);
451-
h->addWidget(resetBtn);
452-
h->addStretch();
447+
topControls->addWidget(reloadBtn);
448+
topControls->addWidget(newBtn);
449+
topControls->addWidget(delBtn);
450+
topControls->addWidget(editBtn);
451+
topControls->addWidget(resetBtn);
452+
topControls->addStretch();
453+
454+
auto *searchLay = new QHBoxLayout;
455+
searchEdit_ = new QLineEdit;
456+
searchEdit_->setPlaceholderText("Search for a word (Latin or Devanagari)...");
457+
clearSearchBtn_ = new QPushButton("Clear");
458+
searchLay->addWidget(new QLabel("Search:"));
459+
searchLay->addWidget(searchEdit_);
460+
searchLay->addWidget(clearSearchBtn_);
453461

454462
table = new QTableWidget(0, 2);
455463
table->setSelectionBehavior(QAbstractItemView::SelectRows);
@@ -473,7 +481,8 @@ class DbEditorTab : public QWidget
473481
log->setMaximumHeight(120);
474482
logLayout->addWidget(log);
475483

476-
v->addLayout(h);
484+
v->addLayout(topControls);
485+
v->addLayout(searchLay);
477486
v->addWidget(table, 1);
478487
v->addWidget(logFrame, 0);
479488

@@ -486,13 +495,48 @@ class DbEditorTab : public QWidget
486495
connect(table->selectionModel(), &QItemSelectionModel::selectionChanged,
487496
this, &DbEditorTab::onSelectionChanged);
488497
connect(table->verticalScrollBar(), &QScrollBar::valueChanged, this, &DbEditorTab::onScroll);
498+
connect(searchEdit_, &QLineEdit::textChanged, this, &DbEditorTab::onSearchTextChanged);
499+
connect(clearSearchBtn_, &QPushButton::clicked, this, [this](){ searchEdit_->clear(); });
489500
}
490501

491502
void setOnDatabaseUpdateCallback(std::function<void()> callback) {
492503
onDatabaseUpdate_ = callback;
493504
}
494505

495506
private:
507+
void onSearchTextChanged(const QString &text) {
508+
if (text.isEmpty()) {
509+
m_isSearchActive = false;
510+
reload();
511+
return;
512+
}
513+
514+
m_isSearchActive = true;
515+
516+
Transliteration transliterator;
517+
std::string devanagari_search_term = transliterator.transliterate(text.toStdString());
518+
519+
log->appendPlainText(QString("Searching for '%1' (%2)...").arg(text, QString::fromStdString(devanagari_search_term)));
520+
521+
DictionaryManager dm;
522+
auto words = dm.searchWords(devanagari_search_term);
523+
524+
table->setSortingEnabled(false);
525+
table->setRowCount(0); // Clear table before populating search results
526+
table->setRowCount(words.size());
527+
528+
for(size_t i = 0; i < words.size(); ++i) {
529+
auto *wItem = new QTableWidgetItem(QString::fromStdString(words[i].first));
530+
auto *fItem = new QTableWidgetItem(QString::number(words[i].second));
531+
wItem->setFlags(wItem->flags() & ~Qt::ItemIsEditable);
532+
fItem->setFlags(fItem->flags() & ~Qt::ItemIsEditable);
533+
table->setItem(i, 0, wItem);
534+
table->setItem(i, 1, fItem);
535+
}
536+
table->setSortingEnabled(true);
537+
log->appendPlainText(QString("Found %1 match(es).").arg(words.size()));
538+
}
539+
496540
void onSortColumnChanged(int logicalIndex) {
497541
m_currentSortColumn = logicalIndex;
498542
m_currentSortOrder = table->horizontalHeader()->sortIndicatorOrder();
@@ -505,6 +549,10 @@ class DbEditorTab : public QWidget
505549
}
506550

507551
void reload() {
552+
if (m_isSearchActive) {
553+
onSearchTextChanged(searchEdit_->text());
554+
return;
555+
}
508556
log->clear();
509557
currentPage_ = 0;
510558
table->setRowCount(0);
@@ -514,7 +562,7 @@ class DbEditorTab : public QWidget
514562
}
515563

516564
void loadMore() {
517-
if (isLoading_) return;
565+
if (isLoading_ || m_isSearchActive) return;
518566
isLoading_ = true;
519567

520568
if (currentPage_ == 0) {
@@ -556,7 +604,7 @@ class DbEditorTab : public QWidget
556604
}
557605

558606
void onScroll(int value) {
559-
if (!isLoading_ && value == table->verticalScrollBar()->maximum()) {
607+
if (!isLoading_ && !m_isSearchActive && value == table->verticalScrollBar()->maximum()) {
560608
loadMore();
561609
}
562610
}
@@ -578,7 +626,6 @@ class DbEditorTab : public QWidget
578626
auto sel = table->selectionModel()->selectedRows();
579627
if (sel.empty()) { log->appendPlainText("Nothing selected."); return; }
580628

581-
// Sort indexes in descending order to safely remove rows from bottom to top
582629
std::sort(sel.begin(), sel.end(), [](const QModelIndex &a, const QModelIndex &b) {
583630
return a.row() > b.row();
584631
});
@@ -649,12 +696,14 @@ class DbEditorTab : public QWidget
649696

650697
private:
651698
QTableWidget *table;
652-
QPushButton *reloadBtn, *newBtn, *delBtn, *resetBtn, *editBtn;
699+
QPushButton *reloadBtn, *newBtn, *delBtn, *resetBtn, *editBtn, *clearSearchBtn_;
700+
QLineEdit *searchEdit_;
653701
QPlainTextEdit *log;
654-
std::function<void()> onDatabaseUpdate_;
702+
std::function<void()> onDatabaseUpdate_ = nullptr;
655703
int currentPage_ = 0;
656704
const int pageSize_ = 50;
657705
bool isLoading_ = false;
706+
bool m_isSearchActive = false;
658707
int m_currentSortColumn = 0;
659708
Qt::SortOrder m_currentSortOrder = Qt::AscendingOrder;
660709
};

src/lekhika_core.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,31 @@ void DictionaryManager::removeWord(const std::string &word) {
298298
sqlite3_finalize(stmt);
299299
}
300300

301+
std::vector<std::pair<std::string, int>>
302+
DictionaryManager::searchWords(const std::string& searchTerm) {
303+
std::vector<std::pair<std::string, int>> results;
304+
if (!db_ || searchTerm.empty()) return results;
305+
sqlite3_stmt *stmt;
306+
307+
// Use LIKE with wildcards to search for the term anywhere in the word
308+
std::string sql_str = "SELECT word, frequency FROM words WHERE word LIKE ? ORDER BY frequency DESC;";
309+
310+
if (sqlite3_prepare_v2(db_, sql_str.c_str(), -1, &stmt, NULL) != SQLITE_OK) {
311+
return results;
312+
}
313+
314+
std::string pattern = "%" + searchTerm + "%";
315+
sqlite3_bind_text(stmt, 1, pattern.c_str(), -1, SQLITE_TRANSIENT);
316+
317+
while (sqlite3_step(stmt) == SQLITE_ROW) {
318+
results.emplace_back((const char *)sqlite3_column_text(stmt, 0),
319+
sqlite3_column_int(stmt, 1));
320+
}
321+
322+
sqlite3_finalize(stmt);
323+
return results;
324+
}
325+
301326
bool DictionaryManager::updateWordFrequency(const std::string &word,
302327
int frequency) {
303328
if (!db_) return false;

src/lekhika_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class DictionaryManager {
3939

4040
enum SortColumn { ByWord = 0, ByFrequency = 1 };
4141
std::vector<std::pair<std::string, int>> getAllWords(int limit = -1, int offset = 0, SortColumn sortBy = ByWord, bool ascending = true);
42+
std::vector<std::pair<std::string, int>> searchWords(const std::string& searchTerm);
4243

4344
// Transaction management
4445
void beginTransaction();

0 commit comments

Comments
 (0)