Index: src/ch/MainWnd.cpp =================================================================== diff -u -r633a533cb6e741d44fe28aa56339e1d2709b1b27 -r8422e5787e56453d78c7270066c3e8d1743ca757 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 633a533cb6e741d44fe28aa56339e1d2709b1b27) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 8422e5787e56453d78c7270066c3e8d1743ca757) @@ -34,11 +34,15 @@ #include "ClipboardMonitor.h" #include #include -#include "../libchcore/TWStringData.h" #include "../common/TShellExtMenuConfig.h" #include "../libchcore/TConfig.h" #include "FileSupport.h" #include "StringHelpers.h" +#include "../libchcore/TCoreException.h" +#include "../libicpf/exception.h" +#include "../libchcore/TTaskManagerStatsSnapshot.h" +#include "../libchcore/TSQLiteSerializerFactory.h" +#include "TRecentPathsTools.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -70,17 +74,16 @@ ///////////////////////////////////////////////////////////////////////////// // CMainWnd construction/destruction CMainWnd::CMainWnd() : - m_pFeedbackFactory(CFeedbackHandlerFactory::CreateFactory()), m_pdlgStatus(NULL), m_pdlgMiniView(NULL), - m_dwLastTime(0) + m_dwLastTime(0), + m_spTasks(), + m_spTaskMgrStats(new chcore::TTaskManagerStatsSnapshot) { } CMainWnd::~CMainWnd() { - if(m_pFeedbackFactory) - m_pFeedbackFactory->Delete(); } // registers main window class @@ -118,7 +121,8 @@ HICON hIcon = (HICON)GetResManager().LoadImage(MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR | LR_VGACOLOR); CString strText = GetApp().GetAppNameVer(); - strText += GetResManager().LoadString(IDS_CH_PORTABLE_STRING); + if(GetApp().IsInPortableMode()) + strText += GetResManager().LoadString(IDS_CH_PORTABLE_STRING); bool bRes=m_ctlTray.CreateIcon(m_hWnd, WM_TRAYNOTIFY, strText, hIcon, 0); if(!bRes) @@ -167,96 +171,103 @@ lpCreateStruct->dwExStyle |= WS_EX_TOPMOST; if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; + + bool bCaughtError = false; + const size_t stMaxErrInfo = 1024; + boost::shared_array szErrInfo(new wchar_t[stMaxErrInfo]); - // get msg id of taskbar created message - m_uiTaskbarRestart = RegisterWindowMessage(_T("TaskbarCreated")); + try + { + // get msg id of taskbar created message + m_uiTaskbarRestart = RegisterWindowMessage(_T("TaskbarCreated")); - // Create the tray icon - ShowTrayIcon(); + // Create the tray icon + ShowTrayIcon(); - // initialize CTaskArray - m_tasks.Create(m_pFeedbackFactory); + if(!LoadTaskManager()) + { + LOG_ERROR(_T("Couldn't load task manager data. User did not allow re-creation of the database.")); + return -1; + } - // load last state - LOG_INFO(_T("Loading existing tasks...")); - CString strPath; - GetApp().GetProgramDataPath(strPath); - strPath += _T("\\Tasks\\"); - m_tasks.SetTasksDir(strPath); + // import tasks specified at command line (before loading current tasks) + const TCommandLineParser& cmdLine = GetApp().GetCommandLine(); + ProcessCommandLine(cmdLine); - // load tasks - m_tasks.LoadDataProgress(); + // start processing of the tasks loaded above and added by a command line + m_spTasks->TasksRetryProcessing(); - // import tasks specified at command line (before loading current tasks) - const TCommandLineParser& cmdLine = GetApp().GetCommandLine(); - ProcessCommandLine(cmdLine); + // start clipboard monitoring + LOG_INFO(_T("Starting clipboard monitor...")); + CClipboardMonitor::StartMonitor(m_spTasks.get()); - // start clipboard monitoring - LOG_INFO(_T("Starting clipboard monitor...")); - CClipboardMonitor::StartMonitor(&m_tasks); + CheckForUpdates(); - EUpdatesFrequency eFrequency = (EUpdatesFrequency)GetPropValue(GetConfig()); - if(eFrequency != eFreq_Never) + SetupTimers(); + + if (GetPropValue(GetConfig())) + PostMessage(WM_SHOWMINIVIEW); + } + catch(chcore::TCoreException& e) { - unsigned long long ullMinInterval = 0; - switch(eFrequency) - { - case eFreq_Daily: - ullMinInterval = 1*24*60*60; - break; - case eFreq_Weekly: - ullMinInterval = 7*24*60*60; - break; - case eFreq_OnceEvery2Weeks: - ullMinInterval = 14*24*60*60; - break; - case eFreq_Monthly: - ullMinInterval = 30*24*60*60; // we don't really care if it is a day less or more - break; - case eFreq_Quarterly: - ullMinInterval = 90*24*60*60; - break; - case eFreq_EveryStartup: - default: - ullMinInterval = 0; - } + bCaughtError = true; + e.GetErrorInfo(szErrInfo.get(), stMaxErrInfo); + } + catch(std::exception& e) + { + bCaughtError = true; + _snwprintf_s(szErrInfo.get(), stMaxErrInfo, _TRUNCATE, _T("%S"), e.what()); + szErrInfo.get()[stMaxErrInfo - 1] = _T('\0'); + } + catch(...) + { + bCaughtError = true; + _snwprintf_s(szErrInfo.get(), stMaxErrInfo, _TRUNCATE, _T("Caught an unknown exception")); + } - // get last check time stored in configuration - unsigned long long ullCurrentStamp = _time64(NULL); - unsigned long long ullTimestamp = GetPropValue(GetConfig()); + if(bCaughtError) + { + LOG_ERROR(szErrInfo.get()); + return -1; + } + return 0; +} - // perform checking for updates only when the minimal interval has passed - if(ullCurrentStamp - ullTimestamp >= ullMinInterval) - { - LOG_INFO(_T("Checking for updates...")); +bool CMainWnd::LoadTaskManager() +{ + using namespace chcore; - CUpdaterDlg* pDlg = new CUpdaterDlg(true); - pDlg->m_bAutoDelete = true; + CString strError; + CString strTasksDir = GetTasksDirectory(); + TSQLiteSerializerFactoryPtr spSerializerFactory(new TSQLiteSerializerFactory(PathFromString(strTasksDir))); + IFeedbackHandlerFactoryPtr spFeedbackFactory(new CFeedbackHandlerFactory); - pDlg->Create(); - chcore::TConfig& rConfig = GetConfig(); - try - { - SetPropValue(rConfig, _time64(NULL)); - rConfig.Write(); - } - catch(icpf::exception& /*e*/) - { - LOG_ERROR(_T("Storing last update check timestamp in configuration failed")); - } + try + { + m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory)); + } + catch(const std::exception& e) + { + strError = e.what(); + } + + if(!strError.IsEmpty()) + { + if(MsgBox(IDS_TASKMANAGER_LOAD_FAILED, MB_ICONERROR | MB_OKCANCEL) == IDOK) + { + m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory, true)); } + else + return false; } - // start saving timer - SetTimer(1023, GetPropValue(GetConfig()), NULL); + // load last state + LOG_INFO(_T("Loading existing tasks...")); - SetTimer(3245, TM_AUTOREMOVE, NULL); - SetTimer(8743, TM_ACCEPTING, NULL); // ends wait state in tasks + // load tasks + m_spTasks->Load(); - if (GetPropValue(GetConfig())) - PostMessage(WM_SHOWMINIVIEW); - - return 0; + return true; } LRESULT CMainWnd::OnTrayNotification(WPARAM wParam, LPARAM lParam) @@ -325,15 +336,18 @@ } case WM_MOUSEMOVE: { - if (m_tasks.GetSize() != 0) + if (m_spTasks->GetSize() != 0) { - _sntprintf(text, _MAX_PATH, _T("%s - %d %%"), GetApp().GetAppName(), m_tasks.GetPercent()); + m_spTasks->GetStatsSnapshot(m_spTaskMgrStats); + + _sntprintf(text, _MAX_PATH, _T("%s - %.0f %%"), GetApp().GetAppName(), m_spTaskMgrStats->GetCombinedProgress() * 100.0); m_ctlTray.SetTooltipText(text); } else { CString strText = GetApp().GetAppNameVer(); - strText += GetResManager().LoadString(IDS_CH_PORTABLE_STRING); + if(GetApp().IsInPortableMode()) + strText += GetResManager().LoadString(IDS_CH_PORTABLE_STRING); m_ctlTray.SetTooltipText(strText); } break; @@ -346,9 +360,9 @@ ///////////////////////////////////////////////////////////////////////////// // CMainWnd/CTrayIcon menu message handlers -void CMainWnd::ShowStatusWindow(const CTaskPtr& spSelect) +void CMainWnd::ShowStatusWindow(const chcore::TTaskPtr& spSelect) { - m_pdlgStatus=new CStatusDlg(&m_tasks, this); // self deleting + m_pdlgStatus=new CStatusDlg(m_spTasks.get(), this); // self deleting m_pdlgStatus->m_spInitialSelection = spSelect; m_pdlgStatus->m_bLockInstance=true; m_pdlgStatus->m_bAutoDelete=true; @@ -380,17 +394,17 @@ case 1023: // autosave timer KillTimer(1023); - m_tasks.SaveData(); + m_spTasks->Store(); SetTimer(1023, GetPropValue(GetConfig()), NULL); break; case 3245: // auto-delete finished tasks timer KillTimer(3245); if (GetPropValue(GetConfig())) { - size_t stSize = m_tasks.GetSize(); - m_tasks.RemoveAllFinished(); - if(m_tasks.GetSize() != stSize && m_pdlgStatus && m_pdlgStatus->m_bLock && IsWindow(m_pdlgStatus->m_hWnd)) + size_t stSize = m_spTasks->GetSize(); + m_spTasks->RemoveAllFinished(); + if(m_spTasks->GetSize() != stSize && m_pdlgStatus && m_pdlgStatus->m_bLock && IsWindow(m_pdlgStatus->m_hWnd)) m_pdlgStatus->SendMessage(WM_UPDATESTATUS); } @@ -399,7 +413,7 @@ case 8743: { // wait state handling section - m_tasks.ResumeWaitingTasks((size_t)GetPropValue(GetConfig())); + m_spTasks->ResumeWaitingTasks((size_t)GetPropValue(GetConfig())); break; } } @@ -433,8 +447,7 @@ if(!pszBuffer || ulLen == 0 || pszBuffer[ulLen - 1] != L'\0') return FALSE; - chcore::TWStringData wstrData(pszBuffer); - AfxMessageBox(wstrData.GetData()); // TEMP = to remove before commit + chcore::TString wstrData(pszBuffer); chcore::TTaskDefinition tTaskDefinition; tTaskDefinition.LoadFromString(wstrData); @@ -456,19 +469,19 @@ else if(iModalResult == -1) // windows has been closed by a parent return TRUE; - dlg.m_vRecent.push_back(dlg.m_tTaskDefinition.GetDestinationPath().ToString()); + TRecentPathsTools::AddNewPath(dlg.m_vRecent, dlg.m_tTaskDefinition.GetDestinationPath().ToString()); SetPropValue(rConfig, dlg.m_vRecent); tTaskDefinition = dlg.m_tTaskDefinition; } // load resource strings - SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_FIRSTCOPY_STRING)); - SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); + chcore::SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_FIRSTCOPY_STRING)); + chcore::SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); // create task with the above definition - CTaskPtr spTask = m_tasks.CreateTask(tTaskDefinition); + chcore::TTaskPtr spTask = m_spTasks->CreateTask(tTaskDefinition); // add to task list and start processing spTask->BeginProcessing(); @@ -489,6 +502,8 @@ cmdLineParser.ParseCommandLine(pszBuffer); ProcessCommandLine(cmdLineParser); + m_spTasks->TasksRetryProcessing(); + return TRUE; } } @@ -500,19 +515,21 @@ { if(rCommandLine.HasTaskDefinitionPath()) { - std::vector vTaskPaths; + chcore::TPathContainer vTaskPaths; rCommandLine.GetTaskDefinitionPaths(vTaskPaths); const size_t stBufferSize = 4096; boost::shared_array szBuffer(new wchar_t[stBufferSize]); - BOOST_FOREACH(const CString& strPath, vTaskPaths) + for(size_t stIndex = 0; stIndex < vTaskPaths.GetCount(); ++stIndex) { + const chcore::TSmartPath& strPath = vTaskPaths.GetAt(stIndex); + bool bImported = false; try { - CTaskPtr spTask = m_tasks.ImportTask(strPath); + chcore::TTaskPtr spTask = m_spTasks->ImportTask(strPath); if(spTask) spTask->Store(); bImported = true; @@ -532,24 +549,22 @@ { ictranslate::CFormat fmt; fmt.SetFormat(_T("Error encountered while importing task from path '%path'. Error: %err.")); - fmt.SetParam(_T("%path"), strPath); + fmt.SetParam(_T("%path"), strPath.ToString()); fmt.SetParam(_T("%error"), szBuffer.get()); LOG_ERROR(fmt); fmt.SetFormat(GetResManager().LoadString(IDS_TASK_IMPORT_FAILED)); - fmt.SetParam(_T("%path"), strPath); + fmt.SetParam(_T("%path"), strPath.ToString()); AfxMessageBox(fmt, MB_OK | MB_ICONERROR); } } - - m_tasks.TasksRetryProcessing(); } } void CMainWnd::OnShowMiniView() { - m_pdlgMiniView=new CMiniViewDlg(&m_tasks, &CStatusDlg::m_bLock, this); // self-deleting + m_pdlgMiniView=new CMiniViewDlg(m_spTasks.get(), &CStatusDlg::m_bLock, this); // self-deleting m_pdlgMiniView->m_bAutoDelete=true; m_pdlgMiniView->m_bLockInstance=true; m_pdlgMiniView->Create(); @@ -565,18 +580,18 @@ if(dlg.DoModal() == IDOK) { - dlg.m_vRecent.push_back(dlg.m_tTaskDefinition.GetDestinationPath().ToString()); + TRecentPathsTools::AddNewPath(dlg.m_vRecent, dlg.m_tTaskDefinition.GetDestinationPath().ToString()); SetPropValue(rConfig, dlg.m_vRecent); chcore::TTaskDefinition tTaskDefinition = dlg.m_tTaskDefinition; // load resource strings - SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_FIRSTCOPY_STRING)); - SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); + chcore::SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_FIRSTCOPY_STRING)); + chcore::SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); // new task - CTaskPtr spTask = m_tasks.CreateTask(tTaskDefinition); + chcore::TTaskPtr spTask = m_spTasks->CreateTask(tTaskDefinition); // start spTask->BeginProcessing(); @@ -589,7 +604,7 @@ { case WM_MINIVIEWDBLCLK: { - CTaskPtr spTask = m_tasks.GetTaskBySessionUniqueID(lParam); + chcore::TTaskPtr spTask = m_spTasks->GetTaskByTaskID(lParam); ShowStatusWindow(spTask); break; } @@ -768,7 +783,7 @@ } chcore::TConfig cfgStorage; - chcore::TWStringData wstrData; + chcore::TString wstrData; cfgShellExt.StoreInConfig(cfgStorage, _T("ShellExtCfg")); cfgStorage.WriteToString(wstrData); @@ -868,13 +883,10 @@ // kill thread that monitors clipboard CClipboardMonitor::StopMonitor(); - m_tasks.StopAllTasks(); + m_spTasks->StopAllTasks(); - // save - m_tasks.SaveData(); - // delete all tasks - m_tasks.RemoveAll(); + m_spTasks->ClearBeforeExit(); } void CMainWnd::OnAppExit() @@ -894,3 +906,75 @@ pDlg->Create(); } + +CString CMainWnd::GetTasksDirectory() const +{ + CString strPath; + GetApp().GetProgramDataPath(strPath); + strPath += _T("\\Tasks\\"); + return strPath; +} + +void CMainWnd::CheckForUpdates() +{ + EUpdatesFrequency eFrequency = (EUpdatesFrequency)GetPropValue(GetConfig()); + if(eFrequency != eFreq_Never) + { + unsigned long long ullMinInterval = 0; + switch(eFrequency) + { + case eFreq_Daily: + ullMinInterval = 1*24*60*60; + break; + case eFreq_Weekly: + ullMinInterval = 7*24*60*60; + break; + case eFreq_OnceEvery2Weeks: + ullMinInterval = 14*24*60*60; + break; + case eFreq_Monthly: + ullMinInterval = 30*24*60*60; // we don't really care if it is a day less or more + break; + case eFreq_Quarterly: + ullMinInterval = 90*24*60*60; + break; + case eFreq_EveryStartup: + default: + ullMinInterval = 0; + } + + // get last check time stored in configuration + unsigned long long ullCurrentStamp = _time64(NULL); + unsigned long long ullTimestamp = GetPropValue(GetConfig()); + + // perform checking for updates only when the minimal interval has passed + if(ullCurrentStamp - ullTimestamp >= ullMinInterval) + { + LOG_INFO(_T("Checking for updates...")); + + CUpdaterDlg* pDlg = new CUpdaterDlg(true); + pDlg->m_bAutoDelete = true; + + pDlg->Create(); + chcore::TConfig& rConfig = GetConfig(); + try + { + SetPropValue(rConfig, _time64(NULL)); + rConfig.Write(); + } + catch(icpf::exception& /*e*/) + { + LOG_ERROR(_T("Storing last update check timestamp in configuration failed")); + } + } + } +} + +void CMainWnd::SetupTimers() +{ + // start saving timer + SetTimer(1023, GetPropValue(GetConfig()), NULL); + + SetTimer(3245, TM_AUTOREMOVE, NULL); + SetTimer(8743, TM_ACCEPTING, NULL); // ends wait state in tasks +}