#include "SRMainFrame.h" #include #include using namespace sword; BOOL SRMainFrame::s_fRegistered = false; namespace sword { char *SWBuf::nullStr = ""; } /* * While SWORD's canon.h does have a form of these abbreviations, * We need consistent 3 letter abbreviations so we define our own. */ WCString SRMainFrame::s_wcsBookNames[BIBLE_TOTAL_BOOKS] = { "Gen","Exo","Lev","Num","Deu","Jos","Jdg","Rut","1Sa","2Sa","1Ki","2Ki","1Ch", "2Ch","Ezr","Neh","Est","Job","Psa","Pro","Ecc","Son","Isa","Jer","Lam","Eze", "Dan","Hos","Joe","Amo","Oba","Jon","Mic","Nah","Hab","Zep","Hag","Zec","Mal", "Mat","Mar","Luk","Joh","Act","Rom","1Co","2Co","Gal","Eph","Phi","Col","1Th", "2Th","1Ti","2Ti","Tit","Phm","Heb","Jam","1Pe","2Pe","1Jo","2Jo","3Jo","Jud", "Rev" }; SRMainFrame::SRMainFrame() :SRFrame() ,m_bufModOptions(NULL) ,m_confOptions(NULL) ,m_menuBar(NULL) ,m_modGreekLex(NULL) ,m_modGreekMorph(NULL) ,m_modHebrewLex(NULL) ,m_modHebrewMorph(NULL) ,m_modBibles(NULL) ,m_modComms(NULL) ,m_modDicts(NULL) ,m_nTotalOpts(0) ,m_swmgr(NULL) ,m_viewChapter(NULL) ,m_viewVerse(NULL) ,m_viewBook(NULL) ,m_viewFind(NULL) ,m_fChapterChanged(TRUE) ,m_nCurrentModule(0) ,m_fInit(FALSE) { // Create a general options file for storing options // and navigaiton history m_confOptions = new SWConfig(".\\options.conf"); m_confOptions->Load(); m_wcsClassName = "SRMainFrame"; m_wcsWindowName = "SwordReader"; m_hInstance = SRFramework::SRApp::GetInstanceHandle(); m_swmgr = new SWMgr(new MarkupFilterMgr(sword::FMT_HTMLHREF, sword::ENC_UTF16)); } SRMainFrame::~SRMainFrame() { SaveOptions(); if(m_swmgr) delete m_swmgr; if(m_bufModOptions) delete [] m_bufModOptions; if(m_viewBook) delete m_viewBook; if(m_viewChapter) delete m_viewChapter; if(m_viewVerse) delete m_viewVerse; if(m_viewFind) delete m_viewFind; if(m_confOptions) delete m_confOptions; if(m_modBibles) delete m_modBibles; if(m_modComms) delete m_modComms; if(m_modDicts) delete m_modDicts; if(m_menuBar) delete m_menuBar; if(m_tabViews) delete m_tabViews; } BOOL SRMainFrame::Register() { WNDCLASS wc; if(s_fRegistered) return TRUE; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = MessageRoute; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = m_hInstance; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = m_wcsClassName.w_str(); if(RegisterClass(&wc) == 0) return FALSE; s_fRegistered = TRUE; return TRUE; } BOOL SRMainFrame::Create() { //If it is already running, then focus on the window, and exit. HWND hWnd = FindWindow(this->m_wcsClassName.w_str(), NULL); if (hWnd) { // set focus to foremost child window // The "| 0x01" is used to bring any owned windows to the foreground and // activate them. SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001)); return FALSE; } RECT bounds = {CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT}; if(!Register()) return FALSE; if(!SRFrame::Create(m_wcsClassName,m_wcsWindowName,WS_VISIBLE, bounds, NULL, NULL, m_hInstance)) return FALSE; return TRUE; } BOOL SRMainFrame::Init() { RECT view_rect; GetClientRect(m_hWnd, &view_rect); CreateCommandBar(); view_rect.bottom -= m_menuBar->Height(); m_tabViews = new SRTabbedViews(); if(!m_tabViews || !m_tabViews->Create(this, view_rect)) return FALSE; m_tabViews->Init(); this->SetFocus(); InitSword(); LoadOptions(); m_viewBook = new SRBookChooser(s_wcsBookNames,MENU_CHAP); if(!m_viewBook || !m_viewBook->Create(this, view_rect)) return FALSE; m_viewVerse = new SRNumberChooser(VERSE, "Select a Verse:",MENU_TEXT); if(!m_viewVerse || !m_viewVerse->Create(this, view_rect)) return FALSE; m_viewChapter = new SRNumberChooser(CHAPTER, "Select a Chapter:",MENU_VERSE); if(!m_viewChapter || !m_viewChapter->Create(this, view_rect)) return FALSE; m_viewFind = new SRFind(); if(!m_viewFind || !m_viewFind->Create(this, view_rect)) return FALSE; m_viewBook->Hide(); m_viewChapter->Hide(); m_viewVerse->Hide(); m_viewFind->Hide(); m_tabViews->Show(); UpdateWindowTitle(); m_fInit = TRUE; return TRUE; } BOOL SRMainFrame::CreateCommandBar() { m_menuBar = new SRMenuBar(); if(!m_menuBar->Create(this, IDM_MENU)) return FALSE; m_menuBar->RedrawMenu(); m_menuBar->Show(); return TRUE; } BOOL SRMainFrame::UpdateWindow() { UpdateWindowTitle(); return m_tabViews->UpdateWindow(); } BOOL SRMainFrame::InitSword() { m_modBibles = new ModuleMap(); m_modComms = new ModuleMap(); m_modDicts = new ModuleMap(); sword::ModMap::iterator it; sword::SWModule* curMod = NULL; for (it = m_swmgr->Modules.begin(); it != m_swmgr->Modules.end(); it++) { curMod = (*it).second; if (!strcmp(curMod->Type(), "Biblical Texts")) { (*m_modBibles)[curMod->Name()] = curMod; } if (!strcmp(curMod->Type(), "Commentaries")) { (*m_modComms)[curMod->Name()] = curMod; } if (!strcmp(curMod->Type(), "Lexicons / Dictionaries")) { (*m_modDicts)[curMod->Name()] = curMod; } if (curMod->getConfig().has("Feature", "GreekDef")) { m_modGreekLex = curMod; m_tabViews->SetGreekDefModule(curMod); } if (curMod->getConfig().has("Feature", "GreekParse")) { m_modGreekMorph = curMod; m_tabViews->SetGreekMorphModule(curMod); } if (curMod->getConfig().has("Feature", "HebrewDef")) { m_modHebrewLex = curMod; m_tabViews->SetHebrewDefModule(curMod); } if (curMod->getConfig().has("Feature", "HebrewParse")) { m_modHebrewMorph = curMod; m_tabViews->SetHebrewMorphModule(curMod); } } // TODO We need to deal with commentaries, dict, devos, etc... if(!m_menuBar || !m_menuBar->FillBiblesSubMenu(m_modBibles, m_tabViews->GetBibleModule(), MENU_BIBLE_TRANS_START)) return FALSE; if(!m_menuBar || !m_menuBar->FillCommsSubMenu(m_modComms, m_tabViews->GetCommModule(), MENU_COMM_TRANS_START)) return FALSE; if(!m_menuBar || !m_menuBar->FillDictsSubMenu(m_modDicts, m_tabViews->GetDictModule(), MENU_DICT_TRANS_START)) return FALSE; // Gets the supported global options and fills the options sub menu. if(!GetSupportedOptions()) return FALSE; m_tabViews->SetSwordReady(); return TRUE; } BOOL SRMainFrame::OnCommand(WORD wNotifyCode, WORD wID, HWND hWndCtl) { INT nBiblesID = 0; INT nCommsID = 0; INT nDictsID = 0; INT nOptsID = 0; INT newValue = (INT)hWndCtl; // I am using this parameter in a strange way I know. TCHAR *pszWordFound = NULL; switch(wID) { case IDOK: ::SendMessage(m_hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)m_hWnd); ::SendMessage (m_hWnd, WM_CLOSE, 0, 0); break; case MENU_ABOUT: m_tabViews->ManualChangeCurrentTab(SR_TAB_ABOUT); break; case MENU_SHUTDOWN: ::SendMessage(m_hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)m_hWnd); ::SendMessage (m_hWnd, WM_CLOSE, 0, 0); ::PostQuitMessage(0); break; case MENU_TEXT: m_tabViews->Show(); m_viewBook->Hide(); m_viewChapter->Hide(); m_viewVerse->Hide(); m_viewFind->Hide(); m_tabViews->RefreshScreen(FALSE); SetFocus(); break; case MENU_BOOK: m_viewBook->SetSelectedBook(m_tabViews->GetCurrentBookNum() + (m_tabViews->GetCurrentTestament() == 1 ? 0 : BIBLE_OT_BOOKS) ); m_viewBook->Show(); m_viewChapter->Hide(); m_viewVerse->Hide(); m_tabViews->Hide(); m_viewFind->Hide(); break; case MENU_CHAP: m_viewChapter->SetEndNumber(m_tabViews->GetCurrentChapterMax()); m_viewChapter->SetSelectedNumber(m_tabViews->GetCurrentChapter()); m_viewChapter->Show(); m_viewBook->Hide(); m_tabViews->Hide(); m_viewVerse->Hide(); m_viewFind->Hide(); break; case MENU_VERSE: m_viewVerse->SetEndNumber(m_tabViews->GetCurrentVerseMax()); m_viewVerse->SetSelectedNumber(m_tabViews->GetCurrentVerse()); m_viewVerse->Show(); m_viewBook->Hide(); m_viewChapter->Hide(); m_tabViews->Hide(); m_viewFind->Hide(); break; case MENU_FIND: m_viewFind->SetContext(m_tabViews->GetCurrentVerseKey(), m_tabViews->GetCurrentModule()); m_viewFind->Show(); m_viewVerse->Hide(); m_viewBook->Hide(); m_viewChapter->Hide(); m_tabViews->Hide(); break; case SR_SETBOOK: SetBook(newValue); break; case SR_SETCHAPTER: SetChapter(newValue); break; case SR_SETVERSE: SetVerse(newValue, wNotifyCode == SR_MSRC_CHOOSER); break; case SR_SETVERSEKEY: SetVerseKey(*reinterpret_cast(hWndCtl)); break; case SR_HYPERLINK_CLICKED: pszWordFound = (TCHAR*)hWndCtl; HandleClickedURL(pszWordFound); //m_tabViews->HyperLinkClicked(); break; default: // Check the custom made menu items... nBiblesID = wID - MENU_BIBLE_TRANS_START; nCommsID = wID - MENU_COMM_TRANS_START; nDictsID = wID - MENU_DICT_TRANS_START; nOptsID = wID - MENU_OPTS_START; if ((nBiblesID >= 0) && (nBiblesID < m_menuBar->GetTotalBibles())) { SelectBibleModule(nBiblesID); m_menuBar->CheckBiblesMenuItem(wID); break; }else if((nCommsID >= 0) && (nCommsID < m_menuBar->GetTotalComms())){ SelectCommModule(nCommsID); m_menuBar->CheckCommsMenuItem(wID); break; }else if((nDictsID >= 0) && (nDictsID < m_menuBar->GetTotalDicts())){ SelectDictModule(nDictsID); m_menuBar->CheckDictsMenuItem(wID); break; }else if((nOptsID >= 0) && (nOptsID < m_menuBar->GetTotalOptions())){ ToggleOption(wID); }else{ return FALSE; } SaveOptions(); } return FALSE; } BOOL SRMainFrame::HandleClickedURL(const WCString &wcsURL) { URL url(wcsURL.c_str()); SWModule *mod = NULL; SWKey *modKey = NULL; if(wcsURL.contains("showNote")){ WCString wcsModule = url.getParameterValue("module"); WCString wcsKey = url.getParameterValue("passage"); WCString wcsValue = url.getParameterValue("value"); WCString wcsType = url.getParameterValue("type"); mod = m_swmgr->getModule(wcsModule.c_str()); mod->setKey(wcsKey.c_str()); mod->RenderText(); SWBuf bufNote = mod->getEntryAttributes()["Footnote"][wcsValue.c_str()]["body"]; WCString wcsNote = ""; if(wcsType == WCString("n")) wcsNote += (const TCHAR*)mod->RenderText(bufNote.c_str()); else if(wcsType == WCString("x")) wcsNote += bufNote.c_str(); wcsNote += ""; m_tabViews->ShowBibleNote(wcsNote); // Send this somewhere and show it... }else if(wcsURL.contains("showStrongs")){ WCString wcsType = url.getParameterValue("type"); WCString wcsValue = url.getParameterValue("value"); if(wcsType.contains("Greek")) m_tabViews->ShowGreekDef(wcsValue); if(wcsType.contains("Hebrew")) m_tabViews->ShowHebrewDef(wcsValue); }else if(wcsURL.contains("showMorph")){ WCString wcsType = url.getParameterValue("type"); WCString wcsValue = url.getParameterValue("value"); if(wcsType.contains("Greek")) m_tabViews->ShowGreekMorph(wcsValue); if(wcsType.contains("Hebrew")) m_tabViews->ShowHebrewMorph(wcsValue); }else if(wcsURL.contains("showRef")){ WCString wcsModule = url.getParameterValue("module"); // Ignored for now... WCString wcsValue = url.getParameterValue("value"); WCString wcsType = url.getParameterValue("type"); if(wcsType == "scripRef"){ SWBuf foot = m_swmgr->getGlobalOption("Footnotes"); SWBuf cross = m_swmgr->getGlobalOption("Cross-references"); SWBuf strongs = m_swmgr->getGlobalOption("Strong's Numbers"); SWBuf morph = m_swmgr->getGlobalOption("Morphological Tags"); m_swmgr->setGlobalOption("Footnotes", "Off"); m_swmgr->setGlobalOption("Cross-references", "Off"); m_swmgr->setGlobalOption("Strong's Numbers", "Off"); m_swmgr->setGlobalOption("Morphological Tags", "Off"); m_tabViews->ShowScriptRef(wcsValue); m_swmgr->setGlobalOption("Footnotes", foot); m_swmgr->setGlobalOption("Cross-references", cross); m_swmgr->setGlobalOption("Strong's Numbers", strongs); m_swmgr->setGlobalOption("Morphological Tags", morph); } return TRUE; } return TRUE; } VOID SRMainFrame::SaveOptions() { CHAR buff[32] = {0}; const SWModule *pModule = NULL; if(!m_fInit || !m_confOptions || !m_tabViews) return; pModule = m_tabViews->GetBibleModule(); if(pModule) (*m_confOptions)["History"]["LastBibleVersion"] = pModule->Name(); (*m_confOptions)["History"]["LastBiblePassage"] = m_tabViews->GetBibleVerseKey().getText(); pModule = m_tabViews->GetCommModule(); if(pModule) (*m_confOptions)["History"]["LastCommVersion"] = pModule->Name(); (*m_confOptions)["History"]["LastCommPassage"] = m_tabViews->GetCommVerseKey().getText(); pModule = m_tabViews->GetDictModule(); if(pModule) (*m_confOptions)["History"]["LastDictVersion"] = pModule->Name(); (*m_confOptions)["History"]["LastDictEntry"] = m_tabViews->GetDictKey().getText(); sprintf(buff, "%d", m_tabViews->GetCurTabSel()); (*m_confOptions)["History"]["LastTabViewed"] = buff; for(int i = 0; i < m_nTotalOpts; i++){ (*m_confOptions)["GlobalOptions"][m_bufModOptions[i].c_str()] = m_swmgr->getGlobalOption(m_bufModOptions[i]); } m_confOptions->Save(); } BOOL SRMainFrame::OnSize(UINT nType, int cx, int cy) { RECT newSize; GetClientRect(m_hWnd, &newSize); newSize.bottom -= m_menuBar->Height(); m_viewFind->MoveWindow(&newSize, TRUE); m_viewBook->MoveWindow(&newSize, TRUE); m_viewChapter->MoveWindow(&newSize, TRUE); m_viewVerse->MoveWindow(&newSize, TRUE); m_tabViews->MoveWindow(&newSize, TRUE); return TRUE; } VOID SRMainFrame::SetBook(INT nBook) { m_tabViews->SetCurrentBookNum(nBook); SaveOptions(); UpdateWindowTitle(); } VOID SRMainFrame::SetChapter(INT nChapter) { m_tabViews->SetCurrentChapter(nChapter); SaveOptions(); UpdateWindowTitle(); } VOID SRMainFrame::SetVerse(INT nVerse, BOOL fScroll) { if(m_tabViews) m_tabViews->SetCurrentVerse(nVerse, fScroll); SaveOptions(); UpdateWindowTitle(); } VOID SRMainFrame::SetVerseKey(VerseKey verse) { m_tabViews->SetCurrentKey(verse); SaveOptions(); UpdateWindowTitle(); } BOOL SRMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { BOOL fRetVal = m_tabViews->OnKeyDown(nChar, nRepCnt, nFlags); SaveOptions(); UpdateWindowTitle(); return fRetVal; } void SRMainFrame::SelectBibleModule(INT nModIndex) { /* TODO This needs to be reworked!!!! */ ModuleMap::iterator it = m_modBibles->begin(); for(int i = 0; i < nModIndex; i++) it++; m_tabViews->SetBibleModule(it->second); SaveOptions(); UpdateWindowTitle(); } void SRMainFrame::SelectCommModule(INT nModIndex) { /* TODO This needs to be reworked!!!! */ ModuleMap::iterator it = m_modComms->begin(); for(int i = 0; i < nModIndex; i++) it++; m_tabViews->SetCommModule(it->second); SaveOptions(); UpdateWindowTitle(); } void SRMainFrame::SelectDictModule(INT nModIndex) { /* TODO This needs to be reworked!!!! */ ModuleMap::iterator it = m_modDicts->begin(); for(int i = 0; i < nModIndex; i++) it++; m_tabViews->SetDictModule(it->second); SaveOptions(); UpdateWindowTitle(); } BOOL SRMainFrame::GetSupportedOptions() { StringList optionNames = m_swmgr->getGlobalOptions(); StringList::iterator i; bool fSupported = true; bool *pfOptsState = NULL; StringList optionValues; INT optionIndex = 0; m_nTotalOpts = 0; if (m_bufModOptions) delete [] m_bufModOptions; // count the supported options for (i = optionNames.begin(); i != optionNames.end(); i++) { optionValues = m_swmgr->getGlobalOptionValues(*i); fSupported = true; for (StringList::iterator j = optionValues.begin(); j != optionValues.end(); j++) { if ((*j != "On") && (*j != "Off")) fSupported = false; } if (fSupported) m_nTotalOpts++; } m_bufModOptions = new SWBuf[m_nTotalOpts]; pfOptsState = new bool[m_nTotalOpts]; // place the options for (i = optionNames.begin(); i != optionNames.end(); i++) { optionValues = m_swmgr->getGlobalOptionValues(*i); fSupported = true; for (StringList::iterator j = optionValues.begin(); j != optionValues.end(); j++) { if ((*j != "On") && (*j != "Off")) fSupported = false; } if (fSupported) { pfOptsState[optionIndex] = strcmp(m_swmgr->getGlobalOption(*i), "On") == 0; m_bufModOptions[optionIndex++] = *i; } } if(!m_menuBar->FillOptionsSubMenu(m_bufModOptions, pfOptsState, MENU_OPTS_START, m_nTotalOpts)) return FALSE; delete [] pfOptsState; return TRUE; } void SRMainFrame::ToggleOption(WORD wID) { if (m_bufModOptions) { for (int i = 0; i < m_nTotalOpts; i++) { SWBuf val = m_swmgr->getGlobalOption(m_bufModOptions[i]); if ((i + MENU_OPTS_START) == wID) { val = (val == "On") ? "Off" : "On"; m_swmgr->setGlobalOption(m_bufModOptions[i], val); m_menuBar->CheckOptionsMenuItem(wID, (val == "On")); m_fChapterChanged = true; } } } m_tabViews->RefreshScreen(TRUE); } VOID SRMainFrame::LoadOptions() { SWBuf val; sword::SWModule* bibleMod = NULL; sword::SWModule* commMod = NULL; sword::SWModule* dictMod = NULL; sword::VerseKey* verse = NULL; sword::StrKey* entry = NULL; INT nCurID = 0; for(int i = 0; i < m_nTotalOpts; i++){ val = (*m_confOptions)["GlobalOptions"].getWithDefault(m_bufModOptions[i],"Off"); m_swmgr->setGlobalOption(m_bufModOptions[i],val); m_menuBar->CheckOptionsMenuItem(i + MENU_OPTS_START, (val == "On" ? TRUE : FALSE)); } bibleMod = m_swmgr->getModule((*m_confOptions)["History"].getWithDefault("LastBibleVersion", "KJV")); if(!bibleMod && m_modBibles){ bibleMod = m_modBibles->begin()->second; } m_tabViews->SetBibleModule(bibleMod); commMod = m_swmgr->getModule((*m_confOptions)["History"].getWithDefault("LastCommVersion", "Clarke")); if(!commMod && m_modComms && m_modComms->size()){ commMod = m_modComms->begin()->second; } m_tabViews->SetCommModule(commMod); dictMod = m_swmgr->getModule((*m_confOptions)["History"].getWithDefault("LastDictVersion", "WebstersDict")); if(!dictMod && m_modDicts && m_modDicts->size()){ dictMod = m_modDicts->begin()->second; } m_tabViews->SetDictModule(dictMod); /*REM nCurID = MENU_TRANS_START; for (ModuleMap::iterator it = m_modTexts->begin(); it != m_modTexts->end(); it++) { if(it->second == m_viewModules[m_nCurrentModule]->GetModule()){ m_menuBar->CheckBiblesMenuItem(nCurID); break; } nCurID++; } */ INT nLastTab = atoi((*m_confOptions)["History"].getWithDefault("LastTabViewed", "0")); m_tabViews->ManualChangeCurrentTab(nLastTab); verse = new VerseKey((*m_confOptions)["History"].getWithDefault("LastBiblePassage", "Gen 1:1")); m_tabViews->SetBibleKey(*verse); delete verse; verse = new VerseKey((*m_confOptions)["History"].getWithDefault("LastCommPassage", "Gen 1:1")); m_tabViews->SetCommKey(*verse); delete verse; entry = new StrKey((*m_confOptions)["History"].getWithDefault("LastDictEntry", "")); m_tabViews->SetDictKey(*entry); delete entry; } void SRMainFrame::SetWindowTitle(const WCString &wcsTitle) { SetWindowText(m_hWnd,wcsTitle.w_str()); } void SRMainFrame::UpdateWindowTitle() { if(m_tabViews) SetWindowText(m_hWnd,m_tabViews->GetCurrentWindowTitle().w_str()); } void SRMainFrame::SetFocus(){ SRWnd::SetFocus(); UpdateWindowTitle(); }