#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include MainFrame::MainFrame(void) : mIsCancelled(false) { mPaintHandler.setCallback(this,&MainFrame::paintHandler); mCloseHandler.setCallback(this,&MainFrame::closeHandler); mQueryEndSessionHandler.setCallback(this,&MainFrame::queryEndSessionHandler); mDestroyHandler.setCallback(this,&MainFrame::destroyHandler); mCommandHandler.setCallback(this,&MainFrame::commandHandler); mKeyDownHandler.setCallback(this,&MainFrame::keyDownHandler); mSizeHandler.setCallback(this,&MainFrame::sizeHandler); mCreateHandler.setCallback(this,&MainFrame::createHandler); mOpenHandler.setCallback(this,&MainFrame::openHandler); mPreOpenHandler.setCallback(this,&MainFrame::preOpenHandler); mPostOpenHandler.setCallback(this,&MainFrame::postOpenHandler); mBrowseSelectHandler.setCallback(this,&MainFrame::browseSelectHandler); insertHandlers(); } MainFrame::~MainFrame() { removeHandlers(); } void MainFrame::insertHandlers(void) { FrameWindow::insertHandler(MainFrame::DestroyHandler,&mDestroyHandler); FrameWindow::insertHandler(VectorHandler::PaintHandler,&mPaintHandler); FrameWindow::insertHandler(VectorHandler::CommandHandler,&mCommandHandler); FrameWindow::insertHandler(VectorHandler::SizeHandler,&mSizeHandler); FrameWindow::insertHandler(VectorHandler::KeyDownHandler,&mKeyDownHandler); FrameWindow::insertHandler(VectorHandler::CloseHandler,&mCloseHandler); FrameWindow::insertHandler(VectorHandler::QueryEndSessionHandler,&mQueryEndSessionHandler); FrameWindow::insertHandler(VectorHandler::CreateHandler,&mCreateHandler); NNTPThread::insertHandler(&mOpenHandler,NNTPThread::MsgOpen); NNTPThread::insertHandler(&mPreOpenHandler,NNTPThread::MsgPreOpen); NNTPThread::insertHandler(&mPostOpenHandler,NNTPThread::MsgPostOpen); } void MainFrame::removeHandlers(void) { FrameWindow::removeHandler(VectorHandler::DestroyHandler,&mDestroyHandler); FrameWindow::removeHandler(VectorHandler::PaintHandler,&mPaintHandler); FrameWindow::removeHandler(VectorHandler::CommandHandler,&mCommandHandler); FrameWindow::removeHandler(VectorHandler::SizeHandler,&mSizeHandler); FrameWindow::removeHandler(VectorHandler::KeyDownHandler,&mKeyDownHandler); FrameWindow::removeHandler(VectorHandler::CreateHandler,&mCreateHandler); FrameWindow::removeHandler(VectorHandler::CloseHandler,&mCloseHandler); FrameWindow::removeHandler(VectorHandler::QueryEndSessionHandler,&mQueryEndSessionHandler); NNTPThread::removeHandler(NNTPThread::MsgOpen); NNTPThread::removeHandler(NNTPThread::MsgPreOpen); NNTPThread::removeHandler(NNTPThread::MsgPostOpen); } CallbackData::ReturnType MainFrame::commandHandler(CallbackData &someCallbackData) { switch(someCallbackData.wParam()) { case IDM_CASCADE : cascade(); break; case IDM_TILE : tile(); break; case IDM_ARRANGE : arrange(); break; case IDM_CLOSEALL : closeAll(); break; case IDM_MINIMIZEALL : minimizeAll(); break; case IDM_RESTOREALL : restoreAll(); break; case NNTP_FILE_OPEN : handleFileOpen(); break; case NNTP_FILE_BROWSE : handleFileBrowse(); break; case NNTP_FILE_EXIT : FrameWindow::postMessage(*this,WM_CLOSE,0,0L); break; case NNTP_NEWS_GETNEWS : mNewsOption.option((NewsOption::Option)someCallbackData.wParam()); handleRetrieve(); break; case NNTP_NEWS_GETGROUPS : mNewsOption.option((NewsOption::Option)someCallbackData.wParam()); handleRetrieve(); break; case NNTP_NEWSGROUPS_SUBSCRIBE : handleSubscribe(); break; case NNTP_IMAGE_FITTOWINDOW : handleImageFitToWindow(); break; case NNTP_OPTIONS_NEWSSERVER : handleNewsServer(); break; case NNTP_OPTIONS_GENERALOPTIONS : handleGeneralOptions(); break; case NNTP_OPTIONS_RASSETTINGS : handleRasSettings(); break; case NNTP_OPTIONS_CLEARLOG : handleClearLog(); break; case NNTP_NEWS_CANCEL : handleCancelNews(); break; case NNTP_VIEW_LOG : handleViewLog(); break; default : break; } return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType MainFrame::keyDownHandler(CallbackData &/*someCallbackData*/) { return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType MainFrame::paintHandler(CallbackData &/*someCallbackData*/) { return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType MainFrame::createHandler(CallbackData &/*someCallbackData*/) { createControls(); show(SW_SHOW); update(); createLogView(); createImageView(); mStatusControl->setText("Ready."); PureMenu mainMenu(::GetMenu(*this)); mainMenu.enableMenuItem(NNTP_NEWS_CANCEL,PureMenu::ByCommand,(PureMenu::InsertFlags)(PureMenu::ItemDisabled|PureMenu::ItemGrayed)); message(mWSASystem.description()); message(mWSASystem.systemStatus()); loadFilterList(); message("to run from command line use 'nntp -host: -user: -password:'"); return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType MainFrame::queryEndSessionHandler(CallbackData &someCallbackData) { if(getClient().hasChildren())return (CallbackData::ReturnType)FALSE; return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType MainFrame::closeHandler(CallbackData &someCallbackData) { destroy(); return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType MainFrame::destroyHandler(CallbackData &/*someCallbackData*/) { cancel(); removeHandlers(); ::PostQuitMessage(0); return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType MainFrame::sizeHandler(CallbackData &someCallbackData) { Rect statusRect; Rect cRect; mStatusControl->windowRect(statusRect); cRect.right(someCallbackData.loWord()); cRect.bottom(someCallbackData.hiWord()); getClient().moveWindow(0,0,cRect.right(),cRect.bottom()-(statusRect.bottom()-statusRect.top())); return (CallbackData::ReturnType)FALSE; } CallbackData::ReturnType MainFrame::browseSelectHandler(CallbackData &someCallbackData) { Array > mdiWindows; String strPathFileName; String strCaption; bool haveImage(false); strPathFileName=(char*)someCallbackData.lParam(); getDocuments(mdiWindows); for(int index=0;index &mdiWindow=mdiWindows[index]; mdiWindow->windowText(strCaption); strCaption=strCaption.betweenString('[',']'); if(!strCaption.isNull()&&strCaption==strPathFileName) { mdiWindow->bringWindowToTop(); haveImage=true; } } if(haveImage)return (CallbackData::ReturnType)FALSE; if(!openDocument(strPathFileName))::MessageBox(::GetFocus(),"NNTP:Error opening document",(LPSTR)strPathFileName,MB_OK); return (CallbackData::ReturnType)FALSE; } void MainFrame::createControls(void) { Rect controlRect; Rect statusRect; mStatusControl=::new StatusBarEx(*this,StatusBarID); mStatusControl.disposition(PointerDisposition::Delete); mStatusControl->clientRect(statusRect); controlRect.bottom(height()/2-statusRect.bottom()); } void MainFrame::getParams(String &hostName,String &userName,String &password) { String lineString; lineString=::GetCommandLine(); lineString=lineString.betweenString(' ',0); if(!lineString.isNull()) { hostName=lineString.betweenString('-',' '); hostName=hostName.betweenString(':',0); userName=lineString.betweenString('-',0); userName=userName.betweenString('-',' '); userName=userName.betweenString(':',0); password=lineString.betweenString('-',0); password=password.betweenString('-',0); password=password.betweenString('-',0); password=password.betweenString(':',0); } if(hostName.isNull()) { OptionsReg optionsReg; hostName=optionsReg.serverName(); userName=optionsReg.userName(); password=optionsReg.password(); } } void MainFrame::handleFileOpen(void) { String strCurrentDirectory; DiskInfo diskInfo; BOOL openResult(FALSE); OpenDialog openFileName; diskInfo.getCurrentDirectory(strCurrentDirectory); openFileName.owner(*this); openFileName.instance(processInstance()); openFileName.filter("Jpg"); openFileName.filterPattern("*.jpg"); openFileName.fileName("*.JPG"); openFileName.fileTitle(""); openFileName.initialDirectory(mLastOpenDirectory.isNull()?strCurrentDirectory:mLastOpenDirectory); openFileName.title("Open File"); openFileName.creationFlags(OpenDialog::EXPLORER|OpenDialog::FILEMUSTEXIST); openResult=openFileName.getOpenFileName(); diskInfo.getCurrentDirectory(mLastOpenDirectory); diskInfo.setCurrentDirectory(strCurrentDirectory); if(!openResult)return; openDocument(openFileName.fileName()); } void MainFrame::handleSubscribe(void) { GroupDialog groupDialog(*this); groupDialog.performDialog(); } void MainFrame::handleNewsServer(void) { String serverName; ServerDialog serverDialog(*this); serverDialog.performDialog(serverName); } void MainFrame::handleGeneralOptions(void) { OptionsDialog optionsDialog(*this); optionsDialog.performDialog(); } void MainFrame::handleRasSettings(void) { RasDialog rasDialog(*this); rasDialog.performDialog(); } void MainFrame::handleCancelNews(void) { mIsCancelled=true; cancel(); message("Cancelled"); } void MainFrame::handleRetrieve(void) { String hostName; String userName; String password; mIsCancelled=false; createLogView(); createImageView(); mMasterList.remove(); if(NewsOption::GetNews==mNewsOption.option()) { if(!getSubscriberList(mSubscriberList)) { message("No newsgroups in subscriber list, nothing to do!"); return; } verifyNewsDirectory(); } getParams(hostName,userName,password); if(hostName.isNull()){message("Invalid host, check settings/command line and restart.");return;} if(!userName.isNull()&&!password.isNull())open(hostName,userName,password); else { message("NNTP is not using AUTHENTICATION."); open(hostName); } } void MainFrame::verifyNewsDirectory(void) { DiskInfo diskInfo; String strNewsDir; String strCurrentDirectory; OptionsReg optionsReg; strNewsDir=optionsReg.newsDir(); diskInfo.getCurrentDirectory(strCurrentDirectory); if(strNewsDir.isNull()){strNewsDir=strCurrentDirectory;optionsReg.newsDir(strNewsDir);} if(!diskInfo.setCurrentDirectory(strNewsDir)) { diskInfo.createDirectory(strNewsDir); diskInfo.setCurrentDirectory(strNewsDir); } } void MainFrame::handleViewLog(void) { createLogView(); } void MainFrame::handleClearLog(void) { if(mLogViewWinCache.isOkay())((LogView&)*mLogViewWinCache).clear(); } void MainFrame::handleFileBrowse(void) { OpenDirectory openDir; OptionsReg optionsReg; String strDirectory; if(!openDir.getOpenDirectory(*this,"Choose Folder",optionsReg.newsDir(),strDirectory))return; BrowseView &browseView=createBrowseView(); browseView.browse(strDirectory); } void MainFrame::handleImageFitToWindow(void) { SmartPointer mdiWindow; if(!getActive(mdiWindow))return; if(!(mdiWindow->className()==String(STRING_DOCUMENTVIEWCLASSNAME)))return; ((ImageView&)*mdiWindow).fitToWindow(); } // **************************************************************************************************** WORD MainFrame::dialHost(void) { RasOptions rasOptions; if(mRasInterface.isOkay()){::MessageBeep(0);return FALSE;} if(!rasOptions.rasState())return TRUE; mRasInterface=::new RasInterface; mRasInterface.disposition(PointerDisposition::Delete); if(!mRasInterface->isOkay()){mRasInterface.destroy();return FALSE;} if(!mRasInterface->login(rasOptions.rasUserName(),rasOptions.rasPassword(),rasOptions.rasEntryName())){mRasInterface.destroy();return FALSE;} return TRUE; } DWORD MainFrame::priorDays(void)const { OptionsReg optionsReg; return optionsReg.priorDays(); } DWORD MainFrame::getSubscriberList(Block &subscriberList) { NewsReg newsReg; subscriberList.remove(); newsReg.queryGroups(subscriberList,NewsReg::QueryActive); return subscriberList.size(); } BOOL MainFrame::openDocument(const String &strPathFileName) { ImageView &imageView=createDocumentView(); return imageView.open(strPathFileName); } BOOL MainFrame::openImage(const String &strPathFileName) { BOOL result(FALSE); SmartPointer mdiWindow; if(!getDocumentClass(String(STRING_IMAGEVIEWCLASSNAME),mdiWindow)) { ImageView &imageView=createImageView(); result=imageView.open(strPathFileName); } else result=((ImageView&)*mdiWindow).open(strPathFileName); return result; } LogView &MainFrame::createLogView(void) { SmartPointer mdiWindow; LogView *pLogView; if(getDocumentClass(String(STRING_LOGVIEWCLASSNAME),mdiWindow)){mdiWindow->top();return (LogView&)*mdiWindow;} pLogView=::new LogView; pLogView->createWindow(*this,String(STRING_LOGVIEWCLASSNAME),"LogView","logMenu","LOG"); insert(*pLogView); return *pLogView; } ImageView &MainFrame::createImageView(void) { SmartPointer mdiWindow; ImageView *pImageView; if(getDocumentClass(String(STRING_IMAGEVIEWCLASSNAME),mdiWindow)){mdiWindow->top();return (ImageView&)*mdiWindow;} pImageView=::new ImageView; pImageView->createWindow(*this,String(STRING_IMAGEVIEWCLASSNAME),"ImageView","imgMenu","PAINT"); insert(*pImageView); return *pImageView; } ImageView &MainFrame::createDocumentView(void) { SmartPointer mdiWindow; ImageView *pImageView; pImageView=::new ImageView; pImageView->createWindow(*this,String(STRING_DOCUMENTVIEWCLASSNAME),"DocView","imgMenu","PAINT"); insert(*pImageView); return *pImageView; } BrowseView &MainFrame::createBrowseView(void) { SmartPointer mdiWindow; BrowseView *pBrowseView; pBrowseView=::new BrowseView; pBrowseView->createWindow(*this,String(STRING_BROWSEVIEWCLASSNAME),"BrowseView","brwMenu","PAINT"); insert(*pBrowseView); pBrowseView->setHandler(&mBrowseSelectHandler); return *pBrowseView; } // ************************** THREAD CALLBACKS ******************************* DWORD MainFrame::preOpenHandler(ThreadMessage &/*someThreadMessage*/) { String retryMsg; RasOptions rasOptions; DWORD maxRetries(rasOptions.rasMaxRetries()); if(dialHost())return FALSE; ::sprintf(retryMsg,"Could not contact host."); message(retryMsg); for(int retryCount=0;retryCount messageIDStrings; String msgString; String strNewsDir; String strPathNewsGroupDirectory; String strPreviousDirectory; OptionsReg optionsReg; strNewsDir=optionsReg.newsDir(); strPathNewsGroupDirectory=strNewsDir+String("\\")+newsGroup; if(!diskInfo.setCurrentDirectory(strPathNewsGroupDirectory)) { diskInfo.createDirectory(strPathNewsGroupDirectory); diskInfo.setCurrentDirectory(strPathNewsGroupDirectory); } message(String("Retrieving message headers for ")+newsGroup); if(recoverLog.haveLog(newsGroup)) { message(String("using recovery file.")); recoverLog.getEntries(newsGroup,messageIDStrings); } else { listGroup(newsGroup,messageIDStrings); recoverLog.setEntries(newsGroup,messageIDStrings); } ::sprintf(msgString,"%s has %ld articles.",(LPSTR)newsGroup,messageIDStrings.size()); message(msgString); getArticles(newsGroup,messageIDStrings); if(!mIsCancelled)recoverLog.removeLog(newsGroup); diskInfo.setCurrentDirectory(strNewsDir); return TRUE; } BOOL MainFrame::getArticles(const String &newsGroup,Block &msgIDs) { MessageLog messageLog; DWORD alreadyHavesInARow(0); BOOL okResult; long elapsedTime; messageLog.setLog(newsGroup); alreadyHavesInARow=0; group(GroupItem(newsGroup)); for(int itemIndex=0;itemIndex articleText; Block headText; String pathFileName; String messageID; MsgID msgID; if(!isConnected())return FALSE; msgID=msgIDs[itemIndex]; if(messageLog.searchItem(msgID)) { message(String("Already have ")+msgID); alreadyHavesInARow++; if(alreadyHavesInARow>250) { String messageID; message("...ping server..."); head(msgID,headText,messageID); alreadyHavesInARow=0; } continue; } else { ::sprintf(pathFileName,"n%ld.new",itemIndex); message(newsGroup+String("(")+msgID+String(")")); alreadyHavesInARow=0; } head(msgID,headText,messageID); if(!inSubject(headText))continue; messageLog.insert(msgID); elapsedTime=::GetTickCount(); okResult=article(msgID,articleText,messageID); elapsedTime=::GetTickCount()-elapsedTime; if(okResult) { String strPathImageFile; saveBlock(pathFileName,articleText); message(String("Retrieved message in ")+String().fromInt(elapsedTime)+String(" (ms)")); message("Decoding '"+pathFileName+"'..."); decode(pathFileName,strPathImageFile); if(!strPathImageFile.isNull()&&openImage(strPathImageFile)) { ::unlink(pathFileName); } } okResult=FALSE; messageLog.flush(); } messageLog.close(); return TRUE; } void MainFrame::loadFilterList(void) { File inFile; String strLine; mFilterList.remove(); if(!inFile.open("filter.txt","rb"))return; message("Loading filter list from 'filter.txt'"); while(true) { if(!inFile.readLine(strLine))break; if(!strLine.length())continue; mFilterList.insert(&strLine); } inFile.close(); } bool MainFrame::inSubject(Block &headText) { String strSubject; if(!mFilterList.size()||!headText.size())return true; for(int index=0;index &stringBlock) { DiskInfo diskInfo; String strCurrDir; if(!stringBlock.size())return FALSE; FileHandle saveFile(pathFileName,FileHandle::Write,FileHandle::ShareRead,FileHandle::Overwrite); if(!saveFile.isOkay()) { int errorCode(::GetLastError()); String strMessage; strMessage.reserve(1024); ::sprintf(strMessage,"Save file returned error code:%d 0x%08lx, attempting to save'%s'",errorCode,errorCode,(char*)(String&)pathFileName); message(strMessage); return FALSE; } for(int itemIndex=0;itemIndex &messageStrings) { for(short itemIndex=0;itemIndex > mdiWindows; String windowText; String strSelText; Block strTitles; getDocuments(mdiWindows); for(int index=0;index &mdiWindow=mdiWindows[index]; mdiWindow->windowText(windowText); strTitles.insert(&windowText); } MoreWindowsDialog moreWindows(*this); if(!moreWindows.performDialog(strTitles,strSelText))return; for(index=0;index &mdiWindow=mdiWindows[index]; mdiWindow->windowText(windowText); if(windowText==strSelText){mdiWindow->top();break;} } }