#include "SRFind.h" #include "SRFramework/SRApp.h" #include "SwordReaderResource.h" #include "SRMainFrame.h" using namespace SRFramework; using namespace sword; BOOL SRFind::s_fRegistered = false; void setPercentCB(char percent, void *userData) { SRFind *caller = static_cast(userData); if(caller) caller->SetProgress((int)percent); } SRFind::SRFind() :m_pEdtQuery(NULL) ,m_pButtonSearch(NULL) ,m_pRadRangeBible(NULL) ,m_pRadRangeTestament(NULL) ,m_pRadRangeBook(NULL) ,m_pRadMethodMultiword(NULL) ,m_pRadMethodExactphrase(NULL) ,m_pListBoxResults(NULL) ,m_pProgressBar(NULL) ,m_pButtonGoTo(NULL) ,m_textPreview(NULL) ,m_wMethodMode(SR_FIND_METHOD_MWORD) ,m_wRangeMode(SR_FIND_RANGE_BIBLE) ,m_modCurText(NULL) { m_wcsClassName = "SRFind"; m_wcsWindowName = "Sword Search Window"; } SRFind::~SRFind() { if(m_textPreview) delete m_textPreview; if(m_pEdtQuery) delete m_pEdtQuery; if(m_pButtonSearch) delete m_pButtonSearch; if(m_pButtonGoTo) delete m_pButtonGoTo; if(m_pListBoxResults) delete m_pListBoxResults; if(m_pRadMethodExactphrase) delete m_pRadMethodExactphrase; if(m_pRadMethodMultiword) delete m_pRadMethodMultiword; if(m_pRadRangeBible) delete m_pRadRangeBible; if(m_pRadRangeBook) delete m_pRadRangeBook; if(m_pRadRangeTestament) delete m_pRadRangeTestament; if(m_pProgressBar) delete m_pProgressBar; } VOID SRFind::SetProgress(INT nPercent) { m_pProgressBar->SetPosition(nPercent); } VOID SRFind::AddResult(WCString &wcsVerse) { wchar_t wverse[16] = {0}; wchar_t wchapt[16] = {0}; VerseKey* verse = new VerseKey(wcsVerse.c_str()); WCString wcsReference = SRMainFrame::GetBookNames()[(verse->Book() - 1) + BIBLE_OT_BOOKS*(verse->Testament() - 1)]; wcsReference += WCString(" ") + WCString(_itow(verse->Chapter(),wchapt, 10)) + WCString(":") + WCString(_itow(verse->Verse(), wverse, 10)); m_verseResults.push_back(*verse); m_pListBoxResults->AddItem(wcsReference); delete verse; } BOOL SRFind::OnCommand(WORD wNotifyCode, WORD wID, HWND hWndCtl) { switch(wID) { case IDC_BTN_SEARCH: Search(); break; case IDC_RAD_BIBLE: m_pRadRangeBible->Check(); m_pRadRangeTestament->Uncheck(); m_pRadRangeBook->Uncheck(); m_wRangeMode = SR_FIND_RANGE_BIBLE; break; case IDC_RAD_TESTAMENT: m_pRadRangeBible->Uncheck(); m_pRadRangeTestament->Check(); m_pRadRangeBook->Uncheck(); m_wRangeMode = SR_FIND_RANGE_TESTAMENT; break; case IDC_RAD_BOOK: m_pRadRangeBible->Uncheck(); m_pRadRangeTestament->Uncheck(); m_pRadRangeBook->Check(); m_wRangeMode = SR_FIND_RANGE_BOOK; break; case IDC_RAD_MWORD: m_pRadMethodMultiword->Check(); m_pRadMethodExactphrase->Uncheck(); m_wMethodMode = SR_FIND_METHOD_MWORD; break; case IDC_RAD_EPHRASE: m_pRadMethodMultiword->Uncheck(); m_pRadMethodExactphrase->Check(); m_wMethodMode = SR_FIND_METHOD_EPHRASE; break; case IDC_LST_RESULTS: ShowPreview(); break; case IDC_BTN_GOTO: GoToVerse(); break; default: return FALSE; } return TRUE; } VOID SRFind::ShowPreview() { int pos = m_pListBoxResults->GetCurSel(); if(pos == LB_ERR) return; VerseKey keyPreview = m_verseResults[pos]; m_modCurText->SetKey(keyPreview); m_textPreview->Clear(); WCString wcsPreview = m_modCurText->StripText(); m_textPreview->AddText(wcsPreview.w_str(), wcsPreview.length()); m_textPreview->UpdateWindow(); } VOID SRFind::GoToVerse() { int pos = m_pListBoxResults->GetCurSel(); if(pos == LB_ERR) return; ::SendMessage(m_pParentWnd->GetWindowHandle(), WM_COMMAND, SR_SETVERSEKEY,(LPARAM)&m_verseResults[pos]); ::SendMessage(m_pParentWnd->GetWindowHandle(), WM_COMMAND, MENU_TEXT,0); } BOOL SRFind::OnPaint() { RECT clientRect; PAINTSTRUCT ps; HDC hdc = BeginPaint(m_hWnd, &ps); HBRUSH brushBG = CreateSolidBrush((COLORREF)BUTTON_BACKGROUND); GetClientRect(m_hWnd, &clientRect); FillRect(hdc, &clientRect, (HBRUSH)GetStockObject(WHITE_BRUSH)); EndPaint(m_hWnd, &ps); PlaceWidgets(); m_textPreview->UpdateWindow(); return TRUE; } LRESULT SRFind::OnCreate(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { m_hWnd = hWnd; RECT nullRECT = {0,0,0,0}; m_pEdtQuery = new SREdit(); if(!m_pEdtQuery || !m_pEdtQuery->Create(this, nullRECT, IDC_EDT_QUERY)) return FALSE; m_pEdtQuery->Show(); m_pButtonSearch = new SRButton(); if(!m_pButtonSearch || !m_pButtonSearch->Create(this, "Search", nullRECT, IDC_BTN_SEARCH)) return FALSE; m_pButtonSearch->Show(); // Radio Buttons m_pRadRangeBible = new SRRadioButton(); if(!m_pRadRangeBible || !m_pRadRangeBible->Create(this, "Whole Bible", nullRECT, IDC_RAD_BIBLE)) return FALSE; m_pRadRangeBible->Show(); m_pRadRangeBible->Check(); m_wRangeMode = SR_FIND_RANGE_BIBLE; m_pRadRangeTestament = new SRRadioButton(); if(!m_pRadRangeTestament || !m_pRadRangeTestament->Create(this, "This Testament", nullRECT, IDC_RAD_TESTAMENT)) return FALSE; m_pRadRangeTestament->Show(); m_pRadRangeBook = new SRRadioButton(); if(!m_pRadRangeBook || !m_pRadRangeBook->Create(this, "This Book", nullRECT, IDC_RAD_BOOK)) return FALSE; m_pRadRangeBook->Show(); m_pRadMethodMultiword = new SRRadioButton(); if(!m_pRadMethodMultiword || !m_pRadMethodMultiword->Create(this, "Multi-word", nullRECT, IDC_RAD_MWORD)) return FALSE; m_pRadMethodMultiword->Show(); m_pRadMethodMultiword->Check(); m_wMethodMode = SR_FIND_METHOD_MWORD; m_pRadMethodExactphrase = new SRRadioButton(); if(!m_pRadMethodExactphrase || !m_pRadMethodExactphrase->Create(this, "Exact Phrase", nullRECT, IDC_RAD_EPHRASE)) return FALSE; m_pRadMethodExactphrase->Show(); m_pListBoxResults = new SRListBox(); if(!m_pListBoxResults || !m_pListBoxResults->Create(this, nullRECT, IDC_LST_RESULTS)) return FALSE; m_pListBoxResults->Show(); m_pProgressBar = new SRProgress(); if(!m_pProgressBar || !m_pProgressBar->Create(this, nullRECT)) return false; m_pProgressBar->Show(); m_pButtonGoTo = new SRButton(); if(!m_pButtonGoTo || !m_pButtonGoTo->Create(this, "Go to", nullRECT, IDC_BTN_GOTO)) return FALSE; m_pButtonGoTo->Show(); m_textPreview = new SRTextView(); RECT tmpRect = {0,0,0,0}; WCString wcsPreview = "preview"; if(!m_textPreview || !m_textPreview->Create(this, tmpRect)) return FALSE; m_textPreview->AddText(wcsPreview.w_str(), wcsPreview.length()); m_textPreview->Show(); PlaceWidgets(); return TRUE; } VOID SRFind::PlaceWidgets() { RECT clientRect = GetBounds(); int width = clientRect.right - clientRect.left; int height = clientRect.bottom - clientRect.top; int searchBtnW = 60; int pad = 2; int btnH = 24; int margin = 2; int row0 = margin; int row1 = row0 + pad + btnH; int row2 = row1 + pad + btnH; int row3 = row2 + pad + btnH; int row4 = row3 + pad + btnH; int row5 = row4 + pad + btnH; int col0 = margin; int textW = (width - (2*margin + pad))/2; int col1 = margin + textW + pad; int gotoBtnW = 60; int queryW = width - (margin + searchBtnW + pad + margin); int listH = height - (row4 + margin); int listW = 80; int prevH = height - (row5 + margin); int prevW = width - (margin + listW + pad + margin); int progW = width - (margin + listW + pad + pad + gotoBtnW + margin); m_pEdtQuery->MoveWindow(col0,row0,queryW, btnH, TRUE); m_pButtonSearch->MoveWindow(col0 + queryW + pad, row0, searchBtnW, btnH, TRUE); m_pRadRangeBible->MoveWindow(col0,row1,textW,btnH,TRUE); m_pRadRangeTestament->MoveWindow(col0,row2,textW,btnH,TRUE); m_pRadRangeBook->MoveWindow(col0,row3,textW,btnH,TRUE); m_pRadMethodMultiword->MoveWindow(col1,row1,textW,btnH,TRUE); m_pRadMethodExactphrase->MoveWindow(col1,row2,textW,btnH,TRUE); m_pListBoxResults->MoveWindow(margin, row4, listW, listH, TRUE); m_pProgressBar->MoveWindow(col0 + listW + pad,row4,progW,btnH,TRUE); m_pButtonGoTo->MoveWindow(col0 + listW + pad + progW + pad,row4, gotoBtnW,btnH,TRUE); m_textPreview->MoveWindow(margin + listW + pad,row5,prevW,prevH); } BOOL SRFind::Register() { // Register window class... WNDCLASS wc; if(s_fRegistered) return TRUE; wc.style = CS_HREDRAW | CS_VREDRAW | CS_PARENTDC; wc.lpfnWndProc = (WNDPROC) MessageRoute; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = m_hInstance; wc.hIcon = NULL; wc.hCursor = 0; wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = 0; wc.lpszClassName = m_wcsClassName.w_str(); if(RegisterClass(&wc) == 0) return FALSE; s_fRegistered = TRUE; return TRUE; } BOOL SRFind::Create(SRFramework::SRWnd *pParentWnd, RECT bounds) { if(!Register()) return FALSE; if(!SRWnd::Create(m_wcsClassName,m_wcsWindowName,WS_CHILD | WS_VISIBLE, bounds, pParentWnd, NULL, m_hInstance)) return FALSE; return TRUE; } VOID SRFind::Search() { // Clone is a bit dangerous, it creates a new SWKey which has to be deleted // thus you cannot simply pass the cloned object to the constructor of // a VerseKey object. SWKey *tmp = m_keyReference.clone(); VerseKey from(tmp); VerseKey to(tmp); delete tmp; ClearForm(); if (m_wRangeMode == SR_FIND_RANGE_BIBLE) from.Testament(1); if ((m_wRangeMode == SR_FIND_RANGE_TESTAMENT)||(m_wRangeMode == SR_FIND_RANGE_BIBLE)) from.Book(1); from.Chapter(1); from.Verse(1); if (m_wRangeMode == SR_FIND_RANGE_BIBLE) to.Testament(2); if ((m_wRangeMode == SR_FIND_RANGE_TESTAMENT)||(m_wRangeMode == SR_FIND_RANGE_BIBLE)) to.Book((to.Testament() == 2) ? BIBLE_NT_BOOKS : BIBLE_OT_BOOKS); to.Chapter(/*to.books[to.Testament() - 1][to.Book() - 1].chapmax*/to.getChapterMax()); to.Verse(/*to.books[to.Testament() - 1][to.Book() - 1].versemax[to.Chapter() - 1]*/to.getVerseMax()); VerseKey verses(from,to); sword::ListKey results; results = m_modCurText->search(m_pEdtQuery->GetText().c_str(), (m_wMethodMode == SR_FIND_METHOD_MWORD) ? -2: -1, 2, &verses, 0, setPercentCB, (void*)this); SetProgress(100); results = TOP; for (int i = 0; !results.Error() && i < results.Count(); i++, results++) { AddResult(WCString(results.getText())); } } VOID SRFind::ClearForm() { WCString wcsPreview = "preview"; SetProgress(0); m_pListBoxResults->Clear(); m_textPreview->Clear(); m_textPreview->AddText(wcsPreview.w_str(), wcsPreview.length()); m_verseResults.clear(); } VOID SRFind::SetContext(VerseKey verse, const SWModule *pModule) { m_keyReference = verse; //TODO BROKEN DUE TO CONSTNESS OF pModule!!! m_modCurText = const_cast(pModule); }