#include "SRModuleView.h" #include "SRFramework/WCString.h" #include "SRMainFrame.h" #include DWORD WINAPI LoadTextThread(LPVOID arg) { SRModuleView *view = reinterpret_cast(arg); if(!view) return 1; view->m_fThreadRunning = TRUE; view->m_wStatusBarHeight = SR_STATUS_BAR_HEIGHT; view->LoadTextView(true); view->m_wStatusBarHeight = 0; if(!view->m_fAbortThread){ view->RefreshWindow(); } view->m_fThreadRunning = FALSE; view->m_fAbortThread = FALSE; return 0; } SRModuleView::SRModuleView(SRViewType viewType) : SRTextView() , m_pModule(NULL) , m_fChapterChanged(FALSE) , m_fSwordInit(FALSE) , m_fThreadRunning(FALSE) , m_fAbortThread(FALSE) , m_viewType(viewType) , m_verse("Gen 1:1") { } SRModuleView::~SRModuleView(void) { if(m_hLoadTextThread) CloseHandle(m_hLoadTextThread); } BOOL SRModuleView::OnCommand(WORD wNotifyCode, WORD wID, HWND hWndCtl) { if(m_pParentWnd){ return m_pParentWnd->OnCommand(wNotifyCode, wID, hWndCtl); } return FALSE; } VOID SRModuleView::SetModule(SWModule *pModule) { if(m_pModule == pModule) return; AbortThread(); m_pModule = pModule; m_fChapterChanged = TRUE; LoadTextView(); } VOID SRModuleView::AbortThread() { DWORD dwTimeout = 200; INT rc; if(m_fThreadRunning){ m_fAbortThread = TRUE; rc = WaitForSingleObject(m_hLoadTextThread, dwTimeout); while(rc == WAIT_FAILED){ ::Sleep(20);// Let's sleep for a bit and give the thread a chance to spawn. rc = WaitForSingleObject(m_hLoadTextThread, dwTimeout); } if(rc == WAIT_TIMEOUT){ // Sometimes the call to ::UpdateWindow never returns. TerminateThread(m_hLoadTextThread, -1); // Clean up from the rogue thread m_fThreadRunning = FALSE; m_fAbortThread = FALSE; m_wStatusBarHeight = 0; } } } VOID SRModuleView::SetKey(const VerseKey &verse) { if(!m_fChapterChanged && m_verse == verse) return; AbortThread(); if(m_viewType == BibleView){ if( (verse.Book() != m_verse.Book()) || ((m_verse.Book() == verse.Book()) && (m_verse.Chapter() != verse.Chapter()))){ m_fChapterChanged = true; m_verse = verse; LoadTextView(); }else{ ScrollToVerse(verse.Verse()); } }else if(m_viewType == CommView){ if(m_verse != verse){ m_fChapterChanged = true; m_verse = verse; LoadTextView(); } } } VOID SRModuleView::SetBook(INT nBook) { if(nBook > BIBLE_OT_BOOKS){ if( m_verse.Testament() != 2 || m_verse.Book() + BIBLE_OT_BOOKS != nBook){ m_verse.Testament(SWORD_NEW_TESTAMENT); m_verse.Book(nBook - BIBLE_OT_BOOKS); m_verse.Chapter(1); m_verse.setVerse(1); } }else{ if( m_verse.Testament() != 1 || m_verse.Book() != nBook){ m_verse.Testament(SWORD_OLD_TESTAMENT); m_verse.Book(nBook); m_verse.Chapter(1); m_verse.setVerse(1); } } m_fChapterChanged = true; } VOID SRModuleView::SetChapter(INT nChapter) { if(m_verse.Chapter() != nChapter){ m_verse.Chapter(nChapter); m_verse.setVerse(1); m_fChapterChanged = true; } } VOID SRModuleView::SetVerse(INT nVerse, BOOL fScroll) { if(nVerse < 0) return; // This isn't a valid verse. if(nVerse == 0) nVerse++; // This chapter starts with a heading or some other pretext, so we normalize the verse number here. if(m_viewType == CommView && m_verse.Verse() == nVerse) return; m_verse.setVerse(nVerse); if(fScroll) ScrollToVerse(m_verse.Verse()); } VOID SRModuleView::Show() { SRTextView::Show(); if(m_fLoadTextDelayed) LoadTextView(FALSE); } VOID SRModuleView::LoadTextView(BOOL fInThread) { WCString buf, text, s; BOOL done = FALSE; char strNum[10]; if(!IsVisible()){ m_fLoadTextDelayed = TRUE; return; }else m_fLoadTextDelayed = FALSE; if(!m_fSwordInit) return; if(!fInThread){ AbortThread(); } VerseKey keyCur(m_verse); if(!fInThread){ // This text should still be valid... if(!m_fChapterChanged) return; Clear(); if(m_viewType == BibleView) keyCur.setVerse(1); }else{ m_fChapterChanged = false; keyCur.setVerse(m_nLoadedTill + 1); } buf = ""; AddText(buf.w_str(), buf.length()); // a