首页 > 代码库 > ToDoList

ToDoList

// ToDoListWnd.cpp : implementation file//#include "stdafx.h"#include "ToDoList.h"#include "ToDoListWnd.h"#include "ToolsCmdlineParser.h"#include "ToolsUserInputDlg.h"#include "Toolshelper.h"#include "tdlexportDlg.h"#include "tasklisthtmlexporter.h"#include "tasklisttxtexporter.h"#include "tdcmsg.h"#include "tdlschemadef.h"#include "tdlprintdialog.h"#include "tdltransformdialog.h"#include "tdstringres.h"#include "tdlcolumnselectiondlg.h"#include "tdlfilterdlg.h"#include "OffsetDatesDlg.h"#include "KeyboardShortcutDisplayDlg.h"#include "tdlimportdialog.h"#include "tdlsetreminderdlg.h"#include "tdlshowreminderdlg.h"#include "tdlmultisortdlg.h"#include "tdladdloggedtimedlg.h"#include "multitaskfile.h"#include "tdcstatic.h"#include "tdlcustomattributedlg.h"#include "tdccustomattributehelper.h"#include "welcomewizard.h"#include "..\shared\aboutdlg.h"#include "..\shared\holdredraw.h"#include "..\shared\autoflag.h"#include "..\shared\enbitmap.h"#include "..\shared\spellcheckdlg.h"#include "..\shared\encolordialog.h"#include "..\shared\winclasses.h"#include "..\shared\wclassdefines.h"#include "..\shared\datehelper.h"#include "..\shared\osversion.h"#include "..\shared\enfiledialog.h"#include "..\shared\misc.h"#include "..\shared\graphicsmisc.h"#include "..\shared\filemisc.h"#include "..\shared\themed.h"#include "..\shared\enstring.h"#include "..\shared\fileregister.h"#include "..\shared\mousewheelMgr.h"#include "..\shared\editshortcutMgr.h"#include "..\shared\dlgunits.h"#include "..\shared\passworddialog.h"#include "..\shared\sysimagelist.h"#include "..\shared\regkey.h"#include "..\shared\uiextensionuihelper.h"#include "..\shared\lightbox.h"#include "..\shared\remotefile.h"#include "..\shared\serverdlg.h"#include "..\shared\focuswatcher.h"#include "..\shared\localizer.h"#include "..\shared\outlookhelper.h"#include "..\3rdparty\gui.h"#include "..\3rdparty\sendfileto.h"#include <shlwapi.h>#include <windowsx.h>#include <direct.h>#include <math.h>#include <afxpriv.h>        // for WM_KICKIDLE#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CToDoListWnd dialog// popup menusenum { TRAYICON, TASKCONTEXT, TABCTRLCONTEXT, HEADERCONTEXT };enum { TB_TOOLBARHIDDEN, TB_DUMMY, TB_TOOLBARANDMENU };enum { FILEALL, NEWTASK, EDITTASK, VIEW, MOVE, SORTTASK, TOOLS, HELP };const int TD_VERSION = 31000;const int BEVEL = 2; // pixelsconst int BORDER = 3; // pixelsconst int TB_VOFFSET = 4;const int ONE_MINUTE = 60000; // millisecondsconst LPCTSTR UPDATE_SCRIPT_PATH = _T("http://www.abstractspoon.com/todolist_update.txt");const LPCTSTR UPDATE_SCRIPT_PATH_MANUAL = _T("http://www.abstractspoon.com/todolist_update_manual.txt");const LPCTSTR UPDATE_SCRIPT_PATH_STAGING = _T("http://www.abstractspoon.com/todolist_update_manual_staging.txt");const LPCTSTR PREF_KEY = _T("Preferences");#define DOPROGRESS(stringID) 	CWaitCursor cursor; 	CStatusBarProgressProxy prog(&m_sbProgress, m_statusBar, CEnString(stringID));enum{	WM_POSTONCREATE = (WM_APP+1),	WM_WEBUPDATEWIZARD,	WM_ADDTOOLBARTOOLS,	WM_APPRESTOREFOCUS,};enum {	TIMER_READONLYSTATUS = 1,	TIMER_TIMESTAMPCHANGE,	TIMER_AUTOSAVE,	TIMER_CHECKOUTSTATUS,	TIMER_DUEITEMS,	TIMER_TIMETRACKING,	TIMER_AUTOMINIMIZE,};enum {	INTERVAL_READONLYSTATUS = 1000,	INTERVAL_TIMESTAMPCHANGE = 10000,	//	INTERVAL_AUTOSAVE, // dynamically determined	INTERVAL_CHECKOUTSTATUS = 5000,	INTERVAL_DUEITEMS = ONE_MINUTE,	INTERVAL_TIMETRACKING = 5000,	//	INTERVAL_AUTOMINIMIZE, // dynamically determined};/////////////////////////////////////////////////////////////////////////////CToDoListWnd::CToDoListWnd() : CFrameWnd(), 		m_bVisible(-1), 		m_mruList(0, _T("MRU"), _T("TaskList%d"), 16, AFX_ABBREV_FILENAME_LEN, CEnString(IDS_RECENTFILES)),		m_nLastSelItem(-1), 		m_nMaxState(TDCMS_NORMAL), 		m_nPrevMaxState(TDCMS_NORMAL),		m_bShowFilterBar(TRUE),		m_bShowStatusBar(TRUE),		m_bInNewTask(FALSE),		m_bSaving(FALSE),		m_mgrShortcuts(FALSE),		m_pPrefs(NULL),		m_bClosing(FALSE),		m_mgrToDoCtrls(m_tabCtrl),		m_bFindShowing(FALSE),		m_bShowProjectName(TRUE),		m_bQueryOpenAllow(FALSE),		m_bPasswordPrompting(TRUE),		m_bShowToolbar(TRUE),		m_bReloading(FALSE),		m_hIcon(NULL),		m_hwndLastFocus(NULL),		m_bStartHidden(FALSE),		m_cbQuickFind(ACBS_ALLOWDELETE | ACBS_ADDTOSTART),		m_bShowTasklistBar(TRUE), 		m_bShowTreeListBar(TRUE),		m_bEndingSession(FALSE),		m_nContextColumnID(TDCC_NONE){	// must do this before initializing any controls	SetupUIStrings();	// delete temporary web-update-wizard	CString sWuwPathTemp = FileMisc::GetAppFolder() + _T("\\WebUpdateSvc2.exe");	::DeleteFile(sWuwPathTemp);	// init preferences	ResetPrefs();	CFilteredToDoCtrl::EnableExtendedSelection(FALSE, TRUE);	m_bAutoMenuEnable = FALSE;}CToDoListWnd::~CToDoListWnd(){	delete m_pPrefs;	if (m_hIcon)		DestroyIcon(m_hIcon);	// cleanup temp files	// Note: Due task notifications are removed by CToDoCtrlMgr	::DeleteFile(FileMisc::GetTempFileName(_T("ToDoList.print"), _T("html")));	::DeleteFile(FileMisc::GetTempFileName(_T("ToDoList.import"), _T("txt")));	::DeleteFile(FileMisc::GetTempFileName(_T("tdt")));}BEGIN_MESSAGE_MAP(CToDoListWnd, CFrameWnd)//{{AFX_MSG_MAP(CToDoListWnd)	ON_WM_QUERYOPEN()	ON_COMMAND(ID_ADDTIMETOLOGFILE, OnAddtimetologfile)	ON_COMMAND(ID_ARCHIVE_SELECTEDTASKS, OnArchiveSelectedTasks)	ON_COMMAND(ID_CLOSEALLBUTTHIS, OnCloseallbutthis)	ON_COMMAND(ID_EDIT_COPYAS_DEPEND, OnCopyTaskasDependency)	ON_COMMAND(ID_EDIT_COPYAS_DEPENDFULL, OnCopyTaskasDependencyFull)	ON_COMMAND(ID_EDIT_COPYAS_PATH, OnCopyTaskasPath)	ON_COMMAND(ID_EDIT_COPYAS_LINK, OnCopyTaskasLink)	ON_COMMAND(ID_EDIT_COPYAS_LINKFULL, OnCopyTaskasLinkFull)	ON_COMMAND(ID_EDIT_CLEARREMINDER, OnEditClearReminder)	ON_COMMAND(ID_EDIT_CLEARTASKCOLOR, OnEditCleartaskcolor)	ON_COMMAND(ID_EDIT_CLEARTASKICON, OnEditCleartaskicon)	ON_COMMAND(ID_EDIT_DECTASKPERCENTDONE, OnEditDectaskpercentdone)	ON_COMMAND(ID_EDIT_DECTASKPRIORITY, OnEditDectaskpriority)	ON_COMMAND(ID_EDIT_FLAGTASK, OnEditFlagtask)	ON_COMMAND(ID_EDIT_INCTASKPERCENTDONE, OnEditInctaskpercentdone)	ON_COMMAND(ID_EDIT_INCTASKPRIORITY, OnEditInctaskpriority)	ON_COMMAND(ID_EDIT_INSERTDATE, OnEditInsertdate)	ON_COMMAND(ID_EDIT_INSERTDATETIME, OnEditInsertdatetime)	ON_COMMAND(ID_EDIT_INSERTTIME, OnEditInserttime)	ON_COMMAND(ID_EDIT_OFFSETDATES, OnEditOffsetdates)	ON_COMMAND(ID_EDIT_REDO, OnEditRedo)	ON_COMMAND(ID_EDIT_SELECTALL, OnEditSelectall)	ON_COMMAND(ID_EDIT_SETREMINDER, OnEditSetReminder)	ON_COMMAND(ID_EDIT_SETTASKICON, OnEditSettaskicon)	ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)	ON_WM_ENABLE()	ON_COMMAND(ID_FILE_CHANGEPASSWORD, OnFileChangePassword)	ON_COMMAND(ID_FILE_OPENARCHIVE, OnFileOpenarchive)	ON_COMMAND(ID_NEXTTASK, OnGotoNexttask)	ON_COMMAND(ID_PREVTASK, OnGotoPrevtask)	ON_WM_MEASUREITEM()	ON_COMMAND(ID_NEWSUBTASK, OnNewsubtask)	ON_COMMAND(ID_NEWTASK, OnNewtask)	ON_COMMAND(ID_PRINTPREVIEW, OnPrintpreview)	ON_COMMAND(ID_EDIT_QUICKFIND, OnQuickFind)	ON_COMMAND(ID_EDIT_QUICKFINDNEXT, OnQuickFindNext)	ON_COMMAND(ID_EDIT_QUICKFINDPREV, OnQuickFindPrev)	ON_COMMAND(ID_SENDTASKS, OnSendTasks)	ON_COMMAND(ID_SEND_SELTASKS, OnSendSelectedTasks)	ON_COMMAND(ID_HELP_KEYBOARDSHORTCUTS, OnShowKeyboardshortcuts)	ON_COMMAND(ID_SHOWTIMELOGFILE, OnShowTimelogfile)	ON_COMMAND(ID_SORT_MULTI, OnSortMulti)	ON_WM_SYSCOLORCHANGE()	ON_COMMAND(ID_TABCTRL_PREFERENCES, OnTabctrlPreferences)	ON_COMMAND(ID_TASKLIST_SELECTCOLUMNS, OnTasklistSelectColumns)	ON_COMMAND(ID_TOOLS_CHECKFORUPDATES, OnToolsCheckforupdates)	ON_COMMAND(ID_TOOLS_TRANSFORM, OnToolsTransformactivetasklist)	ON_UPDATE_COMMAND_UI(ID_ADDTIMETOLOGFILE, OnUpdateAddtimetologfile)	ON_UPDATE_COMMAND_UI(ID_ARCHIVE_SELECTEDTASKS, OnUpdateArchiveSelectedCompletedTasks)	ON_UPDATE_COMMAND_UI(ID_CLOSEALLBUTTHIS, OnUpdateCloseallbutthis)	ON_UPDATE_COMMAND_UI(ID_EDIT_COPYAS_DEPEND, OnUpdateCopyTaskasDependency)	ON_UPDATE_COMMAND_UI(ID_EDIT_COPYAS_DEPENDFULL, OnUpdateCopyTaskasDependencyFull)	ON_UPDATE_COMMAND_UI(ID_EDIT_COPYAS_PATH, OnUpdateCopyTaskasPath)	ON_UPDATE_COMMAND_UI(ID_EDIT_COPYAS_LINK, OnUpdateCopyTaskasLink)	ON_UPDATE_COMMAND_UI(ID_EDIT_COPYAS_LINKFULL, OnUpdateCopyTaskasLinkFull)	ON_UPDATE_COMMAND_UI(ID_EDIT_CLEARREMINDER, OnUpdateEditClearReminder)	ON_UPDATE_COMMAND_UI(ID_EDIT_CLEARTASKCOLOR, OnUpdateEditCleartaskcolor)	ON_UPDATE_COMMAND_UI(ID_EDIT_CLEARTASKICON, OnUpdateEditCleartaskicon)	ON_UPDATE_COMMAND_UI(ID_EDIT_DECTASKPERCENTDONE, OnUpdateEditDectaskpercentdone)	ON_UPDATE_COMMAND_UI(ID_EDIT_DECTASKPRIORITY, OnUpdateEditDectaskpriority)	ON_UPDATE_COMMAND_UI(ID_EDIT_FLAGTASK, OnUpdateEditFlagtask)	ON_UPDATE_COMMAND_UI(ID_EDIT_INCTASKPERCENTDONE, OnUpdateEditInctaskpercentdone)	ON_UPDATE_COMMAND_UI(ID_EDIT_INCTASKPRIORITY, OnUpdateEditInctaskpriority)	ON_UPDATE_COMMAND_UI(ID_EDIT_INSERTDATE, OnUpdateEditInsertdate)	ON_UPDATE_COMMAND_UI(ID_EDIT_INSERTDATETIME, OnUpdateEditInsertdatetime)	ON_UPDATE_COMMAND_UI(ID_EDIT_INSERTTIME, OnUpdateEditInserttime)	ON_UPDATE_COMMAND_UI(ID_EDIT_OFFSETDATES, OnUpdateEditOffsetdates)	ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)	ON_UPDATE_COMMAND_UI(ID_EDIT_SELECTALL, OnUpdateEditSelectall)	ON_UPDATE_COMMAND_UI(ID_EDIT_SETREMINDER, OnUpdateEditSetReminder)	ON_UPDATE_COMMAND_UI(ID_EDIT_SETTASKICON, OnUpdateEditSettaskicon)	ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)	ON_UPDATE_COMMAND_UI(ID_FILE_CHANGEPASSWORD, OnUpdateFileChangePassword)	ON_UPDATE_COMMAND_UI(ID_FILE_OPENARCHIVE, OnUpdateFileOpenarchive)	ON_UPDATE_COMMAND_UI(ID_NEXTTASK, OnUpdateGotoNexttask)	ON_UPDATE_COMMAND_UI(ID_PREVTASK, OnUpdateGotoPrevtask)	ON_UPDATE_COMMAND_UI(ID_NEWSUBTASK, OnUpdateNewsubtask)	ON_UPDATE_COMMAND_UI(ID_EDIT_QUICKFIND, OnUpdateQuickFind)	ON_UPDATE_COMMAND_UI(ID_EDIT_QUICKFINDNEXT, OnUpdateQuickFindNext)	ON_UPDATE_COMMAND_UI(ID_EDIT_QUICKFINDPREV, OnUpdateQuickFindPrev)	ON_UPDATE_COMMAND_UI(ID_SHOWTIMELOGFILE, OnUpdateShowTimelogfile)	ON_UPDATE_COMMAND_UI(ID_SENDTASKS, OnUpdateSendTasks)	ON_UPDATE_COMMAND_UI(ID_SEND_SELTASKS, OnUpdateSendSelectedTasks)	ON_UPDATE_COMMAND_UI(ID_SORT_MULTI, OnUpdateSortMulti)	ON_UPDATE_COMMAND_UI(ID_VIEW_CLEARFILTER, OnUpdateViewClearfilter)	ON_UPDATE_COMMAND_UI(ID_VIEW_COLLAPSEDUE, OnUpdateViewCollapseDuetasks)	ON_UPDATE_COMMAND_UI(ID_VIEW_COLLAPSESTARTED, OnUpdateViewCollapseStartedtasks)	ON_UPDATE_COMMAND_UI(ID_VIEW_COLLAPSEALL, OnUpdateViewCollapseall)	ON_UPDATE_COMMAND_UI(ID_VIEW_COLLAPSETASK, OnUpdateViewCollapsetask)	ON_UPDATE_COMMAND_UI(ID_VIEW_EXPANDDUE, OnUpdateViewExpandDuetasks)	ON_UPDATE_COMMAND_UI(ID_VIEW_EXPANDSTARTED, OnUpdateViewExpandStartedtasks)	ON_UPDATE_COMMAND_UI(ID_VIEW_EXPANDALL, OnUpdateViewExpandall)	ON_UPDATE_COMMAND_UI(ID_VIEW_EXPANDTASK, OnUpdateViewExpandtask)	ON_UPDATE_COMMAND_UI(ID_VIEW_FILTER, OnUpdateViewFilter)	ON_UPDATE_COMMAND_UI(ID_VIEW_PROJECTNAME, OnUpdateViewProjectname)	ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWTASKLISTTABBAR, OnUpdateViewShowTasklistTabbar)	ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWTREELISTTABBAR, OnUpdateViewShowTreeListTabbar)	ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWFILTERBAR, OnUpdateViewShowfilterbar)	ON_UPDATE_COMMAND_UI(ID_VIEW_SORTTASKLISTTABS, OnUpdateViewSorttasklisttabs)	ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS_BAR, OnUpdateViewStatusBar)	ON_UPDATE_COMMAND_UI(ID_VIEW_CYCLETASKVIEWS, OnUpdateViewCycleTaskViews)	ON_UPDATE_COMMAND_UI(ID_VIEW_TOGGLETREEANDLIST, OnUpdateViewToggleTreeandList)	ON_UPDATE_COMMAND_UI(ID_VIEW_TOGGLEFILTER, OnUpdateViewTogglefilter)	ON_UPDATE_COMMAND_UI(ID_VIEW_TOGGLETASKEXPANDED, OnUpdateViewToggletaskexpanded)	ON_UPDATE_COMMAND_UI(ID_VIEW_TOGGLETASKSANDCOMMENTS, OnUpdateViewToggletasksandcomments)	ON_UPDATE_COMMAND_UI(ID_WINDOW1, OnUpdateWindow)	ON_COMMAND(ID_VIEW_CLEARFILTER, OnViewClearfilter)	ON_COMMAND(ID_VIEW_COLLAPSEDUE, OnViewCollapseDuetasks)	ON_COMMAND(ID_VIEW_COLLAPSESTARTED, OnViewCollapseStartedtasks)	ON_COMMAND(ID_VIEW_COLLAPSEALL, OnViewCollapseall)	ON_COMMAND(ID_VIEW_COLLAPSETASK, OnViewCollapsetask)	ON_COMMAND(ID_VIEW_EXPANDDUE, OnViewExpandDuetasks)	ON_COMMAND(ID_VIEW_EXPANDSTARTED, OnViewExpandStartedtasks)	ON_COMMAND(ID_VIEW_EXPANDALL, OnViewExpandall)	ON_COMMAND(ID_VIEW_EXPANDTASK, OnViewExpandtask)	ON_COMMAND(ID_VIEW_FILTER, OnViewFilter)	ON_COMMAND(ID_VIEW_PROJECTNAME, OnViewProjectname)	ON_COMMAND(ID_VIEW_SHOWTASKLISTTABBAR, OnViewShowTasklistTabbar) 	ON_COMMAND(ID_VIEW_SHOWTREELISTTABBAR, OnViewShowTreeListTabbar)	ON_COMMAND(ID_VIEW_SHOWFILTERBAR, OnViewShowfilterbar)	ON_COMMAND(ID_VIEW_SORTTASKLISTTABS, OnViewSorttasklisttabs)	ON_COMMAND(ID_VIEW_STATUS_BAR, OnViewStatusBar)	ON_COMMAND(ID_VIEW_CYCLETASKVIEWS, OnViewCycleTaskViews)	ON_COMMAND(ID_VIEW_TOGGLETREEANDLIST, OnViewToggleTreeandList)	ON_COMMAND(ID_VIEW_TOGGLEFILTER, OnViewTogglefilter)	ON_COMMAND(ID_VIEW_TOGGLETASKEXPANDED, OnViewToggletaskexpanded)	ON_COMMAND(ID_VIEW_TOGGLETASKSANDCOMMENTS, OnViewToggletasksandcomments)	ON_WM_WINDOWPOSCHANGED()	ON_WM_WINDOWPOSCHANGING()	ON_COMMAND(ID_TASKLIST_CUSTOMCOLUMNS, OnTasklistCustomColumns)	ON_COMMAND(ID_EDIT_GOTODEPENDENCY, OnEditGotoDependency)	ON_UPDATE_COMMAND_UI(ID_EDIT_GOTODEPENDENCY, OnUpdateEditGotoDependency)	ON_COMMAND(ID_EDIT_RECURRENCE, OnEditRecurrence)	ON_UPDATE_COMMAND_UI(ID_EDIT_RECURRENCE, OnUpdateEditRecurrence)	ON_WM_QUERYENDSESSION()	ON_COMMAND(ID_EDIT_CLEARFIELD, OnEditClearAttribute)	ON_UPDATE_COMMAND_UI(ID_EDIT_CLEARFIELD, OnUpdateEditClearAttribute)	ON_COMMAND(ID_EDIT_CLEARFOCUSEDFIELD, OnEditClearFocusedAttribute)	ON_UPDATE_COMMAND_UI(ID_EDIT_CLEARFOCUSEDFIELD, OnUpdateEditClearFocusedAttribute)	ON_UPDATE_COMMAND_UI(ID_TASKLIST_CUSTOMCOLUMNS, OnUpdateTasklistCustomcolumns)	ON_COMMAND(ID_ADDTIMETOLOGFILE, OnAddtimetologfile)	ON_UPDATE_COMMAND_UI(ID_ADDTIMETOLOGFILE, OnUpdateAddtimetologfile)	ON_WM_ACTIVATEAPP()	ON_WM_ERASEBKGND()	ON_WM_INITMENUPOPUP()	ON_WM_MOVE()	ON_WM_SYSCOMMAND()	ON_COMMAND(ID_EDIT_PASTEASREF, OnEditPasteAsRef)	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTEASREF, OnUpdateEditPasteAsRef)	//}}AFX_MSG_MAP	ON_CBN_EDITCHANGE(IDC_QUICKFIND, OnEditChangeQuickFind)	ON_CBN_SELCHANGE(IDC_QUICKFIND, OnSelChangeQuickFind)	ON_COMMAND(ID_ABOUT, OnAbout)	ON_COMMAND(ID_ARCHIVE_COMPLETEDTASKS, OnArchiveCompletedtasks)	ON_COMMAND(ID_CLOSE, OnCloseTasklist)	ON_COMMAND(ID_CLOSEALL, OnCloseall)	ON_COMMAND(ID_DELETEALLTASKS, OnDeleteAllTasks)	ON_COMMAND(ID_DELETETASK, OnDeleteTask)	ON_COMMAND(ID_EDIT_CLOCK_TASK, OnEditTimeTrackTask)	ON_COMMAND(ID_EDIT_COPY, OnEditCopy)	ON_COMMAND(ID_EDIT_COPYAS_HTML, OnEditCopyashtml)	ON_COMMAND(ID_EDIT_COPYAS_TEXT, OnEditCopyastext)	ON_COMMAND(ID_EDIT_CUT, OnEditCut)	ON_COMMAND(ID_EDIT_FINDTASKS, OnFindTasks)	ON_COMMAND(ID_EDIT_OPENFILEREF, OnEditOpenfileref)	ON_COMMAND(ID_EDIT_PASTEAFTER, OnEditPasteAfter)	ON_COMMAND(ID_EDIT_PASTESUB, OnEditPasteSub)	ON_COMMAND(ID_EDIT_SETFILEREF, OnEditSetfileref)	ON_COMMAND(ID_EDIT_SPELLCHECKCOMMENTS, OnSpellcheckcomments)	ON_COMMAND(ID_EDIT_SPELLCHECKTITLE, OnSpellchecktitle)	ON_COMMAND(ID_EDIT_TASKCOLOR, OnEditTaskcolor)	ON_COMMAND(ID_EDIT_TASKDONE, OnEditTaskdone)	ON_COMMAND(ID_EDIT_TASKTEXT, OnEditTasktext)	ON_COMMAND(ID_EXIT, OnExit)	ON_COMMAND(ID_FILE_ENCRYPT, OnFileEncrypt)	ON_COMMAND(ID_FILE_RESETVERSION, OnFileResetversion)	ON_COMMAND(ID_LOAD_NORMAL, onl oad)	ON_COMMAND(ID_MAXCOMMENTS, OnMaximizeComments)	ON_COMMAND(ID_MAXTASKLIST, OnMaximizeTasklist)	ON_COMMAND(ID_MINIMIZETOTRAY, OnMinimizeToTray)	ON_COMMAND(ID_MOVETASKDOWN, OnMovetaskdown)	ON_COMMAND(ID_MOVETASKLEFT, OnMovetaskleft)	ON_COMMAND(ID_MOVETASKRIGHT, OnMovetaskright)	ON_COMMAND(ID_MOVETASKUP, OnMovetaskup)	ON_COMMAND(ID_NEW, OnNew)	ON_COMMAND(ID_NEWSUBTASK_ATBOTTOM, OnNewsubtaskAtbottom)	ON_COMMAND(ID_NEWSUBTASK_ATTOP, OnNewsubtaskAttop)	ON_COMMAND(ID_NEWTASK_AFTERSELECTEDTASK, OnNewtaskAfterselectedtask)	ON_COMMAND(ID_NEWTASK_ATBOTTOM, OnNewtaskAtbottom)	ON_COMMAND(ID_NEWTASK_ATBOTTOMSELECTED, OnNewtaskAtbottomSelected)	ON_COMMAND(ID_NEWTASK_ATTOP, OnNewtaskAttop)	ON_COMMAND(ID_NEWTASK_ATTOPSELECTED, OnNewtaskAttopSelected)	ON_COMMAND(ID_NEWTASK_BEFORESELECTEDTASK, OnNewtaskBeforeselectedtask)	ON_COMMAND(ID_NEXTTOPLEVELTASK, OnNexttopleveltask)	ON_COMMAND(ID_OPEN_RELOAD, OnReload)	ON_COMMAND(ID_PREFERENCES, OnPreferences)	ON_COMMAND(ID_PREVTOPLEVELTASK, OnPrevtopleveltask)	ON_COMMAND(ID_PRINT, OnPrint)	ON_COMMAND(ID_SAVEALL, OnSaveall)	ON_COMMAND(ID_SAVEAS, OnSaveas)	ON_COMMAND(ID_SAVE_NORMAL, OnSave)	ON_COMMAND(ID_SORT, OnSort)	ON_COMMAND(ID_TOOLS_CHECKIN, OnToolsCheckin)	ON_COMMAND(ID_TOOLS_CHECKOUT, OnToolsCheckout)	ON_COMMAND(ID_TOOLS_EXPORT, OnExport)	ON_COMMAND(ID_TOOLS_IMPORT, OnImportTasklist)	ON_COMMAND(ID_TOOLS_SPELLCHECKTASKLIST, OnSpellcheckTasklist) 	ON_COMMAND(ID_TOOLS_REMOVEFROMSOURCECONTROL, OnToolsRemovefromsourcecontrol)	ON_COMMAND(ID_TOOLS_TOGGLECHECKIN, OnToolsToggleCheckin)	ON_COMMAND(ID_TRAYICON_CLOSE, OnTrayiconClose)	ON_COMMAND(ID_TRAYICON_CREATETASK, OnTrayiconCreatetask)	ON_COMMAND(ID_TRAYICON_SHOW, OnTrayiconShow)	ON_COMMAND(ID_VIEW_MOVETASKLISTLEFT, OnViewMovetasklistleft)	ON_COMMAND(ID_VIEW_MOVETASKLISTRIGHT, OnViewMovetasklistright)	ON_COMMAND(ID_VIEW_NEXT, OnViewNext)	ON_COMMAND(ID_VIEW_NEXT_SEL, OnViewNextSel)	ON_COMMAND(ID_VIEW_PREV, OnViewPrev)	ON_COMMAND(ID_VIEW_PREV_SEL, OnViewPrevSel)	ON_COMMAND(ID_VIEW_REFRESHFILTER, OnViewRefreshfilter)	ON_COMMAND(ID_VIEW_TOOLBAR, OnViewToolbar)	ON_COMMAND_EX_RANGE(ID_FILE_MRU_FILE1, ID_FILE_MRU_FILE16, OnOpenRecentFile)	ON_COMMAND_RANGE(ID_EDIT_SETPRIORITYNONE, ID_EDIT_SETPRIORITY10, OnSetPriority)	ON_COMMAND_RANGE(ID_NEWTASK_SPLITTASKINTO_TWO, ID_NEWTASK_SPLITTASKINTO_FIVE, OnSplitTaskIntoPieces)	ON_COMMAND_RANGE(ID_SORT_BYFIRST, ID_SORT_BYLAST, OnSortBy)	ON_COMMAND_RANGE(ID_TOOLS_SHOWTASKS_DUETODAY, ID_TOOLS_SHOWTASKS_DUEENDNEXTMONTH, OnToolsShowtasksDue)//	ON_COMMAND_RANGE(ID_TOOLS_USEREXT1, ID_TOOLS_USEREXT16, OnUserUIExtension)	ON_COMMAND_RANGE(ID_TOOLS_USERTOOL1, ID_TOOLS_USERTOOL16, OnUserTool)	ON_COMMAND_RANGE(ID_FILE_OPEN_USERSTORAGE1, ID_FILE_OPEN_USERSTORAGE16, OnFileOpenFromUserStorage)	ON_COMMAND_RANGE(ID_FILE_SAVE_USERSTORAGE1, ID_FILE_SAVE_USERSTORAGE16, OnFileSaveToUserStorage)	ON_COMMAND_RANGE(ID_TRAYICON_SHOWDUETASKS1, ID_TRAYICON_SHOWDUETASKS20, OnTrayiconShowDueTasks)	ON_COMMAND_RANGE(ID_WINDOW1, ID_WINDOW16, OnWindow)	ON_MESSAGE(WM_ADDTOOLBARTOOLS, OnAddToolbarTools)	ON_MESSAGE(WM_APPRESTOREFOCUS, OnAppRestoreFocus)	ON_MESSAGE(WM_GETFONT, OnGetFont)	ON_MESSAGE(WM_GETICON, OnGetIcon)	ON_MESSAGE(WM_HOTKEY, OnHotkey)	ON_MESSAGE(WM_POSTONCREATE, OnPostOnCreate)	ON_MESSAGE(WM_POWERBROADCAST, OnPowerBroadcast)	ON_MESSAGE(WM_WEBUPDATEWIZARD, OnWebUpdateWizard)	ON_NOTIFY(NM_CLICK, IDC_TRAYICON, OnTrayIconClick) 	ON_NOTIFY(NM_DBLCLK, IDC_TRAYICON, OnTrayIconDblClk)	ON_NOTIFY(NM_MCLICK, IDC_TABCONTROL, OnMBtnClickTabcontrol)	ON_NOTIFY(NM_RCLICK, IDC_TRAYICON, OnTrayIconRClick)	ON_NOTIFY(TCN_SELCHANGE, IDC_TABCONTROL, OnSelchangeTabcontrol)	ON_NOTIFY(TCN_SELCHANGING, IDC_TABCONTROL, OnSelchangingTabcontrol)//	ON_NOTIFY(TTN_NEEDTEXTA, 0, OnNeedTooltipText)	ON_NOTIFY(TTN_NEEDTEXTW, 0, OnNeedTooltipText)	ON_REGISTERED_MESSAGE(WM_ACB_ITEMADDED, OnQuickFindItemAdded)	ON_REGISTERED_MESSAGE(WM_FBN_FILTERCHNG, OnSelchangeFilter)	ON_REGISTERED_MESSAGE(WM_FTD_APPLYASFILTER, OnFindApplyAsFilter)	ON_REGISTERED_MESSAGE(WM_FTD_CLOSE, OnFindDlgClose)	ON_REGISTERED_MESSAGE(WM_FTD_ADDSEARCH, OnFindAddSearch)	ON_REGISTERED_MESSAGE(WM_FTD_DELETESEARCH, OnFindDeleteSearch)	ON_REGISTERED_MESSAGE(WM_FTD_FIND, OnFindDlgFind)	ON_REGISTERED_MESSAGE(WM_FTD_SELECTALL, OnFindSelectAll)	ON_REGISTERED_MESSAGE(WM_FTD_SELECTRESULT, OnFindSelectResult)	ON_REGISTERED_MESSAGE(WM_FW_FOCUSCHANGE, OnFocusChange)	ON_REGISTERED_MESSAGE(WM_PGP_CLEARMRU, OnPreferencesClearMRU)	ON_REGISTERED_MESSAGE(WM_PGP_CLEANUPDICTIONARY, OnPreferencesCleanupDictionary)	ON_REGISTERED_MESSAGE(WM_PTDP_LISTCHANGE, OnPreferencesDefaultListChange)	ON_REGISTERED_MESSAGE(WM_PTP_TESTTOOL, OnPreferencesTestTool)	ON_REGISTERED_MESSAGE(WM_TDCM_TASKHASREMINDER, OnToDoCtrlTaskHasReminder)	ON_REGISTERED_MESSAGE(WM_TDCM_TASKISDONE, OnToDoCtrlTaskIsDone)	ON_REGISTERED_MESSAGE(WM_TDCM_LENGTHYOPERATION, OnToDoCtrlDoLengthyOperation)	ON_REGISTERED_MESSAGE(WM_TDCM_TASKLINK, OnToDoCtrlDoTaskLink)	ON_REGISTERED_MESSAGE(WM_TDCM_FAILEDLINK, OnTodoCtrlFailedLink)	ON_REGISTERED_MESSAGE(WM_TDCN_DOUBLECLKREMINDERCOL, OnDoubleClkReminderCol)	ON_REGISTERED_MESSAGE(WM_TDCN_LISTCHANGE, OnToDoCtrlNotifyListChange)	ON_REGISTERED_MESSAGE(WM_TDCN_MODIFY, OnToDoCtrlNotifyMod)	ON_REGISTERED_MESSAGE(WM_TDCN_RECREATERECURRINGTASK, OnToDoCtrlNotifyRecreateRecurringTask)	ON_REGISTERED_MESSAGE(WM_TDCN_TIMETRACK, OnToDoCtrlNotifyTimeTrack)	ON_REGISTERED_MESSAGE(WM_TDCN_VIEWPOSTCHANGE, OnToDoCtrlNotifyViewChange)	ON_REGISTERED_MESSAGE(WM_TDL_GETVERSION , OnToDoListGetVersion)	ON_REGISTERED_MESSAGE(WM_TDL_ISCLOSING , OnToDoListIsClosing)	ON_REGISTERED_MESSAGE(WM_TDL_REFRESHPREFS , OnToDoListRefreshPrefs)	ON_REGISTERED_MESSAGE(WM_TDL_RESTORE , OnToDoListRestore)	ON_REGISTERED_MESSAGE(WM_TDL_SHOWWINDOW , OnToDoListShowWindow)	ON_REGISTERED_MESSAGE(WM_TD_REMINDER, OnToDoCtrlReminder)	ON_REGISTERED_MESSAGE(WM_TLDT_DROP, OnDropFile)	ON_UPDATE_COMMAND_UI(ID_ARCHIVE_COMPLETEDTASKS, OnUpdateArchiveCompletedtasks)	ON_UPDATE_COMMAND_UI(ID_CLOSEALL, OnUpdateCloseall)	ON_UPDATE_COMMAND_UI(ID_DELETEALLTASKS, OnUpdateDeletealltasks) 	ON_UPDATE_COMMAND_UI(ID_DELETETASK, OnUpdateDeletetask)	ON_UPDATE_COMMAND_UI(ID_EDIT_CLOCK_TASK, OnUpdateEditTimeTrackTask)	ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)	ON_UPDATE_COMMAND_UI(ID_EDIT_COPYAS_HTML, OnUpdateEditCopy)	ON_UPDATE_COMMAND_UI(ID_EDIT_COPYAS_TEXT, OnUpdateEditCopy)	ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)	ON_UPDATE_COMMAND_UI(ID_EDIT_OPENFILEREF, OnUpdateEditOpenfileref)	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTEAFTER, OnUpdateEditPasteAfter)	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTESUB, OnUpdateEditPasteSub)	ON_UPDATE_COMMAND_UI(ID_EDIT_SETFILEREF, OnUpdateEditSetfileref)	ON_UPDATE_COMMAND_UI(ID_EDIT_SPELLCHECKCOMMENTS, OnUpdateSpellcheckcomments)	ON_UPDATE_COMMAND_UI(ID_EDIT_SPELLCHECKTITLE, OnUpdateSpellchecktitle)	ON_UPDATE_COMMAND_UI(ID_EDIT_TASKCOLOR, OnUpdateTaskcolor)	ON_UPDATE_COMMAND_UI(ID_EDIT_TASKDONE, OnUpdateTaskdone)	ON_UPDATE_COMMAND_UI(ID_EDIT_TASKTEXT, OnUpdateEditTasktext)	ON_UPDATE_COMMAND_UI(ID_FILE_ENCRYPT, OnUpdateFileEncrypt)	ON_UPDATE_COMMAND_UI(ID_FILE_MRU_FILE1, OnUpdateRecentFileMenu)	ON_UPDATE_COMMAND_UI(ID_FILE_RESETVERSION, OnUpdateFileResetversion)	ON_UPDATE_COMMAND_UI(ID_MAXCOMMENTS, OnUpdateMaximizeComments)	ON_UPDATE_COMMAND_UI(ID_MAXTASKLIST, OnUpdateMaximizeTasklist)	ON_UPDATE_COMMAND_UI(ID_MOVETASKDOWN, OnUpdateMovetaskdown)	ON_UPDATE_COMMAND_UI(ID_MOVETASKLEFT, OnUpdateMovetaskleft)	ON_UPDATE_COMMAND_UI(ID_MOVETASKRIGHT, OnUpdateMovetaskright)	ON_UPDATE_COMMAND_UI(ID_MOVETASKUP, OnUpdateMovetaskup)	ON_UPDATE_COMMAND_UI(ID_NEW, OnUpdateNew)	ON_UPDATE_COMMAND_UI(ID_NEWSUBTASK_ATBOTTOM, OnUpdateNewsubtaskAtBottom)	ON_UPDATE_COMMAND_UI(ID_NEWSUBTASK_ATTOP, OnUpdateNewsubtaskAttop)	ON_UPDATE_COMMAND_UI(ID_NEWTASK, OnUpdateNewtask)	ON_UPDATE_COMMAND_UI(ID_NEWTASK_AFTERSELECTEDTASK, OnUpdateNewtaskAfterselectedtask)	ON_UPDATE_COMMAND_UI(ID_NEWTASK_ATBOTTOM, OnUpdateNewtaskAtbottom)	ON_UPDATE_COMMAND_UI(ID_NEWTASK_ATBOTTOMSELECTED, OnUpdateNewtaskAtbottomSelected)	ON_UPDATE_COMMAND_UI(ID_NEWTASK_ATTOP, OnUpdateNewtaskAttop)	ON_UPDATE_COMMAND_UI(ID_NEWTASK_ATTOPSELECTED, OnUpdateNewtaskAttopSelected)	ON_UPDATE_COMMAND_UI(ID_NEWTASK_BEFORESELECTEDTASK, OnUpdateNewtaskBeforeselectedtask)	ON_UPDATE_COMMAND_UI(ID_NEXTTOPLEVELTASK, OnUpdateNexttopleveltask)	ON_UPDATE_COMMAND_UI(ID_OPEN_RELOAD, OnUpdateReload)	ON_UPDATE_COMMAND_UI(ID_PREVTOPLEVELTASK, OnUpdatePrevtopleveltask)	ON_UPDATE_COMMAND_UI(ID_PRINT, OnUpdatePrint)	ON_UPDATE_COMMAND_UI(ID_SAVEALL, OnUpdateSaveall)	ON_UPDATE_COMMAND_UI(ID_SAVEAS, OnUpdateSaveas)	ON_UPDATE_COMMAND_UI(ID_SAVE_NORMAL, OnUpdateSave)	ON_UPDATE_COMMAND_UI(ID_SB_SELCOUNT, OnUpdateSBSelectionCount)	ON_UPDATE_COMMAND_UI(ID_SB_TASKCOUNT, OnUpdateSBTaskCount)	ON_UPDATE_COMMAND_UI(ID_SORT, OnUpdateSort)	ON_UPDATE_COMMAND_UI(ID_TOOLS_CHECKIN, OnUpdateToolsCheckin)	ON_UPDATE_COMMAND_UI(ID_TOOLS_CHECKOUT, OnUpdateToolsCheckout)	ON_UPDATE_COMMAND_UI(ID_TOOLS_EXPORT, OnUpdateExport)	ON_UPDATE_COMMAND_UI(ID_TOOLS_IMPORT, OnUpdateImport) 	ON_UPDATE_COMMAND_UI(ID_TOOLS_REMOVEFROMSOURCECONTROL, OnUpdateToolsRemovefromsourcecontrol)	ON_UPDATE_COMMAND_UI(ID_TOOLS_SPELLCHECKTASKLIST, OnUpdateSpellcheckTasklist)	ON_UPDATE_COMMAND_UI(ID_TOOLS_TOGGLECHECKIN, OnUpdateToolsToggleCheckin)	ON_UPDATE_COMMAND_UI(ID_TOOLS_TRANSFORM, OnUpdateExport) // use same text as export	ON_UPDATE_COMMAND_UI(ID_VIEW_MOVETASKLISTLEFT, OnUpdateViewMovetasklistleft)	ON_UPDATE_COMMAND_UI(ID_VIEW_MOVETASKLISTRIGHT, OnUpdateViewMovetasklistright)	ON_UPDATE_COMMAND_UI(ID_VIEW_NEXT, OnUpdateViewNext)	ON_UPDATE_COMMAND_UI(ID_VIEW_NEXT_SEL, OnUpdateViewNextSel)	ON_UPDATE_COMMAND_UI(ID_VIEW_PREV, OnUpdateViewPrev)	ON_UPDATE_COMMAND_UI(ID_VIEW_PREV_SEL, OnUpdateViewPrevSel)	ON_UPDATE_COMMAND_UI(ID_VIEW_REFRESHFILTER, OnUpdateViewRefreshfilter)	ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLBAR, OnUpdateViewToolbar)	ON_UPDATE_COMMAND_UI_RANGE(ID_EDIT_SETPRIORITYNONE, ID_EDIT_SETPRIORITY10, OnUpdateSetPriority)		ON_UPDATE_COMMAND_UI_RANGE(ID_NEWTASK_SPLITTASKINTO_TWO, ID_NEWTASK_SPLITTASKINTO_FIVE, OnUpdateSplitTaskIntoPieces)	ON_UPDATE_COMMAND_UI_RANGE(ID_SORT_BYFIRST, ID_SORT_BYLAST, OnUpdateSortBy)//	ON_UPDATE_COMMAND_UI_RANGE(ID_TOOLS_USEREXT1, ID_TOOLS_USEREXT16, OnUpdateUserUIExtension)	ON_UPDATE_COMMAND_UI_RANGE(ID_TOOLS_USERTOOL1, ID_TOOLS_USERTOOL16, OnUpdateUserTool)	ON_WM_CLOSE()	ON_WM_CONTEXTMENU()	ON_WM_COPYDATA()	ON_WM_CREATE()	ON_WM_DRAWITEM()	ON_WM_ERASEBKGND()	ON_WM_HELPINFO()	ON_WM_INITMENUPOPUP()	ON_WM_ENDSESSION()	ON_WM_SIZE()	ON_WM_SYSCOMMAND()	ON_WM_TIMER()	#ifdef _DEBUG	ON_COMMAND(ID_DEBUGENDSESSION, OnDebugEndSession)	ON_COMMAND(ID_DEBUGSHOWSETUPDLG, OnDebugShowSetupDlg)#endifEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CToDoListWnd message handlersvoid CToDoListWnd::SetupUIStrings(){	// set up UI strings for helper classes	CTimeEdit::SetUnits(THU_MINS, CEnString(IDS_TE_MINS), CEnString(IDS_MINS_ABBREV));	CTimeEdit::SetUnits(THU_HOURS, CEnString(IDS_TE_HOURS), CEnString(IDS_HOURS_ABBREV));	CTimeEdit::SetUnits(THU_DAYS, CEnString(IDS_TE_DAYS), CEnString(IDS_DAYS_ABBREV));	CTimeEdit::SetUnits(THU_WEEKS, CEnString(IDS_TE_WEEKS), CEnString(IDS_WEEKS_ABBREV));	CTimeEdit::SetUnits(THU_MONTHS, CEnString(IDS_TE_MONTHS), CEnString(IDS_MONTHS_ABBREV));	CTimeEdit::SetUnits(THU_YEARS, CEnString(IDS_TE_YEARS), CEnString(IDS_YEARS_ABBREV));	CTimeEdit::SetDefaultButtonTip(CEnString(IDS_TIMEUNITS));	CFileEdit::SetDefaultButtonTips(CEnString(IDS_BROWSE), CEnString(IDS_VIEW));	CFileEdit::SetDefaultBrowseTitles(CEnString(IDS_BROWSEFILE_TITLE), CEnString(IDS_BROWSEFOLDER_TITLE));	CTDLRecurringTaskEdit::SetDefaultButtonTip(CEnString(IDS_OPTIONS));	CXmlFileEx::SetUIStrings(CEnString(IDS_ENCRYPTEDFILE), CEnString(IDS_DECRYPTFAILED));/*	CServerDlg::SetItemText(SD_TITLE, IDS_SCD_TITLE);	CServerDlg::SetItemText(IDC_SD_SERVERLABEL, IDS_SD_SERVERLABEL);	CServerDlg::SetItemText(IDC_SD_USERNAMELABEL, IDS_SD_USERNAMELABEL);	CServerDlg::SetItemText(IDC_SD_PASSWORDLABEL, IDS_SD_PASSWORDLABEL);	CServerDlg::SetItemText(IDC_SD_ANONLOGIN, IDS_SD_ANONLOGIN);	CServerDlg::SetItemText(IDOK, IDS_OK);	CServerDlg::SetItemText(IDCANCEL, IDS_CANCEL);	CPasswordDialog::SetItemText(PD_TITLE, IDS_PD_TITLE);	CPasswordDialog::SetItemText(IDC_PD_PASSWORDLABEL, IDS_PD_PASSWORDLABEL);	CPasswordDialog::SetItemText(IDC_PD_CONFIRMLABEL, IDS_PD_CONFIRMLABEL);	CPasswordDialog::SetItemText(DLG_PD_CONFIRMFAILED, IDS_PD_CONFIRMFAILED);	CPasswordDialog::SetItemText(IDOK, IDS_OK);	CPasswordDialog::SetItemText(IDCANCEL, IDS_CANCEL);	CSpellCheckDlg::SetItemText(IDC_SCD_DICTLABEL, IDS_SCD_DICTLABEL);	CSpellCheckDlg::SetItemText(IDC_SCD_BROWSE, IDS_SCD_BROWSE);	CSpellCheckDlg::SetItemText(IDC_SCD_URL, IDS_SCD_URL);	CSpellCheckDlg::SetItemText(IDC_SCD_CHECKINGLABEL, IDS_SCD_CHECKINGLABEL);	CSpellCheckDlg::SetItemText(IDC_SCD_RESTART, IDS_SCD_RESTART);	CSpellCheckDlg::SetItemText(IDC_SCD_REPLACELABEL, IDS_SCD_REPLACELABEL);	CSpellCheckDlg::SetItemText(IDC_SCD_WITHLABEL, IDS_SCD_WITHLABEL);	CSpellCheckDlg::SetItemText(IDC_SCD_REPLACE, IDS_SCD_REPLACE);	CSpellCheckDlg::SetItemText(IDC_SCD_NEXT, IDS_SCD_NEXT);	CSpellCheckDlg::SetItemText(IDOK, IDS_OK);	CSpellCheckDlg::SetItemText(IDCANCEL, IDS_CANCEL);	CSpellCheckDlg::SetItemText(SCD_TITLE, IDS_SCD_TITLE);	CSpellCheckDlg::SetItemText(DLG_SCD_SETUPMSG, IDS_SCD_SETUPMSG);	CSpellCheckDlg::SetItemText(DLG_SCD_DICTFILTER, IDS_SCD_DICTFILTER);	CSpellCheckDlg::SetItemText(DLG_SCD_ENGINEFILTER, IDS_SCD_ENGINEFILTER);	CSpellCheckDlg::SetItemText(DLG_SCD_ENGINETITLE, IDS_SCD_ENGINETITLE);*/	CSpellCheckDlg::SetItemText(DLG_SCD_BROWSETITLE, IDS_SCD_BROWSETITLE);}BOOL CToDoListWnd::OnHelpInfo(HELPINFO* /*pHelpInfo*/){	// always eat this because we handle the F1 ourselves	return FALSE;}void CToDoListWnd::SetUITheme(const CString& sThemeFile){	if (COSVersion() < OSV_XP)		return;	// cache existing theme	CUIThemeFile themeCur = m_theme;	if (CThemed::IsThemeActive() && m_theme.LoadThemeFile(sThemeFile)) 		m_sThemeFile = sThemeFile;	else	{		m_sThemeFile.Empty();		m_theme.Reset();	}		// update the UI	if (themeCur != m_theme)	{		m_cbQuickFind.DestroyWindow();		m_toolbar.DestroyWindow();		m_tbHelper.Release();		InitToolbar();		// reinitialize the menu icon manager		m_mgrMenuIcons.Release();		InitMenuIconManager();	}	else		m_toolbar.SetBackgroundColors(m_theme.crToolbarLight, 										m_theme.crToolbarDark, 										m_theme.HasGradient(), 										m_theme.HasGlass());	m_statusBar.SetUIColors(m_theme.crStatusBarLight, 							m_theme.crStatusBarDark, 							m_theme.crStatusBarText, 							m_theme.HasGradient(), 							m_theme.HasGlass());	m_menubar.SetBackgroundColor(m_theme.crMenuBack);	m_filterBar.SetUIColors(m_theme.crAppBackLight, m_theme.crAppText);	m_tabCtrl.SetBackgroundColor(m_theme.crAppBackDark);	for (int nCtl = 0; nCtl < GetTDCCount(); nCtl++)	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtl);		tdc.SetUITheme(m_theme);	}	if (m_findDlg.GetSafeHwnd())		m_findDlg.SetUITheme(m_theme);	DrawMenuBar();	Invalidate();}BOOL CToDoListWnd::Create(const TDCSTARTUP& startup){	m_startupOptions = startup;	m_bVisible = startup.HasFlag(TLD_FORCEVISIBLE) ? 1 : -1;	m_bUseStagingScript = startup.HasFlag(TLD_STAGING);#ifdef _DEBUG	m_bPasswordPrompting = FALSE;#else	m_bPasswordPrompting = startup.HasFlag(TLD_PASSWORDPROMPTING);#endif	FileMisc::EnableLogging(startup.HasFlag(TLD_LOGGING), TRUE, FALSE);		return CFrameWnd::LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, NULL, NULL);}int CToDoListWnd::GetVersion(){	return TD_VERSION;}int CToDoListWnd::MessageBox(UINT nIDText, UINT nIDCaption, UINT nType, LPCTSTR szData){	if (szData && *szData)		return MessageBox(CEnString(nIDText, szData), nIDCaption, nType);	else		return MessageBox(CEnString(nIDText), nIDCaption, nType);}int CToDoListWnd::MessageBox(const CString& sText, UINT nIDCaption, UINT nType){	return MessageBox(sText, CEnString(nIDCaption), nType);}int CToDoListWnd::MessageBox(const CString& sText, const CString& sCaption, UINT nType){	CString sMessage;	if (!sCaption.IsEmpty())		sMessage.Format(_T("%s|%s"), sCaption, sText);	else		sMessage = sText;	return AfxMessageBox(sMessage, nType);}int CToDoListWnd::OnCreate(LPCREATESTRUCT lpCreateStruct){	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)		return -1;		// set frame icon	HICON hIcon = GraphicsMisc::LoadIcon(IDR_MAINFRAME);	SetIcon(hIcon, FALSE);			// set taskbar icon	hIcon = GraphicsMisc::LoadIcon(IDR_MAINFRAME, 32);	SetIcon(hIcon, TRUE);	SetWindowPos(NULL, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE);	// menu	if (!LoadMenubar())		return -1;	// drop target	if (!m_dropTarget.Register(this, this))		return -1;	// trayicon	// we always create the trayicon (for simplicity) but we only	// show it if required	BOOL bUseSysTray = Prefs().GetUseSysTray();		m_trayIcon.Create(WS_CHILD | (bUseSysTray ? WS_VISIBLE : 0), 						this, 						IDC_TRAYICON, 						IDI_TRAY_STD, 						CString(IDS_COPYRIGHT));		// toolbar	if (!InitToolbar())		return -1;	// statusbar	if (!InitStatusbar())		return -1;	// filterbar	if (!InitFilterbar())		return -1;		// tabctrl	if (!m_tabCtrl.Create(WS_CHILD | WS_VISIBLE | TCS_HOTTRACK | TCS_TABS | TCS_SINGLELINE | TCS_RIGHTJUSTIFY | TCS_TOOLTIPS, 							CRect(0, 0, 10, 10), this, IDC_TABCONTROL))		return -1;	m_tabCtrl.GetToolTips()->ModifyStyle(0, TTS_ALWAYSTIP);	CLocalizer::EnableTranslation(m_tabCtrl, FALSE);	BOOL bStackTabbar = Prefs().GetStackTabbarItems();		m_tabCtrl.ModifyStyle(bStackTabbar ? 0 : TCS_MULTILINE, bStackTabbar ? TCS_MULTILINE : 0);	UpdateTabSwitchTooltip();		if (m_ilTabCtrl.Create(16, 16, ILC_COLOR32 | ILC_MASK, 4, 1))	{		CBitmap bm;		bm.LoadBitmap(IDB_SOURCECONTROL_STD);		m_ilTabCtrl.Add(&bm, RGB(255, 0, 255));		m_tabCtrl.SetImageList(&m_ilTabCtrl);	}	else		return -1;		// UI Font	InitUIFont();	LoadSettings();	// add a barebones tasklist while we‘re still hidden	if (!CreateNewTaskList(FALSE))		return -1;	// timers	SetTimer(TIMER_DUEITEMS, TRUE);	SetTimer(TIMER_TIMETRACKING, TRUE);	// notify users about dodgy content plugins	if (m_mgrContent.SomePluginsHaveBadversions())	{		if (MessageBox(IDS_BADPLUGINVERSIONS, IDS_BADPLUGINTITLE, MB_OKCANCEL) == IDCANCEL)			return -1;	}	// inherited parent task attributes for new tasks	CTDCAttributeArray aParentAttrib;	BOOL bUpdateAttrib;	Prefs().GetParentAttribsUsed(aParentAttrib, bUpdateAttrib);	CFilteredToDoCtrl::SetInheritedParentAttributes(aParentAttrib, bUpdateAttrib);	// theme	SetUITheme(Prefs().GetUITheme());					// late initialization	PostMessage(WM_POSTONCREATE);		return 0; // success}void CToDoListWnd::InitUIFont(){	GraphicsMisc::VerifyDeleteObject(m_fontMain);	HFONT hFontUI = GraphicsMisc::CreateFont(_T("Tahoma"), 8);	if (m_fontMain.Attach(hFontUI))		CDialogHelper::SetFont(this, m_fontMain); // will update all child controls}void CToDoListWnd::InitShortcutManager(){	// setup defaults first	m_mgrShortcuts.AddShortcut(ID_LOAD_NORMAL, ‘O‘, HOTKEYF_CONTROL); 	m_mgrShortcuts.AddShortcut(ID_OPEN_RELOAD, ‘R‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_SAVE_NORMAL, ‘S‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_NEWTASK_BEFORESELECTEDTASK, ‘N‘, HOTKEYF_CONTROL | HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_NEWTASK_AFTERSELECTEDTASK, ‘N‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_NEWSUBTASK_ATBOTTOM, ‘N‘, HOTKEYF_CONTROL | HOTKEYF_SHIFT);	m_mgrShortcuts.AddShortcut(ID_MAXTASKLIST, ‘M‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_MAXCOMMENTS, ‘M‘, HOTKEYF_CONTROL | HOTKEYF_SHIFT);	m_mgrShortcuts.AddShortcut(ID_PRINT, ‘P‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_VIEW_NEXT, VK_TAB, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_VIEW_PREV, VK_TAB, HOTKEYF_CONTROL | HOTKEYF_SHIFT);	m_mgrShortcuts.AddShortcut(ID_EDIT_CUT, ‘X‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EDIT_COPY, ‘C‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EDIT_PASTEAFTER, ‘V‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EDIT_PASTESUB, ‘V‘, HOTKEYF_CONTROL | HOTKEYF_SHIFT);	m_mgrShortcuts.AddShortcut(ID_EDIT_INSERTDATETIME, ‘D‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EDIT_OPENFILEREF, ‘G‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EXIT, VK_F4, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_CLOSE, VK_F4, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_MOVETASKDOWN, VK_DOWN, HOTKEYF_CONTROL | HOTKEYF_EXT);	m_mgrShortcuts.AddShortcut(ID_MOVETASKUP, VK_UP, HOTKEYF_CONTROL | HOTKEYF_EXT);	m_mgrShortcuts.AddShortcut(ID_MOVETASKLEFT, VK_LEFT, HOTKEYF_CONTROL | HOTKEYF_EXT);	m_mgrShortcuts.AddShortcut(ID_MOVETASKRIGHT, VK_RIGHT, HOTKEYF_CONTROL | HOTKEYF_EXT);	m_mgrShortcuts.AddShortcut(ID_DELETETASK, VK_DELETE, HOTKEYF_EXT);	m_mgrShortcuts.AddShortcut(ID_EDIT_TASKTEXT, VK_F2, 0);	m_mgrShortcuts.AddShortcut(ID_EDIT_TASKDONE, VK_SPACE, HOTKEYF_CONTROL | HOTKEYF_SHIFT);	m_mgrShortcuts.AddShortcut(ID_TOOLS_IMPORT, ‘I‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_TOOLS_EXPORT, ‘E‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_HELP, VK_F1, 0);	m_mgrShortcuts.AddShortcut(ID_WINDOW1, ‘1‘, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_WINDOW2, ‘2‘, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_WINDOW3, ‘3‘, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_WINDOW4, ‘4‘, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_WINDOW5, ‘5‘, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_WINDOW6, ‘6‘, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_WINDOW7, ‘7‘, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_WINDOW8, ‘8‘, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_WINDOW9, ‘9‘, HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_TOOLS_TRANSFORM, ‘T‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EDIT_FINDTASKS, ‘F‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EDIT_QUICKFIND, ‘Q‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EDIT_QUICKFINDNEXT, VK_F3, 0);	m_mgrShortcuts.AddShortcut(ID_EDIT_QUICKFINDPREV, VK_F3, HOTKEYF_SHIFT);	m_mgrShortcuts.AddShortcut(ID_VIEW_REFRESHFILTER, VK_F5, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_VIEW_TOGGLEFILTER, VK_F12, 0);	m_mgrShortcuts.AddShortcut(ID_EDIT_SELECTALL, ‘A‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_PREVTASK, VK_F7, 0);	m_mgrShortcuts.AddShortcut(ID_NEXTTASK, VK_F8, 0);	m_mgrShortcuts.AddShortcut(ID_EDIT_UNDO, ‘Z‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EDIT_REDO, ‘Y‘, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_VIEW_TOGGLETREEANDLIST, VK_F10, 0);	m_mgrShortcuts.AddShortcut(ID_VIEW_CYCLETASKVIEWS, VK_F10, HOTKEYF_SHIFT);	m_mgrShortcuts.AddShortcut(ID_VIEW_TOGGLETASKSANDCOMMENTS, VK_F11, 0);	m_mgrShortcuts.AddShortcut(ID_VIEW_TOGGLETASKEXPANDED, VK_SPACE, HOTKEYF_CONTROL | HOTKEYF_ALT);	m_mgrShortcuts.AddShortcut(ID_EDIT_INCTASKPERCENTDONE, VK_ADD, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_EDIT_DECTASKPERCENTDONE, VK_SUBTRACT, HOTKEYF_CONTROL);	m_mgrShortcuts.AddShortcut(ID_VIEW_PREV_SEL, VK_LEFT, HOTKEYF_ALT | HOTKEYF_EXT);	m_mgrShortcuts.AddShortcut(ID_VIEW_NEXT_SEL, VK_RIGHT, HOTKEYF_ALT | HOTKEYF_EXT);		// now init shortcut mgr which will override the defaults	// with the users actual settings	CPreferences prefs;	if (m_mgrShortcuts.Initialize(this, &prefs))	{		// fix for previously adding escape key as a shortcut for IDCLOSE 		// (big mistake)		if (m_mgrShortcuts.GetShortcut(IDCLOSE) == VK_ESCAPE)			m_mgrShortcuts.DeleteShortcut(IDCLOSE);		// fix for paste being wrongly set up		if (m_mgrShortcuts.GetShortcut(ID_EDIT_PASTE))		{			// delete existing			m_mgrShortcuts.DeleteShortcut(ID_EDIT_PASTE);			// if nothing already assigned use Ctrl+V			if (!m_mgrShortcuts.GetShortcut(ID_EDIT_PASTESUB))				m_mgrShortcuts.AddShortcut(ID_EDIT_PASTESUB, ‘V‘, HOTKEYF_CONTROL);		}	}}void CToDoListWnd::InitMenuIconManager(){	if (!m_mgrMenuIcons.Initialize(this))		return;		m_mgrMenuIcons.ClearImages();		// images	UINT nToolbarImageID = IDB_APP_TOOLBAR_STD;	UINT nExtraImageID = IDB_APP_EXTRA_STD;					CUIntArray aCmdIDs;		// toolbar	aCmdIDs.Add(ID_LOAD_NORMAL);	aCmdIDs.Add(ID_SAVE_NORMAL);	aCmdIDs.Add(ID_SAVEALL);		// new tasks	aCmdIDs.Add(GetNewTaskCmdID());	aCmdIDs.Add(GetNewSubtaskCmdID());		aCmdIDs.Add(ID_EDIT_TASKTEXT);	aCmdIDs.Add(ID_EDIT_SETTASKICON);	aCmdIDs.Add(ID_EDIT_SETREMINDER);	aCmdIDs.Add(ID_EDIT_UNDO);	aCmdIDs.Add(ID_EDIT_REDO);	aCmdIDs.Add(ID_MAXTASKLIST);	aCmdIDs.Add(ID_VIEW_EXPANDTASK);	aCmdIDs.Add(ID_VIEW_COLLAPSETASK);	aCmdIDs.Add(ID_VIEW_PREV_SEL);	aCmdIDs.Add(ID_VIEW_NEXT_SEL);	aCmdIDs.Add(ID_EDIT_FINDTASKS);	aCmdIDs.Add(ID_SORT);	aCmdIDs.Add(ID_DELETETASK);		// source control	if (GetTDCCount() && m_mgrToDoCtrls.PathSupportsSourceControl(GetSelToDoCtrl()))	{		CFilteredToDoCtrl& tdc = GetToDoCtrl();		if (tdc.IsCheckedOut())			aCmdIDs.Add(ID_TOOLS_CHECKIN);		else			aCmdIDs.Add(ID_TOOLS_CHECKOUT);	}	else		aCmdIDs.Add(ID_TOOLS_TOGGLECHECKIN);			aCmdIDs.Add(ID_PREFERENCES);	if (m_theme.HasToolbarImageFile(_T("TODOLIST")))	{		COLORREF crMask = CLR_NONE;		CString sImagePath = m_theme.GetToolbarImageFile(_T("TODOLIST"), crMask);		VERIFY(m_mgrMenuIcons.AddImages(aCmdIDs, sImagePath, 16, crMask));	}	else		m_mgrMenuIcons.AddImages(aCmdIDs, nToolbarImageID, 16, RGB(255, 0, 255));	// extra	aCmdIDs.RemoveAll();  	aCmdIDs.Add(ID_HELP_WIKI);  	aCmdIDs.Add(ID_HELP_DONATE);  	aCmdIDs.Add(ID_HELP);	if (m_theme.HasToolbarImageFile(_T("TODOLIST_EXTRA")))	{		COLORREF crMask = CLR_NONE;		CString sImagePath = m_theme.GetToolbarImageFile(_T("TODOLIST_EXTRA"), crMask);		VERIFY(m_mgrMenuIcons.AddImages(aCmdIDs, sImagePath, 16, crMask));	}	else		m_mgrMenuIcons.AddImages(aCmdIDs, nExtraImageID, 16, RGB(255, 0, 255));}void CToDoListWnd::OnShowKeyboardshortcuts() {	CStringArray aMapping;	if (m_mgrShortcuts.BuildMapping(IDR_MAINFRAME, aMapping, ‘|‘))	{		// add a few misc items that don‘t appear in the menus		CString sMisc;		for (int nItem = 0; nItem < NUM_MISCSHORTCUTS; nItem++)		{			if (MISC_SHORTCUTS[nItem].dwShortcut)				sMisc.Format(_T("%s|%s"), m_mgrShortcuts.GetShortcutText(MISC_SHORTCUTS[nItem].dwShortcut), 									CEnString(MISC_SHORTCUTS[nItem].nIDShortcut));			else				sMisc.Empty();			aMapping.Add(sMisc);		}			CKeyboardShortcutDisplayDlg dialog(aMapping, ‘|‘);		dialog.DoModal();	}}LRESULT CToDoListWnd::OnFocusChange(WPARAM wp, LPARAM /*lp*/){	if (m_statusBar.GetSafeHwnd() && IsWindowEnabled() && GetTDCCount() && wp)	{		// grab the previous window in the z-order and if its		// static text then use that as the focus hint		CWnd* pFocus = CWnd::FromHandle((HWND)wp);		const CFilteredToDoCtrl& tdc = GetToDoCtrl();		m_sCurrentFocus.Empty();		if (CDialogHelper::IsChildOrSame(tdc.GetSafeHwnd(), (HWND)wp))		{			m_sCurrentFocus.LoadString(IDS_FOCUS_TASKS);			m_sCurrentFocus += ": ";			m_sCurrentFocus += tdc.GetControlDescription(pFocus);		}		else if (pFocus == m_cbQuickFind.GetWindow(GW_CHILD))		{			m_sCurrentFocus.LoadString(IDS_QUICKFIND);		}		else		{			if (m_findDlg.GetSafeHwnd() && m_findDlg.IsChild(pFocus))			{				m_sCurrentFocus.LoadString(IDS_FINDTASKS);			}			else if (m_filterBar.GetSafeHwnd() && m_filterBar.IsChild(pFocus))			{				m_sCurrentFocus.LoadString(IDS_FOCUS_FILTERBAR);			}						if (!m_sCurrentFocus.IsEmpty())				m_sCurrentFocus += ": ";						m_sCurrentFocus += GetControlLabel(pFocus);		}				// limit length of string		if (m_sCurrentFocus.GetLength() > 22)			m_sCurrentFocus = m_sCurrentFocus.Left(20) + _T("...");		m_statusBar.SetPaneText(m_statusBar.CommandToIndex(ID_SB_FOCUS), m_sCurrentFocus);				// if the status bar is hidden then add text to title bar		if (!m_bShowStatusBar)			UpdateCaption();	}	return 0L;}LRESULT CToDoListWnd::OnGetIcon(WPARAM bLargeIcon, LPARAM /*not used*/){	if (!bLargeIcon)	{		// cache small icon for reuse		if (!m_hIcon)			m_hIcon = CSysImageList(FALSE).ExtractAppIcon();				return (LRESULT)m_hIcon;	}	else		return Default();}BOOL CToDoListWnd::InitStatusbar(){	static SBACTPANEINFO SB_PANES[] = 	{	  { ID_SB_FILEPATH,		MAKEINTRESOURCE(IDS_SB_FILEPATH_TIP), SBACTF_STRETCHY | SBACTF_RESOURCETIP }, 	  { ID_SB_FILEVERSION,	MAKEINTRESOURCE(IDS_SB_FILEVERSION_TIP), SBACTF_AUTOFIT | SBACTF_RESOURCETIP }, 	  { ID_SB_TASKCOUNT,	MAKEINTRESOURCE(IDS_SB_TASKCOUNT_TIP), SBACTF_AUTOFIT | SBACTF_RESOURCETIP }, 	  //{ ID_SB_SPACER }, 	  { ID_SB_SELCOUNT,		MAKEINTRESOURCE(0), SBACTF_AUTOFIT | SBACTF_RESOURCETIP }, 	  { ID_SB_SELTIMEEST,	MAKEINTRESOURCE(IDS_SB_SELTIMEEST_TIP), SBACTF_AUTOFIT | SBACTF_RESOURCETIP }, 	  { ID_SB_SELTIMESPENT,	MAKEINTRESOURCE(IDS_SB_SELTIMESPENT_TIP), SBACTF_AUTOFIT | SBACTF_RESOURCETIP }, 	  { ID_SB_SELCOST,		MAKEINTRESOURCE(IDS_SB_SELCOST_TIP), SBACTF_AUTOFIT | SBACTF_RESOURCETIP }, 	  //{ ID_SB_SPACER }, 	  { ID_SB_FOCUS,		MAKEINTRESOURCE(IDS_SB_FOCUS_TIP), SBACTF_AUTOFIT | SBACTF_RESOURCETIP }, 	};	static int SB_PANECOUNT = sizeof(SB_PANES) / sizeof(SBACTPANEINFO);	if (!m_statusBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, IDC_FILENAME))		return FALSE;	// prevent translation because we handle it manually	CLocalizer::EnableTranslation(m_statusBar, FALSE);	if (!m_statusBar.SetPanes(SB_PANES, SB_PANECOUNT))		return FALSE;	return TRUE;}BOOL CToDoListWnd::InitFilterbar(){	if (!m_filterBar.Create(this))		return FALSE;	m_filterBar.EnableMultiSelection(Prefs().GetMultiSelFilters());	m_filterBar.ShowDefaultFilters(Prefs().GetShowDefaultFilters());	RefreshFilterBarCustomFilters();	return TRUE;}BOOL CToDoListWnd::InitToolbar(){	if (m_toolbar.GetSafeHwnd())		return TRUE;	UINT nStyle = WS_CHILD | CBRS_ALIGN_TOP | WS_CLIPCHILDREN | CBRS_TOOLTIPS;	if (m_bShowToolbar)		nStyle |= WS_VISIBLE;	if (!m_toolbar.CreateEx(this, TBSTYLE_FLAT | TBSTYLE_WRAPABLE, nStyle))		return FALSE;	if (!m_toolbar.LoadToolBar(IDR_APP_TOOLBAR))		return FALSE;	// colors	if (CThemed::IsThemeActive())	{		m_toolbar.SetBackgroundColors(m_theme.crToolbarLight, 												m_theme.crToolbarDark, 												m_theme.HasGradient(), 												m_theme.HasGlass());	}		// toolbar images	if (m_theme.HasToolbarImageFile(_T("TODOLIST")))	{		COLORREF crMask = CLR_NONE;		CString sImagePath = m_theme.GetToolbarImageFile(_T("TODOLIST"), crMask);		VERIFY(m_toolbar.SetImage(sImagePath, crMask));	}	else 	{		const COLORREF MAGENTA = RGB(255, 0, 255);		m_toolbar.SetImage(IDB_APP_TOOLBAR_STD, MAGENTA);	}		// resize the toolbar in one row so that our subsequent calculations work	m_toolbar.GetToolBarCtrl().HideButton(ID_TOOLS_TOGGLECHECKIN, !Prefs().GetEnableSourceControl());	m_toolbar.MoveWindow(0, 0, 1000, 32); 		// insert combobox for quick Find after Find Tasks button	int nPos = m_toolbar.CommandToIndex(ID_EDIT_FINDTASKS) + 1;		TBBUTTON tbbQuickFind = { 0, nPos, 0, TBSTYLE_SEP, 0, NULL };	TBBUTTON tbbSep = { 0, nPos + 1, 0, TBSTYLE_SEP, 0, NULL };		m_toolbar.GetToolBarCtrl().InsertButton(nPos, &tbbQuickFind);	m_toolbar.GetToolBarCtrl().InsertButton(nPos + 1, &tbbSep);		TBBUTTONINFO tbi;	tbi.cbSize = sizeof( TBBUTTONINFO );	tbi.cx = 150;	tbi.dwMask = TBIF_SIZE;  // By index		m_toolbar.GetToolBarCtrl().SetButtonInfo(nPos + 1, &tbi);		CRect rect;	m_toolbar.GetToolBarCtrl().GetItemRect(nPos + 1, &rect);	rect.bottom += 200;		if (!m_cbQuickFind.Create(WS_CHILD | WS_VSCROLL | WS_VISIBLE | CBS_AUTOHSCROLL | 		CBS_DROPDOWN, rect, &m_toolbar, IDC_QUICKFIND))		return FALSE;		m_cbQuickFind.SetFont(&m_fontMain);	m_mgrPrompts.SetComboEditPrompt(m_cbQuickFind, IDS_QUICKFIND);		m_tbHelper.Initialize(&m_toolbar, this);		return TRUE;}void CToDoListWnd::OnEditChangeQuickFind(){	m_cbQuickFind.GetWindowText(m_sQuickFind);		if (!GetToDoCtrl().SelectTask(m_sQuickFind, TDC_SELECTNEXTINCLCURRENT))		GetToDoCtrl().SelectTask(m_sQuickFind, TDC_SELECTFIRST);}void CToDoListWnd::OnSelChangeQuickFind(){	int nSel = m_cbQuickFind.GetCurSel();	if (nSel != CB_ERR)	{		m_sQuickFind = CDialogHelper::GetSelectedItem(m_cbQuickFind);				if (!GetToDoCtrl().SelectTask(m_sQuickFind, TDC_SELECTNEXT))			GetToDoCtrl().SelectTask(m_sQuickFind, TDC_SELECTFIRST);	}}BOOL CToDoListWnd::PreTranslateMessage(MSG* pMsg){	// the only way we get a WM_CLOSE here is if it was sent from an external app	// so we shut down as gracefully as possible	if (pMsg->message == WM_CLOSE && IsWindowEnabled())	{		DoExit();		return TRUE;	}		if (ProcessDialogControlShortcut(pMsg))		return TRUE;	if (IsDroppedComboBox(pMsg->hwnd))		return FALSE;		// process for app level shortcuts first so we can handle	// reserved shortcuts	DWORD dwShortcut = 0;	UINT nCmdID = m_mgrShortcuts.ProcessMessage(pMsg, &dwShortcut);		// if it‘s a reserved shortcut let‘s notify the user to change it	if (CFilteredToDoCtrl::IsReservedShortcut(dwShortcut))	{		int nRet = MessageBox(IDS_RESERVEDSHORTCUT_MSG, IDS_RESERVEDSHORTCUT_TITLE, MB_YESNOCANCEL);				if (nRet == IDYES)			DoPreferences(PREFPAGE_SHORTCUT);				// and keep eating it until the user changes it		return TRUE;	}		// also we handle undo/redo	if (nCmdID != ID_EDIT_UNDO && nCmdID != ID_EDIT_REDO)	{		// now try active task list		if (GetTDCCount() && GetToDoCtrl().PreTranslateMessage(pMsg))			return TRUE;	}		if (nCmdID)	{		BOOL bSendMessage = TRUE; // default				// focus checks		switch (nCmdID)		{		case ID_EDIT_CUT:		case ID_EDIT_COPY:			// tree must have the focus			if (!GetToDoCtrl().TasksHaveFocus())			{				bSendMessage = FALSE;				GetToDoCtrl().ClearCopiedItem();			}			break;						// tree must have the focus		case ID_EDIT_SELECT_ALL: 		case ID_EDIT_PASTE: 		case ID_DELETEALLTASKS:		case ID_DELETETASK:			bSendMessage = GetToDoCtrl().TasksHaveFocus();			break;		}				// send off		if (bSendMessage)		{			SendMessage(WM_COMMAND, nCmdID);			return TRUE;		}	}		// we need to check for <escape>, <tab> and <return>	switch (pMsg->message)	{	case WM_KEYDOWN:		{			switch (pMsg->wParam)			{			case VK_ESCAPE:				if (Prefs().GetEscapeMinimizes() && GetCapture() == NULL)				{					// if the window with the target is either a combobox or					// the child edit of a combobox and the combo is					// dropped down then let it thru else if the target is					// a child of ours then treat as a cancel					BOOL bHandle = TRUE;										if (CWinClasses::IsClass(pMsg->hwnd, WC_COMBOBOX))						bHandle = !ComboBox_GetDroppedState(pMsg->hwnd);										else if (CWinClasses::IsClass(::GetParent(pMsg->hwnd), WC_COMBOBOX))						bHandle = !ComboBox_GetDroppedState(::GetParent(pMsg->hwnd));										else if (GetTDCCount() && GetToDoCtrl().IsTaskLabelEditing())						bHandle = FALSE;										if (bHandle && ::IsChild(*this, pMsg->hwnd))					{						OnCancel();						return TRUE;					}				}				break;							case VK_TAB: // tabbing away from Quick Find -> tasks				if (::IsChild(m_cbQuickFind, pMsg->hwnd))				{					GetToDoCtrl().SetFocusToTasks();					return TRUE;				}				break;							case VK_RETURN: // hitting return in filter bar and quick find				if (Prefs().GetFocusTreeOnEnter())				{					CWnd* pFocus = GetFocus();										if (pFocus && (m_filterBar.IsChild(pFocus) || m_cbQuickFind.IsChild(pFocus)))					{						if (!ControlWantsEnter(*pFocus))							GetToDoCtrl().SetFocusToTasks();						return FALSE; // continue routing					}				}				break;			}		}		break;	}		return CFrameWnd::PreTranslateMessage(pMsg);}void CToDoListWnd::OnCancel(){	ASSERT (Prefs().GetEscapeMinimizes());	// if the close button has been configured to Minimize to tray	// then do that here else normal minimize 	int nOption = Prefs().GetSysTrayOption();		if (nOption == STO_ONMINCLOSE || nOption == STO_ONCLOSE)		MinimizeToTray();	else		SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);}void CToDoListWnd::OnDeleteTask() {	if (GetToDoCtrl().GetSelectedItem())		GetToDoCtrl().DeleteSelectedTask();}void CToDoListWnd::OnDeleteAllTasks() {	if (GetToDoCtrl().DeleteAllTasks())	{//		m_mgrToDoCtrls.ClearFilePath(GetSelToDoCtrl()); // this will ensure that the user must explicitly overwrite the original file		UpdateStatusbar();	}}void CToDoListWnd::OnSave() {	if (SaveTaskList(GetSelToDoCtrl()) == TDCO_SUCCESS)		UpdateCaption();}BOOL CToDoListWnd::DoBackup(int nIndex){	if (!Prefs().GetBackupOnSave())		return TRUE;	CString sTDLPath = m_mgrToDoCtrls.GetFilePath(nIndex);	if (sTDLPath.IsEmpty())		return TRUE; // not yet saved	// get backup path	CString sBackupFolder = Prefs().GetBackupLocation(sTDLPath);	sBackupFolder.TrimRight();	// cull old backups	int nKeepBackups = Prefs().GetKeepBackupCount();	if (nKeepBackups)	{		CStringArray aFiles;		CString sPath = CFileBackup::BuildBackupPath(sTDLPath, sBackupFolder, FBS_APPVERSION, _T(""));		CString sDrive, sFolder, sFName, sExt, sPattern;		FileMisc::SplitPath(sPath, &sDrive, &sFolder, &sFName, &sExt);		FileMisc::MakePath(sPath, sDrive, sFolder);				int nFiles = FileMisc::FindFiles(sPath, aFiles, FALSE, sFName + _T("*") + sExt);		if (nFiles >= nKeepBackups)		{			Misc::SortArray(aFiles); // sorts oldest backups first			// cull as required			while (aFiles.GetSize() >= nKeepBackups)			{				DeleteFile(aFiles[0]);				aFiles.RemoveAt(0);			}		}	}	CFileBackup backup;	return backup.MakeBackup(sTDLPath, sBackupFolder, FBS_APPVERSION | FBS_TIMESTAMP, _T(""));}TDC_FILE CToDoListWnd::SaveTaskList(int nIndex, LPCTSTR szFilePath, BOOL bAuto){	CAutoFlag af(m_bSaving, TRUE);	CString sFilePath = szFilePath ? szFilePath : m_mgrToDoCtrls.GetFilePath(nIndex);	CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);	tdc.Flush();	// build dialog title, incorporating tasklist name	CString sName = m_mgrToDoCtrls.GetFriendlyProjectName(nIndex);	CEnString sTitle(IDS_SAVETASKLIST_TITLE, sName);		// conditions for saving	// 1. Save As... ie szFilePath != NULL and not empty	// 2. tasklist has been modified	if ((szFilePath && !sFilePath.IsEmpty()) || tdc.IsModified())	{		CPreferences prefs;				// do this in a loop in case the save fails for _any_ reason		while (TRUE)		{			if (sFilePath.IsEmpty()) // means first time save			{				// activate tasklist				if (!SelectToDoCtrl(nIndex, (nIndex != GetSelToDoCtrl())))					return TDCO_CANCELLED;								// use tab text as hint to user				sFilePath = m_mgrToDoCtrls.GetFilePath(nIndex, FALSE);				CFileSaveDialog dialog(sTitle, 										GetDefaultFileExt(), 										sFilePath, 										EOFN_DEFAULTSAVE, 										GetFileFilter(FALSE), 										this);								// get the user‘s last choice of saving new tasklists				// as the best hint for this time				BOOL bUnicode = prefs.GetProfileInt(PREF_KEY, _T("UnicodeNewTasklists"), TRUE);				dialog.m_ofn.nFilterIndex = (bUnicode ? 2 : 1);								if (dialog.DoModal(&prefs) != IDOK)					return TDCO_CANCELLED; // user elected not to proceed								// else make sure the file is not readonly				sFilePath = dialog.GetPathName();				// check for format change				bUnicode = (dialog.m_ofn.nFilterIndex == 2);				tdc.SetUnicode(bUnicode);						// save this choice as the best hint for the next new tasklist				prefs.WriteProfileInt(PREF_KEY, _T("UnicodeNewTasklists"), bUnicode);								// else make sure the file is not readonly				if (CDriveInfo::IsReadonlyPath(sFilePath) > 0)				{					CEnString sMessage(IDS_SAVEREADONLY, sFilePath);										if (MessageBox(sMessage, sTitle, MB_OKCANCEL) == IDCANCEL)						return TDCO_CANCELLED; // user elected not to proceed					else					{						sFilePath.Empty(); // try again						continue;					}				}			}			// back file up			DoBackup(nIndex);						// update source control status			const CPreferencesDlg& userPrefs = Prefs();			BOOL bSrcControl = m_mgrToDoCtrls.PathSupportsSourceControl(sFilePath);						tdc.SetStyle(TDCS_ENABLESOURCECONTROL, bSrcControl);			tdc.SetStyle(TDCS_CHECKOUTONLOAD, bSrcControl ? userPrefs.GetAutoCheckOut() : FALSE);						TDC_FILE nSave = TDCO_SUCCESS;			CTaskFile tasks;			// scoped to end status bar progress			// before calling UpdateStatusbar			{				DOPROGRESS(IDS_SAVINGPROGRESS)				nSave = tdc.Save(tasks, sFilePath);								// send to storage as appropriate				TSM_TASKLISTINFO storageInfo;								if (nSave == TDCO_SUCCESS && m_mgrToDoCtrls.GetStorageDetails(nIndex, storageInfo))				{					m_mgrStorage.StoreTasklist(&storageInfo, &tasks, -1, &prefs);				}			}			if (nSave == TDCO_SUCCESS)			{				m_mgrToDoCtrls.SetModifiedStatus(nIndex, FALSE);				m_mgrToDoCtrls.RefreshLastModified(nIndex);				m_mgrToDoCtrls.RefreshReadOnlyStatus(nIndex);				m_mgrToDoCtrls.RefreshPathType(nIndex);								if (userPrefs.GetAddFilesToMRU() && !m_mgrToDoCtrls.UsesStorage(nIndex))					m_mruList.Add(sFilePath);								UpdateCaption();				UpdateStatusbar();								// auto-export after saving				CString sExt;								if (userPrefs.GetAutoExport() && GetAutoExportExtension(sExt))				{					DOPROGRESS(IDS_EXPORTPROGRESS)					// construct output path					CString sExportPath = userPrefs.GetAutoExportFolderPath();					CString sDrive, sFolder, sFName;										FileMisc::SplitPath(sFilePath, &sDrive, &sFolder, &sFName);										if (!sExportPath.IsEmpty() && FileMisc::CreateFolder(sExportPath))						FileMisc::MakePath(sFilePath, NULL, sExportPath, sFName, sExt);					else						FileMisc::MakePath(sFilePath, sDrive, sFolder, sFName, sExt);										// The current contents of ‘tasks‘ is ‘All Tasks‘ and 					// ‘All Columns‘ but NOT ‘Html Comments‘.					// So if user either wants ‘Filtered Tasks‘ or ‘Html Comments‘ or					// only ‘Visible Columns‘ we need to grab the tasks again.					BOOL bFiltered = (userPrefs.GetExportFilteredOnly() && (tdc.HasCustomFilter() || tdc.HasFilter()));										if (bFiltered || userPrefs.GetExportToHTML() || !userPrefs.GetExportAllAttributes())					{						TSD_TASKS nWhatTasks = bFiltered ? TSDT_FILTERED : TSDT_ALL;						TDCGETTASKS filter;												if (!userPrefs.GetExportAllAttributes())						{							CTDCColumnIDArray aCols;							tdc.GetVisibleColumns(aCols);														MapColumnsToAttributes(aCols, filter.aAttribs);														// add comments always							filter.aAttribs.Add(TDCA_COMMENTS);						}												BOOL bHtmlComments = userPrefs.GetExportToHTML();						BOOL bTransform = FileMisc::FileExists(userPrefs.GetSaveExportStylesheet());												// set the html image folder to be the output path with						// an different extension						CString sImgFolder;												if (bHtmlComments)						{							sImgFolder = sFilePath;							FileMisc::ReplaceExtension(sImgFolder, _T("html_images"));						}												tasks.Reset();						GetTasks(tdc, bHtmlComments, bTransform, nWhatTasks, filter, 0, tasks, sImgFolder); 					}										// save intermediate tasklist to file as required					LogIntermediateTaskList(tasks, tdc.GetFilePath());					// want HTML 					if (userPrefs.GetExportToHTML())					{						Export2Html(tasks, sFilePath, userPrefs.GetSaveExportStylesheet());					}					else if (userPrefs.GetOtherExporter() != -1)					{						int nExporter = userPrefs.GetOtherExporter();						m_mgrImportExport.ExportTaskList(&tasks, sFilePath, nExporter, TRUE);					}				}								// we‘re done				break;			}			else if (!bAuto)			{				// error handling if this is not an auto-save				if (nSave == TDCO_NOTALLOWED)				{					CEnString sMessage(IDS_SAVEACCESSDENIED, sFilePath);										if (IDYES == MessageBox(sMessage, sTitle, MB_YESNOCANCEL | MB_ICONEXCLAMATION))					{						sFilePath.Empty(); // try again						continue;					}					else // clear modified status					{						tdc.SetModified(FALSE);						m_mgrToDoCtrls.SetModifiedStatus(nIndex, FALSE);						break;					}				}				else				{					CString sMessage;										switch (nSave)					{					case TDCO_CANCELLED:						break;											case TDCO_BADMSXML:						sMessage.Format(IDS_SAVEBADXML, sFilePath);						break;											case TDCO_INUSE:						sMessage.Format(IDS_SAVESHARINGVIOLATION, sFilePath);						break;											case TDCO_NOTCHECKEDOUT:						sMessage.Format(IDS_SAVENOTCHECKEDOUT, sFilePath);						break;											default:						sMessage.Format(IDS_UNKNOWNSAVEERROR2, sFilePath, (nSave - (int)TDCO_OTHER));						break;					}										if (!sMessage.IsEmpty())						MessageBox(sMessage, sTitle, MB_OK);				}				break; // we‘re done			}			else // bAuto == TRUE			{				break; // we‘re done			}		}	}	return TDCO_SUCCESS;}BOOL CToDoListWnd::GetAutoExportExtension(CString& sExt) const{	sExt.Empty();	if (Prefs().GetExportToHTML())		sExt = ".html";	else	{		int nExporter = Prefs().GetOtherExporter();		if (nExporter != -1)			sExt = m_mgrImportExport.GetExporterFileExtension(nExporter);	}	return !sExt.IsEmpty();}LPCTSTR CToDoListWnd::GetFileFilter(BOOL bOpen){	static CEnString TDLFILEOPENFILTER(IDS_TDLFILEOPENFILTER);	static CEnString XMLFILEOPENFILTER(IDS_XMLFILEOPENFILTER);	static CEnString TDLFILESAVEFILTER(IDS_TDLFILESAVEFILTER);	static CEnString XMLFILESAVEFILTER(IDS_XMLFILESAVEFILTER);		if (Prefs().GetEnableTDLExtension())		return bOpen ? TDLFILEOPENFILTER : TDLFILESAVEFILTER;		// else	return bOpen ? XMLFILEOPENFILTER : XMLFILESAVEFILTER;}LPCTSTR CToDoListWnd::GetDefaultFileExt(){	static LPCTSTR TDLEXT = _T("tdl");	static LPCTSTR XMLEXT = _T("xml");		if (Prefs().GetEnableTDLExtension())		return TDLEXT;	else		return XMLEXT;}void CToDoListWnd::UpdateStatusbar(){	if (!m_sbProgress.IsActive() && GetTDCCount())	{		// get display path		int nTasklist = GetSelToDoCtrl();		const CFilteredToDoCtrl& tdc = GetToDoCtrl(nTasklist);		CEnString sText = m_mgrToDoCtrls.GetDisplayPath(nTasklist);		if (sText.IsEmpty())			sText.LoadString(ID_SB_FILEPATH);				else if (tdc.IsUnicode())			sText += _T(" (Unicode)");				m_statusBar.SetPaneText(m_statusBar.CommandToIndex(ID_SB_FILEPATH), sText);		// get file version		sText.Format(ID_SB_FILEVERSION, tdc.GetFileVersion());		m_statusBar.SetPaneText(m_statusBar.CommandToIndex(ID_SB_FILEVERSION), sText);	}}void CToDoListWnd::OnLoad() {	CPreferences prefs;	CFileOpenDialog dialog(IDS_OPENTASKLIST_TITLE, 							GetDefaultFileExt(), 							NULL, 							EOFN_DEFAULTOPEN | OFN_ALLOWMULTISELECT,							GetFileFilter(TRUE), 							this);		const UINT BUFSIZE = 1024 * 5;	static TCHAR FILEBUF[BUFSIZE] = { 0 };		dialog.m_ofn.lpstrFile = FILEBUF;	dialog.m_ofn.nMaxFile = BUFSIZE;		if (dialog.DoModal(&prefs) == IDOK)	{		CWaitCursor cursor;		POSITION pos = dialog.GetStartPosition();				while (pos)		{			CString sTaskList = dialog.GetNextPathName(pos);			TDC_FILE nOpen = OpenTaskList(sTaskList);						if (nOpen == TDCO_SUCCESS)			{				Resize();				UpdateWindow();			}			else				HandleLoadTasklistError(nOpen, sTaskList);		}				RefreshTabOrder();	}}void CToDoListWnd::HandleLoadTasklistError(TDC_FILE nErr, LPCTSTR szTaskList){	CEnString sMessage, sTitle(IDS_OPENTASKLIST_TITLE);		switch (nErr)	{	case TDCO_SUCCESS:		break; // not an error!			case TDCO_CANCELLED:		break; 			case TDCO_NOTEXIST:		sMessage.Format(IDS_TASKLISTNOTFOUND, szTaskList);		break;			case TDCO_NOTTASKLIST:		sMessage.Format(IDS_INVALIDTASKLIST, szTaskList);		break;			case TDCO_NOTALLOWED:		sMessage.Format(IDS_OPENACCESSDENIED, szTaskList);		break;	case TDCO_INUSE:		sMessage.Format(IDS_OPENSHARINGVIOLATION, szTaskList);		break;			case TDCO_BADMSXML:		sMessage.Format(IDS_BADXML, szTaskList);		break;			case TDCO_NOENCRYPTIONDLL:		sMessage.Format(IDS_NOENCRYPTIONDLL, szTaskList);		break;			case TDCO_UNKNOWNENCRYPTION:		sMessage.Format(IDS_UNKNOWNENCRYPTION, szTaskList);		break;			default: // all the other errors		sMessage.Format(IDS_UNKNOWNOPENERROR, szTaskList, nErr - (int)TDCO_OTHER);		break;	}		if (!sMessage.IsEmpty())		MessageBox(sMessage, sTitle, MB_OK);}void CToDoListWnd::SaveSettings(){	CPreferences prefs;	// pos	WINDOWPLACEMENT wp;	GetWindowPlacement(&wp);		prefs.WriteProfileInt(_T("Pos"), _T("Left"), wp.rcNormalPosition.left);	prefs.WriteProfileInt(_T("Pos"), _T("Top"), wp.rcNormalPosition.top);	prefs.WriteProfileInt(_T("Pos"), _T("Right"), wp.rcNormalPosition.right);	prefs.WriteProfileInt(_T("Pos"), _T("Bottom"), wp.rcNormalPosition.bottom);// 	FileMisc::LogText(_T("SavePosition: TopLeft=(%d,%d) BotRight=(%d,%d) MinPos=(%d,%d) MaxPos=(%d,%d)"), // 						wp.rcNormalPosition.left, wp.rcNormalPosition.top,// 						wp.rcNormalPosition.right, wp.rcNormalPosition.bottom,// 						wp.ptMaxPosition.x, wp.ptMaxPosition.y,// 						wp.ptMinPosition.x, wp.ptMinPosition.y);	prefs.WriteProfileInt(_T("Pos"), _T("Hidden"), !m_bVisible);	prefs.WriteProfileInt(_T("Pos"), _T("Maximized"), IsZoomed());		// version	prefs.WriteProfileInt(_T("Version"), _T("Version"), GetVersion());		// last open files	int nCount = GetTDCCount();	int nSel = GetSelToDoCtrl(); // and last active file		if (nCount) // but don‘t overwrite files saved in OnQueryEndSession() or OnClose()	{		for (int nTDC = 0, nItem = 0; nTDC < nCount; nTDC++)		{			CString sFilePath = m_mgrToDoCtrls.GetFilePath(nTDC);			TSM_TASKLISTINFO storageInfo;			if (m_mgrToDoCtrls.GetStorageDetails(nTDC, storageInfo))			{				sFilePath = storageInfo.EncodeInfo(Prefs().GetSaveStoragePasswords());#ifdef _DEBUG				ASSERT(storageInfo.DecodeInfo(sFilePath));				ASSERT(storageInfo.EncodeInfo(TRUE) == sFilePath);#endif			}			else // make file paths relative			{				FileMisc::MakeRelativePath(sFilePath, FileMisc::GetAppFolder(), FALSE);			}			CString sKey = Misc::MakeKey(_T("LastFile%d"), nItem);			prefs.WriteProfileString(_T("Settings"), sKey, sFilePath);						if (nSel == nTDC)				prefs.WriteProfileString(_T("Settings"), _T("LastActiveFile"), sFilePath);			nItem++;		}				prefs.WriteProfileInt(_T("Settings"), _T("NumLastFiles"), nCount);	}	// other settings	prefs.WriteProfileInt(_T("Settings"), _T("ViewState"), m_nMaxState);	prefs.WriteProfileInt(_T("Settings"), _T("ShowFilterBar"), m_bShowFilterBar);	prefs.WriteProfileInt(_T("Settings"), _T("ToolbarOption"), m_bShowToolbar ? TB_TOOLBARANDMENU : TB_TOOLBARHIDDEN);	prefs.WriteProfileInt(_T("Settings"), _T("ShowProjectName"), m_bShowProjectName);	prefs.WriteProfileInt(_T("Settings"), _T("ShowStatusBar"), m_bShowStatusBar);	prefs.WriteProfileInt(_T("Settings"), _T("ShowTasklistBar"), m_bShowTasklistBar);	prefs.WriteProfileInt(_T("Settings"), _T("ShowTreeListBar"), m_bShowTreeListBar);	if (m_findDlg.GetSafeHwnd())		prefs.WriteProfileInt(_T("Settings"), _T("FindTasksVisible"), m_bFindShowing && m_findDlg.IsWindowVisible());		if (Prefs().GetAddFilesToMRU())		m_mruList.WriteList(prefs, TRUE);	// quick find items	nCount = m_cbQuickFind.GetCount();	prefs.WriteProfileInt(_T("QuickFind"), _T("Count"), nCount);	for (int nItem = 0; nItem < nCount; nItem++)	{		CString sItem, sKey = Misc::MakeKey(_T("Item%d"), nItem);		m_cbQuickFind.GetLBText(nItem, sItem);		prefs.WriteProfileString(_T("QuickFind"), sKey, sItem);	}	// save to permanent storage	prefs.Save();}LRESULT CToDoListWnd::OnWebUpdateWizard(WPARAM /*wp*/, LPARAM /*lp*/){	ASSERT (Prefs().GetAutoCheckForUpdates());	CheckForUpdates(FALSE);	return 0L;}LRESULT CToDoListWnd::OnAddToolbarTools(WPARAM /*wp*/, LPARAM /*lp*/){	Misc::ProcessMsgLoop();	AppendTools2Toolbar();	return 0L;}TDC_PREPAREPATH CToDoListWnd::PrepareFilePath(CString& sFilePath, TSM_TASKLISTINFO* pInfo){	TDC_PREPAREPATH nType = TDCPP_NONE;	TSM_TASKLISTINFO temp;	if (pInfo == NULL)		pInfo = &temp;	// first test for storage	if (pInfo->DecodeInfo(sFilePath, Prefs().GetSaveStoragePasswords()))	{		sFilePath = pInfo->szLocalFileName;		// check for overflow and non-existence		if (FileMisc::FileExists(sFilePath))			nType = TDCPP_STORAGE;		else			sFilePath.Empty();	}	// else it‘s a file path.	// if it starts with a colon then we need to find the removable drive it‘s stored on	else if (!sFilePath.IsEmpty())	{		if (sFilePath[0] == ‘:‘)		{			for (int nDrive = 4; nDrive <= 26; nDrive++) // from D: upwards			{				if (CDriveInfo::GetType(nDrive) == DRIVE_REMOVABLE)				{					CString sTryPath = CDriveInfo::GetLetter(nDrive) + sFilePath;					if (FileMisc::FileExists(sTryPath))					{						sFilePath = sTryPath;						break; // finished					}				}			}		}		else			FileMisc::MakeFullPath(sFilePath, FileMisc::GetAppFolder()); // handle relative paths		// check for existence		if (FileMisc::FileExists(sFilePath))			nType = TDCPP_FILE;		else			sFilePath.Empty();	}		return nType;}LRESULT CToDoListWnd::OnPostOnCreate(WPARAM /*wp*/, LPARAM /*lp*/){	// late initialization	CMouseWheelMgr::Initialize();	CEditShortcutMgr::Initialize();	CFocusWatcher::Initialize(this);	InitShortcutManager();	InitMenuIconManager();	// reminders	m_reminders.Initialize(this);	// with or without Stickies Support	const CPreferencesDlg& userPrefs = Prefs();	CString sStickiesPath;		if (userPrefs.GetUseStickies(sStickiesPath))		VERIFY(m_reminders.UseStickies(TRUE, sStickiesPath));		// light boxing 	if (Prefs().GetEnableLightboxMgr())		CLightBoxMgr::Initialize(this, m_theme.crAppBackDark);		// add outstanding translated items to dictionary	if (CLocalizer::GetTranslationOption() == ITTTO_ADD2DICTIONARY)	{		CUIntArray aDictVersion, aAppVersion;		VERIFY (FileMisc::GetAppVersion(aAppVersion));		BOOL bUpdateDict = !CLocalizer::GetDictionaryVersion(aDictVersion) ||							aDictVersion.GetSize() < 2;		if (!bUpdateDict)		{			// check if the major or minor version has increased			bUpdateDict = (FileMisc::CompareVersions(aAppVersion, aDictVersion, 2) > 0);			// check for pre-release build then update			if (!bUpdateDict && aAppVersion[2] >= 297)			{				// compare entire version string				bUpdateDict = (FileMisc::CompareVersions(aAppVersion, aDictVersion) > 0);			}		}		if (bUpdateDict)			TranslateUIElements();	}	RestoreVisibility();		// load last open tasklists	CAutoFlag af(m_bReloading, TRUE);	CPreferences prefs;	// initialize Progress first time	m_sbProgress.BeginProgress(m_statusBar, CEnString(IDS_STARTUPPROGRESS));	// open cmdline tasklist	int nTDCCount = prefs.GetProfileInt(_T("Settings"), _T("NumLastFiles"), 0);	if (!m_startupOptions.HasFilePath() || nTDCCount)	{		// if we have a file on the commandline or any previous tasklists		// set the prompt of the initial tasklist to something appropriate		//	TODO	}		// theme	SetUITheme(userPrefs.GetUITheme());	// cache empty flag for later	BOOL bStartupEmpty = m_startupOptions.HasFlag(TLD_STARTEMPTY);	// what to (re)load?	BOOL bReloadTasklists = (!bStartupEmpty && userPrefs.GetReloadTasklists());		// filepath overrides	if (m_startupOptions.HasFilePath())	{		ProcessStartupOptions(m_startupOptions);		// don‘t reload previous if a tasklist was actually loaded		if (!m_mgrToDoCtrls.IsPristine(0))			bReloadTasklists = FALSE;	}		m_startupOptions.Reset(); // always		// load last files	if (bReloadTasklists)	{		// get the last active tasklist		CString sLastActiveFile = prefs.GetProfileString(_T("Settings"), _T("LastActiveFile")), sOrgLastActiveFile;		BOOL bCanDelayLoad = userPrefs.GetEnableDelayedLoading();		for (int nTDC = 0; nTDC < nTDCCount; nTDC++)		{			CString sKey = Misc::MakeKey(_T("LastFile%d"), nTDC);			CString sLastFile = prefs.GetProfileString(_T("Settings"), sKey);			if (!sLastFile.IsEmpty())			{				// delay-open all but the non-active tasklist				// unless the tasklist has reminders				BOOL bActiveTDC = (sLastFile == sLastActiveFile);				if (!bActiveTDC && bCanDelayLoad && !m_reminders.ToDoCtrlHasReminders(sLastFile))				{					DelayOpenTaskList(sLastFile);				}				else				{					TDC_FILE nResult = OpenTaskList(sLastFile, FALSE);					// if the last active tasklist was cancelled then					// delay load it and mark the last active todoctrl as not found					if (bActiveTDC && nResult != TDCO_SUCCESS)					{						sOrgLastActiveFile = sLastActiveFile;						sLastActiveFile.Empty();						if (nResult == TDCO_CANCELLED && bCanDelayLoad)							DelayOpenTaskList(sLastFile);					}				}			}		}				// process all pending messages		Misc::ProcessMsgLoop();		// if the last active tasklist could not be loaded then we need to find another		if (GetTDCCount())		{			// make Last Active Files actual filepaths			PrepareFilePath(sLastActiveFile);			PrepareFilePath(sOrgLastActiveFile);			if (sLastActiveFile.IsEmpty())			{				for (int nTDC = 0; nTDC < GetTDCCount() && sLastActiveFile.IsEmpty(); nTDC++)				{					CFilteredToDoCtrl& tdc = GetToDoCtrl(nTDC);					// ignore original active tasklist					if (tdc.GetFilePath() != sOrgLastActiveFile)					{						if (VerifyTaskListOpen(nTDC, FALSE))							sLastActiveFile = tdc.GetFilePath();					}				}			}			// if nothing suitable found then create an empty tasklist			if (sLastActiveFile.IsEmpty())			{				if (GetTDCCount() == 0)					CreateNewTaskList(FALSE);			}			else if (!SelectToDoCtrl(sLastActiveFile, FALSE))				SelectToDoCtrl(0, FALSE); // the first one			Resize();		}	}	// if there‘s only one tasklist open and it‘s pristine then 	// it‘s the original one so add a sample task unless 	// ‘empty‘ flag is set	if (GetTDCCount() == 1 && m_mgrToDoCtrls.IsPristine(0))	{		if (!bStartupEmpty)		{			CFilteredToDoCtrl& tdc = GetToDoCtrl();			ASSERT (tdc.GetTaskCount() == 0);			tdc.CreateNewTask(CEnString(IDS_SAMPLETASK), TDC_INSERTATTOP, FALSE);			tdc.SetModified(FALSE);						m_mgrToDoCtrls.SetModifiedStatus(0, FALSE);			UpdateCaption();		}	}	else // due task notifications	{		int nDueBy = userPrefs.GetNotifyDueByOnLoad();				if (nDueBy != PFP_DONTNOTIFY)		{			UpdateWindow();			m_tabCtrl.UpdateWindow();						int nCtrls = GetTDCCount();						for (int nCtrl = 0; nCtrl < nCtrls; nCtrl++)			{				if (m_mgrToDoCtrls.IsLoaded(nCtrl))					DoDueTaskNotification(nCtrl, nDueBy);			}		}	}	// refresh toolbar ‘tools‘ buttons unless minimized because	// we must handle it when we‘re first shown	if (m_bShowToolbar && AfxGetApp()->m_nCmdShow != SW_SHOWMINIMIZED)		AppendTools2Toolbar();	// web update	if (Prefs().GetAutoCheckForUpdates())		PostMessage(WM_WEBUPDATEWIZARD);	// current focus	PostMessage(WM_FW_FOCUSCHANGE, (WPARAM)::GetFocus(), 0L);	RefreshTabOrder();	// end progress before refreshing statusbar	m_sbProgress.EndProgress();	UpdateStatusbar();	// find tasks dialog	InitFindDialog();	if (prefs.GetProfileInt(_T("Settings"), _T("FindTasksVisible"), 0))	{		OnFindTasks();				if (userPrefs.GetRefreshFindOnLoad())			m_findDlg.RefreshSearch();	}	// log the app and its dlls for debugging	FileMisc::LogAppModuleState(FBM_SORTBY_HMODULE);	return 0L;}void CToDoListWnd::CheckForUpdates(BOOL bManual){	CPreferences prefs;	// only check once a day	int nLastUpdate = prefs.GetProfileInt(_T("Updates"), _T("LastUpdate"), 0);	int nToday = (int)CDateHelper::GetDate(DHD_TODAY);	if (!bManual && nLastUpdate >= nToday)		return;	prefs.WriteProfileInt(_T("Updates"), _T("LastUpdate"), nToday);	// get the app wuw path	CString sFolder, sDrive;	CString sWuwPath = FileMisc::GetAppFolder() + _T("\\WebUpdateSvc.exe");	// check for existence if manual	if (bManual && !FileMisc::FileExists(sWuwPath))	{		LPCTSTR DOWNLOAD_WUW_PATH = _T("http://www.abstractspoon.com/todolist_wuw.zip");		if (MessageBox(IDS_NOWUW, 0, MB_YESNO) == IDYES)			::ShellExecute(NULL, _T("open"), DOWNLOAD_WUW_PATH, NULL, NULL, SW_HIDE);		else			return;	}	// because the download may include the WuW we copy it to a temp name	// so that the original can be overwritten.	CString sWuwPathTemp = FileMisc::GetAppFolder() + _T("\\WebUpdateSvc2.exe");	if (::CopyFile(sWuwPath, sWuwPathTemp, FALSE))		sWuwPath = sWuwPathTemp;	if (bManual)	{		if (m_bUseStagingScript)			::ShellExecute(NULL, _T("open"), sWuwPath, UPDATE_SCRIPT_PATH_STAGING, NULL, SW_HIDE);		else			::ShellExecute(NULL, _T("open"), sWuwPath, UPDATE_SCRIPT_PATH_MANUAL, NULL, SW_HIDE);	}	else		::ShellExecute(NULL, _T("open"), sWuwPath, UPDATE_SCRIPT_PATH, NULL, SW_HIDE);} 	void CToDoListWnd::LoadSettings(){	// settings	CPreferences prefs;	BOOL bMaxTasklists = prefs.GetProfileInt(_T("Settings"), _T("SimpleMode"), FALSE); // backward compatibility	m_nMaxState = (TDC_MAXSTATE)prefs.GetProfileInt(_T("Settings"), _T("ViewState"), bMaxTasklists ? TDCMS_MAXTASKLIST : TDCMS_NORMAL);	m_bShowFilterBar = prefs.GetProfileInt(_T("Settings"), _T("ShowFilterBar"), m_bShowFilterBar);	m_bShowProjectName = prefs.GetProfileInt(_T("Settings"), _T("ShowProjectName"), m_bShowProjectName);		m_bShowStatusBar = prefs.GetProfileInt(_T("Settings"), _T("ShowStatusBar"), m_bShowStatusBar);	m_statusBar.ShowWindow(m_bShowStatusBar ? SW_SHOW : SW_HIDE);		// toolbar	m_bShowToolbar = (prefs.GetProfileInt(_T("Settings"), _T("ToolbarOption"), TB_TOOLBARANDMENU) != TB_TOOLBARHIDDEN);	m_toolbar.ShowWindow(m_bShowToolbar ? SW_SHOW : SW_HIDE);	m_toolbar.EnableWindow(m_bShowToolbar);	// tabbars	m_bShowTasklistBar = prefs.GetProfileInt(_T("Settings"), _T("ShowTasklistBar"), TRUE);	m_bShowTreeListBar = prefs.GetProfileInt(_T("Settings"), _T("ShowTreeListBar"), TRUE);	// pos	RestorePosition();	// user preferences	const CPreferencesDlg& userPrefs = Prefs();		// MRU	if (userPrefs.GetAddFilesToMRU())		m_mruList.ReadList(prefs);		// note: we do not restore visibility until OnPostOnCreate	// default attributes	UpdateDefaultTaskAttributes(userPrefs);		// hotkey	UpdateGlobalHotkey();		// time periods	CTimeHelper::SetHoursInOneDay(userPrefs.GetHoursInOneDay());	CTimeHelper::SetDaysInOneWeek(userPrefs.GetDaysInOneWeek());	// support for .tdl	CFileRegister filereg(_T("tdl"), _T("tdl_Tasklist"));		if (userPrefs.GetEnableTDLExtension())		filereg.RegisterFileType(_T("Tasklist"), 0);	else		filereg.UnRegisterFileType();	// support for tdl protocol	EnableTDLProtocol(userPrefs.GetEnableTDLProtocol());	// previous quick find items	int nCount = prefs.GetProfileInt(_T("QuickFind"), _T("Count"), 0);	for (int nItem = 0; nItem < nCount; nItem++)	{		CString sKey = Misc::MakeKey(_T("Item%d"), nItem);		m_cbQuickFind.AddUniqueItem(prefs.GetProfileString(_T("QuickFind"), sKey));	}	// Recently modified period	CFilteredToDoCtrl::SetRecentlyModifiedPeriod(userPrefs.GetRecentlyModifiedPeriod());}void CToDoListWnd::EnableTDLProtocol(BOOL bEnable){	if (bEnable)	{		CRegKey reg;		if (reg.Open(HKEY_CLASSES_ROOT, _T("tdl")) == ERROR_SUCCESS)		{			reg.Write(_T(""), _T("URL: ToDoList protocol"));			reg.Write(_T("URL Protocol"), _T(""));			// write exe name out			CString sAppPath = FileMisc::GetAppFileName() + _T(" -l \"%1\"");			reg.Close();			if (reg.Open(HKEY_CLASSES_ROOT, _T("tdl\\shell\\open\\command")) == ERROR_SUCCESS)				reg.Write(_T(""), sAppPath);		}	}	else		CRegKey::DeleteKey(HKEY_CLASSES_ROOT, _T("tdl"));}void CToDoListWnd::RestoreVisibility(){	const CPreferencesDlg& userPrefs = Prefs();	CPreferences prefs;	int nDefShowState = AfxGetApp()->m_nCmdShow;	BOOL bShowOnStartup = userPrefs.GetShowOnStartup();	BOOL bMaximized = prefs.GetProfileInt(_T("Pos"), _T("Maximized"), FALSE) || (nDefShowState == SW_SHOWMAXIMIZED);	BOOL bMinimized = !bShowOnStartup && (nDefShowState == SW_SHOWMINIMIZED || nDefShowState == SW_SHOWMINNOACTIVE);		if (bMinimized)	{		bMaximized = FALSE; // can‘t be max-ed and min-ed		m_bStartHidden = TRUE;	}		if (m_bVisible == -1) // not yet set	{		m_bVisible = TRUE;				// the only reason it can be hidden is if it uses the systray		// and the user has elected to not have it show at startup		// and it was hidden the last time it closed or its set to run		// minimized and that is the trigger to hide it		if (!bShowOnStartup && userPrefs.GetUseSysTray())		{			if (prefs.GetProfileInt(_T("Pos"), _T("Hidden"), FALSE))				m_bVisible = FALSE;						// also if wp.showCmd == minimized and we would hide to sys			// tray when minimized then hide here too			else if (nDefShowState == SW_SHOWMINIMIZED || nDefShowState == SW_SHOWMINNOACTIVE)			{				int nSysTrayOption = Prefs().GetSysTrayOption();								if (nSysTrayOption == STO_ONMINIMIZE || nSysTrayOption == STO_ONMINCLOSE)					m_bVisible = FALSE;			}		}	}		if (m_bVisible)	{		int nShowCmd = (bMaximized ? SW_SHOWMAXIMIZED : 						(bMinimized ? SW_SHOWMINIMIZED : SW_SHOW));		 		ShowWindow(nShowCmd); 		Invalidate(); 		UpdateWindow();	}	else		m_bStartHidden = TRUE;	// don‘t set topmost if maximized	if (userPrefs.GetAlwaysOnTop() && !bMaximized)		SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);}void CToDoListWnd::RestorePosition(){	CPreferences prefs;	int nLeft = prefs.GetProfileInt(_T("Pos"), _T("Left"), -1);	int nTop = prefs.GetProfileInt(_T("Pos"), _T("Top"), -1);	int nRight = prefs.GetProfileInt(_T("Pos"), _T("Right"), -1);	int nBottom = prefs.GetProfileInt(_T("Pos"), _T("Bottom"), -1);		CRect rect(nLeft, nTop, nRight, nBottom);		if (rect.Width() > 0 && rect.Height() > 0)	{		// ensure this intersects with the desktop by a decent amount		int BORDER = 200;		rect.DeflateRect(BORDER, BORDER);		CRect rScreen;		if (GraphicsMisc::GetAvailableScreenSpace(rect, rScreen))		{			rect.InflateRect(BORDER, BORDER);			// because the position was saved using the results of 			// GetWindowPlacement we must use SetWindowPlacement			// to restore the window			WINDOWPLACEMENT wp = { 0 };			wp.rcNormalPosition = rect;			wp.ptMaxPosition.x = -1;			wp.ptMaxPosition.y = -1;			wp.ptMinPosition.x = -1;			wp.ptMinPosition.y = -1;// 			FileMisc::LogText(_T("RestorePosition: TopLeft=(%d,%d) BotRight=(%d,%d) MinPos=(%d,%d) MaxPos=(%d,%d)"), // 								wp.rcNormalPosition.left, wp.rcNormalPosition.top,// 								wp.rcNormalPosition.right, wp.rcNormalPosition.bottom,// 								wp.ptMaxPosition.x, wp.ptMaxPosition.y,// 								wp.ptMinPosition.x, wp.ptMinPosition.y);			SetWindowPlacement(&wp);		}		else			rect.SetRectEmpty();	}		// first time or monitors changed?	if (rect.IsRectEmpty())	{		rect.SetRect(0, 0, 1024, 730); // default		// make sure it fits the screen		CRect rScreen;		GraphicsMisc::GetAvailableScreenSpace(rScreen);		if (rect.Height() > rScreen.Height())			rect.bottom = rScreen.Height();		MoveWindow(rect);		CenterWindow();	}}void CToDoListWnd::OnNew() {	CreateNewTaskList(FALSE);	RefreshTabOrder();}BOOL CToDoListWnd::CreateNewTaskList(BOOL bAddDefTask){	CFilteredToDoCtrl* pNew = NewToDoCtrl();		if (pNew)	{		int nNew = AddToDoCtrl(pNew);				// insert a default task		if (bAddDefTask)		{			if (pNew->GetTaskCount() == 0)				VERIFY (CreateNewTask(CEnString(IDS_TASK), TDC_INSERTATTOP, FALSE));		}		else // ensure it is empty			pNew->DeleteAllTasks();				// clear modified flag		pNew->SetModified(FALSE);		m_mgrToDoCtrls.SetModifiedStatus(nNew, FALSE);	}	return (pNew != NULL);}void CToDoListWnd::OnUpdateDeletetask(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(!tdc.IsReadOnly() && tdc.HasSelection());	}void CToDoListWnd::OnUpdateEditTasktext(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(nSelCount == 1 && !tdc.IsReadOnly());	}void CToDoListWnd::OnUpdateTaskcolor(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(!tdc.IsReadOnly() && tdc.HasSelection() && 		Prefs().GetTextColorOption() == COLOROPT_DEFAULT);	}void CToDoListWnd::OnUpdateTaskdone(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		if (nSelCount == 1)		pCmdUI->SetCheck(tdc.IsSelectedTaskDone() ? 1 : 0);		pCmdUI->Enable(!tdc.IsReadOnly() && GetToDoCtrl().GetSelectedItem());	}void CToDoListWnd::OnUpdateDeletealltasks(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(!tdc.IsReadOnly() && GetToDoCtrl().GetTaskCount());	}void CToDoListWnd::OnUpdateSave(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(GetTDCCount() && tdc.IsModified() && !tdc.IsReadOnly());	}void CToDoListWnd::OnUpdateNew(CCmdUI* pCmdUI)  {	pCmdUI->Enable(TRUE);	}BOOL CToDoListWnd::OnEraseBkgnd(CDC* pDC) {	if (!GetTDCCount())		return CFrameWnd::OnEraseBkgnd(pDC);	CDialogHelper::ExcludeChild(this, pDC, &m_toolbar);	CDialogHelper::ExcludeChild(this, pDC, &m_statusBar);	CDialogHelper::ExcludeChild(this, pDC, &m_tabCtrl);	CDialogHelper::ExcludeChild(this, pDC, &m_filterBar);	CDialogHelper::ExcludeChild(this, pDC, &GetToDoCtrl());	CRect rClient;	GetClientRect(rClient);	if (CThemed::IsThemeActive())	{		// paint between the window top and the top of the toolbar		// in toolbar color		if (m_bShowToolbar)		{			CRect rToolbar = CDialogHelper::OffsetCtrl(this, &m_toolbar);			pDC->FillSolidRect(rClient.left, rClient.top, rClient.Width(), rToolbar.top, m_theme.crToolbarLight);			rClient.top += rToolbar.bottom;// + 2;		}		// we need to paint a smidgen between the base of the toolbar		// and the top of the tab bar in crAppBackDark 		if (WantTasklistTabbarVisible())		{			pDC->FillSolidRect(rClient.left, rClient.top, rClient.Width(), 5, m_theme.crAppBackDark);			rClient.top += 5;		}		// and then the rest in crAppBackLight		pDC->FillSolidRect(rClient, m_theme.crAppBackLight);	}	else		pDC->FillSolidRect(rClient, GetSysColor(COLOR_3DFACE));	// we must draw out own bevel below the toolbar (or menu if the toolbar is not visible)	int nVPos = 0;		if (m_bShowToolbar)	{		if (COSVersion() <= OSV_XP)			pDC->FillSolidRect(rClient.left, nVPos, rClient.Width(), 1, m_theme.crAppLinesDark);				nVPos = m_toolbar.GetHeight() + TB_VOFFSET;	}		pDC->FillSolidRect(rClient.left, nVPos, rClient.Width(), 1, m_theme.crAppLinesDark);	pDC->FillSolidRect(rClient.left, nVPos + 1, rClient.Width(), 1, m_theme.crAppLinesLight);		// bevel below filter bar	if (m_bShowFilterBar)	{		CRect rFilter;		m_filterBar.GetWindowRect(rFilter);		ScreenToClient(rFilter);		int nVPos = rFilter.bottom;		pDC->FillSolidRect(rClient.left, nVPos, rClient.Width(), 1, m_theme.crAppLinesDark);		pDC->FillSolidRect(rClient.left, nVPos + 1, rClient.Width(), 1, m_theme.crAppLinesLight);	}	// bevel above the statusbar if themed	if (m_bShowStatusBar && CThemed::IsThemeActive())	{		CRect rStatBar;		m_statusBar.GetWindowRect(rStatBar);		ScreenToClient(rStatBar);		pDC->FillSolidRect(0, rStatBar.top - 2, rClient.Width(), 1, m_theme.crAppLinesDark);		pDC->FillSolidRect(0, rStatBar.top - 1, rClient.Width(), 1, m_theme.crAppLinesLight);	}	// this is definitely amongst the worst hacks I‘ve ever had to implement.	// It occurs because the CSysImageList class seems to not initialize 	// properly unless the main window is visible. so in the case of starting hidden	// or starting minimized we must wait until we become visible before	// adding the tools to the toolbar.	if (m_bStartHidden)	{		m_bStartHidden = FALSE;		PostMessage(WM_ADDTOOLBARTOOLS);	}	return TRUE;}void CToDoListWnd::OnSortBy(UINT nCmdID) {	if (nCmdID == ID_SORT_MULTI)		return;	TDC_COLUMN nSortBy = GetSortBy(nCmdID);		// update todoctrl	GetToDoCtrl().Sort(nSortBy);}void CToDoListWnd::OnUpdateSortBy(CCmdUI* pCmdUI){	if (pCmdUI->m_nID == ID_SORT_MULTI)		return;	CFilteredToDoCtrl& tdc = GetToDoCtrl();	// disable if column not visible	TDC_COLUMN nSortBy = GetSortBy(pCmdUI->m_nID);	pCmdUI->Enable(tdc.IsColumnShowing(nSortBy));	// only set the radio button if we‘re not multisorting	BOOL bChecked = !tdc.IsMultiSorting() && (tdc.GetSortBy() == nSortBy);	pCmdUI->SetRadio(bChecked);	// let menu icon manager handle setting selected state	switch (pCmdUI->m_nID)	{	case ID_SORT_NONE:		pCmdUI->Enable(TRUE);		break;	case ID_SORT_BYCOLOR:		pCmdUI->Enable(Prefs().GetTextColorOption() == COLOROPT_DEFAULT);		break;	case ID_SORT_BYPATH:		pCmdUI->Enable(tdc.GetView() != FTCV_TASKTREE);		break;	}}TDC_COLUMN CToDoListWnd::GetSortBy(UINT nSortID) {	switch (nSortID)	{	case ID_SORT_BYNAME:			return TDCC_CLIENT;	case ID_SORT_BYID:				return TDCC_ID;	case ID_SORT_BYALLOCTO:			return TDCC_ALLOCTO;	case ID_SORT_BYALLOCBY:			return TDCC_ALLOCBY;	case ID_SORT_BYSTATUS:			return TDCC_STATUS;	case ID_SORT_BYCATEGORY:		return TDCC_CATEGORY;	case ID_SORT_BYTAG:				return TDCC_TAGS;	case ID_SORT_BYPERCENT:			return TDCC_PERCENT;	case ID_SORT_BYTIMEEST:			return TDCC_TIMEEST;	case ID_SORT_BYTIMESPENT:		return TDCC_TIMESPENT;	case ID_SORT_BYSTARTDATE:		return TDCC_STARTDATE;	case ID_SORT_BYDUEDATE:			return TDCC_DUEDATE;	case ID_SORT_BYDONEDATE:		return TDCC_DONEDATE; 	case ID_SORT_BYDONE:			return TDCC_DONE;	case ID_SORT_BYPRIORITY:		return TDCC_PRIORITY;	case ID_SORT_BYCREATEDBY:		return TDCC_CREATEDBY;	case ID_SORT_BYCREATIONDATE:	return TDCC_CREATIONDATE;	case ID_SORT_BYMODIFYDATE:		return TDCC_LASTMOD;	case ID_SORT_BYRISK:			return TDCC_RISK;	case ID_SORT_BYEXTERNALID:		return TDCC_EXTERNALID;	case ID_SORT_BYCOST:			return TDCC_COST;	case ID_SORT_BYVERSION:			return TDCC_VERSION;	case ID_SORT_BYRECURRENCE:		return TDCC_RECURRENCE;	case ID_SORT_NONE:				return TDCC_NONE;	case ID_SORT_BYFLAG:			return TDCC_FLAG;	case ID_SORT_BYREMAINING:		return TDCC_REMAINING;	case ID_SORT_BYRECENTEDIT:		return TDCC_RECENTEDIT;	case ID_SORT_BYICON:			return TDCC_ICON;	case ID_SORT_BYFILEREF:			return TDCC_FILEREF;	case ID_SORT_BYTIMETRACKING:	return TDCC_TRACKTIME;	case ID_SORT_BYPATH:			return TDCC_PATH;	case ID_SORT_BYCOLOR:			return TDCC_COLOR;	case ID_SORT_BYDEPENDENCY:		return TDCC_DEPENDENCY;	case ID_SORT_BYPOSITION:		return TDCC_POSITION;	}		// handle custom columns	if (nSortID >= ID_SORT_BYCUSTOMCOLUMN_FIRST && nSortID <= ID_SORT_BYCUSTOMCOLUMN_LAST)		return (TDC_COLUMN)(TDCC_CUSTOMCOLUMN_FIRST + (nSortID - ID_SORT_BYCUSTOMCOLUMN_FIRST));	// all else	ASSERT (0);	return TDCC_NONE;}UINT CToDoListWnd::GetSortID(TDC_COLUMN nSortBy) {	switch (nSortBy)	{	case TDCC_CLIENT:		return ID_SORT_BYNAME;	case TDCC_ID:			return ID_SORT_BYID;	case TDCC_ALLOCTO:		return ID_SORT_BYALLOCTO;	case TDCC_ALLOCBY:		return ID_SORT_BYALLOCBY;	case TDCC_STATUS:		return ID_SORT_BYSTATUS;	case TDCC_CATEGORY:		return ID_SORT_BYCATEGORY;	case TDCC_TAGS:			return ID_SORT_BYTAG;	case TDCC_PERCENT:		return ID_SORT_BYPERCENT;	case TDCC_TIMEEST:		return ID_SORT_BYTIMEEST;	case TDCC_TIMESPENT:	return ID_SORT_BYTIMESPENT;	case TDCC_STARTDATE:	return ID_SORT_BYSTARTDATE;	case TDCC_DUEDATE:		return ID_SORT_BYDUEDATE;	case TDCC_DONEDATE:		return ID_SORT_BYDONEDATE;	case TDCC_DONE:			return ID_SORT_BYDONE;	case TDCC_PRIORITY:		return ID_SORT_BYPRIORITY;	case TDCC_FLAG:			return ID_SORT_BYFLAG;	case TDCC_CREATEDBY:	return ID_SORT_BYCREATEDBY;	case TDCC_CREATIONDATE:	return ID_SORT_BYCREATIONDATE;	case TDCC_LASTMOD:		return ID_SORT_BYMODIFYDATE;	case TDCC_RISK:			return ID_SORT_BYRISK;	case TDCC_EXTERNALID:	return ID_SORT_BYEXTERNALID;	case TDCC_COST:			return ID_SORT_BYCOST;	case TDCC_VERSION:		return ID_SORT_BYVERSION;	case TDCC_RECURRENCE:	return ID_SORT_BYRECURRENCE;	case TDCC_REMAINING:	return ID_SORT_BYREMAINING;	case TDCC_RECENTEDIT:	return ID_SORT_BYRECENTEDIT;	case TDCC_NONE:			return ID_SORT_NONE;	case TDCC_ICON:			return ID_SORT_BYICON;	case TDCC_FILEREF:		return ID_SORT_BYFILEREF;	case TDCC_TRACKTIME:	return ID_SORT_BYTIMETRACKING;	case TDCC_PATH:			return ID_SORT_BYPATH;	case TDCC_COLOR:		return ID_SORT_BYCOLOR;	case TDCC_POSITION:		return ID_SORT_BYPOSITION;	}		// handle custom columns	if (nSortBy >= TDCC_CUSTOMCOLUMN_FIRST && nSortBy < TDCC_CUSTOMCOLUMN_LAST)		return (ID_SORT_BYCUSTOMCOLUMN_FIRST + (nSortBy - TDCC_CUSTOMCOLUMN_FIRST));	// all else	ASSERT (0);	return 0;}void CToDoListWnd::OnNewtaskAttopSelected() {	VERIFY (CreateNewTask(CEnString(IDS_TASK), TDC_INSERTATTOPOFSELTASKPARENT));}void CToDoListWnd::OnNewtaskAtbottomSelected() {	VERIFY (CreateNewTask(CEnString(IDS_TASK), TDC_INSERTATBOTTOMOFSELTASKPARENT));}void CToDoListWnd::OnNewtaskAfterselectedtask() {	VERIFY (CreateNewTask(CEnString(IDS_TASK), TDC_INSERTAFTERSELTASK));}void CToDoListWnd::OnNewtaskBeforeselectedtask() {	VERIFY (CreateNewTask(CEnString(IDS_TASK), TDC_INSERTBEFORESELTASK));}void CToDoListWnd::OnNewsubtaskAtbottom() {	VERIFY (CreateNewTask(CEnString(IDS_TASK), TDC_INSERTATBOTTOMOFSELTASK));}void CToDoListWnd::OnNewsubtaskAttop() {	VERIFY (CreateNewTask(CEnString(IDS_TASK), TDC_INSERTATTOPOFSELTASK));}void CToDoListWnd::OnNewtaskAttop() {	VERIFY (CreateNewTask(CEnString(IDS_TASK), TDC_INSERTATTOP));}void CToDoListWnd::OnNewtaskAtbottom() {	VERIFY (CreateNewTask(CEnString(IDS_TASK), TDC_INSERTATBOTTOM));}BOOL CToDoListWnd::CreateNewTask(LPCTSTR szTitle, TDC_INSERTWHERE nInsertWhere, BOOL bEdit){	CFilteredToDoCtrl& tdc = GetToDoCtrl();		return (tdc.CreateNewTask(szTitle, nInsertWhere, bEdit) != NULL);}void CToDoListWnd::OnUpdateSort(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(tdc.IsSortable() && tdc.GetTaskCount());	}void CToDoListWnd::OnEditTaskcolor() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		if (!tdc.IsReadOnly() && tdc.HasSelection())	{		CEnColorDialog dialog(tdc.GetSelectedTaskColor(), CC_FULLOPEN | CC_RGBINIT);				if (dialog.DoModal() == IDOK)			tdc.SetSelectedTaskColor(dialog.GetColor());	}}void CToDoListWnd::OnEditCleartaskcolor() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		if (!tdc.IsReadOnly() && tdc.HasSelection())		tdc.ClearSelectedTaskColor();}void CToDoListWnd::OnUpdateEditCleartaskcolor(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(!tdc.IsReadOnly() && tdc.HasSelection() && 					Prefs().GetTextColorOption() == COLOROPT_DEFAULT &&					tdc.GetSelectedTaskColor() != 0);	}void CToDoListWnd::OnEditTaskdone() {	GetToDoCtrl().SetSelectedTaskDone(!GetToDoCtrl().IsSelectedTaskDone());}void CToDoListWnd::OnEditTasktext() {	GetToDoCtrl().EditSelectedTask();}void CToDoListWnd::OnTrayIconClick(NMHDR* /*pNMHDR*/, LRESULT* pResult){	SetFocus();	Show(Prefs().GetToggleTrayVisibility());	*pResult = 0;}LRESULT CToDoListWnd::OnToDoListShowWindow(WPARAM /*wp*/, LPARAM /*lp*/){	Show(FALSE);	return 0;}LRESULT CToDoListWnd::OnToDoListGetVersion(WPARAM /*wp*/, LPARAM /*lp*/){	return GetVersion();}LRESULT CToDoListWnd::OnToDoListRefreshPrefs(WPARAM /*wp*/, LPARAM /*lp*/){	// sent by the app object if registry settings have changed	ResetPrefs();	// mark all tasklists as needing update	m_mgrToDoCtrls.SetAllNeedPreferenceUpdate(TRUE);		// then update active tasklist	UpdateToDoCtrlPreferences();	return 0;}void CToDoListWnd::OnTrayIconDblClk(NMHDR* /*pNMHDR*/, LRESULT* pResult){	Show(FALSE);		*pResult = 0;}void CToDoListWnd::OnTrayiconCreatetask() {	Show(FALSE);		// create a task at the top of the tree	GetToDoCtrl().CreateNewTask(CEnString(IDS_TASK), TDC_INSERTATTOP);}void CToDoListWnd::OnTrayIconRClick(NMHDR* pNMHDR, LRESULT* pResult){	SetForegroundWindow();		// show context menu	CEnMenu menu;		if (menu.LoadMenu(IDR_MISC, m_trayIcon.GetSafeHwnd(), TRUE))	{		CMenu* pSubMenu = menu.GetSubMenu(TRAYICON);		pSubMenu->SetDefaultItem(ID_TRAYICON_SHOW);				if (pSubMenu)		{			m_mgrToDoCtrls.PreparePopupMenu(*pSubMenu, ID_TRAYICON_SHOWDUETASKS1);						NM_TRAYICON* pNMTI = (NM_TRAYICON*)pNMHDR;			// in order to ensure that multiple password dialogs cannot 			// appear we must make sure that all the command handling is			// done before we return from here			UINT nCmdID = ::TrackPopupMenu(*pSubMenu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_LEFTBUTTON, 											pNMTI->ptAction.x, pNMTI->ptAction.y, 0, *this, NULL);			PostMessage(WM_NULL);			if (nCmdID != (UINT)-1)				SendMessage(WM_COMMAND, nCmdID);		}	}		*pResult = 0;}void CToDoListWnd::OnClose() {	if (!m_bEndingSession)	{		int nSysTrayOption = Prefs().GetSysTrayOption();				if (nSysTrayOption == STO_ONCLOSE || nSysTrayOption == STO_ONMINCLOSE)			MinimizeToTray();				else // shutdown but user can cancel			DoExit();	}	// else we‘ve already shutdown}void CToDoListWnd::MinimizeToTray(){	// end whatever the user is doing	GetToDoCtrl().Flush();	// save prev state so we can restore properly	CPreferences().WriteProfileInt(_T("Pos"), _T("Maximized"), IsZoomed());		if (Prefs().GetAutoSaveOnSwitchApp())	{		// save all		SaveAll(TDLS_FLUSH | TDLS_AUTOSAVE);	}		// hide main window	Gui::MinToTray(*this); // courtesy of floyd	m_bVisible = FALSE;		// hide find dialog	ShowFindDialog(FALSE);}void CToDoListWnd::ShowFindDialog(BOOL bShow){	if (bShow)	{		if (m_bVisible && m_findDlg.GetSafeHwnd() && IsWindowVisible())			m_findDlg.Show(TRUE);	}	else // hide	{		if (m_findDlg.GetSafeHwnd())		{			m_bFindShowing = m_findDlg.IsWindowVisible();			m_findDlg.Show(FALSE);		}		else			m_bFindShowing = FALSE;	}}void CToDoListWnd::OnTrayiconClose() {	DoExit();}LRESULT CToDoListWnd::OnToDoCtrlNotifyListChange(WPARAM /*wp*/, LPARAM lp){	// decide whether the filter controls need updating	switch (lp)	{	case TDCA_ALLOCTO:	case TDCA_ALLOCBY:	case TDCA_STATUS:	case TDCA_CATEGORY:	case TDCA_VERSION:	case TDCA_TAGS:		RefreshFilterControls();		break;	}		return 0L;}LRESULT CToDoListWnd::OnToDoCtrlNotifyViewChange(WPARAM wp, LPARAM lp){	if (GetTDCCount())	{		if (lp != (LPARAM)wp)		{			CFocusWatcher::UpdateFocus();			m_filterBar.RefreshFilterControls(GetToDoCtrl());		}		else		{			int breakpoint = 0;		}	}	return 0L;}LRESULT CToDoListWnd::OnToDoCtrlNotifyTimeTrack(WPARAM /*wp*/, LPARAM lp){	BOOL bTrack = lp;	if (bTrack && Prefs().GetExclusiveTimeTracking())	{		// end time tracking on every other tasklist		int nSel = GetSelToDoCtrl();		ASSERT (nSel != -1);		for (int nCtrl = 0; nCtrl < GetTDCCount(); nCtrl++)		{			if (nCtrl != nSel)				GetToDoCtrl(nCtrl).EndTimeTracking();		}	}	return 0L;}	LRESULT CToDoListWnd::OnToDoCtrlNotifyRecreateRecurringTask(WPARAM wp, LPARAM lp){	DWORD dwTaskID = wp, dwNewTaskID = lp;	// is there a reminder that we need to copy for the new task	CFilteredToDoCtrl& tdc = GetToDoCtrl();	TDCREMINDER rem;	int nRem = m_reminders.FindReminder(dwTaskID, &tdc);	if (nRem != -1)	{		// get the existing reminder		m_reminders.GetReminder(nRem, rem);		// init for new task		rem.bEnabled = TRUE;		rem.dDaysSnooze = 0.0;		rem.dwTaskID = dwNewTaskID;		// add for the new task ID		m_reminders.SetReminder(rem);		// delete the original only if the task id has changed		if (dwNewTaskID != dwTaskID)					m_reminders.RemoveReminder(dwTaskID, rem.pTDC);	}	return 0L;}LRESULT CToDoListWnd::OnToDoCtrlNotifyMod(WPARAM wp, LPARAM lp){	int nTDC = m_mgrToDoCtrls.FindToDoCtrl((HWND)wp);	if (nTDC == -1)	{		// could be a notification from a TDC not yet added		return 0L;	}	BOOL bWasMod = m_mgrToDoCtrls.GetModifiedStatus(nTDC);	m_mgrToDoCtrls.SetModifiedStatus(nTDC, TRUE);	// update the caption only if the control was not previously modified	// or the project name changed	if (!bWasMod)		UpdateCaption();	TDC_ATTRIBUTE nAttrib = (TDC_ATTRIBUTE)lp;	switch (nAttrib)	{	case TDCA_PROJNAME:		{			// update caption if not already done			if (bWasMod)				UpdateCaption();			// update tab order			if (Prefs().GetKeepTabsOrdered())				RefreshTabOrder();		}		break;	// update due items	case TDCA_DONEDATE:	case TDCA_DUEDATE:		OnTimerDueItems(nTDC);		break;	// reminders	case TDCA_DELETE:		m_reminders.RemoveDeletedTaskReminders(&GetToDoCtrl(nTDC));		break;	}	// status bar	UpdateStatusbar();	// refresh toolbar states	PostMessage(WM_IDLEUPDATECMDUI, TRUE);	// do we need to update the current todoctrl‘s	// custom attributes on the find dialog?	if (m_findDlg.GetSafeHwnd() && nAttrib == TDCA_CUSTOMATTRIBDEFS)	{		UpdateFindDialogCustomAttributes(&GetToDoCtrl());	}	return 0L;}void CToDoListWnd::UpdateCaption(){	int nSel = GetSelToDoCtrl();		CString sProjectName = m_mgrToDoCtrls.UpdateTabItemText(nSel);	CFilteredToDoCtrl& tdc = GetToDoCtrl();		UINT nIDStatus = 0;		if (m_mgrToDoCtrls.GetReadOnlyStatus(nSel) > 0)		nIDStatus = IDS_STATUSREADONLY;		else if (tdc.CompareFileFormat() == TDCFF_NEWER)		nIDStatus = IDS_STATUSNEWERFORMAT;		else if (m_mgrToDoCtrls.GetReadOnlyStatus(nSel) == 0 && 		m_mgrToDoCtrls.PathSupportsSourceControl(nSel))	{		if (tdc.IsCheckedOut())			nIDStatus = IDS_STATUSCHECKEDOUT;		else			nIDStatus = IDS_STATUSCHECKEDIN;	}	else if (!Prefs().GetEnableSourceControl() && m_mgrToDoCtrls.IsSourceControlled(nSel))	{		nIDStatus = IDS_STATUSSOURCECONTROLLED;	}		CString sCaption, sCopyright(MAKEINTRESOURCE(IDS_COPYRIGHT));	CEnString sStatus(nIDStatus);		// add current focus text as required	if (nIDStatus)	{		if (m_bShowStatusBar || m_sCurrentFocus.IsEmpty())			sCaption.Format(_T("%s [%s] - %s"), sProjectName, sStatus, sCopyright);		else			sCaption.Format(_T("%s [%s][%s] - %s"), sProjectName, m_sCurrentFocus, sStatus, sCopyright);	}	else	{		if (m_bShowStatusBar || m_sCurrentFocus.IsEmpty())			sCaption.Format(_T("%s - %s"), sProjectName, sCopyright);		else			sCaption.Format(_T("%s [%s] - %s"), sProjectName, m_sCurrentFocus, sCopyright);	}		// prepend task pathname if tasklist not visible	if (m_nMaxState == TDCMS_MAXCOMMENTS)	{		// quote the path to help it stand-out		CString sTaskPath;		sTaskPath.Format(_T("\"%s\""), tdc.GetSelectedTaskPath(TRUE, 100));				if (!sTaskPath.IsEmpty())			sCaption = sTaskPath + " - " + sCaption;	}		SetWindowText(sCaption);	// set tray tip too	UpdateTooltip();}void CToDoListWnd::UpdateTooltip(){    // base the tooltip on our current caption    CString sTooltip;    GetWindowText(sTooltip);    // move copyright to next line and remove ‘-‘    sTooltip.Replace(_T(" - "), _T("\n"));    // prefix with selected task as first line    CFilteredToDoCtrl& tdc = GetToDoCtrl();    DWORD dwSelID = tdc.GetSelectedTaskID();    if (dwSelID)    {        CString sSelItem = tdc.GetTaskTitle(dwSelID);        // maximum length of tooltip is 128 including null        if (sSelItem.GetLength() > (128 - sTooltip.GetLength() - 6))        {            sSelItem = sSelItem.Left(128 - sTooltip.GetLength() - 6);            sSelItem += _T("...");        }        else if (tdc.GetSelectedCount() > 1)            sSelItem += _T(", ...");        sTooltip = sSelItem + _T("\n") + sTooltip;    }    m_trayIcon.SetTip(sTooltip);}BOOL CToDoListWnd::Export2Html(const CTaskFile& tasks, LPCTSTR szFilePath, LPCTSTR szStylesheet) const{	CWaitCursor cursor;		if (FileMisc::FileExists(szStylesheet))	{		return tasks.TransformToFile(szStylesheet, szFilePath, Prefs().GetHtmlCharSet());	}		// else default export	return m_mgrImportExport.ExportTaskListToHtml(&tasks, szFilePath);}void CToDoListWnd::OnSaveas() {	int nSel = GetSelToDoCtrl();	CFilteredToDoCtrl& tdc = GetToDoCtrl(nSel);	// use tab text as hint to user	CString sFilePath = m_mgrToDoCtrls.GetFilePath(nSel, FALSE);	CPreferences prefs;	// display the dialog	CFileSaveDialog dialog(IDS_SAVETASKLISTAS_TITLE,							GetDefaultFileExt(), 							sFilePath, 							EOFN_DEFAULTSAVE,							GetFileFilter(FALSE), 							this);		// always use the tasklist‘s own format for initializing the file dialog	dialog.m_ofn.nFilterIndex = tdc.IsUnicode() ? 2 : 1;		int nRes = dialog.DoModal(&prefs);		if (nRes == IDOK)	{		BOOL bWasUnicode = tdc.IsUnicode();		BOOL bUnicode = (dialog.m_ofn.nFilterIndex == 2);		tdc.SetUnicode(bUnicode);		// save this choice as the best hint for the next new tasklist		CPreferences().WriteProfileInt(PREF_KEY, _T("UnicodeNewTasklists"), bUnicode); 		if (SaveTaskList(nSel, dialog.GetPathName()) == TDCO_SUCCESS)		{			//m_mgrToDoCtrls.ClearWebDetails(nSel); // because it‘s no longer a remote file		}		else // restore previous file format			tdc.SetUnicode(bWasUnicode);		UpdateStatusbar();	}}void CToDoListWnd::OnUpdateSaveas(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(tdc.GetTaskCount() || tdc.IsModified());}void CToDoListWnd::OnContextMenu(CWnd* pWnd, CPoint point) {	static UINT nActiveMenuID = 0; // prevent reentrancy	UINT nMenuID = 0;	const CFilteredToDoCtrl& tdc = GetToDoCtrl();		if (pWnd == &m_tabCtrl)	{		// if point.x,y are both -1 then we just use the cursor pos		// which is what windows appears to do mostly/sometimes		if (point.x == -1 && point.y == -1)		{			CRect rTab;						if (m_tabCtrl.GetItemRect(m_tabCtrl.GetCurSel(), rTab))			{				point = rTab.CenterPoint();				m_tabCtrl.ClientToScreen(&point);								// load popup menu				nMenuID = TABCTRLCONTEXT;			}		}		else		{			// activate clicked tab			TCHITTESTINFO tcht = { { point.x, point.y }, TCHT_NOWHERE  };			m_tabCtrl.ScreenToClient(&tcht.pt);						int nTab = m_tabCtrl.HitTest(&tcht);						if (nTab != -1 && !(tcht.flags & TCHT_NOWHERE))			{				if (nTab != m_tabCtrl.GetCurSel())				{					if (!SelectToDoCtrl(nTab, TRUE))						return; // user cancelled				}								m_tabCtrl.SetFocus(); // give user feedback								// load popup menu				nMenuID = TABCTRLCONTEXT;			}		}	}	else if (pWnd == (CWnd*)&tdc) // try active todoctrl	{		TDC_HITTEST nHit = tdc.HitTest(point);		switch (nHit)		{		case TDCHT_NOWHERE:			break;		case TDCHT_TASKLIST:		case TDCHT_TASK:			if (tdc.WantTaskContextMenu())			{				nMenuID = TASKCONTEXT;				// if point.x,y are both -1 then we request the current 				// selection position				if (point.x == -1 && point.y == -1)				{					CRect rSelection;					if (tdc.GetSelectionBoundingRect(rSelection))					{						tdc.ClientToScreen(rSelection);						point.x = min(rSelection.left + 50, rSelection.CenterPoint().x);						point.y = rSelection.top + 8;					}					else					{						nMenuID = 0; // no context menu					}				}			}			break;		case TDCHT_COLUMNHEADER:			nMenuID = HEADERCONTEXT;			break;		}	}		// show the menu	if (nMenuID && nMenuID != nActiveMenuID)	{		CEnMenu menu;				if (menu.LoadMenu(IDR_MISC, NULL, TRUE))		{			CMenu* pPopup = menu.GetSubMenu(nMenuID);						if (pPopup)			{				// some special handling				switch (nMenuID)				{				case TASKCONTEXT:					m_nContextColumnID = tdc.ColumnHitTest(point);					PrepareEditMenu(pPopup);					break;				case TABCTRLCONTEXT:					PrepareSourceControlMenu(pPopup);					break;				}								CToolbarHelper::PrepareMenuItems(pPopup, this);								nActiveMenuID = nMenuID;				pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, point.x, point.y, this);				nActiveMenuID = 0;			}		}	}	else		CFrameWnd::OnContextMenu(pWnd, point);}void CToDoListWnd::OnTrayiconShow() {	Show(FALSE);}void CToDoListWnd::OnTrayiconShowDueTasks(UINT nCmdID) {	int nTDC = nCmdID - ID_TRAYICON_SHOWDUETASKS1;	int nSelTDC = GetSelToDoCtrl();	// verify password if encrypted tasklist is active	// unless app is already visible	if (!m_bVisible || IsIconic() || (nTDC != nSelTDC))	{		if (!VerifyToDoCtrlPassword(nTDC))			return;	}	CFilteredToDoCtrl& tdc = GetToDoCtrl(nTDC);	if (!DoDueTaskNotification(nTDC, PFP_DUETODAY))	{		CEnString sMessage(IDS_NODUETODAY, m_mgrToDoCtrls.GetFriendlyProjectName(nTDC));		MessageBox(sMessage);//, IDS_DUETASKS_TITLE);	}}LRESULT CToDoListWnd::OnHotkey(WPARAM /*wp*/, LPARAM /*lp*/){	Show(TRUE);	return 0L;}BOOL CToDoListWnd::VerifyToDoCtrlPassword() const{	return VerifyToDoCtrlPassword(GetSelToDoCtrl());}BOOL CToDoListWnd::VerifyToDoCtrlPassword(int nIndex) const{	if (m_bPasswordPrompting)	{		CEnString sExplanation(IDS_SELECTENCRYPTED, 								m_mgrToDoCtrls.GetFriendlyProjectName(nIndex));		return GetToDoCtrl(nIndex).VerifyPassword(sExplanation);	}		// else	return TRUE;}void CToDoListWnd::Show(BOOL bAllowToggle){	if (GetSelToDoCtrl() == -1)		return;		if (!m_bVisible || !IsWindowVisible()) // restore from the tray	{		SetForegroundWindow();				if (!VerifyToDoCtrlPassword())			return;		m_bVisible = TRUE;		Gui::RestoreFromTray(*this, CPreferences().GetProfileInt(_T("Pos"), _T("Maximized"), FALSE));		// restore find dialog		if (m_bFindShowing)			m_findDlg.Show();	}	else if (IsIconic())	{		SetForegroundWindow();		ShowWindow(SW_RESTORE); // this will force a password check	}	// if we‘re already visible then either bring to the foreground 	// or hide if we‘re right at the top of the z-order	else if (!bAllowToggle || Gui::IsObscured(*this) || !Gui::HasFocus(*this, TRUE))		SetForegroundWindow();	else if (Prefs().GetSysTrayOption() == STO_NONE)		ShowWindow(SW_MINIMIZE);	else // hide to system tray		MinimizeToTray();		// refresh all tasklists if we are visible	if (m_bVisible && !IsIconic())	{		const CPreferencesDlg& userPrefs = Prefs();				if (userPrefs.GetReadonlyReloadOption() != RO_NO)			OnTimerReadOnlyStatus();				if (userPrefs.GetTimestampReloadOption() != RO_NO)			OnTimerTimestampChange();				if (userPrefs.GetEnableSourceControl())			OnTimerCheckoutStatus();	}		GetToDoCtrl().SetFocusToTasks();}#ifdef _DEBUGvoid CToDoListWnd::OnDebugEndSession() { 	SendMessage(WM_QUERYENDSESSION); 	SendMessage(WM_ENDSESSION, 1, 0); }void CToDoListWnd::OnDebugShowSetupDlg() { 	CTDLWelcomeWizard dialog;	dialog.DoModal();}#endifvoid CToDoListWnd::TranslateUIElements() { 	// show progress bar	DOPROGRESS(IDS_UPDATINGDICTIONARY)	// disable translation of top-level menu names in	// IDR_MISC, IDR_PLACEHOLDERS, IDR_TREEDRAGDROP	CLocalizer::IgnoreString(_T("TrayIcon"));	CLocalizer::IgnoreString(_T("TaskContext"));	CLocalizer::IgnoreString(_T("TabCtrl"));	CLocalizer::IgnoreString(_T("TasklistHeader"));	CLocalizer::IgnoreString(_T("CommentsPopup"));	CLocalizer::IgnoreString(_T("ToolsDialog"));	CLocalizer::IgnoreString(_T("TreeDragDrop"));	// disable light box manager temporarily	// to avoid the disabling effect whenever 	// a dialog is created	if (Prefs().GetEnableLightboxMgr())		CLightBoxMgr::Release();	CLocalizer::ForceTranslateAllUIElements(IDS_FIRSTSTRING, IDS_LASTSTRING);	// force a redraw of whole UI	if (IsWindowVisible())	{		ShowWindow(SW_HIDE);		ShowWindow(SW_SHOW);	}		SetForegroundWindow();	// restore light box manager	if (Prefs().GetEnableLightboxMgr())		CLightBoxMgr::Initialize(this, m_theme.crAppBackDark);}void CToDoListWnd::OnUpdateRecentFileMenu(CCmdUI* pCmdUI) {	// check that this is not occurring because our CFrameWnd	// base class is routing this to the first item in a submenu	if (pCmdUI->m_pMenu && 		pCmdUI->m_pMenu->GetMenuItemID(pCmdUI->m_nIndex) == (UINT)-1)		return;	m_mruList.UpdateMenu(pCmdUI);	}BOOL CToDoListWnd::OnOpenRecentFile(UINT nID){	ASSERT(nID >= ID_FILE_MRU_FILE1);	ASSERT(nID < ID_FILE_MRU_FILE1 + (UINT)m_mruList.GetSize());		int nIndex = nID - ID_FILE_MRU_FILE1;		CString sTaskList = m_mruList[nIndex];	TDC_FILE nOpen = OpenTaskList(sTaskList);		if (nOpen == TDCO_SUCCESS)	{		Resize();		UpdateWindow();	}	else	{		HandleLoadTasklistError(nOpen, sTaskList);				if (nOpen != TDCO_CANCELLED)			m_mruList.Remove(nIndex);	}	RefreshTabOrder();		// always return TRUE to say we handled it	return TRUE;}void CToDoListWnd::RefreshTabOrder(){	if (Prefs().GetKeepTabsOrdered())	{		int nSelOrg = GetSelToDoCtrl();		int nSel = m_mgrToDoCtrls.SortToDoCtrlsByName();				if (nSel != nSelOrg)			SelectToDoCtrl(nSel, FALSE);	}}TDC_FILE CToDoListWnd::DelayOpenTaskList(LPCTSTR szFilePath){	ASSERT (Prefs().GetEnableDelayedLoading()); // sanity check	// decode/prepare filepath	CString sFilePath(szFilePath);	TSM_TASKLISTINFO storageInfo;	TDC_PREPAREPATH nPathType = PrepareFilePath(sFilePath, &storageInfo);	if (nPathType == TDCPP_NONE)		return TDCO_NOTEXIST;	// see if the tasklist is already open	if (SelectToDoCtrl(sFilePath, TRUE))		return TDCO_SUCCESS;	// delay load the file, visible but disabled	CFilteredToDoCtrl* pTDC = NewToDoCtrl(TRUE, FALSE);	// if this is a ‘special‘ temp file then assume TDL automatically	// named it when handling WM_ENDSESSION. 	BOOL bDelayLoad = !IsEndSessionFilePath(sFilePath);	COleDateTime dtEarliest;	if (bDelayLoad)		bDelayLoad = pTDC->DelayLoad(sFilePath, dtEarliest);	if (bDelayLoad)	{		// now we have to check for whether the tasklist has due tasks 		// and the user wants notification		int nNotifyDueBy = Prefs().GetNotifyDueByOnLoad();		if (nNotifyDueBy != PFP_DONTNOTIFY && CDateHelper::IsDateSet(dtEarliest.m_dt))		{			// check the date against when the user wants notifying			DH_DATE nDate = DHD_TODAY;						switch (nNotifyDueBy)			{			case PFP_DUETODAY:		/*nDate = DHD_TODAY;*/		break;			case PFP_DUETOMORROW:	nDate = DHD_TOMORROW;		break;			case PFP_DUETHISWEEK:	nDate = DHD_ENDTHISWEEK;	break;			case PFP_DUENEXTWEEK:	nDate = DHD_ENDNEXTWEEK;	break;			case PFP_DUETHISMONTH:	nDate = DHD_ENDTHISMONTH;	break;			case PFP_DUENEXTMONTH:	nDate = DHD_ENDNEXTMONTH;	break;			default:				ASSERT (0);			}						COleDateTime dtDueWhen = CDateHelper::GetDate(nDate);						bDelayLoad = (dtDueWhen < dtEarliest);		}	}	// if the delay load failed for any reason we need to delete the tasklist	// and fallback on the default load mechanism	if (!bDelayLoad)	{		pTDC->DestroyWindow();		delete pTDC;		// note: we use the original filepath in case it is 		// actually storage info		return OpenTaskList(szFilePath, FALSE);	}		int nCtrl = m_mgrToDoCtrls.AddToDoCtrl(pTDC, &storageInfo, FALSE); // FALSE == not yet loaded		// update due item status	if (CDateHelper::IsDateSet(dtEarliest))	{		TDCM_DUESTATUS nStatus = TDCM_FUTURE;		COleDateTime dtToday = COleDateTime::GetCurrentTime();		if (floor(dtEarliest) < floor(dtToday))			nStatus = TDCM_PAST;		else if (floor(dtEarliest) == floor(dtToday))			nStatus = TDCM_TODAY;		m_mgrToDoCtrls.SetDueItemStatus(nCtrl, nStatus);	}			return TDCO_SUCCESS;}CString CToDoListWnd::GetEndSessionFilePath(){	return FileMisc::GetTempFileName(_T("tde"));}BOOL CToDoListWnd::IsEndSessionFilePath(const CString& sFilePath){	if (!FileMisc::FileExists(sFilePath))		return FALSE;	if (!FileMisc::HasExtension(sFilePath, _T("tmp")))		return FALSE;		if (!FileMisc::IsTempFile(sFilePath))		return FALSE;	if (FileMisc::GetFileNameFromPath(sFilePath).Find(_T("tde")) != 0)		return FALSE;	// passed all the tests	return TRUE;}TDC_ARCHIVE CToDoListWnd::GetAutoArchiveOptions(LPCTSTR szFilePath, CString& sArchivePath, BOOL& bRemoveFlagged) const{	TDC_ARCHIVE nRemove = TDC_REMOVENONE;	bRemoveFlagged = FALSE;	const CPreferencesDlg& userPrefs = Prefs();		if (userPrefs.GetAutoArchive())	{		if (userPrefs.GetRemoveArchivedTasks())		{			if (userPrefs.GetRemoveOnlyOnAbsoluteCompletion())				nRemove = TDC_REMOVEIFSIBLINGSANDSUBTASKSCOMPLETE;			else				nRemove = TDC_REMOVEALL;			bRemoveFlagged = !userPrefs.GetDontRemoveFlagged();		}				sArchivePath = m_mgrToDoCtrls.GetArchivePath(szFilePath);	}	else		sArchivePath.Empty();	return nRemove;}TDC_FILE CToDoListWnd::OpenTaskList(LPCTSTR szFilePath, BOOL bNotifyDueTasks){	CString sFilePath(szFilePath);	TDC_PREPAREPATH nType = PrepareFilePath(sFilePath);		if (nType == TDCPP_NONE)		return TDCO_NOTEXIST;		// see if the tasklist is already open	int nExist = m_mgrToDoCtrls.FindToDoCtrl(sFilePath);		if (nExist != -1)	{		// reload provided there are no existing changes		// and the timestamp has changed		if (!m_mgrToDoCtrls.GetModifiedStatus(nExist) &&			m_mgrToDoCtrls.RefreshLastModified(nExist))		{			ReloadTaskList(nExist, bNotifyDueTasks);		}				// then select		if (SelectToDoCtrl(nExist, TRUE))			return TDCO_SUCCESS;	}		// create a new todoltrl for this tasklist 	const CPreferencesDlg& userPrefs = Prefs();	CFilteredToDoCtrl* pTDC = NewToDoCtrl();	CHoldRedraw hr(pTDC->GetSafeHwnd());		// handles simple and storage tasklists	// we use szFilePath because it may be storage Info not a true path	TSM_TASKLISTINFO storageInfo;	TDC_FILE nOpen = OpenTaskList(pTDC, sFilePath, &storageInfo);		if (nOpen == TDCO_SUCCESS)	{		int nTDC = AddToDoCtrl(pTDC, &storageInfo);		// notify readonly		CheckNotifyReadonly(nTDC);		// reload any reminders		m_reminders.AddToDoCtrl(*pTDC);				// notify user of due tasks if req		if (bNotifyDueTasks)			DoDueTaskNotification(nTDC, userPrefs.GetNotifyDueByOnLoad());				// save checkout status		if (userPrefs.GetAutoCheckOut())			m_mgrToDoCtrls.SetLastCheckoutStatus(nTDC, pTDC->IsCheckedOut());		// check for automatic naming when handling WM_ENDSESSION. 		// so we clear the filename and mark it as modified		if (IsEndSessionFilePath(sFilePath))		{			pTDC->ClearFilePath();			pTDC->SetModified();		}				UpdateCaption();		UpdateStatusbar();		OnTimerDueItems(nTDC);				// update search		if (userPrefs.GetRefreshFindOnLoad() && m_findDlg.GetSafeHwnd())			m_findDlg.RefreshSearch();	}	else if (GetTDCCount() >= 1) // only delete if there‘s another ctrl existing	{		pTDC->DestroyWindow();		delete pTDC;	}	else // re-add	{		AddToDoCtrl(pTDC);	}		return nOpen;}TDC_FILE CToDoListWnd::OpenTaskList(CFilteredToDoCtrl* pTDC, LPCTSTR szFilePath, TSM_TASKLISTINFO* pInfo){	CString sFilePath(szFilePath);	CTaskFile tasks;	TDC_FILE nOpen = TDCO_UNSET;	TSM_TASKLISTINFO storageInfo;	TDC_PREPAREPATH nType = PrepareFilePath(sFilePath, &storageInfo);	// handle bad path	if ((szFilePath && *szFilePath) && sFilePath.IsEmpty())		return TDCO_NOTEXIST;	DOPROGRESS(IDS_LOADINGPROGRESS)	if (sFilePath.IsEmpty())	{		sFilePath = pTDC->GetFilePath(); // ie. reload	}	else	{		switch (nType)		{		case TDCPP_STORAGE:			{				CPreferences prefs;				// retrieve file from storage				if (m_mgrStorage.RetrieveTasklist(&storageInfo, &tasks, -1, &prefs))				{					// handle returned tasks					if (tasks.GetTaskCount())					{						// merge returned tasks with this tasklist						// TODO						nOpen = TDCO_SUCCESS;					}					// return update storage info					if (pInfo)						*pInfo = storageInfo;				}				else					nOpen = TDCO_CANCELLED;			}			break;		case TDCPP_FILE:			{				BOOL bSrcControl = m_mgrToDoCtrls.PathSupportsSourceControl(szFilePath);				pTDC->SetStyle(TDCS_ENABLESOURCECONTROL, bSrcControl);				pTDC->SetStyle(TDCS_CHECKOUTONLOAD, bSrcControl ? Prefs().GetAutoCheckOut() : FALSE);			}			break;		case TDCPP_NONE:		default:			ASSERT(0);			break;		}	}		// has the load already been handled?	if (nOpen == TDCO_UNSET)		nOpen = pTDC->Load(sFilePath, tasks);	if (nOpen == TDCO_SUCCESS)	{		// update readonly status		m_mgrToDoCtrls.UpdateToDoCtrlReadOnlyUIState(*pTDC);		const CPreferencesDlg& userPrefs = Prefs();		// certain operations cannot be performed on ‘storage‘ tasklists		if (nType == TDCPP_FILE)		{			// archive completed tasks?			if (!pTDC->IsReadOnly())			{				CString sArchivePath;				BOOL bRemoveFlagged;				TDC_ARCHIVE nRemove = GetAutoArchiveOptions(szFilePath, sArchivePath, bRemoveFlagged);							if (!sArchivePath.IsEmpty())					pTDC->ArchiveDoneTasks(sArchivePath, nRemove, bRemoveFlagged);			}			if (userPrefs.GetAddFilesToMRU())				m_mruList.Add(sFilePath);		}		if (userPrefs.GetExpandTasksOnLoad())			pTDC->ExpandTasks(TDCEC_ALL);				// update find dialog with this ToDoCtrl‘s custom attributes		UpdateFindDialogCustomAttributes(pTDC);	}	else		pTDC->SetModified(FALSE);	return nOpen;}void CToDoListWnd::CheckNotifyReadonly(int nIndex) const{	ASSERT(nIndex != -1);	const CPreferencesDlg& userPrefs = Prefs();	if (nIndex >= 0 && userPrefs.GetNotifyReadOnly())	{		CEnString sMessage;		CString sDisplayPath = m_mgrToDoCtrls.GetDisplayPath(nIndex);		CString sFilePath = m_mgrToDoCtrls.GetFilePath(nIndex);		const CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);				if (CDriveInfo::IsReadonlyPath(sFilePath) > 0)			sMessage.Format(IDS_OPENREADONLY, sDisplayPath);				else if (!userPrefs.GetEnableSourceControl() && m_mgrToDoCtrls.IsSourceControlled(nIndex))			sMessage.Format(IDS_OPENSOURCECONTROLLED, sDisplayPath);				else if (tdc.CompareFileFormat() == TDCFF_NEWER)			sMessage.Format(IDS_OPENNEWER, sDisplayPath);				if (!sMessage.IsEmpty())			MessageBox(sMessage, IDS_OPENTASKLIST_TITLE);	}}void CToDoListWnd::UpdateFindDialogCustomAttributes(const CFilteredToDoCtrl* pTDC){	if (pTDC == NULL && GetTDCCount() == 0)		return; // nothing to do	CTDCCustomAttribDefinitionArray aTDCAttribDefs, aAllAttribDefs;	// all tasklists	int nTDC = GetTDCCount();	while (nTDC--)	{		const CFilteredToDoCtrl& tdc = GetToDoCtrl(nTDC);		tdc.GetCustomAttributeDefs(aTDCAttribDefs);		CTDCCustomAttributeHelper::AppendUniqueAttributes(aTDCAttribDefs, aAllAttribDefs);	}		// active tasklist	if (pTDC == NULL)	{		ASSERT(GetTDCCount() > 0);		pTDC = &GetToDoCtrl();	}	ASSERT (pTDC);	pTDC->GetCustomAttributeDefs(aTDCAttribDefs);	// do the update	m_findDlg.SetCustomAttributes(aTDCAttribDefs, aAllAttribDefs);}BOOL CToDoListWnd::DoDueTaskNotification(int nDueBy){	return DoDueTaskNotification(GetSelToDoCtrl(), nDueBy);}BOOL CToDoListWnd::DoDueTaskNotification(int nTDC, int nDueBy){	// check userPrefs	if (nDueBy == -1)		return TRUE; // nothing to do		if (nTDC != -1 && !VerifyTaskListOpen(nTDC, FALSE))		return TRUE; // no error. user cancelled	CFilteredToDoCtrl& tdc = m_mgrToDoCtrls.GetToDoCtrl(nTDC);	const CPreferencesDlg& userPrefs = Prefs();		// preferences	BOOL bParentTitleCommentsOnly = userPrefs.GetExportParentTitleCommentsOnly();	BOOL bDueTaskTitlesOnly = userPrefs.GetDueTaskTitlesOnly();	CString sStylesheet = userPrefs.GetDueTaskStylesheet();	BOOL bTransform = FileMisc::FileExists(sStylesheet);	BOOL bHtmlNotify = userPrefs.GetDisplayDueTasksInHtml();		DWORD dwFlags = TDCGTF_FILENAME;		if (bHtmlNotify)		dwFlags |= TDCGTF_HTMLCOMMENTS;	if (bTransform)		dwFlags |= TDCGTF_TRANSFORM;	// due task notification preference overrides Export preference	if (bDueTaskTitlesOnly)		dwFlags |= TDCGTF_TITLESONLY;	else if (bParentTitleCommentsOnly)		dwFlags |= TDCGTF_PARENTTITLECOMMENTSONLY;	TDC_GETTASKS nFilter = TDCGT_DUE;	UINT nIDDueBy = IDS_DUETODAY;		switch (nDueBy)	{	case PFP_DUETODAY:		break; // done			case PFP_DUETOMORROW:		nIDDueBy = IDS_DUETOMORROW;		nFilter = TDCGT_DUETOMORROW;		break;			case PFP_DUETHISWEEK:		nIDDueBy = IDS_DUETHISWEEK;		nFilter = TDCGT_DUETHISWEEK;		break;			case PFP_DUENEXTWEEK:		nIDDueBy = IDS_DUENEXTWEEK;		nFilter = TDCGT_DUENEXTWEEK;		break;			case PFP_DUETHISMONTH:		nIDDueBy = IDS_DUETHISMONTH;		nFilter = TDCGT_DUETHISMONTH;		break;			case PFP_DUENEXTMONTH:		nIDDueBy = IDS_DUENEXTMONTH;		nFilter = TDCGT_DUENEXTMONTH;		break;			default:		ASSERT (0);		return FALSE;	}		TDCGETTASKS filter(nFilter, dwFlags);	filter.sAllocTo = userPrefs.GetDueTaskPerson();	CTaskFile tasks;	if (!tdc.GetTasks(tasks, filter))		return FALSE;		// set an appropriate title	tasks.SetReportAttributes(CEnString(nIDDueBy));	tasks.SetCharSet(userPrefs.GetHtmlCharSet());	// save intermediate tasklist to file as required	LogIntermediateTaskList(tasks, tdc.GetFilePath());	// nasty hack to prevent exporters adding space for notes	BOOL bSpaceForNotes = userPrefs.GetExportSpaceForNotes();	if (bSpaceForNotes)		CPreferences().WriteProfileInt(PREF_KEY, _T("ExportSpaceForNotes"), FALSE);		// different file for each	CString sTempFile;	sTempFile.Format(_T("ToDoList.due.%d"), nTDC);	sTempFile = FileMisc::GetTempFileName(sTempFile, bHtmlNotify ? _T("html") : _T("txt"));				BOOL bRes = FALSE;		if (bHtmlNotify) // display in browser?	{		if (bTransform)			bRes = tasks.TransformToFile(sStylesheet, sTempFile, userPrefs.GetHtmlCharSet());		else			bRes = m_mgrImportExport.ExportTaskListToHtml(&tasks, sTempFile);	}	else		bRes = m_mgrImportExport.ExportTaskListToText(&tasks, sTempFile);	if (bRes)	{		Show(FALSE);		m_mgrToDoCtrls.ShowDueTaskNotification(nTDC, sTempFile, bHtmlNotify);	}	// undo hack	if (bSpaceForNotes)		CPreferences().WriteProfileInt(PREF_KEY, _T("ExportSpaceForNotes"), TRUE);		return TRUE;}CString CToDoListWnd::GetTitle() {	static CString sTitle(_T("ToDoList 6.8.10 Feature Release"));	CLocalizer::IgnoreString(sTitle);	return sTitle;}void CToDoListWnd::OnAbout() {	CString sVersion;	sVersion.Format(_T("<b>%s</b> (c) AbstractSpoon 2003-14"), GetTitle());	CLocalizer::IgnoreString(sVersion);	CAboutDlg dialog(IDR_MAINFRAME, 					ABS_LISTCOPYRIGHT, 					sVersion,					CEnString(IDS_ABOUTHEADING), 					CEnString(IDS_ABOUTCONTRIBUTION), 					// format the link into the license so that it is not translated					CEnString(IDS_LICENSE, _T("\"http://www.opensource.org/licenses/eclipse-1.0.php\"")), 					1, 1, 12, 1, 250);		dialog.DoModal();}void CToDoListWnd::OnPreferences() {	DoPreferences();}void CToDoListWnd::DoPreferences(int nInitPage) {	// take a copy of current userPrefs to check changes against	const CPreferencesDlg curPrefs; 		// kill timers	SetTimer(TIMER_READONLYSTATUS, FALSE);	SetTimer(TIMER_TIMESTAMPCHANGE, FALSE);	SetTimer(TIMER_CHECKOUTSTATUS, FALSE);	SetTimer(TIMER_AUTOSAVE, FALSE);	SetTimer(TIMER_TIMETRACKING, FALSE);	SetTimer(TIMER_AUTOMINIMIZE, FALSE);	// restore translation of dynamic menu items shortcut prefs	EnableDynamicMenuTranslation(TRUE);		ASSERT(m_pPrefs);	UINT nRet = m_pPrefs->DoModal(nInitPage);		// updates userPrefs	RedrawWindow();	ResetPrefs();	const CPreferencesDlg& userPrefs = Prefs();		if (nRet == IDOK)	{		SetUITheme(userPrefs.GetUITheme());		// lightbox mgr		if (curPrefs.GetEnableLightboxMgr() != userPrefs.GetEnableLightboxMgr())		{			if (userPrefs.GetEnableLightboxMgr())				CLightBoxMgr::Initialize(this, m_theme.crAppBackDark);			else				CLightBoxMgr::Release();		}		// mark all todoctrls as needing refreshing		m_mgrToDoCtrls.SetAllNeedPreferenceUpdate(TRUE); 				// delete fonts if they appear to have changed		// and recreate in UpdateToDoCtrlPrefs		CString sFaceName;		int nFontSize;				if (!userPrefs.GetTreeFont(sFaceName, nFontSize) || !GraphicsMisc::SameFont(m_fontTree, sFaceName, nFontSize))			GraphicsMisc::VerifyDeleteObject(m_fontTree);				if (!userPrefs.GetCommentsFont(sFaceName, nFontSize) || !GraphicsMisc::SameFont(m_fontComments, sFaceName, nFontSize))			GraphicsMisc::VerifyDeleteObject(m_fontComments);				BOOL bResizeDlg = FALSE;				// topmost		BOOL bTopMost = (userPrefs.GetAlwaysOnTop() && !IsZoomed());				SetWindowPos(bTopMost ? &wndTopMost : &wndNoTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);				// tray icon		m_trayIcon.ShowTrayIcon(userPrefs.GetUseSysTray());				// support for .tdl		if (curPrefs.GetEnableTDLExtension() != userPrefs.GetEnableTDLExtension())		{			CFileRegister filereg(_T("tdl"), _T("tdl_Tasklist"));						if (userPrefs.GetEnableTDLExtension())				filereg.RegisterFileType(_T("Tasklist"), 0);			else				filereg.UnRegisterFileType();		}		// support for tdl web protocol		if (curPrefs.GetEnableTDLProtocol() != userPrefs.GetEnableTDLProtocol())			EnableTDLProtocol(userPrefs.GetEnableTDLProtocol());		// language		CString sLangFile = userPrefs.GetLanguageFile();		BOOL bAdd2Dict = userPrefs.GetEnableAdd2Dictionary();		if (UpdateLanguageTranslationAndRestart(sLangFile, bAdd2Dict, curPrefs))		{			DoExit(TRUE);			return;		}		// default task attributes		UpdateDefaultTaskAttributes(userPrefs);		// source control		BOOL bSourceControl = userPrefs.GetEnableSourceControl();				if (curPrefs.GetEnableSourceControl() != bSourceControl ||			curPrefs.GetSourceControlLanOnly() != userPrefs.GetSourceControlLanOnly())		{			// update all open files to ensure they‘re in the right state			int nCtrl = GetTDCCount();						while (nCtrl--)			{				CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);								// check files in if we‘re disabling sc and this file is				// checked out. however although we 				// are checking in, the file cannot be edited by the user				// until they remove the file from under source control				if (!bSourceControl && tdc.IsCheckedOut())				{					if (tdc.IsModified())						tdc.Save();										tdc.CheckIn();				}				// else checkout if we‘re enabling and auto-checkout is also enabled				else if (bSourceControl)				{					// there can be two reasons for wanting to check out a file					// either the autocheckout preference is set or its a local					// file which is not checked out but has been modified and source					// control now covers all files in which case we save it first					BOOL bPathSupports = m_mgrToDoCtrls.PathSupportsSourceControl(nCtrl);					BOOL bNeedsSave = bPathSupports && !tdc.IsCheckedOut() && tdc.IsModified();					BOOL bWantCheckOut = bNeedsSave || (bPathSupports && userPrefs.GetAutoCheckOut());										if (bNeedsSave)						tdc.Save(); // save silently										tdc.SetStyle(TDCS_ENABLESOURCECONTROL, bPathSupports);					tdc.SetStyle(TDCS_CHECKOUTONLOAD, bPathSupports && userPrefs.GetAutoCheckOut());										if (bWantCheckOut && !tdc.IsCheckedOut())						tdc.CheckOut();				}				// re-sync				m_mgrToDoCtrls.UpdateToDoCtrlReadOnlyUIState(nCtrl);								m_mgrToDoCtrls.RefreshModifiedStatus(nCtrl);				m_mgrToDoCtrls.RefreshLastModified(nCtrl);				m_mgrToDoCtrls.UpdateTabItemText(nCtrl);			}		}				m_toolbar.GetToolBarCtrl().HideButton(ID_TOOLS_TOGGLECHECKIN, !bSourceControl);		// check box in front of task title.		// this is tricky because the checkbox won‘t display if the completion		// column is visible. ie. the completion column take precedence.		// so if the user has just turned on the checkbox in front of		// the task title then we need to turn off the completion column		// on all those tasklists currently showing it. But we only need to do		// this on those tasklists which are managing their own columns else		// it will be handled when we update the preferences in due course.		if (userPrefs.GetTreeCheckboxes() && !curPrefs.GetTreeCheckboxes())		{			int nCtrl = GetTDCCount();							while (nCtrl--)			{				if (m_mgrToDoCtrls.HasOwnColumns(nCtrl))				{					CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);					if (tdc.IsColumnShowing(TDCC_DONE))					{						CTDCColumnIDArray aColumns;						int nCol = tdc.GetVisibleColumns(aColumns);						while (nCol--)						{							if (aColumns[nCol] == TDCC_DONE)							{								aColumns.RemoveAt(nCol);								break;							}						}						tdc.SetVisibleColumns(aColumns);					}				}			}			}		// same again for task icons		if (userPrefs.GetTreeTaskIcons() && !curPrefs.GetTreeTaskIcons())		{			int nCtrl = GetTDCCount();							while (nCtrl--)			{				if (m_mgrToDoCtrls.HasOwnColumns(nCtrl))				{					CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);					if (tdc.IsColumnShowing(TDCC_ICON))					{						CTDCColumnIDArray aColumns;						int nCol = tdc.GetVisibleColumns(aColumns);						while (nCol--)						{							if (aColumns[nCol] == TDCC_ICON)							{								aColumns.RemoveAt(nCol);								break;							}						}						tdc.SetVisibleColumns(aColumns);					}				}			}			}		// menu icons		UINT nPrevID = MapNewTaskPos(curPrefs.GetNewTaskPos(), FALSE);		m_mgrMenuIcons.ChangeImageID(nPrevID, GetNewTaskCmdID());		nPrevID = MapNewTaskPos(curPrefs.GetNewSubtaskPos(), TRUE);		m_mgrMenuIcons.ChangeImageID(nPrevID, GetNewSubtaskCmdID());				// reload menu 		LoadMenubar();				// tab bar		bResizeDlg |= (curPrefs.GetAutoHideTabbar() != userPrefs.GetAutoHideTabbar());				if (curPrefs.GetStackTabbarItems() != userPrefs.GetStackTabbarItems())		{			BOOL bStackTabbar = userPrefs.GetStackTabbarItems();						bResizeDlg = TRUE;			m_tabCtrl.ModifyStyle(bStackTabbar ? 0 : TCS_MULTILINE, bStackTabbar ? TCS_MULTILINE : 0);		}		else			m_tabCtrl.Invalidate(); // handle priority colour changes					// visible filter controls		if (m_bShowFilterBar)			bResizeDlg = TRUE;		BOOL bEnableMultiSel = userPrefs.GetMultiSelFilters();		BOOL bPrevMultiSel = curPrefs.GetMultiSelFilters();		if (bPrevMultiSel != bEnableMultiSel)		{			m_filterBar.EnableMultiSelection(bEnableMultiSel);			// if it was was previously multisel (but not now) then			// refresh the filter because we may have gone from			// multiple selection down to only one			OnViewRefreshfilter();		}		m_filterBar.ShowDefaultFilters(userPrefs.GetShowDefaultFilters());		// title filter option		PUIP_MATCHTITLE nTitleOption = userPrefs.GetTitleFilterOption();		PUIP_MATCHTITLE nPrevTitleOption = curPrefs.GetTitleFilterOption();		if (nPrevTitleOption != nTitleOption)			OnViewRefreshfilter();		// inherited parent task attributes for new tasks		CTDCAttributeArray aParentAttrib;		BOOL bUpdateAttrib;		userPrefs.GetParentAttribsUsed(aParentAttrib, bUpdateAttrib);		CFilteredToDoCtrl::SetInheritedParentAttributes(aParentAttrib, bUpdateAttrib);						// hotkey		UpdateGlobalHotkey();				// time periods		CTimeHelper::SetHoursInOneDay(userPrefs.GetHoursInOneDay());		CTimeHelper::SetDaysInOneWeek(userPrefs.GetDaysInOneWeek());		CDateHelper::SetWeekendDays(userPrefs.GetWeekendDays());				RefreshTabOrder();				// time tracking		if (curPrefs.GetTrackNonActiveTasklists() != userPrefs.GetTrackNonActiveTasklists())			RefreshPauseTimeTracking();				UpdateCaption();		UpdateTabSwitchTooltip();		// colours		if (m_findDlg.GetSafeHwnd())			m_findDlg.RefreshUserPreferences();				// active tasklist userPrefs		UpdateToDoCtrlPreferences();		// then refresh filter bar for any new default cats, statuses, etc		m_filterBar.RefreshFilterControls(GetToDoCtrl());				if (bResizeDlg)			Resize();		// Stickies Support		CString sStickiesPath;		if (userPrefs.GetUseStickies(sStickiesPath))			VERIFY(m_reminders.UseStickies(TRUE, sStickiesPath));		else			m_reminders.UseStickies(FALSE);		// Recently modified period		CFilteredToDoCtrl::SetRecentlyModifiedPeriod(userPrefs.GetRecentlyModifiedPeriod());				// don‘t ask me for the full details on this but it seems as		// though the CSysImageList class is waiting to process a 		// message before we can switch image sizes so we put it		// right at the end after everything is done.		Misc::ProcessMsgLoop();		AppendTools2Toolbar(TRUE);	}		// finally set or terminate the various status check timers	SetTimer(TIMER_READONLYSTATUS, (userPrefs.GetReadonlyReloadOption() != RO_NO));	SetTimer(TIMER_TIMESTAMPCHANGE, (userPrefs.GetTimestampReloadOption() != RO_NO));	SetTimer(TIMER_AUTOSAVE, userPrefs.GetAutoSaveFrequency());	SetTimer(TIMER_CHECKOUTSTATUS, (userPrefs.GetCheckoutOnCheckin() || userPrefs.GetAutoCheckinFrequency()));	SetTimer(TIMER_TIMETRACKING, TRUE);	SetTimer(TIMER_AUTOMINIMIZE, userPrefs.GetAutoMinimizeFrequency());	// re-disable dynamic menu translation	EnableDynamicMenuTranslation(FALSE);}BOOL CToDoListWnd::UpdateLanguageTranslationAndRestart(const CString& sLangFile, BOOL bAdd2Dict, 													   const CPreferencesDlg& curPrefs){	BOOL bDefLang = (CTDLLanguageComboBox::GetDefaultLanguage() == sLangFile);			if (curPrefs.GetLanguageFile() != sLangFile)	{		if (bDefLang || FileMisc::FileExists(sLangFile))		{			// if the language file exists and has changed then inform the user that they to restart			// Note: restarting will also handle bAdd2Dict			if (MessageBox(IDS_RESTARTTOCHANGELANGUAGE, 0, MB_YESNO) == IDYES)			{				return TRUE;			}		}	}	// else if the the user wants to enable/disable ‘Add2Dictionary‘	else if (bAdd2Dict != curPrefs.GetEnableAdd2Dictionary())	{		if (bAdd2Dict && !bDefLang)		{			CLocalizer::SetTranslationOption(ITTTO_ADD2DICTIONARY);			TranslateUIElements();		}		else // disable ‘Add2Dictionary‘			CLocalizer::SetTranslationOption(ITTTO_TRANSLATEONLY);	}	// no need to restart	return FALSE;}void CToDoListWnd::UpdateDefaultTaskAttributes(const CPreferencesDlg& prefs){	m_tdiDefault.sTitle = CEnString(IDS_TASK);	m_tdiDefault.color = prefs.GetDefaultColor();	m_tdiDefault.dateStart.m_dt = prefs.GetAutoDefaultStartDate() ? -1 : 0;	m_tdiDefault.sAllocBy = prefs.GetDefaultAllocBy();	m_tdiDefault.sStatus = prefs.GetDefaultStatus();	m_tdiDefault.dTimeEstimate = prefs.GetDefaultTimeEst(m_tdiDefault.nTimeEstUnits);	m_tdiDefault.dTimeSpent = prefs.GetDefaultTimeSpent(m_tdiDefault.nTimeSpentUnits);	m_tdiDefault.nTimeSpentUnits = m_tdiDefault.nTimeEstUnits; // to match	m_tdiDefault.sCreatedBy = prefs.GetDefaultCreatedBy();	m_tdiDefault.dCost = prefs.GetDefaultCost();	m_tdiDefault.sCommentsTypeID = prefs.GetDefaultCommentsFormat();	m_tdiDefault.nPriority = prefs.GetDefaultPriority();	m_tdiDefault.nRisk = prefs.GetDefaultRisk();		prefs.GetDefaultCategories(m_tdiDefault.aCategories);	prefs.GetDefaultAllocTo(m_tdiDefault.aAllocTo);	prefs.GetDefaultTags(m_tdiDefault.aTags);		m_mgrImportExport.SetDefaultTaskAttributes(m_tdiDefault);}BOOL CToDoListWnd::LoadMenubar(){	m_menubar.DestroyMenu();		if (!m_menubar.LoadMenu(IDR_MAINFRAME))		return FALSE;	SetMenu(&m_menubar);	m_hMenuDefault = m_menubar;	#ifdef _DEBUG	// add menu option to simulate WM_QUERYENDSESSION	m_menubar.InsertMenu((UINT)-1, MFT_STRING, ID_DEBUGENDSESSION, _T("EndSession"));	CLocalizer::EnableTranslation(ID_DEBUGENDSESSION, FALSE);	// and option to display setup dialog on demand	m_menubar.InsertMenu((UINT)-1, MFT_STRING, ID_DEBUGSHOWSETUPDLG, _T("Show Setup"));	CLocalizer::EnableTranslation(ID_DEBUGSHOWSETUPDLG, FALSE);#endif	if (Prefs().GetShowTasklistCloseButton()) 		m_menubar.AddMDIButton(MEB_CLOSE, ID_CLOSE);	if (CThemed::IsThemeActive())		m_menubar.SetBackgroundColor(m_theme.crMenuBack);	DrawMenuBar();	// disable translation of dynamic menus	EnableDynamicMenuTranslation(FALSE);	return TRUE;}void CToDoListWnd::EnableDynamicMenuTranslation(BOOL bEnable){	CLocalizer::EnableTranslation(ID_FILE_MRU_FIRST, ID_FILE_MRU_LAST, bEnable);	CLocalizer::EnableTranslation(ID_WINDOW1, ID_WINDOW16, bEnable);	CLocalizer::EnableTranslation(ID_TOOLS_USERTOOL1, ID_TOOLS_USERTOOL16, bEnable);	CLocalizer::EnableTranslation(ID_FILE_OPEN_USERSTORAGE1, ID_FILE_OPEN_USERSTORAGE16, bEnable);	CLocalizer::EnableTranslation(ID_FILE_SAVE_USERSTORAGE1, ID_FILE_SAVE_USERSTORAGE16, bEnable);	CLocalizer::EnableTranslation(ID_TRAYICON_SHOWDUETASKS1, ID_TRAYICON_SHOWDUETASKS20, bEnable);}void CToDoListWnd::UpdateGlobalHotkey(){	static DWORD dwPrevHotkey = 0;	DWORD dwHotkey = Prefs().GetGlobalHotkey();		if (dwPrevHotkey == dwHotkey)		return;		if (dwHotkey == 0) // disabled		::UnregisterHotKey(*this, 1);	else	{		// map modifiers to those wanted by RegisterHotKey		DWORD dwPrefMods = HIWORD(dwHotkey);		DWORD dwVKey = LOWORD(dwHotkey);				DWORD dwMods = (dwPrefMods & HOTKEYF_ALT) ? MOD_ALT : 0;		dwMods |= (dwPrefMods & HOTKEYF_CONTROL) ? MOD_CONTROL : 0;		dwMods |= (dwPrefMods & HOTKEYF_SHIFT) ? MOD_SHIFT : 0;				RegisterHotKey(*this, 1, dwMods, dwVKey);	}	dwPrevHotkey = dwHotkey;}void CToDoListWnd::RefreshPauseTimeTracking(){	// time tracking	int nCtrl = GetTDCCount();	int nSel = GetSelToDoCtrl();	BOOL bTrackActiveOnly = !Prefs().GetTrackNonActiveTasklists();		while (nCtrl--)	{		BOOL bSel = (nCtrl == nSel);		CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);				tdc.PauseTimeTracking(bSel ? FALSE : bTrackActiveOnly);	}}BOOL CToDoListWnd::ProcessStartupOptions(const TDCSTARTUP& startup){	// 1. check if we can handle a task link	if (startup.HasFlag(TLD_TASKLINK))	{		CStringArray aFiles;		if (startup.GetFilePaths(aFiles))		{			CString sFile;			DWORD dwTaskID = 0;			CFilteredToDoCtrl::ParseTaskLink(aFiles[0], dwTaskID, sFile);			return DoTaskLink(sFile, dwTaskID);		}		// else		return FALSE;	}	// 2. execute a command	if (startup.HasCommandID())	{		SendMessage(WM_COMMAND, MAKEWPARAM(startup.GetCommandID(), 0), 0);		return TRUE;	}	// 3. try open/import file	if (startup.HasFilePath())	{		int nFirstSel = -1;		BOOL bSuccess = FALSE;		CStringArray aFilePaths;		int nNumFiles = startup.GetFilePaths(aFilePaths);		for (int nFile = 0; nFile < nNumFiles; nFile++)		{			const CString& sFilePath = aFilePaths[nFile];						if (startup.HasFlag(TLD_IMPORTFILE))			{				if (ImportFile(sFilePath, TRUE))				{					bSuccess = TRUE;				}			}			else			{				BOOL bCanDelayLoad = Prefs().GetEnableDelayedLoading();				// open the first tasklist fully and the rest delayed				if (!bSuccess || !Prefs().GetEnableDelayedLoading())				{					if (OpenTaskList(sFilePath, FALSE) == TDCO_SUCCESS)					{						bSuccess = TRUE;					}				}				else if (DelayOpenTaskList(sFilePath) == TDCO_SUCCESS)				{					bSuccess = TRUE;				}			}			// snapshot the first success for subsequent selection			if (bSuccess && (nFirstSel == -1))				nFirstSel = GetSelToDoCtrl();		}				// exit on failure		if (!bSuccess)			return FALSE;		// set selection to first tasklist loaded		ASSERT((nFirstSel != -1) && (nFirstSel < GetTDCCount()));		SelectToDoCtrl(nFirstSel, FALSE);	}		CFilteredToDoCtrl& tdc = GetToDoCtrl();	BOOL bRes = FALSE;		if (startup.HasFlag(TLD_NEWTASK))	{		CEnString sNewTask;		BOOL bEditTask = FALSE;				// we edit the task name if no name was supplied		if (!startup.GetNewTask(sNewTask))		{			sNewTask.LoadString(IDS_TASK);			bEditTask = TRUE;		}				// do we have a parent task ?		if (tdc.SelectTask(startup.GetParentTaskID()))		{			bRes = CreateNewTask(sNewTask, TDC_INSERTATTOPOFSELTASK, FALSE);		}		// or a sibling task ?		else if (tdc.SelectTask(startup.GetSiblingTaskID()))		{			bRes = CreateNewTask(sNewTask, TDC_INSERTAFTERSELTASK, FALSE);		}			else		{			bRes = CreateNewTask(sNewTask, TDC_INSERTATTOP, FALSE);		}			// creation date		double dDate;		if (startup.GetCreationDate(dDate))			tdc.SetSelectedTaskDate(TDCD_CREATE, dDate);				// edit task title?		if (bRes && bEditTask)			PostMessage(WM_COMMAND, ID_EDIT_TASKTEXT);	}	else if (startup.GetTaskID())	{		bRes = tdc.SelectTask(startup.GetTaskID());	}	else // works on the currently selected item(s)	{		bRes = (tdc.GetSelectedCount() > 0);	}	// rest of task attributes	if (bRes)	{		CStringArray aItems;		CString sItem;		int nItem;		double dItem;				if (startup.GetComments(sItem))			tdc.SetSelectedTaskComments(sItem, sItem);				if (startup.GetExternalID(sItem))			tdc.SetSelectedTaskExtID(sItem);				if (startup.GetVersion(sItem))			tdc.SetSelectedTaskVersion(sItem);				if (startup.GetAllocTo(aItems))			tdc.SetSelectedTaskAllocTo(aItems);				if (startup.GetAllocBy(sItem))			tdc.SetSelectedTaskAllocBy(sItem);				if (startup.GetCategories(aItems))			tdc.SetSelectedTaskCategories(aItems);				if (startup.GetTags(aItems))			tdc.SetSelectedTaskTags(aItems);				if (startup.GetStatus(sItem))			tdc.SetSelectedTaskStatus(sItem);				if (startup.GetFileRef(sItem))			tdc.SetSelectedTaskFileRef(sItem);		if (startup.GetPriority(nItem))			tdc.SetSelectedTaskPriority(nItem);		if (startup.GetRisk(nItem))			tdc.SetSelectedTaskRisk(nItem);		if (startup.GetPercentDone(nItem))			tdc.SetSelectedTaskPercentDone(nItem);		if (startup.GetCost(dItem))			tdc.SetSelectedTaskCost(dItem);		if (startup.GetTimeEst(dItem))			tdc.SetSelectedTaskTimeEstimate(dItem); // in hours		if (startup.GetTimeSpent(dItem))			tdc.SetSelectedTaskTimeSpent(dItem); // in hours		if (startup.GetStartDate(dItem))			tdc.SetSelectedTaskDate(TDCD_START, dItem);		if (startup.GetDueDate(dItem))			tdc.SetSelectedTaskDate(TDCD_DUE, dItem);		if (startup.GetDoneDate(dItem))			tdc.SetSelectedTaskDate(TDCD_DONE, dItem);	}	return bRes;}BOOL CToDoListWnd::OnCopyData(CWnd* /*pWnd*/, COPYDATASTRUCT* pCopyDataStruct){	BOOL bRes = FALSE;	switch (pCopyDataStruct->dwData)	{	case TDL_STARTUP:		{			ASSERT(pCopyDataStruct->cbData =http://www.mamicode.com/= sizeof(TDCSTARTUP));"tdl://%ld"), tdc.GetSelectedTaskID());		break;			case TDCTC_ASDEPENDS:		sTasks.Format(_T("%ld"), tdc.GetSelectedTaskID());		break;			case TDCTC_ASLINKFULL:		sTasks.Format(_T("tdl://%s?%ld"), 						tdc.GetFilePath(),						tdc.GetSelectedTaskID());		sTasks.Replace(_T(" "), _T("%20"));		break;			case TDCTC_ASDEPENDSFULL:		sTasks.Format(_T("%s?%ld"), 						tdc.GetFilePath(),						tdc.GetSelectedTaskID());		break;	case TDCTC_ASPATH:		sTasks = tdc.GetSelectedTaskPath(TRUE);		break;	}	Misc::CopyTexttoClipboard(sTasks, *this);}void CToDoListWnd::OnUpdateEditCopy(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().GetSelectedCount() > 0);}BOOL CToDoListWnd::CanCreateNewTask(TDC_INSERTWHERE nInsertWhere) const{	return GetToDoCtrl().CanCreateNewTask(nInsertWhere);}void CToDoListWnd::OnUpdateNewtaskAttopSelected(CCmdUI* pCmdUI) {	pCmdUI->Enable(CanCreateNewTask(TDC_INSERTATTOPOFSELTASKPARENT));}void CToDoListWnd::OnUpdateNewtaskAtbottomSelected(CCmdUI* pCmdUI) {	pCmdUI->Enable(CanCreateNewTask(TDC_INSERTATBOTTOMOFSELTASKPARENT));}void CToDoListWnd::OnUpdateNewtaskAfterselectedtask(CCmdUI* pCmdUI) {	pCmdUI->Enable(CanCreateNewTask(TDC_INSERTAFTERSELTASK));}void CToDoListWnd::OnUpdateNewtaskBeforeselectedtask(CCmdUI* pCmdUI) {	pCmdUI->Enable(CanCreateNewTask(TDC_INSERTBEFORESELTASK));}void CToDoListWnd::OnUpdateNewsubtaskAttop(CCmdUI* pCmdUI) {	pCmdUI->Enable(CanCreateNewTask(TDC_INSERTATTOPOFSELTASK));}void CToDoListWnd::OnUpdateNewsubtaskAtBottom(CCmdUI* pCmdUI) {	pCmdUI->Enable(CanCreateNewTask(TDC_INSERTATBOTTOMOFSELTASK));}void CToDoListWnd::OnUpdateNewtaskAttop(CCmdUI* pCmdUI) {	pCmdUI->Enable(CanCreateNewTask(TDC_INSERTATTOP));}void CToDoListWnd::OnUpdateNewtaskAtbottom(CCmdUI* pCmdUI) {	pCmdUI->Enable(CanCreateNewTask(TDC_INSERTATBOTTOM));}void CToDoListWnd::OnMaximizeTasklist() {	// toggle max state on or off	switch (m_nMaxState)	{	case TDCMS_MAXTASKLIST:		// turn off maximize tasklist by restoring previous max state		m_nMaxState = m_nPrevMaxState;		m_nPrevMaxState = TDCMS_NORMAL; // reset		break;	case TDCMS_MAXCOMMENTS:		// turn on maximize tasklist and save previous max state		m_nMaxState = TDCMS_MAXTASKLIST;		m_nPrevMaxState = TDCMS_MAXCOMMENTS;		break;	case TDCMS_NORMAL:		// turn on maximize tasklist		m_nMaxState = TDCMS_MAXTASKLIST;		m_nPrevMaxState = TDCMS_NORMAL; // reset		break;	}		// update active tasklist	GetToDoCtrl().SetMaximizeState(m_nMaxState);	Invalidate();	// and caption	UpdateCaption();}void CToDoListWnd::OnUpdateMaximizeTasklist(CCmdUI* pCmdUI) {	pCmdUI->SetCheck(m_nMaxState == TDCMS_MAXTASKLIST ? 1 : 0);}void CToDoListWnd::OnMaximizeComments() {	// toggle max state on or off	switch (m_nMaxState)	{	case TDCMS_MAXCOMMENTS:		// toggle off maximize comments by restoring previous max state		m_nMaxState = m_nPrevMaxState;		m_nPrevMaxState = TDCMS_NORMAL; // reset		break;	case TDCMS_MAXTASKLIST:		// turn on maximize comments and save previous max state		m_nMaxState = TDCMS_MAXCOMMENTS;		m_nPrevMaxState = TDCMS_MAXTASKLIST;		break;	case TDCMS_NORMAL:		// turn on maximize comments		m_nMaxState = TDCMS_MAXCOMMENTS;		m_nPrevMaxState = TDCMS_NORMAL; // reset		break;	}		// update active tasklist	GetToDoCtrl().SetMaximizeState(m_nMaxState);	Invalidate();	// and caption	UpdateCaption();}void CToDoListWnd::OnUpdateMaximizeComments(CCmdUI* pCmdUI) {	pCmdUI->SetCheck(m_nMaxState == TDCMS_MAXCOMMENTS ? 1 : 0);}void CToDoListWnd::OnReload() {	int nSel = GetSelToDoCtrl();		if (m_mgrToDoCtrls.GetModifiedStatus(nSel))	{ 		if (IDYES != MessageBox(IDS_CONFIRMRELOAD, IDS_CONFIRMRELOAD_TITLE, MB_YESNOCANCEL | MB_DEFBUTTON2))		{			return;		}	}		// else reload	ReloadTaskList(nSel);	RefreshTabOrder();}BOOL CToDoListWnd::ReloadTaskList(int nIndex, BOOL bNotifyDueTasks, BOOL bNotifyError){	CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);		TDC_FILE nRes = OpenTaskList(&tdc);		if (nRes == TDCO_SUCCESS)	{		const CPreferencesDlg& userPrefs = Prefs();				// update file status		if (userPrefs.GetAutoCheckOut())			m_mgrToDoCtrls.SetLastCheckoutStatus(nIndex, tdc.IsCheckedOut());				m_mgrToDoCtrls.RefreshLastModified(nIndex);		m_mgrToDoCtrls.SetModifiedStatus(nIndex, FALSE);		m_mgrToDoCtrls.UpdateTabItemText(nIndex);				// notify user of due tasks if req		if (bNotifyDueTasks)			DoDueTaskNotification(nIndex, userPrefs.GetNotifyDueByOnLoad());				UpdateCaption();		UpdateStatusbar();	}	else if (bNotifyError)	{		HandleLoadTasklistError(nRes, tdc.GetFilePath());	}	return (nRes == TDCO_SUCCESS);}void CToDoListWnd::OnUpdateReload(CCmdUI* pCmdUI) {	int nSel = GetSelToDoCtrl();		pCmdUI->Enable(!m_mgrToDoCtrls.GetFilePath(nSel).IsEmpty());}void CToDoListWnd::OnSize(UINT nType, int cx, int cy) {	CFrameWnd::OnSize(nType, cx, cy);		// ensure m_cbQuickFind is positioned correctly	int nPos = m_toolbar.CommandToIndex(ID_EDIT_FINDTASKS) + 2;	CRect rNewPos, rOrgPos;	m_toolbar.GetItemRect(nPos, rNewPos);	m_toolbar.ClientToScreen(rNewPos);	m_cbQuickFind.CWnd::GetWindowRect(rOrgPos);	// check if it needs to be moved	if (rNewPos.TopLeft() != rOrgPos.TopLeft())	{		m_toolbar.ScreenToClient(rNewPos);		rNewPos.bottom = rNewPos.top + 200;		m_cbQuickFind.MoveWindow(rNewPos);	}	// topmost?	BOOL bMaximized = (nType == SIZE_MAXIMIZED);		if (nType != SIZE_MINIMIZED)		Resize(cx, cy, bMaximized);		// if not maximized then set topmost if that‘s the preference	BOOL bTopMost = (Prefs().GetAlwaysOnTop() && !bMaximized) ? 1 : 0;		// do nothing if no change	BOOL bIsTopMost = (GetExStyle() & WS_EX_TOPMOST) ? 1 : 0;		if (bTopMost != bIsTopMost)		SetWindowPos(bTopMost ? &wndTopMost : &wndNoTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);}BOOL CToDoListWnd::CalcToDoCtrlRect(CRect& rect, int cx, int cy, BOOL bMaximized){	if (!cx && !cy)	{		CRect rClient;		GetClientRect(rClient);				cx = rClient.right;		cy = rClient.bottom;		bMaximized = IsZoomed();				// check again 		if (!cx && !cy)			return FALSE;	}		CRect rTaskList(0, BEVEL, cx - BEVEL, cy);		// toolbar	if (m_bShowToolbar)  		rTaskList.top += m_toolbar.GetHeight() + TB_VOFFSET;		// resize tabctrl	CDeferWndMove dwm(0); // dummy		CPoint ptOrg(0, rTaskList.top);	int nTabHeight = ReposTabBar(dwm, ptOrg, cx, TRUE);		if (nTabHeight)		rTaskList.top += nTabHeight + 1; // hide the bottom of the tab ctrl		// filter controls	int nInset = (CThemed().IsNonClientThemed() ? BORDER : BEVEL);	int nFilterWidth = cx - 2 * nInset;	int nFilterHeight = m_bShowFilterBar ? m_filterBar.CalcHeight(nFilterWidth) : 0;		if (nFilterHeight)		rTaskList.top += nFilterHeight;// + 4;		// statusbar	if (m_bShowStatusBar)	{		CRect rStatus;		m_statusBar.GetWindowRect(rStatus);		ScreenToClient(rStatus);		rTaskList.bottom = rStatus.top - BORDER;	}	else		rTaskList.bottom = cy - BORDER;		// shrink slightly so that edit controls do not merge with window border	rTaskList.DeflateRect(nInset, nInset, nInset, nInset);	rect = rTaskList;		return TRUE;}void CToDoListWnd::Resize(int cx, int cy, BOOL bMaximized){	static int nLastCx = 0, nLastCy = 0;	if (!cx && !cy)	{		CRect rClient;		GetClientRect(rClient);				cx = rClient.right;		cy = rClient.bottom;		bMaximized = IsZoomed();				// check again 		if (!cx && !cy)			return;	}	if (cx == nLastCx && cy == nLastCy && !GetTDCCount())		return;	nLastCx = cx;	nLastCy = cy;		// resize in one go	CDlgUnits dlu(*this);	CDeferWndMove dwm(6);	CRect rTaskList(0, BEVEL, cx - BEVEL, cy);		// toolbar	if (m_bShowToolbar) // showing toolbar		rTaskList.top += m_toolbar.Resize(cx, CPoint(0, TB_VOFFSET)) + TB_VOFFSET;		// resize tabctrl	CPoint ptOrg(0, rTaskList.top);	int nTabHeight = ReposTabBar(dwm, ptOrg, cx);		if (nTabHeight)		rTaskList.top += nTabHeight + 1; // hide the bottom of the tab ctrl		// filter controls	int nInset = (CThemed().IsNonClientThemed() ? BORDER : BEVEL);	int nFilterWidth = cx - 2 * nInset;	int nFilterHeight = m_bShowFilterBar ? m_filterBar.CalcHeight(nFilterWidth) : 0;		dwm.MoveWindow(&m_filterBar, nInset, rTaskList.top, nFilterWidth, nFilterHeight);		if (nFilterHeight)		rTaskList.top += nFilterHeight;// + 4;		// statusbar has already been automatically resized unless it‘s invisible	CRect rStatus(0, cy, cx, cy);	if (m_bShowStatusBar)	{		m_statusBar.GetWindowRect(rStatus);		ScreenToClient(rStatus);	}	else		dwm.MoveWindow(&m_statusBar, rStatus, FALSE);		// finally the active todoctrl	if (GetTDCCount())	{		if (m_bShowStatusBar)			rTaskList.bottom = rStatus.top - BORDER;		else			rTaskList.bottom = rStatus.bottom - BORDER;				// shrink slightly so that edit controls do not merge with window border		rTaskList.DeflateRect(nInset, nInset, nInset, nInset);		dwm.MoveWindow(&GetToDoCtrl(), rTaskList);#ifdef _DEBUG		CRect rect;		CalcToDoCtrlRect(rect, cx, cy, IsZoomed());		ASSERT(rect == rTaskList);#endif	}}BOOL CToDoListWnd::WantTasklistTabbarVisible() const { 	BOOL bWantTabbar = (GetTDCCount() > 1 || !Prefs().GetAutoHideTabbar()); 	bWantTabbar &= m_bShowTasklistBar;	return bWantTabbar;}int CToDoListWnd::ReposTabBar(CDeferWndMove& dwm, const CPoint& ptOrg, int nWidth, BOOL bCalcOnly){	CRect rTabs(0, 0, nWidth, 0);	m_tabCtrl.AdjustRect(TRUE, rTabs);	int nTabHeight = rTabs.Height() - 4;		rTabs = dwm.OffsetCtrl(this, IDC_TABCONTROL); // not actually a move	rTabs.right = nWidth + 1;	rTabs.bottom = rTabs.top + nTabHeight;	rTabs.OffsetRect(0, ptOrg.y - rTabs.top + 1); // add a pixel between tabbar and toolbar		BOOL bNeedTabCtrl = WantTasklistTabbarVisible();		if (!bCalcOnly)	{		dwm.MoveWindow(&m_tabCtrl, rTabs);				// hide and disable tabctrl if not needed		m_tabCtrl.ShowWindow(bNeedTabCtrl ? SW_SHOW : SW_HIDE);		m_tabCtrl.EnableWindow(bNeedTabCtrl);		if (bNeedTabCtrl)			UpdateTabSwitchTooltip();	}		return bNeedTabCtrl ? rTabs.Height() : 0;}void CToDoListWnd::OnPrint() {	DoPrint();}void CToDoListWnd::DoPrint(BOOL bPreview){	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelTDC = GetSelToDoCtrl();	// pass the project name as the title field	CString sTitle = m_mgrToDoCtrls.GetFriendlyProjectName(nSelTDC);	// export to html and then print in IE	CTDLPrintDialog dialog(sTitle, bPreview, tdc.GetView());		if (dialog.DoModal() != IDOK)		return;	RedrawWindow();		// always use the same file	CString sTempFile = FileMisc::GetTempFileName(_T("ToDoList.print"), _T("html"));		// stylesheets don‘t seem to like the way we do html comments	CString sStylesheet = dialog.GetStylesheet();	BOOL bTransform = FileMisc::FileExists(sStylesheet);	sTitle = dialog.GetTitle();		// export	DOPROGRESS(bPreview ? IDS_PPREVIEWPROGRESS : IDS_PRINTPROGRESS)	CTaskFile tasks;	GetTasks(tdc, TRUE, bTransform, dialog.GetTaskSelection(), tasks, NULL);	// add title and date, and style 	COleDateTime date;	if (dialog.GetWantDate())		date = COleDateTime::GetCurrentTime();	tasks.SetReportAttributes(sTitle, date);	// add export style	if (!bTransform)	{		TDLPD_STYLE nStyle = dialog.GetExportStyle();		tasks.SetMetaData(TDL_EXPORTSTYLE, Misc::Format(nStyle));	}		// save intermediate tasklist to file as required	LogIntermediateTaskList(tasks, tdc.GetFilePath());	if (!Export2Html(tasks, sTempFile, sStylesheet))		return;		// print from browser	CRect rHidden(-20, -20, -10, -10); // create IE off screen		if (m_IE.GetSafeHwnd() || m_IE.Create(NULL, WS_CHILD | WS_VISIBLE, rHidden, this, (UINT)IDC_STATIC))	{		double dFileSize = FileMisc::GetFileSize(sTempFile);		BOOL bPrintBkgnd = Prefs().GetColorTaskBackground();		if (bPreview)			m_IE.PrintPreview(sTempFile, bPrintBkgnd);		else			m_IE.Print(sTempFile, bPrintBkgnd);	}	else // try sending to browser	{		int nRes = (int)::ShellExecute(*this, bPreview ? _T("print") : NULL, sTempFile, NULL, NULL, SW_HIDE);										if (nRes < 32)			MessageBox(IDS_PRINTFAILED, IDS_PRINTFAILED_TITLE, MB_OK);	}}void CToDoListWnd::OnUpdatePrint(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().GetTaskCount());}int CToDoListWnd::AddToDoCtrl(CFilteredToDoCtrl* pTDC, TSM_TASKLISTINFO* pInfo, BOOL bResizeDlg){	// add tdc first to ensure tab controls has some	// items before we query it for its size	int nSel = m_mgrToDoCtrls.AddToDoCtrl(pTDC, pInfo);		// make sure size is right	CRect rTDC;		if (CalcToDoCtrlRect(rTDC))		pTDC->MoveWindow(rTDC);		SelectToDoCtrl(nSel, FALSE);	pTDC->SetFocusToTasks();		// make sure the tab control is correctly sized	if (bResizeDlg)		Resize();		// if this is the only control then set or terminate the various status 	// check timers	if (GetTDCCount() == 1)	{		const CPreferencesDlg& userPrefs = Prefs();				SetTimer(TIMER_READONLYSTATUS, userPrefs.GetReadonlyReloadOption() != RO_NO);		SetTimer(TIMER_TIMESTAMPCHANGE, userPrefs.GetTimestampReloadOption() != RO_NO);		SetTimer(TIMER_AUTOSAVE, userPrefs.GetAutoSaveFrequency());		SetTimer(TIMER_CHECKOUTSTATUS, 				userPrefs.GetCheckoutOnCheckin() ||	userPrefs.GetAutoCheckinFrequency());	}		// make sure everything looks okay	Invalidate();	UpdateWindow();		return nSel;}void CToDoListWnd::SetTimer(UINT nTimerID, BOOL bOn){	if (bOn)	{		UINT nPeriod = 0;				switch (nTimerID)		{		case TIMER_READONLYSTATUS:			nPeriod = INTERVAL_READONLYSTATUS;			break;					case TIMER_TIMESTAMPCHANGE:			nPeriod = INTERVAL_TIMESTAMPCHANGE;			break;					case TIMER_AUTOSAVE:			nPeriod = (Prefs().GetAutoSaveFrequency() * ONE_MINUTE);			break;					case TIMER_CHECKOUTSTATUS:			nPeriod = INTERVAL_CHECKOUTSTATUS;			break;					case TIMER_DUEITEMS:			nPeriod = INTERVAL_DUEITEMS;			break;					case TIMER_TIMETRACKING:			nPeriod = INTERVAL_TIMETRACKING;			break;					case TIMER_AUTOMINIMIZE:			nPeriod = (Prefs().GetAutoMinimizeFrequency() * ONE_MINUTE);			break;		}				if (nPeriod)		{			UINT nID = CFrameWnd::SetTimer(nTimerID, nPeriod, NULL);			ASSERT (nID);		}	}	else		KillTimer(nTimerID);}void CToDoListWnd::OnTimer(UINT nIDEvent) {	CFrameWnd::OnTimer(nIDEvent);		// if we are disabled (== modal dialog visible) then do not respond	if (!IsWindowEnabled())		return;		// don‘t check whilst in the middle of saving or closing	if (m_bSaving || m_bClosing)		return;		// if no controls are active kill the timers	if (!GetTDCCount())	{		SetTimer(TIMER_READONLYSTATUS, FALSE);		SetTimer(TIMER_TIMESTAMPCHANGE, FALSE);		SetTimer(TIMER_AUTOSAVE, FALSE);		SetTimer(TIMER_CHECKOUTSTATUS, FALSE);		SetTimer(TIMER_DUEITEMS, FALSE);		SetTimer(TIMER_TIMETRACKING, FALSE);		SetTimer(TIMER_AUTOMINIMIZE, FALSE);		return;	}		switch (nIDEvent)	{	case TIMER_READONLYSTATUS:		OnTimerReadOnlyStatus();		break;			case TIMER_TIMESTAMPCHANGE:		OnTimerTimestampChange();		break;			case TIMER_AUTOSAVE:		OnTimerAutoSave();		break;			case TIMER_CHECKOUTSTATUS:		OnTimerCheckoutStatus();		break;			case TIMER_DUEITEMS:		OnTimerDueItems();		break;			case TIMER_TIMETRACKING:		OnTimerTimeTracking();		break;			case TIMER_AUTOMINIMIZE:		OnTimerAutoMinimize();		break;	}}BOOL CToDoListWnd::IsActivelyTimeTracking() const{	// cycle thru tasklists until we find a time tracker	int nCtrl = GetTDCCount();		while (nCtrl--)	{		if (GetToDoCtrl(nCtrl).IsActivelyTimeTracking())			return TRUE;	}	// else	return FALSE;}void CToDoListWnd::OnTimerTimeTracking(){	AF_NOREENTRANT // macro helper			static BOOL bWasTimeTracking = FALSE;	BOOL bNowTimeTracking = IsActivelyTimeTracking();			if (bWasTimeTracking != bNowTimeTracking)	{		UINT nIDTrayIcon = (bNowTimeTracking ? IDI_TRAYTRACK_STD : IDI_TRAY_STD);		m_trayIcon.SetIcon(nIDTrayIcon);		// set the main window icon also as this helps the user know what‘s going on		HICON hIcon = GraphicsMisc::LoadIcon(nIDTrayIcon);		SetIcon(hIcon, FALSE);	}		bWasTimeTracking = bNowTimeTracking;}void CToDoListWnd::OnTimerDueItems(int nCtrl){	AF_NOREENTRANT // macro helper			int nFrom = (nCtrl == -1) ? 0 : nCtrl;	int nTo = (nCtrl == -1) ? GetTDCCount() - 1 : nCtrl;	BOOL bRepaint = FALSE;		for (nCtrl = nFrom; nCtrl <= nTo; nCtrl++)	{		// first we search for overdue items on each tasklist and if that		// fails to find anything we then search for items due today		// but only if the tasklist is fully loaded		if (m_mgrToDoCtrls.IsLoaded(nCtrl))		{			CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);			TDCM_DUESTATUS nStatus = TDCM_NONE;						if (tdc.HasOverdueTasks()) // takes priority				nStatus = TDCM_PAST;			else if (tdc.HasDueTodayTasks())				nStatus = TDCM_TODAY;						if (nStatus != m_mgrToDoCtrls.GetDueItemStatus(nCtrl))			{				m_mgrToDoCtrls.SetDueItemStatus(nCtrl, nStatus);				bRepaint = TRUE;			}		}	}	if (bRepaint)		m_tabCtrl.Invalidate(FALSE);}void CToDoListWnd::OnTimerReadOnlyStatus(int nCtrl){	AF_NOREENTRANT // macro helper			const CPreferencesDlg& userPrefs = Prefs();		// work out whether we should check remote files or not	BOOL bCheckRemoteFiles = (nCtrl != -1);		if (!bCheckRemoteFiles)	{		static int nElapsed = 0;		UINT nRemoteFileCheckInterval = userPrefs.GetRemoteFileCheckFrequency() * 1000; // in ms				nElapsed %= nRemoteFileCheckInterval;		bCheckRemoteFiles = !nElapsed;				nElapsed += INTERVAL_READONLYSTATUS;	}		int nReloadOption = userPrefs.GetReadonlyReloadOption();		ASSERT (nReloadOption != RO_NO);		// process files	CString sFileList;	int nFrom = (nCtrl == -1) ? 0 : nCtrl;	int nTo = (nCtrl == -1) ? GetTDCCount() - 1 : nCtrl;		for (nCtrl = nFrom; nCtrl <= nTo; nCtrl++)	{		// don‘t check delay-loaded tasklists		if (!m_mgrToDoCtrls.IsLoaded(nCtrl))			continue;				// don‘t check removeable drives		int nType = m_mgrToDoCtrls.GetFilePathType(nCtrl);		        if (nType == TDCM_UNDEF || nType == TDCM_REMOVABLE)			continue;				// check remote files?		if (!bCheckRemoteFiles && nType == TDCM_REMOTE)			continue;						if (m_mgrToDoCtrls.RefreshReadOnlyStatus(nCtrl))		{			CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);					BOOL bReadOnly = m_mgrToDoCtrls.GetReadOnlyStatus(nCtrl);			BOOL bReload = FALSE;						if (nReloadOption == RO_ASK)			{				CString sFilePath = tdc.GetFilePath();				CEnString sMessage(bReadOnly ? IDS_WRITABLETOREADONLY : IDS_READONLYTOWRITABLE, sFilePath);								if (!bReadOnly) // might been modified					sMessage += CEnString(IDS_WANTRELOAD);				UINT nRet = MessageBox(sMessage, IDS_STATUSCHANGE_TITLE, !bReadOnly ? MB_YESNOCANCEL : MB_OK);								bReload = (nRet == IDYES || nRet == IDOK);			}			else				bReload = !bReadOnly; // now writable						if (bReload && ReloadTaskList(nCtrl, FALSE, (nReloadOption == RO_ASK)))			{				// notify the user if we haven‘t already				if (nReloadOption == RO_NOTIFY)				{					sFileList += tdc.GetFriendlyProjectName();					sFileList += "\n";				}			}			else // update the UI			{				if (nCtrl == m_tabCtrl.GetCurSel())					UpdateCaption();								m_mgrToDoCtrls.UpdateToDoCtrlReadOnlyUIState(nCtrl);				m_mgrToDoCtrls.UpdateTabItemText(nCtrl);			}		}	}		// do we need to notify the user?	if (!sFileList.IsEmpty())	{		CEnString sMessage(IDS_TASKLISTSRELOADED, sFileList);		m_trayIcon.ShowBalloon(sMessage, CEnString(IDS_TIMESTAMPCHANGE_BALLOONTITLE), NIIF_INFO);	}}void CToDoListWnd::OnTimerTimestampChange(int nCtrl){	AF_NOREENTRANT // macro helper			const CPreferencesDlg& userPrefs = Prefs();	int nReloadOption = userPrefs.GetTimestampReloadOption();		ASSERT (nReloadOption != RO_NO);		// work out whether we should check remote files or not	BOOL bCheckRemoteFiles = (nCtrl != -1);		if (!bCheckRemoteFiles)	{		static int nElapsed = 0;		UINT nRemoteFileCheckInterval = userPrefs.GetRemoteFileCheckFrequency() * 1000; // in ms				nElapsed %= nRemoteFileCheckInterval;		bCheckRemoteFiles = !nElapsed;				nElapsed += INTERVAL_TIMESTAMPCHANGE;	}		// process files	CString sFileList;	int nFrom = (nCtrl == -1) ? 0 : nCtrl;	int nTo = (nCtrl == -1) ? GetTDCCount() - 1 : nCtrl;		for (nCtrl = nFrom; nCtrl <= nTo; nCtrl++)	{		// don‘t check delay-loaded tasklists		if (!m_mgrToDoCtrls.IsLoaded(nCtrl))			continue;		// don‘t check removeable drives		int nType = m_mgrToDoCtrls.GetFilePathType(nCtrl);		        if (nType == TDCM_UNDEF || nType == TDCM_REMOVABLE)			continue;				// check remote files?		if (!bCheckRemoteFiles && nType == TDCM_REMOTE)			continue;				if (m_mgrToDoCtrls.RefreshLastModified(nCtrl))		{			CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);			BOOL bReload = TRUE; // default						if (nReloadOption == RO_ASK)			{				CString sFilePath = tdc.GetFilePath();							CEnString sMessage(IDS_MODIFIEDELSEWHERE, sFilePath);				sMessage += CEnString(IDS_WANTRELOAD);								bReload = (MessageBox(sMessage, IDS_TIMESTAMPCHANGE_TITLE, MB_YESNOCANCEL) == IDYES);			}						if (bReload && ReloadTaskList(nCtrl, FALSE, (nReloadOption == RO_ASK)))			{				// notify the user if we haven‘t already				if (nReloadOption == RO_NOTIFY)				{					sFileList += tdc.GetFriendlyProjectName();					sFileList += "\n";				}			}			else			{				// update UI				if (nCtrl == m_tabCtrl.GetCurSel())					UpdateCaption();								m_mgrToDoCtrls.UpdateToDoCtrlReadOnlyUIState(nCtrl);				m_mgrToDoCtrls.UpdateTabItemText(nCtrl);			}		}	}		// do we need to notify the user?	if (!sFileList.IsEmpty())	{		CEnString sMessage(IDS_TASKLISTSRELOADED, sFileList);		m_trayIcon.ShowBalloon(sMessage, CEnString(IDS_TIMESTAMPCHANGE_BALLOONTITLE), NIIF_INFO);	}}void CToDoListWnd::OnTimerAutoSave(){	AF_NOREENTRANT // macro helper			// don‘t save if the user is editing a task label	if (!GetToDoCtrl().IsTaskLabelEditing())		SaveAll(TDLS_AUTOSAVE);}void CToDoListWnd::OnTimerAutoMinimize(){	AF_NOREENTRANT // macro helper	if (!IsWindowVisible() || IsIconic())		return;	LASTINPUTINFO lii = { sizeof(LASTINPUTINFO), 0 };		if (GetLastInputInfo(&lii))	{		double dElapsed = (GetTickCount() - lii.dwTime);		dElapsed /= ONE_MINUTE; // convert to minutes				// check		if (dElapsed > (double)Prefs().GetAutoMinimizeFrequency())			ShowWindow(SW_MINIMIZE);	}}void CToDoListWnd::OnTimerCheckoutStatus(int nCtrl){	AF_NOREENTRANT // macro helper			const CPreferencesDlg& userPrefs = Prefs();		// work out whether we should check remote files or not	BOOL bCheckRemoteFiles = (nCtrl != -1);		if (!bCheckRemoteFiles)	{		static int nElapsed = 0;		UINT nRemoteFileCheckInterval = userPrefs.GetRemoteFileCheckFrequency() * 1000; // in ms				nElapsed %= nRemoteFileCheckInterval;		bCheckRemoteFiles = !nElapsed;				nElapsed += INTERVAL_CHECKOUTSTATUS;	}		// process files	CString sFileList;	int nFrom = (nCtrl == -1) ? 0 : nCtrl;	int nTo = (nCtrl == -1) ? GetTDCCount() - 1 : nCtrl;		for (nCtrl = nFrom; nCtrl <= nTo; nCtrl++)	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);				if (!m_mgrToDoCtrls.PathSupportsSourceControl(nCtrl))            continue;				// try to check out only if the previous attempt failed		if (!tdc.IsCheckedOut() && userPrefs.GetCheckoutOnCheckin())		{			// we only try to check if the previous checkout failed			if (!m_mgrToDoCtrls.GetLastCheckoutStatus(nCtrl))			{				if (tdc.CheckOut())				{					// update timestamp 					m_mgrToDoCtrls.RefreshLastModified(nCtrl);					m_mgrToDoCtrls.SetLastCheckoutStatus(nCtrl, TRUE);										if (nCtrl == m_tabCtrl.GetCurSel())						UpdateCaption();										m_mgrToDoCtrls.UpdateToDoCtrlReadOnlyUIState(nCtrl);					m_mgrToDoCtrls.UpdateTabItemText(nCtrl);										// notify the user if the trayicon is visible					sFileList += tdc.GetFriendlyProjectName();					sFileList += "\n";				}				else // make sure we try again later					m_mgrToDoCtrls.SetLastCheckoutStatus(nCtrl, FALSE);			}		}		// only checkin if sufficient time has elapsed since last mod		// and there are no mods outstanding		else if (tdc.IsCheckedOut() && userPrefs.GetAutoCheckinFrequency())		{			if (!tdc.IsModified())			{				double dElapsed = COleDateTime::GetCurrentTime() - tdc.GetLastTaskModified();				dElapsed *= 24 * 60; // convert to minutes								if (dElapsed > (double)userPrefs.GetAutoCheckinFrequency())				{					if (tdc.CheckIn())						{						m_mgrToDoCtrls.UpdateToDoCtrlReadOnlyUIState(nCtrl);						m_mgrToDoCtrls.RefreshLastModified(nCtrl);						m_mgrToDoCtrls.SetLastCheckoutStatus(nCtrl, TRUE);						m_mgrToDoCtrls.UpdateTabItemText(nCtrl);												UpdateCaption();					}				}			}		}	}	// do we need to notify the user?	if (!sFileList.IsEmpty())	{		CEnString sMessage(IDS_TASKLISTSCHECKEDOUT, sFileList);		m_trayIcon.ShowBalloon(sMessage, _T("Source Control Change(s)"), NIIF_INFO);	}}void CToDoListWnd::OnNeedTooltipText(NMHDR* pNMHDR, LRESULT* pResult){	static CString sTipText;	sTipText.Empty();	switch (pNMHDR->idFrom)	{	case ID_TOOLS_USERTOOL1:	case ID_TOOLS_USERTOOL2:	case ID_TOOLS_USERTOOL3:	case ID_TOOLS_USERTOOL4:	case ID_TOOLS_USERTOOL5:	case ID_TOOLS_USERTOOL6:	case ID_TOOLS_USERTOOL7:	case ID_TOOLS_USERTOOL8:	case ID_TOOLS_USERTOOL9:	case ID_TOOLS_USERTOOL10:	case ID_TOOLS_USERTOOL11:	case ID_TOOLS_USERTOOL12:	case ID_TOOLS_USERTOOL13:	case ID_TOOLS_USERTOOL14:	case ID_TOOLS_USERTOOL15:	case ID_TOOLS_USERTOOL16:		{			USERTOOL ut;			if (Prefs().GetUserTool(pNMHDR->idFrom - ID_TOOLS_USERTOOL1, ut))				sTipText = ut.sToolName;		}		break;	default:		// tab control popups		if (pNMHDR->idFrom >= 0 && pNMHDR->idFrom < (UINT)m_mgrToDoCtrls.GetCount())		{			sTipText = m_mgrToDoCtrls.GetTabItemTooltip(pNMHDR->idFrom);		}		break;	}	if (!sTipText.IsEmpty())	{		TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR;		pTTT->lpszText = (LPTSTR)(LPCTSTR)sTipText;	}	*pResult = 0;}void CToDoListWnd::OnUpdateUserTool(CCmdUI* pCmdUI) {	if (pCmdUI->m_pMenu && pCmdUI->m_nID == ID_TOOLS_USERTOOL1) // only handle first item	{		CUserToolArray aTools;		Prefs().GetUserTools(aTools);				CToolsHelper th(Prefs().GetEnableTDLExtension(), ID_TOOLS_USERTOOL1);		th.UpdateMenu(pCmdUI, aTools, m_mgrMenuIcons);	}	else if (m_bShowToolbar) 	{		int nTool = pCmdUI->m_nID - ID_TOOLS_USERTOOL1;		ASSERT (nTool >= 0 && nTool < 16);		USERTOOL ut;				if (Prefs().GetUserTool(nTool, ut))			pCmdUI->Enable(TRUE);	}}void CToDoListWnd::OnUserTool(UINT nCmdID) {	int nTool = nCmdID - ID_TOOLS_USERTOOL1;	USERTOOL ut;		ASSERT (nTool >= 0 && nTool < 16);	const CPreferencesDlg& prefs = Prefs();		if (prefs.GetUserTool(nTool, ut))	{		// Save all tasklists before executing the user tool		if (prefs.GetAutoSaveOnRunTools())		{			if (SaveAll(TDLS_FLUSH) == TDCO_CANCELLED)				return;		}		USERTOOLARGS args;		PopulateToolArgs(args);		CToolsHelper th(prefs.GetEnableTDLExtension(), ID_TOOLS_USERTOOL1);		th.RunTool(ut, args, this);	}}void CToDoListWnd::AddUserStorageToMenu(CMenu* pMenu) {	if (pMenu)	{		const UINT MENUSTARTID = pMenu->GetMenuItemID(0);		// delete existing entries		int nStore = 16;		while (nStore--)		{			pMenu->DeleteMenu(nStore, MF_BYPOSITION);		}				// if we have any tools to add we do it here		int nNumStorage = min(m_mgrStorage.GetNumStorage(), 16);		if (nNumStorage)		{			UINT nFlags = (MF_BYPOSITION | MF_STRING);			for (int nStore = 0; nStore < nNumStorage; nStore++)			{				CString sMenuItem, sText = m_mgrStorage.GetStorageMenuText(nStore);												if (nStore < 9)					sMenuItem.Format(_T("&%d %s"), nStore + 1, sText);				else					sMenuItem = sText;								// special case: if this is a ‘Save‘ menu item				// then the we disable it if it‘s the same as				// the current tasklist‘s storage				UINT nExtraFlags = 0;/*				if (MENUSTARTID == ID_FILE_SAVE_USERSTORAGE1)				{					int nTDC = GetSelToDoCtrl();					TSM_TASKLISTINFO storageInfo;					if (m_mgrToDoCtrls.GetStorageDetails(nTDC, storageInfo))					{						if (m_mgrStorage.FindStorage(storageInfo.sStorageID) == nStore)							nExtraFlags = (MF_GRAYED | MF_CHECKED);					}				}*/								pMenu->InsertMenu(nStore, nFlags | nExtraFlags, MENUSTARTID + nStore, sMenuItem);				// add icon if available				HICON hIcon = m_mgrStorage.GetStorageIcon(nStore);				if (hIcon)					m_mgrMenuIcons.AddImage(MENUSTARTID + nStore, hIcon);			}		}		else // if nothing to add just re-add placeholder		{			pMenu->InsertMenu(0, MF_BYPOSITION | MF_STRING | MF_GRAYED, MENUSTARTID, _T("3rd Party Storage"));		}	}}void CToDoListWnd::OnFileOpenFromUserStorage(UINT nCmdID) {	int nStorage = nCmdID - ID_FILE_OPEN_USERSTORAGE1;		ASSERT (nStorage >= 0 && nStorage < 16);	TSM_TASKLISTINFO storageInfo;	CPreferences prefs;	CTaskFile tasks;	if (m_mgrStorage.RetrieveTasklist(&storageInfo, &tasks, nStorage, &prefs))	{		if (tasks.GetTaskCount())		{			VERIFY(CreateNewTaskList(FALSE));						CFilteredToDoCtrl& tdc = GetToDoCtrl(); 			VERIFY(tdc.InsertTasks(tasks, TDC_INSERTATTOP));			// attach the returned storage info to this tasklist			m_mgrToDoCtrls.SetStorageDetails(GetSelToDoCtrl(), storageInfo);		}		else if (storageInfo.szLocalFileName[0])		{			TDC_FILE nOpen = OpenTaskList(storageInfo.szLocalFileName, TRUE);						if (nOpen == TDCO_SUCCESS)			{				// attach the returned storage info to this tasklist				int nTDC = m_mgrToDoCtrls.FindToDoCtrl(storageInfo.szLocalFileName);				ASSERT(nTDC == GetSelToDoCtrl());								m_mgrToDoCtrls.SetStorageDetails(nTDC, storageInfo);			}			else				HandleLoadTasklistError(nOpen, storageInfo.szDisplayName);		}		else		{			// TODO		}				UpdateCaption();		UpdateStatusbar();		Resize();		UpdateWindow();	}}void CToDoListWnd::OnFileSaveToUserStorage(UINT nCmdID) {	int nStorage = (nCmdID - ID_FILE_SAVE_USERSTORAGE1);		ASSERT (nStorage >= 0 && nStorage < 16);	CFilteredToDoCtrl& tdc = GetToDoCtrl();	CString sLocalPath, sTdcPath = tdc.GetFilePath();	// retrieve any existing storage info for this tasklist	int nTDC = GetSelToDoCtrl();	TSM_TASKLISTINFO storageInfo;	if (m_mgrToDoCtrls.GetStorageDetails(nTDC, storageInfo))	{		sLocalPath = storageInfo.szLocalFileName;		// clear the storage info ID if we are changing		// the destination		if (nStorage != m_mgrStorage.FindStorage(storageInfo.sStorageID))			storageInfo.Reset();	}	if (sLocalPath.IsEmpty())	{		sLocalPath = sTdcPath = tdc.GetFilePath();		if (sLocalPath.IsEmpty())			sLocalPath = FileMisc::GetTempFileName(m_mgrToDoCtrls.GetFriendlyProjectName(nTDC), _T("tdl"));	}	CTaskFile tasks;	VERIFY (tdc.Save(tasks, sLocalPath) == TDCO_SUCCESS);	// restore previous task path	if (sTdcPath != sLocalPath)	{		tdc.SetFilePath(sTdcPath);	}	else // prevent this save triggering a reload	{		m_mgrToDoCtrls.RefreshLastModified(nTDC);	}	_tcsncpy(storageInfo.szLocalFileName, sLocalPath, _MAX_PATH);			CPreferences prefs;	if (m_mgrStorage.StoreTasklist(&storageInfo, &tasks, nStorage, &prefs))	{		m_mgrToDoCtrls.SetStorageDetails(nTDC, storageInfo);				UpdateCaption();		UpdateStatusbar();		Resize();		UpdateWindow();	}	// else assume that the plugin handled any problems}void CToDoListWnd::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) {	// test for top-level menus	if (bSysMenu)		return;	if (m_menubar.GetSubMenu(FILEALL) == pPopupMenu)	{		// insert Min to sys tray if appropriate 		BOOL bHasMinToTray = (::GetMenuString(*pPopupMenu, ID_MINIMIZETOTRAY, NULL, 0, MF_BYCOMMAND) != 0);				if (Prefs().GetSysTrayOption() == STO_ONCLOSE || Prefs().GetSysTrayOption() == STO_ONMINCLOSE)		{			if (!bHasMinToTray)				pPopupMenu->InsertMenu(ID_EXIT, MF_BYCOMMAND, ID_MINIMIZETOTRAY, CEnString(ID_MINIMIZETOTRAY));		}		else if (bHasMinToTray) // then remove		{			pPopupMenu->DeleteMenu(ID_MINIMIZETOTRAY, MF_BYCOMMAND);		}	}	else if (m_menubar.GetSubMenu(EDITTASK) == pPopupMenu)	{		// remove relevant commands from the edit menu		PrepareEditMenu(pPopupMenu);	}	else if (m_menubar.GetSubMenu(SORTTASK) == pPopupMenu)	{		// remove relevant commands from the sort menu		PrepareSortMenu(pPopupMenu);	}	else if (m_menubar.GetSubMenu(TOOLS) == pPopupMenu)	{		// remove relevant commands from the sort menu		PrepareSourceControlMenu(pPopupMenu);	}	else // all other sub-menus	{		// test for ‘Open From...‘		if (pPopupMenu->GetMenuItemID(0) == ID_FILE_OPEN_USERSTORAGE1)		{			AddUserStorageToMenu(pPopupMenu);		}		// test for ‘save To...‘		else if (pPopupMenu->GetMenuItemID(0) == ID_FILE_SAVE_USERSTORAGE1)		{			AddUserStorageToMenu(pPopupMenu);		}	}	CFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);}void CToDoListWnd::OnViewToolbar() {	m_bShowToolbar = !m_bShowToolbar;	m_toolbar.ShowWindow(m_bShowToolbar ? SW_SHOW : SW_HIDE);	m_toolbar.EnableWindow(m_bShowToolbar);	Resize();	Invalidate(TRUE);}void CToDoListWnd::OnUpdateViewToolbar(CCmdUI* pCmdUI) {	pCmdUI->SetCheck(m_bShowToolbar);}void CToDoListWnd::AppendTools2Toolbar(BOOL bAppend){	CToolsHelper th(Prefs().GetEnableTDLExtension(), ID_TOOLS_USERTOOL1);		if (bAppend)	{		// then re-add		CUserToolArray aTools;		Prefs().GetUserTools(aTools);				th.AppendToolsToToolbar(aTools, m_toolbar, ID_PREFERENCES);		// refresh tooltips		m_tbHelper.Release();		m_tbHelper.Initialize(&m_toolbar, this);	}	else // remove	{		th.RemoveToolsFromToolbar(m_toolbar, ID_PREFERENCES);	}	// resize toolbar to accept the additional buttons	Resize();}void CToDoListWnd::OnSort() {	GetToDoCtrl().Resort(TRUE);}void CToDoListWnd::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) {	CFrameWnd::OnWindowPosChanged(lpwndpos);}void CToDoListWnd::OnArchiveCompletedtasks() {	CWaitCursor cursor;	int nSelTDC = GetSelToDoCtrl();		if (m_mgrToDoCtrls.ArchiveDoneTasks(nSelTDC))	{		// auto-reload archive if it‘s loaded		CString sArchivePath = m_mgrToDoCtrls.GetArchivePath(nSelTDC);		int nArchiveTDC = m_mgrToDoCtrls.FindToDoCtrl(sArchivePath);		if (nArchiveTDC != -1 && m_mgrToDoCtrls.IsLoaded(nArchiveTDC))			ReloadTaskList(nArchiveTDC, FALSE, FALSE);			UpdateCaption();	}}void CToDoListWnd::OnUpdateArchiveCompletedtasks(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(!tdc.IsReadOnly() && !m_mgrToDoCtrls.GetArchivePath(tdc.GetFilePath()).IsEmpty());}void CToDoListWnd::OnArchiveSelectedTasks() {	CWaitCursor cursor;	int nSelTDC = GetSelToDoCtrl();		if (m_mgrToDoCtrls.ArchiveSelectedTasks(nSelTDC))	{		// auto-reload archive if it‘s loaded		CString sArchivePath = m_mgrToDoCtrls.GetArchivePath(nSelTDC);		int nArchiveTDC = m_mgrToDoCtrls.FindToDoCtrl(sArchivePath);		if (nArchiveTDC != -1 && m_mgrToDoCtrls.IsLoaded(nArchiveTDC))			ReloadTaskList(nArchiveTDC, FALSE, FALSE);			UpdateCaption();	}}void CToDoListWnd::OnUpdateArchiveSelectedCompletedTasks(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(!tdc.IsReadOnly() && !m_mgrToDoCtrls.GetArchivePath(tdc.GetFilePath()).IsEmpty());}void CToDoListWnd::OnMovetaskdown() {	GetToDoCtrl().MoveSelectedTask(TDCM_DOWN);	}void CToDoListWnd::OnUpdateMovetaskdown(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanMoveSelectedTask(TDCM_DOWN));	}void CToDoListWnd::OnMovetaskup() {	GetToDoCtrl().MoveSelectedTask(TDCM_UP);	}void CToDoListWnd::OnUpdateMovetaskup(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanMoveSelectedTask(TDCM_UP));	}void CToDoListWnd::OnMovetaskright() {	GetToDoCtrl().MoveSelectedTask(TDCM_RIGHT);	}void CToDoListWnd::OnUpdateMovetaskright(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanMoveSelectedTask(TDCM_RIGHT));	}void CToDoListWnd::OnMovetaskleft() {	GetToDoCtrl().MoveSelectedTask(TDCM_LEFT);	}void CToDoListWnd::OnUpdateMovetaskleft(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanMoveSelectedTask(TDCM_LEFT));	}CFilteredToDoCtrl& CToDoListWnd::GetToDoCtrl(){	return GetToDoCtrl(GetSelToDoCtrl());}CFilteredToDoCtrl& CToDoListWnd::GetToDoCtrl(int nIndex){	return m_mgrToDoCtrls.GetToDoCtrl(nIndex);}const CFilteredToDoCtrl& CToDoListWnd::GetToDoCtrl() const{	return GetToDoCtrl(GetSelToDoCtrl());}const CFilteredToDoCtrl& CToDoListWnd::GetToDoCtrl(int nIndex) const{	return m_mgrToDoCtrls.GetToDoCtrl(nIndex);}CFilteredToDoCtrl* CToDoListWnd::NewToDoCtrl(BOOL bVisible, BOOL bEnabled){	CFilteredToDoCtrl* pTDC = NULL;		// if the active tasklist is untitled and unmodified then reuse it	if (GetTDCCount())	{		int nSel = GetSelToDoCtrl();		CFilteredToDoCtrl& tdc = GetToDoCtrl();				// make sure that we don‘t accidently reuse a just edited tasklist		tdc.Flush(); 				if (m_mgrToDoCtrls.IsPristine(nSel))		{			pTDC = &tdc;			m_mgrToDoCtrls.RemoveToDoCtrl(nSel, FALSE);						// make sure we reset the selection to a valid index			if (GetTDCCount())			{				// try leaving the selection as-is				if (nSel >= GetTDCCount())					nSel--; // try the preceding item								SelectToDoCtrl(nSel, FALSE);			}						return pTDC;		}	}		// else	pTDC = new CFilteredToDoCtrl(m_mgrContent, Prefs().GetDefaultCommentsFormat());		if (pTDC && CreateToDoCtrl(pTDC, bVisible, bEnabled))		return pTDC;		// else	delete pTDC;	return NULL;}BOOL CToDoListWnd::CreateToDoCtrl(CFilteredToDoCtrl* pTDC, BOOL bVisible, BOOL bEnabled){	// create somewhere out in space	CRect rCtrl(-32010, -32010, -32000, -32000);	if (pTDC->Create(rCtrl, this, IDC_TODOLIST, bVisible, bEnabled))	{		// set font to our font		CDialogHelper::SetFont(pTDC, m_fontMain, FALSE);				if (!m_ilCheckboxes.GetSafeHandle())			InitCheckboxImageList();				UpdateToDoCtrlPreferences(pTDC);		if (CThemed::IsThemeActive())			pTDC->SetUITheme(m_theme);		for (int nExt = 0; nExt < m_mgrUIExtensions.GetNumUIExtensions(); nExt++)			pTDC->AddView(m_mgrUIExtensions.GetUIExtension(nExt));				return TRUE;	}		return FALSE;}BOOL CToDoListWnd::InitCheckboxImageList(){	if (m_ilCheckboxes.GetSafeHandle())		return TRUE;		const int nStates[] = { -1, CBS_UNCHECKEDNORMAL, CBS_CHECKEDNORMAL };//, CBS_MIXEDNORMAL };	const int nNumStates = sizeof(nStates) / sizeof(int);		CThemed th;		if (th.Open(this, _T("BUTTON")) && th.AreControlsThemed())	{		th.BuildImageList(m_ilCheckboxes, BP_CHECKBOX, nStates, nNumStates);	}		// unthemed + fallback	if (!m_ilCheckboxes.GetSafeHandle())	{		CBitmap bitmap;		bitmap.LoadBitmap(IDB_CHECKBOXES);				BITMAP BM;		bitmap.GetBitmap(&BM);				if (m_ilCheckboxes.Create(BM.bmWidth / nNumStates, BM.bmHeight, ILC_COLOR32 | ILC_MASK, 0, 1))			m_ilCheckboxes.Add(&bitmap, 255);	}		return (NULL != m_ilCheckboxes.GetSafeHandle());}void CToDoListWnd::OnMBtnClickTabcontrol(NMHDR* pNMHDR, LRESULT* pResult) {	NMTCMBTNCLK* pTCHDR = (NMTCMBTNCLK*)pNMHDR;		// check valid tab	if (pTCHDR->iTab >= 0)	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(pTCHDR->iTab);		tdc.Flush();				CloseToDoCtrl(pTCHDR->iTab);				if (!GetTDCCount())			CreateNewTaskList(FALSE);	}	*pResult = 0;}void CToDoListWnd::OnSelchangeTabcontrol(NMHDR* /*pNMHDR*/, LRESULT* pResult) {	// show the incoming selection	int nCurSel = GetSelToDoCtrl();	// check password if necessary	if (m_nLastSelItem != -1 && !VerifyToDoCtrlPassword())	{		m_tabCtrl.SetCurSel(m_nLastSelItem);		return;	}	int nDueBy = Prefs().GetNotifyDueByOnSwitch();		if (nCurSel != -1)	{		// make sure it‘s loaded		if (!VerifyTaskListOpen(nCurSel, (nDueBy == -1)))		{			// restore the previous tab			m_tabCtrl.SetCurSel(m_nLastSelItem);			return;		}		CFilteredToDoCtrl& tdc = GetToDoCtrl(nCurSel);		UpdateToDoCtrlPreferences(&tdc);		// update the filter selection 		RefreshFilterControls(); 				// update status bar		UpdateStatusbar();		UpdateCaption();		// make sure size is right		CRect rTDC;				if (CalcToDoCtrlRect(rTDC))			tdc.MoveWindow(rTDC, FALSE);		// refresh view state		tdc.SetMaximizeState(m_nMaxState);		tdc.EnableWindow(TRUE);		tdc.ShowWindow(SW_SHOW);		tdc.PauseTimeTracking(FALSE); // always	}		// hide the outgoing selection	if (m_nLastSelItem != -1)	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(m_nLastSelItem);		tdc.ShowWindow(SW_HIDE);		tdc.EnableWindow(FALSE);		tdc.PauseTimeTracking(!Prefs().GetTrackNonActiveTasklists());		m_nLastSelItem = -1; // reset	}		if (nCurSel != -1)	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(nCurSel);		// update find dialog with this ToDoCtrl‘s custom attributes		UpdateFindDialogCustomAttributes(&tdc);		// leave focus setting till last else the ‘old‘ tasklist flashes		tdc.SetFocusToTasks();		// notify user of due tasks if req		DoDueTaskNotification(nCurSel, nDueBy);		UpdateAeroFeatures();	}	InitMenuIconManager();		*pResult = 0;}void CToDoListWnd::RefreshFilterControls(){	CFilteredToDoCtrl& tdc = GetToDoCtrl();	// if this tasklist‘s filter is an unnamed custom one	RefreshFilterBarCustomFilters();	// get existing filter bar size so we can determine if a 	// resize if required	CRect rFilter;	m_filterBar.GetClientRect(rFilter);	m_filterBar.RefreshFilterControls(tdc);	CRect rClient;	GetClientRect(rClient);	if (m_filterBar.CalcHeight(rClient.Width()) != rFilter.Height())		Resize();}void CToDoListWnd::OnSelchangingTabcontrol(NMHDR* /*pNMHDR*/, LRESULT* pResult) {	// cache the outgoing selection	m_nLastSelItem = GetSelToDoCtrl();		// and flush	if (m_nLastSelItem != -1)	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(m_nLastSelItem);		tdc.Flush();		// and save		if (Prefs().GetAutoSaveOnSwitchTasklist() && !tdc.GetFilePath().IsEmpty() && tdc.IsModified())		{			tdc.Save();			m_mgrToDoCtrls.SetModifiedStatus(m_nLastSelItem, FALSE); 			m_mgrToDoCtrls.RefreshLastModified(m_nLastSelItem); 			m_mgrToDoCtrls.RefreshReadOnlyStatus(m_nLastSelItem); 			m_mgrToDoCtrls.RefreshPathType(m_nLastSelItem); 		}	}		*pResult = 0;}TDC_FILE CToDoListWnd::ConfirmSaveTaskList(int nIndex, DWORD dwFlags){	BOOL bClosingWindows = Misc::HasFlag(dwFlags, TDLS_CLOSINGWINDOWS);	BOOL bClosingTaskList = Misc::HasFlag(dwFlags, TDLS_CLOSINGTASKLISTS) || bClosingWindows; // sanity check	TDC_FILE nSave = TDCO_SUCCESS;		// save changes	CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);		if (tdc.IsModified())	{		BOOL bFirstTimeSave = tdc.GetFilePath().IsEmpty();		// if we are closing Windows, we don‘t bother asking		// we just save and get out as fast as poss		if (bClosingWindows)		{			// if it‘s a first time save we just save to a temp file			if (bFirstTimeSave)				tdc.Save(GetEndSessionFilePath());			else				tdc.Save();			return TDCO_SUCCESS;		}		// else we obey the user‘s preferences		else if (bClosingTaskList && (bFirstTimeSave || Prefs().GetConfirmSaveOnExit()))		{			// make sure app is visible			Show(FALSE);			// save tasklist			CString sName = m_mgrToDoCtrls.GetFriendlyProjectName(nIndex);			CEnString sMessage(IDS_SAVEBEFORECLOSE, sName);						// don‘t allow user to cancel if closing down			int nRet = MessageBox(sMessage, IDS_CONFIRMSAVE_TITLE, bClosingWindows ? MB_YESNO : MB_YESNOCANCEL);						if (nRet == IDYES)			{				// note: we omit the auto save parameter here because we want the user to				// be notified of any problems				nSave = SaveTaskList(nIndex);				// if the save failed (as opposed to cancelled) then we must				// propagate this upwards				if (nSave != TDCO_SUCCESS && nSave != TDCO_CANCELLED)					return nSave;				// user can still cancel save dialog even if closing down				// but not if closing windows				else if (nSave == TDCO_CANCELLED)					nRet = bClosingWindows ? IDNO : IDCANCEL;			}						ASSERT (!(bClosingWindows && nRet == IDCANCEL)); // sanity check						if (nRet == IDCANCEL)				return TDCO_CANCELLED;			else			{				tdc.SetModified(FALSE); // so we don‘t get prompted again				m_mgrToDoCtrls.SetModifiedStatus(nIndex, FALSE);			}		}		else			nSave = SaveTaskList(nIndex, NULL, Misc::HasFlag(dwFlags, TDLS_AUTOSAVE));	}		return nSave; // user did not cancel}BOOL CToDoListWnd::CloseToDoCtrl(int nIndex){	ASSERT (nIndex >= 0);	ASSERT (nIndex < GetTDCCount());	CFilteredToDoCtrl& tdcSel = GetToDoCtrl();	CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);	tdc.Flush(TRUE);		if (ConfirmSaveTaskList(nIndex, TDLS_CLOSINGTASKLISTS) != TDCO_SUCCESS)		return FALSE;		// remove any find results associated with this tasklist	if (m_findDlg.GetSafeHwnd())		m_findDlg.DeleteResults(&tdc);		CWaitCursor cursor;	// save off current reminders	m_reminders.CloseToDoCtrl(tdc);	int nNewSel = m_mgrToDoCtrls.RemoveToDoCtrl(nIndex, TRUE);		if (nNewSel != -1)	{		// if we‘re closing TDL then the main window will not		// be visible at this point so we don‘t have to worry about		// encrypted tasklists becoming visible. however if as a result		// of this closure an encrypted tasklist would become visible		// then we need to prompt for a password and if this fails		// we must create another tasklist to hide the encrypted one.		// unless the tasklist being closed was not active and the 		// new selection hasn‘t actually changed		BOOL bCheckPassword = !m_bClosing && (&GetToDoCtrl(nNewSel) != &tdcSel);		if (!SelectToDoCtrl(nNewSel, bCheckPassword))		{			CreateNewTaskList(FALSE);			RefreshTabOrder();		}		if (!m_bClosing)			Resize();	}		return TRUE;}void CToDoListWnd::OnCloseTasklist() {	int nSel = GetSelToDoCtrl();	CFilteredToDoCtrl& tdc = GetToDoCtrl(nSel);	// make sure there are no edits pending	tdc.Flush(TRUE); 		// check if its a pristine tasklist and the last tasklist and 	// if so only close it if the default comments type has changed	if (m_mgrToDoCtrls.IsPristine(nSel) && GetTDCCount() == 1)		return;		CloseToDoCtrl(nSel);		// if empty then create a new dummy item			if (!GetTDCCount())		CreateNewTaskList(FALSE);	else		Resize();}BOOL CToDoListWnd::SelectToDoCtrl(LPCTSTR szFilePath, BOOL bCheckPassword, int nNotifyDueTasksBy){	int nCtrl = m_mgrToDoCtrls.FindToDoCtrl(szFilePath);		if (nCtrl != -1)	{		SelectToDoCtrl(nCtrl, bCheckPassword, nNotifyDueTasksBy);		return TRUE;	}		return FALSE;}int CToDoListWnd::GetSelToDoCtrl() const { 	if (m_tabCtrl.GetSafeHwnd()) 		return m_tabCtrl.GetCurSel(); 	else		return -1;}BOOL CToDoListWnd::VerifyTaskListOpen(int nIndex, BOOL bWantNotifyDueTasks){	if (!m_mgrToDoCtrls.IsLoaded(nIndex))	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);		TSM_TASKLISTINFO storageInfo;		CString sFilePath = tdc.GetFilePath();		if (m_mgrToDoCtrls.GetStorageDetails(nIndex, storageInfo))			sFilePath = storageInfo.EncodeInfo();		if (OpenTaskList(&tdc, sFilePath, &storageInfo) == TDCO_SUCCESS)		{			// make sure hidden windows stay hidden			if (nIndex != GetSelToDoCtrl())				tdc.ShowWindow(SW_HIDE);			// notify readonly			Resize();			CheckNotifyReadonly(nIndex);			m_mgrToDoCtrls.SetLoaded(nIndex);			m_mgrToDoCtrls.UpdateTabItemText(nIndex);			// update storage info			m_mgrToDoCtrls.SetStorageDetails(nIndex, storageInfo);			if (bWantNotifyDueTasks)				DoDueTaskNotification(nIndex, Prefs().GetNotifyDueByOnLoad());			return TRUE;		}		return FALSE;	}	return TRUE;}BOOL CToDoListWnd::SelectToDoCtrl(int nIndex, BOOL bCheckPassword, int nNotifyDueTasksBy){	ASSERT (nIndex >= 0);	ASSERT (nIndex < GetTDCCount());		// load and show the chosen item	// we don‘t need to do a ‘open‘ due task notification if the caller	// has asked for a notification anyway	if (!m_bClosing)	{		// if the tasklist is not loaded and we verify its loading		// then we know that the password (if there is one) has been 		// verified and doesn‘t need checking again		if (!m_mgrToDoCtrls.IsLoaded(nIndex) )		{			if (!VerifyTaskListOpen(nIndex, nNotifyDueTasksBy == -1))			{				// TODO				return FALSE;			}			else				bCheckPassword = FALSE;		}	}	// validate password first if necessary	if (bCheckPassword && !VerifyToDoCtrlPassword(nIndex))		return FALSE;		int nCurSel = GetSelToDoCtrl(); // cache this	// resize tdc first	CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);	CRect rTDC;		if (CalcToDoCtrlRect(rTDC))		tdc.MoveWindow(rTDC);		m_tabCtrl.SetCurSel(nIndex); // this changes the selected CToDoCtrl	m_tabCtrl.UpdateWindow();		if (!m_bClosing)		UpdateToDoCtrlPreferences();		const CPreferencesDlg& userPrefs = Prefs();	tdc.EnableWindow(TRUE);	tdc.SetFocusToTasks();	tdc.ShowWindow(SW_SHOW);	tdc.PauseTimeTracking(FALSE); // always	tdc.SetMaximizeState(m_nMaxState);	// if the tasklist is encrypted and todolist always prompts for password	// then disable Flip3D and Aero Peek	UpdateAeroFeatures();	// before hiding the previous selection	if (nCurSel != -1 && nCurSel != nIndex)	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(nCurSel);				tdc.ShowWindow(SW_HIDE);		tdc.EnableWindow(FALSE);		tdc.PauseTimeTracking(!userPrefs.GetTrackNonActiveTasklists());	}		if (!m_bClosing)	{		if (userPrefs.GetReadonlyReloadOption() != RO_NO)			OnTimerReadOnlyStatus(nIndex);				if (userPrefs.GetTimestampReloadOption() != RO_NO)			OnTimerTimestampChange(nIndex);				if (userPrefs.GetEnableSourceControl())			OnTimerCheckoutStatus(nIndex);				UpdateCaption();		UpdateStatusbar();				// update the filter selection		RefreshFilterControls();		// and the menu icon manager		InitMenuIconManager();		// and current directory		UpdateCwd();		DoDueTaskNotification(nNotifyDueTasksBy);	}	return TRUE;}void CToDoListWnd::UpdateAeroFeatures(){#ifdef _DEBUG	BOOL bEnable = !GetToDoCtrl().IsEncrypted();#else	BOOL bEnable = (!m_bPasswordPrompting || !GetToDoCtrl().IsEncrypted());#endif	// Disable peek and other dynamic views if the active tasklist is encrypted	GraphicsMisc::EnableFlip3D(*this, bEnable);	if (!GraphicsMisc::EnableAeroPeek(*this, bEnable))		GraphicsMisc::ForceIconicRepresentation(*this, !bEnable);}void CToDoListWnd::UpdateToDoCtrlPreferences(){	// check if this has already been done since the last userPrefs change	int nSel = GetSelToDoCtrl();		if (m_mgrToDoCtrls.GetNeedsPreferenceUpdate(nSel))	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(nSel);		UpdateToDoCtrlPreferences(&tdc);		// we do column visibility a bit different because 		// the manager knows whether the columns have been fiddled 		// with or not		CTDCColumnIDArray aColumns;		m_mgrToDoCtrls.RefreshColumns(nSel, aColumns);		// and filter bar relies on this tdc‘s visible columns		m_filterBar.SetVisibleFilters(aColumns);				// reset flag		m_mgrToDoCtrls.SetNeedsPreferenceUpdate(nSel, FALSE);	}}void CToDoListWnd::UpdateToDoCtrlPreferences(CFilteredToDoCtrl* pTDC){	const CPreferencesDlg& userPrefs = Prefs();	CFilteredToDoCtrl& tdc = *pTDC;	tdc.NotifyBeginPreferencesUpdate();		CTDCStylesMap styles;	styles.InitHashTable(TDCS_LAST);		styles[TDCS_ALLOWPARENTTIMETRACKING] = userPrefs.GetAllowParentTimeTracking();	styles[TDCS_ALLOWREFERENCEEDITING] = userPrefs.GetAllowReferenceEditing();	styles[TDCS_ALWAYSHIDELISTPARENTS] = userPrefs.GetAlwaysHideListParents();	styles[TDCS_AUTOADJUSTDEPENDENCYDATES] = userPrefs.GetAutoAdjustDependentsDates();	styles[TDCS_AUTOCALCPERCENTDONE] = userPrefs.GetAutoCalcPercentDone();	styles[TDCS_AUTOCALCTIMEESTIMATES] = userPrefs.GetAutoCalcTimeEstimates();	styles[TDCS_AUTOREPOSCTRLS] = userPrefs.GetAutoReposCtrls();	styles[TDCS_AVERAGEPERCENTSUBCOMPLETION] = userPrefs.GetAveragePercentSubCompletion();	styles[TDCS_CALCREMAININGTIMEBYDUEDATE] = (userPrefs.GetTimeRemainingCalculation() == PTCP_REMAININGTTIMEISDUEDATE);	styles[TDCS_CALCREMAININGTIMEBYPERCENT] = (userPrefs.GetTimeRemainingCalculation() == PTCP_REMAININGTTIMEISPERCENTAGE);	styles[TDCS_CALCREMAININGTIMEBYSPENT] = (userPrefs.GetTimeRemainingCalculation() == PTCP_REMAININGTTIMEISSPENT);	styles[TDCS_COLORTEXTBYATTRIBUTE] = (userPrefs.GetTextColorOption() == COLOROPT_ATTRIB);	styles[TDCS_COLORTEXTBYNONE] = (userPrefs.GetTextColorOption() == COLOROPT_NONE);	styles[TDCS_COLORTEXTBYPRIORITY] = (userPrefs.GetTextColorOption() == COLOROPT_PRIORITY);	styles[TDCS_COLUMNHEADERSORTING] = userPrefs.GetEnableColumnHeaderSorting();	styles[TDCS_COMMENTSUSETREEFONT] = userPrefs.GetCommentsUseTreeFont();	styles[TDCS_CONFIRMDELETE] = userPrefs.GetConfirmDelete();	styles[TDCS_DISPLAYHMSTIMEFORMAT] = userPrefs.GetUseHMSTimeFormat();	styles[TDCS_DONEHAVELOWESTPRIORITY] = userPrefs.GetDoneTasksHaveLowestPriority();	styles[TDCS_DONEHAVELOWESTRISK] = userPrefs.GetDoneTasksHaveLowestRisk();	styles[TDCS_DUEHAVEHIGHESTPRIORITY] = userPrefs.GetDueTasksHaveHighestPriority();	styles[TDCS_FOCUSTREEONENTER] = userPrefs.GetFocusTreeOnEnter();	styles[TDCS_FULLROWSELECTION] = userPrefs.GetFullRowSelection();	styles[TDCS_HIDEDONETIMEFIELD] = userPrefs.GetHideDoneTimeField();	styles[TDCS_HIDEDUETIMEFIELD] = userPrefs.GetHideDueTimeField();	styles[TDCS_HIDEPERCENTFORDONETASKS] = userPrefs.GetHidePercentForDoneTasks();	styles[TDCS_HIDEPRIORITYNUMBER] = userPrefs.GetHidePriorityNumber();	styles[TDCS_HIDESTARTDUEFORDONETASKS] = userPrefs.GetHideStartDueForDoneTasks();	styles[TDCS_HIDESTARTTIMEFIELD] = userPrefs.GetHideStartTimeField();	styles[TDCS_HIDEZEROPERCENTDONE] = userPrefs.GetHideZeroPercentDone();	styles[TDCS_HIDEZEROTIMECOST] = userPrefs.GetHideZeroTimeCost();	styles[TDCS_INCLUDEDONEINAVERAGECALC] = userPrefs.GetIncludeDoneInAverageCalc();	styles[TDCS_INCLUDEDONEINPRIORITYCALC] = userPrefs.GetIncludeDoneInPriorityRiskCalc();	styles[TDCS_INCLUDEDONEINRISKCALC] = userPrefs.GetIncludeDoneInPriorityRiskCalc();	styles[TDCS_INCLUDEUSERINCHECKOUT] = userPrefs.GetIncludeUserNameInCheckout();	styles[TDCS_LOGTASKTIMESEPARATELY] = userPrefs.GetLogTaskTimeSeparately();	styles[TDCS_LOGTIMETRACKING] = userPrefs.GetLogTimeTracking();	styles[TDCS_NODUEDATEISDUETODAY] = userPrefs.GetNoDueDateIsDueToday();	styles[TDCS_PAUSETIMETRACKINGONSCRNSAVER] = !userPrefs.GetTrackOnScreenSaver();	styles[TDCS_REFILTERONMODIFY] = userPrefs.GetReFilterOnModify();	styles[TDCS_RESORTONMODIFY] = userPrefs.GetReSortOnModify();	styles[TDCS_RESTOREFILTERS] = userPrefs.GetRestoreTasklistFilters();	styles[TDCS_RIGHTSIDECOLUMNS] = userPrefs.GetShowColumnsOnRight();	styles[TDCS_ROUNDTIMEFRACTIONS] = userPrefs.GetRoundTimeFractions();	styles[TDCS_SHAREDCOMMENTSHEIGHT] = userPrefs.GetSharedCommentsHeight();	styles[TDCS_SHOWCOMMENTSALWAYS] = userPrefs.GetShowCommentsAlways();	styles[TDCS_SHOWCOMMENTSINLIST] = userPrefs.GetShowComments();	styles[TDCS_SHOWCTRLSASCOLUMNS] = userPrefs.GetShowCtrlsAsColumns();	styles[TDCS_SHOWDATESINISO] = userPrefs.GetDisplayDatesInISO();	styles[TDCS_SHOWDEFAULTTASKICONS] = userPrefs.GetShowDefaultTaskIcons();	styles[TDCS_SHOWFIRSTCOMMENTLINEINLIST] = userPrefs.GetDisplayFirstCommentLine();	styles[TDCS_SHOWINFOTIPS] = userPrefs.GetShowInfoTips();	styles[TDCS_SHOWNONFILEREFSASTEXT] = userPrefs.GetShowNonFilesAsText();	styles[TDCS_SHOWPARENTSASFOLDERS] = userPrefs.GetShowParentsAsFolders();	styles[TDCS_SHOWPATHINHEADER] = userPrefs.GetShowPathInHeader();	styles[TDCS_SHOWPERCENTASPROGRESSBAR] = userPrefs.GetShowPercentAsProgressbar();	styles[TDCS_SHOWPROJECTNAME] = m_bShowProjectName;	styles[TDCS_SHOWSUBTASKCOMPLETION] = userPrefs.GetShowSubtaskCompletion();	styles[TDCS_SHOWTREELISTBAR] = m_bShowTreeListBar;	styles[TDCS_SHOWWEEKDAYINDATES] = userPrefs.GetShowWeekdayInDates();	styles[TDCS_SORTDONETASKSATBOTTOM] = userPrefs.GetSortDoneTasksAtBottom();	styles[TDCS_SORTVISIBLETASKSONLY] = FALSE;//userPrefs.GetSortVisibleOnly();	styles[TDCS_STRIKETHOUGHDONETASKS] = userPrefs.GetStrikethroughDone();	styles[TDCS_TASKCOLORISBACKGROUND] = userPrefs.GetColorTaskBackground();	styles[TDCS_TRACKSELECTEDTASKONLY] = !userPrefs.GetTrackNonSelectedTasks();	styles[TDCS_TREATSUBCOMPLETEDASDONE] = userPrefs.GetTreatSubCompletedAsDone();	styles[TDCS_TREECHECKBOXES] = userPrefs.GetTreeCheckboxes();	styles[TDCS_TREETASKICONS] = userPrefs.GetTreeTaskIcons();	styles[TDCS_USEEARLIESTDUEDATE] = (userPrefs.GetDueDateCalculation() == PTCP_EARLIESTDUEDATE);	styles[TDCS_USEEARLIESTSTARTDATE] = (userPrefs.GetStartDateCalculation() == PTCP_EARLIESTSTARTDATE);	styles[TDCS_USEHIGHESTPRIORITY] = userPrefs.GetUseHighestPriority();	styles[TDCS_USEHIGHESTRISK] = userPrefs.GetUseHighestRisk();	styles[TDCS_USELATESTDUEDATE] = (userPrefs.GetDueDateCalculation() == PTCP_LATESTDUEDATE);	styles[TDCS_USELATESTSTARTDATE] = (userPrefs.GetStartDateCalculation() == PTCP_LATESTSTARTDATE);	styles[TDCS_USEPERCENTDONEINTIMEEST] = userPrefs.GetUsePercentDoneInTimeEst();	styles[TDCS_USES3RDPARTYSOURCECONTROL] = userPrefs.GetUsing3rdPartySourceControl();	styles[TDCS_WARNADDDELETEARCHIVE] = userPrefs.GetWarnAddDeleteArchive();	styles[TDCS_WEIGHTPERCENTCALCBYNUMSUB] = userPrefs.GetWeightPercentCompletionByNumSubtasks();	// source control	BOOL bSrcControl = m_mgrToDoCtrls.PathSupportsSourceControl(tdc.GetFilePath());		styles[TDCS_ENABLESOURCECONTROL] = bSrcControl;	styles[TDCS_CHECKOUTONLOAD] = bSrcControl && userPrefs.GetAutoCheckOut();		// set the styles in one hit	tdc.SetStyles(styles);	// layout	tdc.SetLayoutPositions((TDC_UILOCATION)userPrefs.GetControlsPos(), 							(TDC_UILOCATION)userPrefs.GetCommentsPos(), 							TRUE);		// info tips	tdc.SetMaxInfotipCommentsLength(userPrefs.GetMaxInfoTipCommentsLength());		// update default task preferences	tdc.SetDefaultTaskAttributes(m_tdiDefault);	// default string lists	CStringArray aItems;		if (userPrefs.GetDefaultListItems(PTDP_CATEGORY, aItems))		aItems.Append(m_tdiDefault.aCategories);	tdc.SetDefaultCategoryNames(aItems, userPrefs.GetCategoryListIsReadonly());	if (userPrefs.GetDefaultListItems(PTDP_ALLOCTO, aItems))		aItems.Append(m_tdiDefault.aAllocTo);		tdc.SetDefaultAllocToNames(aItems, userPrefs.GetAllocToListIsReadonly());		userPrefs.GetDefaultListItems(PTDP_STATUS, aItems);	tdc.SetDefaultStatusNames(aItems, userPrefs.GetStatusListIsReadonly());		userPrefs.GetDefaultListItems(PTDP_ALLOCBY, aItems);	tdc.SetDefaultAllocByNames(aItems, userPrefs.GetAllocByListIsReadonly());			// fonts	if (!m_fontTree.GetSafeHandle() || !m_fontComments.GetSafeHandle())	{		CString sFaceName;		int nFontSize;				if (!m_fontTree.GetSafeHandle() && userPrefs.GetTreeFont(sFaceName, nFontSize))			m_fontTree.Attach(GraphicsMisc::CreateFont(sFaceName, nFontSize));				if (!m_fontComments.GetSafeHandle() && userPrefs.GetCommentsFont(sFaceName, nFontSize))			m_fontComments.Attach(GraphicsMisc::CreateFont(sFaceName, nFontSize));	}		tdc.SetTreeFont(m_fontTree);	tdc.SetCommentsFont(m_fontComments);		// colours	tdc.SetGridlineColor(userPrefs.GetGridlineColor());	tdc.SetCompletedTaskColor(userPrefs.GetDoneTaskColor());	tdc.SetAlternateLineColor(userPrefs.GetAlternateLineColor());	tdc.SetFlaggedTaskColor(userPrefs.GetFlaggedTaskColor());	tdc.SetReferenceTaskColor(userPrefs.GetReferenceTaskColor());	tdc.SetPriorityColors(m_aPriorityColors);	COLORREF color, crToday;	userPrefs.GetStartedTaskColors(color, crToday);	tdc.SetStartedTaskColors(color, crToday);	userPrefs.GetDueTaskColors(color, crToday);	tdc.SetDueTaskColors(color, crToday);		CTDCColorMap mapColors;	CAttribColorArray aColors;	TDC_ATTRIBUTE nAttrib = TDCA_NONE;	int nColor = userPrefs.GetAttributeColors(nAttrib, aColors);		while (nColor--)	{		ATTRIBCOLOR& ac = aColors[nColor];		mapColors[ac.sAttrib] = ac.color;	}	tdc.SetAttributeColors(nAttrib, mapColors);	// drag drop	tdc.SetSubtaskDragDropPos(userPrefs.GetNewSubtaskPos() == PUIP_TOP);		// misc	tdc.SetMaxColumnWidth(userPrefs.GetMaxColumnWidth());	tdc.SetCheckImageList(m_ilCheckboxes);	tdc.SetPercentDoneIncrement(userPrefs.GetPercentDoneIncrement());	CString sStatus;	userPrefs.GetCompletionStatus(sStatus);	tdc.SetCompletionStatus(sStatus);		tdc.Flush(); // clear any outstanding issues	// we‘re done	tdc.NotifyEndPreferencesUpdate();}void CToDoListWnd::UpdateTabSwitchTooltip(){	CToolTipCtrl* pTT = m_tabCtrl.GetToolTips();		if (pTT)	{		// get the string for tab switching		CString sShortcut = m_mgrShortcuts.GetShortcutTextByCmd(ID_VIEW_NEXT);				if (sShortcut.IsEmpty())			sShortcut = m_mgrShortcuts.GetShortcutTextByCmd(ID_VIEW_PREV);				pTT->DelTool(&m_tabCtrl); // always				if (!sShortcut.IsEmpty())		{			CEnString sTip(IDS_TABSWITCHTOOLTIP, sShortcut);			pTT->AddTool(&m_tabCtrl, sTip);		}	}}void CToDoListWnd::OnSaveall() {	SaveAll(TDLS_INCLUDEUNSAVED | TDLS_FLUSH);}void CToDoListWnd::OnUpdateSaveall(CCmdUI* pCmdUI) {	pCmdUI->Enable(m_mgrToDoCtrls.AnyIsModified());}void CToDoListWnd::OnCloseall() {	// save first	TDC_FILE nSaveAll = SaveAll(TDLS_INCLUDEUNSAVED | TDLS_CLOSINGTASKLISTS | TDLS_FLUSH);	if (nSaveAll != TDCO_SUCCESS)		return;	// remove tasklists	int nCtrl = GetTDCCount();		while (nCtrl--)		m_mgrToDoCtrls.RemoveToDoCtrl(nCtrl, TRUE);	// if empty then create a new dummy item			if (!GetTDCCount())		CreateNewTaskList(FALSE);	else		Resize();}void CToDoListWnd::OnUpdateCloseall(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetTDCCount());}BOOL CToDoListWnd::DoQueryEndSession(BOOL bQuery, BOOL bEnding){	HWND hWnd = GetSafeHwnd();	// what we do here depends on whether we‘re on Vista or not	// we test for this by trying to load the new API functions	if (bQuery)	{		CEnString sReason(IDS_SHUTDOWNBLOCKREASON);		// if Vista and handling WM_QUERYENDSESSION		// we register our reason and return TRUE to		// get more time to clean up in WM_ENDSESSION		if (Misc::ShutdownBlockReasonCreate(hWnd, sReason))			return TRUE;		// else we‘re XP so we return TRUE to let shutdown continue		return TRUE;	}	// else do a proper shutdown	m_bEndingSession = TRUE;	DoExit(FALSE, bEnding);			// cleanup our shutdown reason if not handled in DoExit	Misc::ShutdownBlockReasonDestroy(hWnd);	// and return anything because it‘s ignored	return TRUE;}BOOL CToDoListWnd::OnQueryEndSession() {	if (!CFrameWnd::OnQueryEndSession())		return FALSE;		return DoQueryEndSession(TRUE, FALSE);}void CToDoListWnd::OnEndSession(BOOL bEnding) {	CFrameWnd::OnEndSession(bEnding);	DoQueryEndSession(FALSE, bEnding);}void CToDoListWnd::OnExit(){	DoExit();}void CToDoListWnd::OnMinimizeToTray(){	MinimizeToTray();}BOOL CToDoListWnd::DoExit(BOOL bRestart, BOOL bClosingWindows) {	ASSERT (!(bClosingWindows && bRestart));    // save all first to ensure new tasklists get reloaded on startup	DWORD dwSaveFlags = TDLS_INCLUDEUNSAVED | TDLS_CLOSINGTASKLISTS | TDLS_FLUSH;	if (bClosingWindows)		dwSaveFlags |= TDLS_CLOSINGWINDOWS;	TDC_FILE nSaveAll = SaveAll(dwSaveFlags);	if (nSaveAll != TDCO_SUCCESS)        return FALSE; // user cancelled		// save settings before we close the tasklists	// to snapshot the currently open tasklists	SaveSettings(); 	m_bClosing = TRUE;		// hide the window as soon as possible so users do not	// see the machinations of closing down	if (m_bFindShowing)		m_findDlg.ShowWindow(SW_HIDE);	ShowWindow(SW_HIDE);		// remove tasklists	int nCtrl = GetTDCCount();			while (nCtrl--)		VERIFY(CloseToDoCtrl(nCtrl)); // shouldn‘t fail now		// if there are any still open then the user must have cancelled else destroy the window	ASSERT (GetTDCCount() == 0);		if (GetTDCCount() == 0)	{		// this will save any left over settings 		// when it goes out of scope		{			CPreferences prefs; 			m_mgrImportExport.Release();			m_tbHelper.Release();			m_mgrShortcuts.Release(&prefs);			m_mgrImportExport.Release();			m_mgrUIExtensions.Release();			m_mgrStorage.Release();						CFocusWatcher::Release();			CMouseWheelMgr::Release();			CEditShortcutMgr::Release();		}		// cleanup our shutdown reason		Misc::ShutdownBlockReasonDestroy(*this);		DestroyWindow();				if (bRestart)		{			CString sParams = AfxGetApp()->m_lpCmdLine;			::ShellExecute(NULL, NULL, FileMisc::GetModuleFileName(), sParams, NULL, SW_SHOW);		}		return TRUE;	}	// cancel	m_bClosing = FALSE;	return FALSE;}void CToDoListWnd::OnImportTasklist() {	CString sImportPath;	TDLID_IMPORTTO nImportTo = TDIT_NEWTASKLIST;	int nImporter = -1;		do	{		CTDLImportDialog dialog(m_mgrImportExport);		if (dialog.DoModal() == IDOK)		{			// check file can be opened			nImportTo = dialog.GetImportTo();			nImporter = dialog.GetImporterIndex();			if (dialog.GetImportFromClipboard())			{				sImportPath = FileMisc::GetTempFileName(_T("ToDoList.import"), _T("txt"));				FileMisc::SaveFile(sImportPath, dialog.GetImportClipboardText());			}			else				sImportPath = dialog.GetImportFilePath();			// check file accessibility			if (sImportPath.IsEmpty() || FileMisc::CanOpenFile(sImportPath, TRUE))				break;			// else			MessageBox(CEnString(IDS_IMPORTFILE_CANTOPEN, sImportPath), IDS_IMPORTTASKLIST_TITLE);			sImportPath.Empty();		}		else // cancel			return;	}	while (sImportPath.IsEmpty());	// load/import tasks	DOPROGRESS(IDS_IMPORTPROGRESS)	// do the import	CTaskFile tasks;	BOOL bCancel = !m_mgrImportExport.ImportTaskList(sImportPath, &tasks, nImporter);	if (bCancel)		return;	if (!tasks.GetTaskCount())	{		// notify user		MessageBox(IDS_NOTASKSIMPORTED);	}	else	{		if (nImportTo == TDIT_NEWTASKLIST)			VERIFY(CreateNewTaskList(FALSE));				CFilteredToDoCtrl& tdc = GetToDoCtrl(); 		TDC_INSERTWHERE nWhere = (nImportTo == TDIT_SELECTEDTASK) ? TDC_INSERTATTOPOFSELTASK : TDC_INSERTATTOP;				VERIFY(tdc.InsertTasks(tasks, nWhere));		// if a new tasklist then set the project name		if (nImportTo == TDIT_NEWTASKLIST)			tdc.SetProjectName(tasks.GetProjectName());		m_mgrToDoCtrls.RefreshModifiedStatus(GetSelToDoCtrl());		UpdateCaption();	}}void CToDoListWnd::OnSetPriority(UINT nCmdID) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		if (!tdc.IsReadOnly() && tdc.HasSelection())	{		if (nCmdID == ID_EDIT_SETPRIORITYNONE) 			tdc.SetSelectedTaskPriority(-2);		else			tdc.SetSelectedTaskPriority(nCmdID - ID_EDIT_SETPRIORITY0);	}}void CToDoListWnd::OnUpdateSetPriority(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(!tdc.IsReadOnly() && nSelCount);		int nPriority = pCmdUI->m_nID - ID_EDIT_SETPRIORITY0;		if (pCmdUI->m_nID == ID_EDIT_SETPRIORITYNONE)		nPriority = -2;		pCmdUI->SetCheck(nPriority == tdc.GetSelectedTaskPriority());}void CToDoListWnd::OnEditSetfileref() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		if (!tdc.IsReadOnly() && tdc.HasSelection())	{		CPreferences prefs;		CFileOpenDialog dialog(IDS_SETFILEREF_TITLE, 								NULL, 								tdc.GetSelectedTaskFileRef(), 								EOFN_DEFAULTOPEN, 								CEnString(IDS_ALLFILEFILTER));				if (dialog.DoModal(&prefs) == IDOK)			tdc.SetSelectedTaskFileRef(dialog.GetPathName());	}}void CToDoListWnd::OnUpdateEditSetfileref(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(!tdc.IsReadOnly() && tdc.HasSelection());}void CToDoListWnd::OnEditOpenfileref() {	GetToDoCtrl().GotoSelectedTaskFileRef();}void CToDoListWnd::OnUpdateEditOpenfileref(CCmdUI* pCmdUI) {	CEnString sFileRef = GetToDoCtrl().GetSelectedTaskFileRef();		if (sFileRef.IsEmpty())		pCmdUI->Enable(FALSE);	else	{		pCmdUI->Enable(TRUE);		// restrict file length to 250 pixels		CClientDC dc(this);		sFileRef.FormatDC(&dc, 250, ES_PATH);		pCmdUI->SetText(sFileRef);	}}LRESULT CToDoListWnd::OnPreferencesDefaultListChange(WPARAM wp, LPARAM lp){	// decode params	int nList = LOWORD(wp);	BOOL bAdd = HIWORD(wp);	LPCTSTR szItem = (LPCTSTR)lp;	switch (nList)	{	case PTDP_ALLOCBY:		break;	case PTDP_ALLOCTO:		break;	case PTDP_STATUS:		break;	case PTDP_CATEGORY:		break;	}	return 0L;}void CToDoListWnd::PopulateToolArgs(USERTOOLARGS& args) const{	const CFilteredToDoCtrl& tdc = GetToDoCtrl();			args.sTasklist = tdc.GetFilePath();	args.sTaskTitle = tdc.GetSelectedTaskTitle();	args.sTaskExtID = tdc.GetSelectedTaskExtID();	args.sTaskComments = tdc.GetSelectedTaskComments();	args.sTaskFileLink = tdc.GetSelectedTaskFileRef();	args.sTaskAllocBy = tdc.GetSelectedTaskAllocBy();		CDWordArray aIDs;	DWORD dwTemp;		if (tdc.GetSelectedTaskIDs(aIDs, dwTemp, FALSE))		args.sTaskIDs = Misc::FormatArray(aIDs, _T("|"));		CStringArray aAllocTo;		if (tdc.GetSelectedTaskAllocTo(aAllocTo))		args.sTaskAllocTo = Misc::FormatArray(aAllocTo, _T("|"));}LRESULT CToDoListWnd::OnPreferencesTestTool(WPARAM /*wp*/, LPARAM lp){	USERTOOL* pTool = (USERTOOL*)lp;		if (pTool)	{		USERTOOLARGS args;		PopulateToolArgs(args);		CToolsHelper th(Prefs().GetEnableTDLExtension(), ID_TOOLS_USERTOOL1);		th.TestTool(*pTool, args, m_pPrefs);	}		return 0;}LRESULT CToDoListWnd::OnPreferencesClearMRU(WPARAM /*wp*/, LPARAM /*lp*/){	m_mruList.RemoveAll();	m_mruList.WriteList(CPreferences());		return 0;}LRESULT CToDoListWnd::OnPreferencesCleanupDictionary(WPARAM /*wp*/, LPARAM lp){	LPCTSTR szLangFile = (LPCTSTR)lp;	ASSERT(szLangFile && *szLangFile);	if (szLangFile && *szLangFile)	{		DOPROGRESS(IDS_CLEANINGDICTPROGRESS)		CString sMasterDict = FileMisc::GetFolderFromFilePath(szLangFile);		sMasterDict += _T("\\YourLanguage.csv");		return CLocalizer::CleanupDictionary(sMasterDict);	}		return 0;}void CToDoListWnd::PrepareSortMenu(CMenu* pMenu){	const CFilteredToDoCtrl& tdc = GetToDoCtrl();			if (Prefs().GetShowEditMenuAsColumns())	{		int nCountLastSep = 0;				for (int nItem = 0; nItem < (int)pMenu->GetMenuItemCount(); nItem++)		{			BOOL bDelete = FALSE;			BOOL bIsSeparator = FALSE;			UINT nMenuID = pMenu->GetMenuItemID(nItem);						switch (nMenuID)			{			case ID_SORT_BYCOST:		bDelete = !tdc.IsColumnShowing(TDCC_COST); break;			case ID_SORT_BYFLAG:		bDelete = !tdc.IsColumnShowing(TDCC_FLAG); break; 			case ID_SORT_BYDONEDATE:	bDelete = !tdc.IsColumnShowing(TDCC_DONEDATE); break; 			case ID_SORT_BYPRIORITY:	bDelete = !tdc.IsColumnShowing(TDCC_PRIORITY); break; 			case ID_SORT_BYPERCENT:		bDelete = !tdc.IsColumnShowing(TDCC_PERCENT); break; 			case ID_SORT_BYSTARTDATE:	bDelete = !tdc.IsColumnShowing(TDCC_STARTDATE); break; 			case ID_SORT_BYDUEDATE:		bDelete = !tdc.IsColumnShowing(TDCC_DUEDATE); break; 			case ID_SORT_BYTIMEEST:		bDelete = !tdc.IsColumnShowing(TDCC_TIMEEST); break; 			case ID_SORT_BYID:			bDelete = !tdc.IsColumnShowing(TDCC_ID); break; 			case ID_SORT_BYDONE:		bDelete = !tdc.IsColumnShowing(TDCC_DONE); break; 			case ID_SORT_BYALLOCBY:		bDelete = !tdc.IsColumnShowing(TDCC_ALLOCBY); break; 			case ID_SORT_BYSTATUS:		bDelete = !tdc.IsColumnShowing(TDCC_STATUS); break; 			case ID_SORT_BYCATEGORY:	bDelete = !tdc.IsColumnShowing(TDCC_CATEGORY); break; 			case ID_SORT_BYTIMESPENT:	bDelete = !tdc.IsColumnShowing(TDCC_TIMESPENT); break; 			case ID_SORT_BYALLOCTO:		bDelete = !tdc.IsColumnShowing(TDCC_ALLOCTO); break; 			case ID_SORT_BYCREATIONDATE:bDelete = !tdc.IsColumnShowing(TDCC_CREATIONDATE); break; 			case ID_SORT_BYCREATEDBY:	bDelete = !tdc.IsColumnShowing(TDCC_CREATEDBY); break; 			case ID_SORT_BYMODIFYDATE:	bDelete = !tdc.IsColumnShowing(TDCC_LASTMOD); break; 			case ID_SORT_BYRISK:		bDelete = !tdc.IsColumnShowing(TDCC_RISK); break; 			case ID_SORT_BYEXTERNALID:	bDelete = !tdc.IsColumnShowing(TDCC_EXTERNALID); break; 			case ID_SORT_BYVERSION:		bDelete = !tdc.IsColumnShowing(TDCC_VERSION); break; 			case ID_SORT_BYRECURRENCE:	bDelete = !tdc.IsColumnShowing(TDCC_RECURRENCE); break; 			case ID_SORT_BYREMAINING:	bDelete = !tdc.IsColumnShowing(TDCC_REMAINING); break; 			case ID_SORT_BYRECENTEDIT:	bDelete = !tdc.IsColumnShowing(TDCC_RECENTEDIT); break; 			case ID_SORT_BYICON:		bDelete = !tdc.IsColumnShowing(TDCC_ICON); break; 			case ID_SORT_BYFILEREF:		bDelete = !tdc.IsColumnShowing(TDCC_FILEREF); break; 			case ID_SORT_BYTIMETRACKING:bDelete = !tdc.IsColumnShowing(TDCC_TRACKTIME); break; 			case ID_SORT_BYPATH:		bDelete = !tdc.IsColumnShowing(TDCC_PATH); break; 			case ID_SORT_BYTAG:			bDelete = !tdc.IsColumnShowing(TDCC_TAGS); break; 			case ID_SORT_BYDEPENDENCY:	bDelete = !tdc.IsColumnShowing(TDCC_DEPENDENCY); break; 	//		case ID_SORT_BYCOLOR: bDelete = (Prefs().GetTextColorOption() != COLOROPT_DEFAULT); break; 			case ID_SEPARATOR: 				bIsSeparator = TRUE;				bDelete = (nCountLastSep == 0);				nCountLastSep = 0;				break;			default: bDelete = FALSE; break; 			}			// delete the item else increment the count since the last separator			if (bDelete)			{				pMenu->DeleteMenu(nItem, MF_BYPOSITION);				nItem--;			}			else if (!bIsSeparator)				nCountLastSep++;		}	}	// custom sort columns	// first delete all custom columns and the related separator	int nPosUnsorted = -1;	for (int nItem = 0; nItem < (int)pMenu->GetMenuItemCount(); nItem++)	{		UINT nMenuID = pMenu->GetMenuItemID(nItem);		if (nMenuID >= ID_SORT_BYCUSTOMCOLUMN_FIRST && nMenuID <= ID_SORT_BYCUSTOMCOLUMN_LAST)		{			pMenu->DeleteMenu(nItem, MF_BYPOSITION);			nItem--;		}	}	// separator is just before the separator before ‘unsorted entry‘	int nInsert = CEnMenu::GetMenuItemPos(pMenu->GetSafeHmenu(), ID_SORT_NONE) - 1;	ASSERT(nInsert >= 0);	// delete separator if exist	if (nInsert > 0 && pMenu->GetMenuItemID(nInsert - 1) == 0)	{		nInsert--;		pMenu->DeleteMenu(nInsert, MF_BYPOSITION);	}	// then re-add	CTDCCustomAttribDefinitionArray aAttribDefs;	if (tdc.GetCustomAttributeDefs(aAttribDefs))	{		// re-add separator on demand		BOOL bWantSep = TRUE;		for (int nCol = 0; nCol < aAttribDefs.GetSize(); nCol++)		{			const TDCCUSTOMATTRIBUTEDEFINITION& attribDef = aAttribDefs[nCol];			if (attribDef.bEnabled && attribDef.SupportsFeature(TDCCAF_SORT))			{				if (bWantSep)				{					bWantSep = FALSE;					pMenu->InsertMenu(nInsert, MF_BYPOSITION);					nInsert++;				}				UINT nMenuID = (attribDef.GetColumnID() - TDCC_CUSTOMCOLUMN_FIRST) + ID_SORT_BYCUSTOMCOLUMN_FIRST;				CEnString sColumn(IDS_CUSTOMCOLUMN, attribDef.sLabel);				pMenu->InsertMenu(nInsert, MF_BYPOSITION, nMenuID, sColumn);				nInsert++;			}		}	}}void CToDoListWnd::PrepareSourceControlMenu(CMenu* pMenu){	if (Prefs().GetEnableSourceControl())		return;	int nCountLastSep = 0;		for (int nItem = 0; nItem < (int)pMenu->GetMenuItemCount(); nItem++)	{		BOOL bDelete = FALSE;		BOOL bIsSeparator = FALSE;		UINT nMenuID = pMenu->GetMenuItemID(nItem);				switch (nMenuID)		{		case -1: // its a popup so recursively handle it			{				CMenu* pPopup = pMenu->GetSubMenu(nItem);				PrepareEditMenu(pPopup);								// if the popup is now empty remove it too				bDelete = !pPopup->GetMenuItemCount();			}			break;			        case ID_TOOLS_CHECKIN:        case ID_TOOLS_CHECKOUT:			bDelete = TRUE;			break;					case ID_SEPARATOR: 			bIsSeparator = TRUE;			bDelete = (nCountLastSep == 0);			nCountLastSep = 0;			break;		default: bDelete = FALSE; break; 		}		// delete the item else increment the count since the last separator		if (bDelete)		{			pMenu->DeleteMenu(nItem, MF_BYPOSITION);			nItem--;		}		else if (!bIsSeparator)			nCountLastSep++;	}}void CToDoListWnd::PrepareEditMenu(CMenu* pMenu){	if (!Prefs().GetShowEditMenuAsColumns())		return;	const CFilteredToDoCtrl& tdc = GetToDoCtrl();		int nCountLastSep = 0;		for (int nItem = 0; nItem < (int)pMenu->GetMenuItemCount(); nItem++)	{		BOOL bDelete = FALSE;		BOOL bIsSeparator = FALSE;		UINT nMenuID = pMenu->GetMenuItemID(nItem);				switch (nMenuID)		{		case -1: // its a popup so recursively handle it			{				CMenu* pPopup = pMenu->GetSubMenu(nItem);				if (pPopup)				{					PrepareEditMenu(pPopup);									// if the popup is now empty remove it too					bDelete = !pPopup->GetMenuItemCount();				}			}			break;					case ID_EDIT_TASKCOLOR:		case ID_EDIT_CLEARTASKCOLOR:			bDelete = (Prefs().GetTextColorOption() != COLOROPT_DEFAULT);			break;			        case ID_EDIT_DECTASKPRIORITY:        case ID_EDIT_INCTASKPRIORITY:		case ID_EDIT_SETPRIORITYNONE:         case ID_EDIT_SETPRIORITY0:        case ID_EDIT_SETPRIORITY1:        case ID_EDIT_SETPRIORITY2:        case ID_EDIT_SETPRIORITY3:        case ID_EDIT_SETPRIORITY4:        case ID_EDIT_SETPRIORITY5:        case ID_EDIT_SETPRIORITY6:        case ID_EDIT_SETPRIORITY7:        case ID_EDIT_SETPRIORITY8:        case ID_EDIT_SETPRIORITY9:        case ID_EDIT_SETPRIORITY10:			bDelete = !tdc.IsColumnShowing(TDCC_PRIORITY);			break;					case ID_EDIT_OFFSETDATES:			bDelete = !(tdc.IsColumnShowing(TDCC_STARTDATE) ||						tdc.IsColumnShowing(TDCC_DUEDATE) || 						tdc.IsColumnShowing(TDCC_DONEDATE));			break;			        case ID_EDIT_CLOCK_TASK:			bDelete = !(tdc.IsColumnShowing(TDCC_TRACKTIME) ||						tdc.IsColumnShowing(TDCC_TIMESPENT));			break;        case ID_SHOWTIMELOGFILE:			bDelete = !((tdc.IsColumnShowing(TDCC_TRACKTIME) ||						tdc.IsColumnShowing(TDCC_TIMESPENT)) &&						Prefs().GetLogTimeTracking());			break;			        case ID_EDIT_DECTASKPERCENTDONE:	bDelete = !tdc.IsColumnShowing(TDCC_PERCENT); break;        case ID_EDIT_INCTASKPERCENTDONE:	bDelete = !tdc.IsColumnShowing(TDCC_PERCENT); break;        case ID_EDIT_OPENFILEREF:			bDelete = !tdc.IsColumnShowing(TDCC_FILEREF); break;		case ID_EDIT_SETFILEREF:			bDelete = !tdc.IsColumnShowing(TDCC_FILEREF); break;        case ID_EDIT_FLAGTASK:				bDelete = !tdc.IsColumnShowing(TDCC_FLAG); break;        case ID_EDIT_RECURRENCE:			bDelete = !tdc.IsColumnShowing(TDCC_RECURRENCE); break;        case ID_EDIT_GOTODEPENDENCY:		bDelete = !tdc.IsColumnShowing(TDCC_DEPENDENCY); break;        case ID_EDIT_SETTASKICON:			        case ID_EDIT_CLEARTASKICON:				bDelete = !(tdc.IsColumnShowing(TDCC_ICON) || Prefs().GetTreeTaskIcons()); 			break;		case ID_SEPARATOR: 			bIsSeparator = TRUE;			bDelete = (nCountLastSep == 0);			nCountLastSep = 0;			break;		default: bDelete = FALSE; break; 		}		// delete the item else increment the count since the last separator		if (bDelete)		{			pMenu->DeleteMenu(nItem, MF_BYPOSITION);			nItem--;		}		else if (!bIsSeparator)			nCountLastSep++;	}	// make sure last item is not a separator	int nLastItem = (int)pMenu->GetMenuItemCount() - 1;	if (pMenu->GetMenuItemID(nLastItem) == 0)		pMenu->DeleteMenu(nLastItem, MF_BYPOSITION);}void CToDoListWnd::OnViewNext() {	if (GetTDCCount() < 2)		return;		int nNext = GetSelToDoCtrl() + 1;		if (nNext >= GetTDCCount())		nNext = 0;		SelectToDoCtrl(nNext, TRUE, Prefs().GetNotifyDueByOnSwitch());}void CToDoListWnd::OnUpdateViewNext(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetTDCCount() > 1);}void CToDoListWnd::OnViewPrev() {	if (GetTDCCount() < 2)		return;		int nPrev = GetSelToDoCtrl() - 1;		if (nPrev < 0)		nPrev = GetTDCCount() - 1;		SelectToDoCtrl(nPrev, TRUE, Prefs().GetNotifyDueByOnSwitch());}void CToDoListWnd::OnUpdateViewPrev(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetTDCCount() > 1);}void CToDoListWnd::OnSysCommand(UINT nID, LPARAM lParam) {	switch (nID)	{	case SC_MINIMIZE:		// we don‘t minimize if we‘re going to be hiding to then system tray		{			m_hwndLastFocus = ::GetFocus();			int nSysTrayOption = Prefs().GetSysTrayOption();						if (nSysTrayOption == STO_ONMINIMIZE || nSysTrayOption == STO_ONMINCLOSE)				MinimizeToTray();			else			{				// SPECIAL FIX: Apparently when Ultramon hooks the minimize				// button it ends up sending us a close message!				ShowWindow(SW_MINIMIZE);			}			return; // eat it		}	case SC_HOTKEY:		Show(FALSE);		return;			case SC_CLOSE:		// don‘t allow closing whilst reloading tasklists		if (m_bReloading)			return;		break;	case SC_RESTORE:	case SC_MAXIMIZE:		PostMessage(WM_APPRESTOREFOCUS, 0L, (LPARAM)m_hwndLastFocus);		break;	}	CFrameWnd::OnSysCommand(nID, lParam);}void CToDoListWnd::OnUpdateImport(CCmdUI* pCmdUI) {	pCmdUI->Enable(!GetToDoCtrl().IsReadOnly());}UINT CToDoListWnd::MapNewTaskPos(int nPos, BOOL bSubtask){	if (!bSubtask) // task	{		switch (nPos)		{		case PUIP_TOP:		return ID_NEWTASK_ATTOP;		case PUIP_BOTTOM:	return ID_NEWTASK_ATBOTTOM;		case PUIP_BELOW:	return ID_NEWTASK_AFTERSELECTEDTASK;					case PUIP_ABOVE: 		default:			return ID_NEWTASK_BEFORESELECTEDTASK;		}	}	else // subtask	{		if (nPos == PUIP_BOTTOM)			return ID_NEWSUBTASK_ATBOTTOM;		else			return ID_NEWSUBTASK_ATTOP;	}}UINT CToDoListWnd::GetNewTaskCmdID(){	return MapNewTaskPos(Prefs().GetNewTaskPos(), FALSE);}UINT CToDoListWnd::GetNewSubtaskCmdID(){	return MapNewTaskPos(Prefs().GetNewSubtaskPos(), TRUE);}void CToDoListWnd::OnNewtask() {	// convert to users choice	SendMessage(WM_COMMAND, GetNewTaskCmdID());}void CToDoListWnd::OnUpdateNewtask(CCmdUI* pCmdUI) {	switch (GetNewTaskCmdID())	{	case ID_NEWTASK_ATTOPSELECTED:		OnUpdateNewtaskAttopSelected(pCmdUI);		break;	case ID_NEWTASK_ATBOTTOMSELECTED:			OnUpdateNewtaskAtbottomSelected(pCmdUI);		break;		case ID_NEWTASK_AFTERSELECTEDTASK:		OnUpdateNewtaskAfterselectedtask(pCmdUI);		break;	case ID_NEWTASK_BEFORESELECTEDTASK:		OnUpdateNewtaskBeforeselectedtask(pCmdUI);		break;	case ID_NEWTASK_ATTOP:		OnUpdateNewtaskAttop(pCmdUI);		break;	case ID_NEWTASK_ATBOTTOM:		OnUpdateNewtaskAtbottom(pCmdUI);		break;	}}void CToDoListWnd::OnNewsubtask() {	// convert to users choice	SendMessage(WM_COMMAND, GetNewSubtaskCmdID());}void CToDoListWnd::OnUpdateNewsubtask(CCmdUI* pCmdUI) {	switch (GetNewSubtaskCmdID())	{	case ID_NEWSUBTASK_ATTOP:		OnUpdateNewsubtaskAttop(pCmdUI);		break;	case ID_NEWSUBTASK_ATBOTTOM:		OnUpdateNewsubtaskAtBottom(pCmdUI);		break;	}}void CToDoListWnd::OnToolsCheckout() {	int nSel = GetSelToDoCtrl();	// sanity check	if (!m_mgrToDoCtrls.CanCheckOut(nSel))		return;		CAutoFlag af(m_bSaving, TRUE);	CString sCheckedOutTo;	CFilteredToDoCtrl& tdc = GetToDoCtrl(nSel);		if (tdc.CheckOut(sCheckedOutTo))	{		m_mgrToDoCtrls.UpdateToDoCtrlReadOnlyUIState(nSel);		m_mgrToDoCtrls.SetLastCheckoutStatus(nSel, TRUE);		m_mgrToDoCtrls.RefreshLastModified(nSel);				UpdateCaption();		// update menu icon mgr		m_mgrMenuIcons.ChangeImageID(ID_TOOLS_CHECKOUT, ID_TOOLS_CHECKIN);	}	else // failed	{		m_mgrToDoCtrls.SetLastCheckoutStatus(nSel, FALSE);				// notify user		CEnString sMessage;				if (!sCheckedOutTo.IsEmpty())		{			sMessage.Format(IDS_CHECKEDOUTBYOTHER, tdc.GetFilePath(), sCheckedOutTo);		}		else		{			// if sCheckedOutTo is empty then the error is most likely because			// the file has been deleted or cannot be opened for editing			sMessage.Format(IDS_CHECKOUTFAILED, tdc.GetFilePath());		}				MessageBox(sMessage, IDS_CHECKOUT_TITLE, MB_OK | MB_ICONEXCLAMATION);	}}void CToDoListWnd::OnUpdateToolsCheckout(CCmdUI* pCmdUI) {	int nSel = GetSelToDoCtrl();		pCmdUI->Enable(m_mgrToDoCtrls.CanCheckOut(nSel));}void CToDoListWnd::OnToolsToggleCheckin() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		if (tdc.IsCheckedOut())		OnToolsCheckin();	else		OnToolsCheckout();}void CToDoListWnd::OnUpdateToolsToggleCheckin(CCmdUI* pCmdUI) {	int nSel = GetSelToDoCtrl();	BOOL bEnable = m_mgrToDoCtrls.CanCheckInOut(nSel);		pCmdUI->Enable(bEnable);	pCmdUI->SetCheck(bEnable && GetToDoCtrl().IsCheckedOut() ? 1 : 0);}void CToDoListWnd::OnToolsCheckin() {	int nSel = GetSelToDoCtrl();	// sanity check	if (!m_mgrToDoCtrls.CanCheckIn(nSel))		return;		CAutoFlag af(m_bSaving, TRUE);	CFilteredToDoCtrl& tdc = GetToDoCtrl(nSel);	ASSERT (!tdc.GetFilePath().IsEmpty());		tdc.Flush();		// save modifications	TDC_FILE nSave = TDCO_SUCCESS;	if (tdc.IsModified())	{		if (Prefs().GetConfirmSaveOnExit())		{			CString sName = m_mgrToDoCtrls.GetFriendlyProjectName(nSel);			CEnString sMessage(IDS_SAVEBEFORECHECKIN, sName);						int nRet = MessageBox(sMessage, IDS_CHECKIN_TITLE, MB_YESNOCANCEL);						switch (nRet)			{			case IDYES:				nSave = SaveTaskList(nSel);				break;							case IDNO:				ReloadTaskList(nSel, FALSE, FALSE);				break;							case IDCANCEL:				return;			}		}		else			SaveTaskList(nSel); 	}		if (nSave == TDCO_SUCCESS && tdc.CheckIn())		{		m_mgrToDoCtrls.UpdateToDoCtrlReadOnlyUIState(nSel);		m_mgrToDoCtrls.RefreshLastModified(nSel);		UpdateCaption();		// update menu icon mgr		m_mgrMenuIcons.ChangeImageID(ID_TOOLS_CHECKIN, ID_TOOLS_CHECKOUT);	}	m_mgrToDoCtrls.SetLastCheckoutStatus(nSel, TRUE); // so we won‘t try to immediately check it out again}void CToDoListWnd::OnUpdateToolsCheckin(CCmdUI* pCmdUI) {	int nSel = GetSelToDoCtrl();		pCmdUI->Enable(m_mgrToDoCtrls.CanCheckIn(nSel));}void CToDoListWnd::OnExport() {	const CPreferencesDlg& userPrefs = Prefs();		int nTDCCount = GetTDCCount(), nSelTDC = GetSelToDoCtrl();	ASSERT (nTDCCount >= 1);	CTDLExportDlg dialog(m_mgrImportExport, 						nTDCCount == 1, 						GetToDoCtrl().GetView(),						userPrefs.GetExportVisibleColsOnly(), 						m_mgrToDoCtrls.GetFilePath(nSelTDC, FALSE), 						userPrefs.GetAutoExportFolderPath());		// keep showing the dialog until either the user	// selects a filename which does not match a tasklist	// or they confirm that they want to overwrite the tasklist	CString sExportPath;	BOOL bOverWrite = FALSE;	int nFormat = -1;	while (!bOverWrite)	{		if (dialog.DoModal() != IDOK)			return;		sExportPath = dialog.GetExportPath();		nFormat = dialog.GetExportFormat();		// interested in overwriting single files		if (nTDCCount == 1 || !dialog.GetExportAllTasklists() || dialog.GetExportOneFile())		{			// check with user if they are about to override a tasklist			if (m_mgrToDoCtrls.FindToDoCtrl(sExportPath) != -1)			{				UINT nRet = MessageBox(IDS_CONFIRM_EXPORT_OVERWRITE, 0, MB_YESNOCANCEL, sExportPath);				if (nRet == IDCANCEL)					return;				// else				bOverWrite = (nRet == IDYES);			}			else				bOverWrite = TRUE; // nothing to fear		}		else // check all open tasklists		{			CString sFilePath, sExt = m_mgrImportExport.GetExporterFileExtension(nFormat);					for (int nCtrl = 0; nCtrl < nTDCCount; nCtrl++)			{				CString sPath = m_mgrToDoCtrls.GetFilePath(nCtrl);				CString sFName;										FileMisc::SplitPath(sPath, NULL, NULL, &sFName);				FileMisc::MakePath(sFilePath, NULL, sExportPath, sFName, sExt);				if (m_mgrToDoCtrls.FindToDoCtrl(sFilePath) != -1)				{					UINT nRet = MessageBox(IDS_CONFIRM_EXPORT_OVERWRITE, 0, MB_YESNOCANCEL, sFilePath);					if (nRet == IDCANCEL)						return;					// else					bOverWrite = (nRet == IDYES);					break;				}			}			// no matches?			bOverWrite = TRUE; // nothing to fear		}	}	UpdateWindow();	// export	DOPROGRESS(IDS_EXPORTPROGRESS)		BOOL bHtmlComments = (nFormat == EXPTOHTML);	if (nTDCCount == 1 || !dialog.GetExportAllTasklists())	{		// set the html image folder to be the output path with		// an different extension		CString sImgFolder;				if (bHtmlComments)		{			sImgFolder = sExportPath;			FileMisc::ReplaceExtension(sImgFolder, _T("html_images"));			FileMisc::DeleteFolderContents(sImgFolder, TRUE);		}				CFilteredToDoCtrl& tdc = GetToDoCtrl(nSelTDC);		CTaskFile tasks;		// Note: don‘t need to verify password if encrypted tasklist is active		GetTasks(tdc, bHtmlComments, FALSE, dialog.GetTaskSelection(), tasks, sImgFolder);		// add project name as report title		CString sTitle = m_mgrToDoCtrls.GetFriendlyProjectName(nSelTDC);		tasks.SetReportAttributes(sTitle);				// save intermediate tasklist to file as required		LogIntermediateTaskList(tasks, tdc.GetFilePath());		if (m_mgrImportExport.ExportTaskList(&tasks, sExportPath, nFormat, FALSE))		{			// and preview			if (userPrefs.GetPreviewExport())				FileMisc::Run(*this, sExportPath, NULL, SW_SHOWNORMAL);		}	} 	// multiple tasklists	else if (dialog.GetExportOneFile())	{		CMultiTaskFile taskFiles;				for (int nCtrl = 0; nCtrl < nTDCCount; nCtrl++)		{			// verify password			if (nCtrl != nSelTDC && !VerifyToDoCtrlPassword(nCtrl))				continue;						CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);			tdc.LockWindowUpdate();						// make sure it‘s loaded			if (VerifyTaskListOpen(nCtrl, FALSE))			{				CTaskFile& tasks = taskFiles.GetTaskFile(nCtrl);				tasks.Reset();								// set the html image folder to be the output path with				// an different extension				CString sImgFolder;								if (bHtmlComments)				{					sImgFolder = sExportPath;					FileMisc::ReplaceExtension(sImgFolder, _T("html_images"));				}								GetTasks(tdc, bHtmlComments, FALSE, dialog.GetTaskSelection(), tasks, sImgFolder);								// add project name as report title				CString sTitle = m_mgrToDoCtrls.GetFriendlyProjectName(nCtrl);				tasks.SetReportAttributes(sTitle);				// save intermediate tasklist to file as required				LogIntermediateTaskList(tasks, tdc.GetFilePath());			}						tdc.UnlockWindowUpdate();		}				Resize();				if (m_mgrImportExport.ExportTaskLists(&taskFiles, sExportPath, nFormat, FALSE))		{			// and preview			if (userPrefs.GetPreviewExport())				FileMisc::Run(*this, sExportPath, NULL, SW_SHOWNORMAL);		}	}	else // separate files	{		CString sExt = m_mgrImportExport.GetExporterFileExtension(nFormat);				for (int nCtrl = 0; nCtrl < nTDCCount; nCtrl++)		{			// verify password			if (nCtrl != nSelTDC && !VerifyToDoCtrlPassword(nCtrl))				continue;						CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);			tdc.LockWindowUpdate();						// make sure it‘s loaded			if (VerifyTaskListOpen(nCtrl, FALSE))			{				// build filepath if required (if exporter has an extension)				CString sFilePath;				BOOL bOverWrite = -1;								if (!sExt.IsEmpty())				{					CString sPath = m_mgrToDoCtrls.GetFilePath(nCtrl);										// if the file has not been saved before we use the tab text					// and prompt the user to confirm					if (sPath.IsEmpty())					{						sPath = m_mgrToDoCtrls.GetFilePath(nCtrl, FALSE);						FileMisc::MakePath(sFilePath, NULL, sExportPath, sPath, sExt);												CFileSaveDialog dlgFile(IDS_EXPORTFILEAS_TITLE,												sExt, 												sFilePath, 												EOFN_DEFAULTSAVE,												m_mgrImportExport.GetExporterFileFilter(nFormat));												CPreferences prefs;						if (dlgFile.DoModal(&prefs) == IDOK)							sFilePath = dlgFile.GetPathName();						else							continue; // next tasklist					}					else					{						CString sFName;						FileMisc::SplitPath(sPath, NULL, NULL, &sFName);						FileMisc::MakePath(sFilePath, NULL, sExportPath, sFName, sExt);					}				}								// set the html image folder to be the output path with				// an different extension				CString sImgFolder;								if (bHtmlComments)				{					sImgFolder = sFilePath;					FileMisc::ReplaceExtension(sImgFolder, _T("html_images"));				}								CTaskFile tasks;				GetTasks(tdc, bHtmlComments, FALSE, dialog.GetTaskSelection(), tasks, sImgFolder);								// add project name as report title				CString sTitle = m_mgrToDoCtrls.GetFriendlyProjectName(nCtrl);				tasks.SetReportAttributes(sTitle);				// save intermediate tasklist to file as required				LogIntermediateTaskList(tasks, tdc.GetFilePath());				m_mgrImportExport.ExportTaskList(&tasks, sFilePath, nFormat, FALSE);			}						tdc.UnlockWindowUpdate();		}	}}int CToDoListWnd::GetTasks(CFilteredToDoCtrl& tdc, BOOL bHtmlComments, BOOL bTransform, 						  TSD_TASKS nWhatTasks, TDCGETTASKS& filter, DWORD dwSelFlags, 						  CTaskFile& tasks, LPCTSTR szHtmlImageDir) const{	// preferences	const CPreferencesDlg& userPrefs = Prefs();		// project name	tasks.SetProjectName(tdc.GetFriendlyProjectName());	tasks.SetCharSet(userPrefs.GetHtmlCharSet());		// export flags	filter.dwFlags |= TDCGTF_FILENAME;	if (userPrefs.GetExportParentTitleCommentsOnly())		filter.dwFlags |= TDCGTF_PARENTTITLECOMMENTSONLY;	if (bHtmlComments)	{		filter.dwFlags |= TDCGTF_HTMLCOMMENTS;		tasks.SetHtmlImageFolder(szHtmlImageDir);		// And delete all existing images in that folder		if (szHtmlImageDir && *szHtmlImageDir)			FileMisc::DeleteFolderContents(szHtmlImageDir, TRUE);		if (bTransform)		{			ASSERT(bHtmlComments);			filter.dwFlags |= TDCGTF_TRANSFORM;		}	}	// get the tasks	tdc.Flush();		switch (nWhatTasks)	{	case TSDT_ALL:		{			// if there‘s a filter present then we toggle it off 			// grab the tasks and then toggle it back on			BOOL bNeedToggle = (tdc.HasFilter() || tdc.HasCustomFilter());			if (bNeedToggle)			{				::LockWindowUpdate(tdc.GetSafeHwnd());				tdc.ToggleFilter();			}			tdc.GetTasks(tasks, filter);			if (bNeedToggle)			{				tdc.ToggleFilter();				::LockWindowUpdate(NULL);			}		}		break;	case TSDT_FILTERED:		// if no filter is present then this just gets the whole lot		tdc.GetFilteredTasks(tasks, filter);		break;	case TSDT_SELECTED:		tdc.GetSelectedTasks(tasks, filter, dwSelFlags);		break;	}		// delete the HTML image folder if it is empty	// this will fail if it is not empty.	if (bHtmlComments && szHtmlImageDir && *szHtmlImageDir)		RemoveDirectory(szHtmlImageDir);		return tasks.GetTaskCount();}int CToDoListWnd::GetTasks(CFilteredToDoCtrl& tdc, BOOL bHtmlComments, BOOL bTransform, 							const CTaskSelectionDlg& taskSel, CTaskFile& tasks, LPCTSTR szHtmlImageDir) const{	DWORD dwSelFlags = 0;    TSD_TASKS nWhatTasks = taskSel.GetWantWhatTasks();		if (taskSel.GetWantSelectedTasks())	{		if (!taskSel.GetWantSelectedSubtasks()) 			dwSelFlags |= TDCGSTF_NOTSUBTASKS;		if (taskSel.GetWantSelectedParentTask())			dwSelFlags |= TDCGSTF_IMMEDIATEPARENT;	}	TDC_GETTASKS nFilter = TDCGT_ALL;		// build filter	if (taskSel.GetWantCompletedTasks() && !taskSel.GetWantInCompleteTasks())		nFilter = TDCGT_DONE;			else if (!taskSel.GetWantCompletedTasks() && taskSel.GetWantInCompleteTasks())		nFilter = TDCGT_NOTDONE;			TDCGETTASKS filter(nFilter);	// attributes to export	switch (taskSel.GetAttributeOption())	{	case TSDA_ALL:		break;	case TSDA_VISIBLE:		{			CTDCColumnIDArray aCols;			tdc.GetVisibleColumns(aCols);			MapColumnsToAttributes(aCols, filter.aAttribs);			if (taskSel.GetWantCommentsWithVisible())				filter.aAttribs.Add(TDCA_COMMENTS);			filter.aAttribs.Add(TDCA_CUSTOMATTRIB); // always		}		break;	case TSDA_USER:		taskSel.GetUserAttributes(filter.aAttribs);		filter.dwFlags |= TDCGTF_USERCOLUMNS;		break;	}		// get the tasks   return GetTasks(tdc, bHtmlComments, bTransform, nWhatTasks, filter, dwSelFlags, tasks, szHtmlImageDir);}void CToDoListWnd::OnUpdateExport(CCmdUI* pCmdUI) {	// make sure at least one control has items	int nCtrl = GetTDCCount();		while (nCtrl--)	{		if (GetToDoCtrl().GetTaskCount())		{			pCmdUI->Enable(TRUE);			return;		}	}		// else	pCmdUI->Enable(FALSE);}void CToDoListWnd::OnToolsTransformactivetasklist() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	// pass the project name as the title field	CString sTitle = tdc.GetProjectName();	CTDLTransformDialog dialog(sTitle, tdc.GetView());		if (dialog.DoModal() != IDOK)		return;		CString sStylesheet = dialog.GetStylesheet();	sTitle = dialog.GetTitle();		// output path	CString sOutputPath(tdc.GetFilePath()); 	{		if (!sOutputPath.IsEmpty())			FileMisc::ReplaceExtension(sOutputPath, _T("html"));		CPreferences prefs;		CFileSaveDialog dialog(IDS_SAVETRANSFORM_TITLE,								_T("html"), 								sOutputPath, 								OFN_OVERWRITEPROMPT, 								CEnString(IDS_TRANSFORMFILEFILTER), 								this);				if (dialog.DoModal(&prefs) != IDOK)			return; // user elected not to proceed				sOutputPath = dialog.GetPathName();	}		// export	DOPROGRESS(IDS_TRANSFORMPROGRESS)	// set the html image folder to be the same as the 	// output path without the extension	CString sHtmlImgFolder(sOutputPath);	FileMisc::ReplaceExtension(sHtmlImgFolder, _T("html_images"));		CTaskFile tasks;	GetTasks(tdc, TRUE, TRUE, dialog.GetTaskSelection(), tasks, sHtmlImgFolder);	// add title and date 	COleDateTime date;	if (dialog.GetWantDate())		date = COleDateTime::GetCurrentTime();	tasks.SetReportAttributes(sTitle, date);		// save intermediate tasklist to file as required	LogIntermediateTaskList(tasks, tdc.GetFilePath());		if (tasks.TransformToFile(sStylesheet, sOutputPath, Prefs().GetHtmlCharSet()))	{		// preview		if (Prefs().GetPreviewExport())			FileMisc::Run(*this, sOutputPath, NULL, SW_SHOWNORMAL);	}}BOOL CToDoListWnd::LogIntermediateTaskList(CTaskFile& tasks, LPCTSTR szRefPath){	if (FileMisc::IsLoggingEnabled())	{		CString sRefName = FileMisc::RemoveExtension(FileMisc::GetFileNameFromPath(szRefPath));		CString sTempTaskPath = FileMisc::GetTempFileName(sRefName, _T("intermediate.txt")); 		return tasks.Save(sTempTaskPath);	}	// else	return TRUE;}void CToDoListWnd::OnNexttopleveltask() {	GetToDoCtrl().GotoNextTopLevelTask(TDCG_NEXT);}void CToDoListWnd::OnPrevtopleveltask() {	GetToDoCtrl().GotoNextTopLevelTask(TDCG_PREV);}void CToDoListWnd::OnUpdateNexttopleveltask(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanGotoNextTopLevelTask(TDCG_NEXT));}void CToDoListWnd::OnUpdatePrevtopleveltask(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanGotoNextTopLevelTask(TDCG_PREV));}void CToDoListWnd::OnGotoNexttask() {	GetToDoCtrl().GotoNextTask(TDCG_NEXT);}void CToDoListWnd::OnGotoPrevtask() {	GetToDoCtrl().GotoNextTask(TDCG_PREV);}void CToDoListWnd::OnUpdateGotoPrevtask(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanGotoNextTask(TDCG_PREV));}void CToDoListWnd::OnUpdateGotoNexttask(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanGotoNextTask(TDCG_NEXT));}//------------------------------------------------------------------------BOOL CToDoListWnd::InitFindDialog(BOOL bShow){	if (!m_findDlg.GetSafeHwnd())	{		UpdateFindDialogCustomAttributes();		VERIFY(m_findDlg.Initialize(this));		if (CThemed::IsThemeActive())			m_findDlg.SetUITheme(m_theme);		if (bShow)			m_findDlg.Show(bShow);	}	return (m_findDlg.GetSafeHwnd() != NULL);}void CToDoListWnd::OnFindTasks() {	InitFindDialog();	if (IsWindowVisible())	{		// remove results from encrypted tasklists but not from the 		// active tasklist		if (!m_findDlg.IsWindowVisible())		{			int nSelTDC = GetSelToDoCtrl();			int nTDC = GetTDCCount();			while (nTDC--)			{				const CFilteredToDoCtrl& tdc = GetToDoCtrl(nTDC);				if (nTDC != nSelTDC && tdc.IsEncrypted())					m_findDlg.DeleteResults(&tdc);			}		}		m_findDlg.Show();	}		m_bFindShowing = TRUE;}LRESULT CToDoListWnd::OnFindDlgClose(WPARAM /*wp*/, LPARAM /*lp*/){	m_bFindShowing = FALSE;	GetToDoCtrl().SetFocusToTasks();	return 0L;}LRESULT CToDoListWnd::OnFindDlgFind(WPARAM /*wp*/, LPARAM /*lp*/){	// set up the search	BOOL bSearchAll = m_findDlg.GetSearchAllTasklists();	int nSelTaskList = GetSelToDoCtrl();		int nFrom = bSearchAll ? 0 : nSelTaskList;	int nTo = bSearchAll ? GetTDCCount() - 1 : nSelTaskList;		// search params	SEARCHPARAMS params;	if (m_findDlg.GetSearchParams(params))	{		int nSel = GetSelToDoCtrl();		int bFirst = TRUE;				for (int nCtrl = nFrom; nCtrl <= nTo; nCtrl++)		{			// load or verify password unless tasklist is already active			if (nCtrl != nSel)			{				// load if necessary (in which case the password will have been checked)				if (!m_mgrToDoCtrls.IsLoaded(nCtrl))				{					if (!VerifyTaskListOpen(nCtrl, FALSE))						continue;				}				else if (!VerifyToDoCtrlPassword(nCtrl))					continue;			}						CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);			CResultArray aResults;			CHoldRedraw hr(m_bFindShowing ? m_findDlg : NULL);						if (tdc.FindTasks(params, aResults))			{				// use tasklist title from tabctrl				CString sTitle = m_mgrToDoCtrls.GetTabItemText(nCtrl);								m_findDlg.AddHeaderRow(sTitle, !bFirst);								for (int nResult = 0; nResult < aResults.GetSize(); nResult++)					AddFindResult(aResults[nResult], &tdc);								bFirst = FALSE;			}		}	}			// auto-select single results/*	if (m_findDlg.GetResultCount() == 1)	{		CFTDResultsArray results;		m_findDlg.GetAllResults(results);		ASSERT (results.GetSize() == 1);				if (OnFindSelectResult(0, (LPARAM)&results[0]))			m_findDlg.Show(FALSE);		}	else*/		m_findDlg.SetActiveWindow();		return 0;}void CToDoListWnd::AddFindResult(const SEARCHRESULT& result, const CFilteredToDoCtrl* pTDC){	CString sTitle = pTDC->GetTaskTitle(result.dwTaskID);	//CString sPath = pTDC->GetTaskPath(result.dwID);		m_findDlg.AddResult(result, sTitle, /*sPath,*/ pTDC);}LRESULT CToDoListWnd::OnFindSelectResult(WPARAM /*wp*/, LPARAM lp){	// extract Task ID	FTDRESULT* pResult = (FTDRESULT*)lp;	ASSERT (pResult->dwTaskID); 		int nCtrl = m_mgrToDoCtrls.FindToDoCtrl(pResult->pTDC);	ASSERT(nCtrl != -1);		if (m_tabCtrl.GetCurSel() != nCtrl)	{		if (!SelectToDoCtrl(nCtrl, TRUE))			return 0L;	}		// we can‘t use pResult->pTDC because it‘s const	CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);	tdc.SetFocusToTasks();		if (tdc.GetSelectedTaskID() != pResult->dwTaskID)	{		if (!tdc.SelectTask(pResult->dwTaskID))		{			// perhaps the task is filtered out so we toggle the filter			// and try again			if (tdc.HasFilter())			{				tdc.ToggleFilter();				// if that also fails, we restore the filter				if (!tdc.SelectTask(pResult->dwTaskID))					tdc.ToggleFilter();			}		}		Invalidate();		UpdateWindow();	}		return 1L;}LRESULT CToDoListWnd::OnFindSelectAll(WPARAM /*wp*/, LPARAM /*lp*/){	if (!m_findDlg.GetResultCount())		return 0;		CWaitCursor cursor;		for (int nTDC = 0; nTDC < GetTDCCount(); nTDC++)	{		CFilteredToDoCtrl& tdc = GetToDoCtrl(nTDC);		tdc.DeselectAll();				// collate the taskIDs		CDWordArray aTaskIDs;		m_findDlg.GetResultIDs(&tdc, aTaskIDs);		// select them in one hit		if (aTaskIDs.GetSize())			tdc.MultiSelectItems(aTaskIDs, TSHS_SELECT, (nTDC == GetSelToDoCtrl()));	}	// if find dialog is floating then hide it	if (!m_findDlg.IsDocked())		m_findDlg.Show(FALSE);		return 0;}LRESULT CToDoListWnd::OnFindApplyAsFilter(WPARAM /*wp*/, LPARAM lp){	CString sCustom((LPCTSTR)lp);	SEARCHPARAMS filter;	m_findDlg.GetSearchParams(filter);	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.SetCustomFilter(filter, sCustom);	tdc.SetFocusToTasks();		RefreshFilterBarCustomFilters();	m_filterBar.RefreshFilterControls(tdc);	// if find dialog is floating then hide it	if (!m_findDlg.IsDocked())		m_findDlg.Show(FALSE);		return 0;}LRESULT CToDoListWnd::OnFindAddSearch(WPARAM /*wp*/, LPARAM /*lp*/){	RefreshFilterBarCustomFilters();	return 0;}LRESULT CToDoListWnd::OnFindDeleteSearch(WPARAM /*wp*/, LPARAM /*lp*/){	RefreshFilterBarCustomFilters();	return 0;}void CToDoListWnd::RefreshFilterBarCustomFilters(){	CStringArray aFilters;		m_findDlg.GetSavedSearches(aFilters);	// check for unnamed filter	if (m_findDlg.GetSafeHwnd())	{		CEnString sUnNamed(IDS_UNNAMEDFILTER);		if (m_findDlg.GetActiveSearch().IsEmpty() && Misc::Find(aFilters, sUnNamed, FALSE, FALSE) == -1)			aFilters.Add(sUnNamed);	}	m_filterBar.AddCustomFilters(aFilters);}//------------------------------------------------------------------------LRESULT CToDoListWnd::OnDropFile(WPARAM wParam, LPARAM lParam){	TLDT_DATA* pData = http://www.mamicode.com/(TLDT_DATA*)wParam;"");		if (FileMisc::HasExtension(sFile, _T("tdl")) || FileMisc::HasExtension(sFile, _T("xml"))) // tasklist		{			TDC_FILE nRes = OpenTaskList(sFile);			HandleLoadTasklistError(nRes, sFile);		}	}	return 0L;}void CToDoListWnd::OnViewMovetasklistright() {	m_mgrToDoCtrls.MoveToDoCtrl(GetSelToDoCtrl(), 1);}void CToDoListWnd::OnUpdateViewMovetasklistright(CCmdUI* pCmdUI) {	pCmdUI->Enable(!Prefs().GetKeepTabsOrdered() &&					m_mgrToDoCtrls.CanMoveToDoCtrl(GetSelToDoCtrl(), 1));}void CToDoListWnd::OnViewMovetasklistleft() {	m_mgrToDoCtrls.MoveToDoCtrl(GetSelToDoCtrl(), -1);}void CToDoListWnd::OnUpdateViewMovetasklistleft(CCmdUI* pCmdUI) {	pCmdUI->Enable(!Prefs().GetKeepTabsOrdered() &&					m_mgrToDoCtrls.CanMoveToDoCtrl(GetSelToDoCtrl(), -1));}void CToDoListWnd::OnToolsShowtasksDue(UINT nCmdID) {	int nDueBy = PFP_DUETODAY;	UINT nIDDueBy = IDS_NODUETODAY;		switch (nCmdID)	{	case ID_TOOLS_SHOWTASKS_DUETODAY:		break; // done			case ID_TOOLS_SHOWTASKS_DUETOMORROW:		nIDDueBy = IDS_NODUETOMORROW;		nDueBy = PFP_DUETOMORROW;		break;			case ID_TOOLS_SHOWTASKS_DUEENDTHISWEEK:		nIDDueBy = IDS_NODUETHISWEEK;		nDueBy = PFP_DUETHISWEEK;		break;			case ID_TOOLS_SHOWTASKS_DUEENDNEXTWEEK:		nIDDueBy = IDS_NODUENEXTWEEK;		nDueBy = PFP_DUENEXTWEEK;		break;			case ID_TOOLS_SHOWTASKS_DUEENDTHISMONTH:		nIDDueBy = IDS_NODUETHISMONTH;		nDueBy = PFP_DUETHISMONTH;		break;			case ID_TOOLS_SHOWTASKS_DUEENDNEXTMONTH:		nIDDueBy = IDS_NODUENEXTMONTH;		nDueBy = PFP_DUENEXTMONTH;		break;			default:		ASSERT(0);		return;	}		if (!DoDueTaskNotification(nDueBy))	{		MessageBox(nIDDueBy, 0, MB_OK, m_mgrToDoCtrls.GetFriendlyProjectName(GetSelToDoCtrl()));	}}void CToDoListWnd::ResetPrefs(){	delete m_pPrefs;	m_pPrefs = new CPreferencesDlg(&m_mgrShortcuts, IDR_MAINFRAME, &m_mgrContent, &m_mgrImportExport);		// update	m_mgrToDoCtrls.SetPrefs(m_pPrefs); 		// grab current colors	Prefs().GetPriorityColors(m_aPriorityColors);	m_filterBar.SetPriorityColors(m_aPriorityColors);}const CPreferencesDlg& CToDoListWnd::Prefs() const{	ASSERT (m_pPrefs);	return *m_pPrefs;}void CToDoListWnd::OnSpellcheckcomments() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.SpellcheckSelectedTask(FALSE);}void CToDoListWnd::OnUpdateSpellcheckcomments(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(tdc.CanSpellcheckSelectedTaskComments());}void CToDoListWnd::OnSpellchecktitle() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.SpellcheckSelectedTask(TRUE);}void CToDoListWnd::OnUpdateSpellchecktitle(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(!tdc.GetSelectedTaskTitle().IsEmpty());}void CToDoListWnd::OnFileEncrypt() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	if (!tdc.IsReadOnly())	{		BOOL bWasEncrypted = tdc.IsEncrypted();		CString sPassword = tdc.GetPassword();		// if the tasklist is already encrypted then verify password		// before allowing change		if (!bWasEncrypted || VerifyToDoCtrlPassword())			tdc.EnableEncryption(!tdc.IsEncrypted());		// make sure we disable encryption on the archive too		if (bWasEncrypted)		{			CString sArchive = m_mgrToDoCtrls.GetArchivePath(GetSelToDoCtrl());			if (FileMisc::FileExists(sArchive))			{				CTaskFile archive(sPassword);				if (archive.Load(sArchive))				{					archive.SetPassword(NULL); // remove password					archive.Save(sArchive);				}			}		}	}	UpdateAeroFeatures();}void CToDoListWnd::OnUpdateFileEncrypt(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(tdc.CanEncrypt() && !tdc.IsReadOnly());	pCmdUI->SetCheck(tdc.IsEncrypted() ? 1 : 0);}void CToDoListWnd::OnFileResetversion() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		if (!tdc.IsReadOnly())	{		tdc.ResetFileVersion();		tdc.SetModified();				UpdateStatusbar();		UpdateCaption();	}}void CToDoListWnd::OnUpdateFileResetversion(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(!tdc.IsReadOnly());}void CToDoListWnd::OnSpellcheckTasklist() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.Spellcheck();}void CToDoListWnd::OnUpdateSpellcheckTasklist(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(tdc.GetTaskCount());}TDC_FILE CToDoListWnd::SaveAll(DWORD dwFlags){	TDC_FILE nSaveAll = TDCO_SUCCESS;	int nCtrl = GetTDCCount();	BOOL bIncUnsaved = Misc::HasFlag(dwFlags, TDLS_INCLUDEUNSAVED);	BOOL bClosingWindows = Misc::HasFlag(dwFlags, TDLS_CLOSINGWINDOWS);	BOOL bClosingAll = Misc::HasFlag(dwFlags, TDLS_CLOSINGTASKLISTS);			// scoped to end status bar progress	// before calling UpdateStatusbar	{		DOPROGRESS(IDS_SAVINGPROGRESS)		while (nCtrl--)		{			CFilteredToDoCtrl& tdc = GetToDoCtrl(nCtrl);			// bypass unsaved tasklists unless closing Windows			if (!bClosingWindows && !bIncUnsaved && tdc.GetFilePath().IsEmpty())				continue;						if (Misc::HasFlag(dwFlags, TDLS_FLUSH))				tdc.Flush(bClosingAll);					TDC_FILE nSave = ConfirmSaveTaskList(nCtrl, dwFlags);			if (nSave == TDCO_CANCELLED) // user cancelled				return TDCO_CANCELLED;			// else cache any failure w/o overwriting previous			if (nSaveAll == TDCO_SUCCESS)				nSaveAll = nSave;			m_mgrToDoCtrls.UpdateTabItemText(nCtrl);		}	}		if (!bClosingWindows)	{		UpdateCaption();		UpdateStatusbar();	}	    return nSaveAll;}void CToDoListWnd::OnEditTimeTrackTask() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.TimeTrackSelectedTask();}void CToDoListWnd::OnUpdateEditTimeTrackTask(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(tdc.CanTimeTrackSelectedTask());	pCmdUI->SetCheck(tdc.IsSelectedTaskBeingTimeTracked() ? 1 : 0);}void CToDoListWnd::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct){	if (nIDCtl == IDC_TABCONTROL)	{		TDCM_DUESTATUS nStatus = m_mgrToDoCtrls.GetDueItemStatus(lpDrawItemStruct->itemID);		if (nStatus == TDCM_PAST || nStatus == TDCM_TODAY)		{			// determine appropriate due colour			COLORREF crDue, crDueToday;			GetToDoCtrl(lpDrawItemStruct->itemID).GetDueTaskColors(crDue, crDueToday);			COLORREF crTag = (nStatus == TDCM_PAST) ? crDue : crDueToday;			if (crTag != CLR_NONE)			{				CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);				const CRect& rect = lpDrawItemStruct->rcItem;				// draw a little tag in the top left corner				for (int nHPos = 0; nHPos < 6; nHPos++)				{					for (int nVPos = 0; nVPos < 6 - nHPos; nVPos++)					{						pDC->SetPixelV(rect.left + nHPos, rect.top + nVPos, crTag);					}				}				// draw a black line between the two				pDC->SelectStockObject(BLACK_PEN);				pDC->MoveTo(rect.left, rect.top + 6);				pDC->LineTo(rect.left + 7, rect.top - 1);			}		}		return;	}	else if (nIDCtl == 0 && lpDrawItemStruct->itemID == ID_CLOSE)	{		if (m_menubar.DrawMDIButton(lpDrawItemStruct))			return;	}	CFrameWnd::OnDrawItem(nIDCtl, lpDrawItemStruct);} void CToDoListWnd::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) {	if (nIDCtl == 0 && lpMeasureItemStruct->itemID == ID_CLOSE)	{		if (m_menubar.MeasureMDIButton(lpMeasureItemStruct))			return;	}		CFrameWnd::OnMeasureItem(nIDCtl, lpMeasureItemStruct);}void CToDoListWnd::OnViewNextSel() {	GetToDoCtrl().SelectNextTasksInHistory();}void CToDoListWnd::OnUpdateViewNextSel(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanSelectNextTasksInHistory());}void CToDoListWnd::OnViewPrevSel() {	GetToDoCtrl().SelectPrevTasksInHistory();}void CToDoListWnd::OnUpdateViewPrevSel(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanSelectPrevTasksInHistory());}void CToDoListWnd::OnSplitTaskIntoPieces(UINT nCmdID) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nNumPieces = 2 + (nCmdID - ID_NEWTASK_SPLITTASKINTO_TWO);		tdc.SplitSelectedTask(nNumPieces);}void CToDoListWnd::OnUpdateSplitTaskIntoPieces(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(tdc.CanSplitSelectedTask());}void CToDoListWnd::OnViewExpandtask() {	GetToDoCtrl().ExpandTasks(TDCEC_SELECTED, TRUE);}void CToDoListWnd::OnUpdateViewExpandtask(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanExpandTasks(TDCEC_SELECTED, TRUE));}void CToDoListWnd::OnViewCollapsetask() {	GetToDoCtrl().ExpandTasks(TDCEC_SELECTED, FALSE);}void CToDoListWnd::OnUpdateViewCollapsetask(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanExpandTasks(TDCEC_SELECTED, FALSE));}void CToDoListWnd::OnViewExpandall() {	GetToDoCtrl().ExpandTasks(TDCEC_ALL, TRUE);}void CToDoListWnd::OnUpdateViewExpandall(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanExpandTasks(TDCEC_ALL, TRUE));}void CToDoListWnd::OnViewCollapseall() {	GetToDoCtrl().ExpandTasks(TDCEC_ALL, FALSE);}void CToDoListWnd::OnUpdateViewCollapseall(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanExpandTasks(TDCEC_ALL, FALSE));}void CToDoListWnd::OnViewExpandDuetasks() {	GetToDoCtrl().ExpandTasks(TDCEC_DUE, TRUE);}void CToDoListWnd::OnUpdateViewExpandDuetasks(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanExpandTasks(TDCEC_DUE, TRUE));}void CToDoListWnd::OnViewCollapseDuetasks() {	GetToDoCtrl().ExpandTasks(TDCEC_DUE, FALSE);}void CToDoListWnd::OnUpdateViewCollapseDuetasks(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanExpandTasks(TDCEC_DUE, FALSE));}void CToDoListWnd::OnViewExpandStartedtasks() {	GetToDoCtrl().ExpandTasks(TDCEC_STARTED, TRUE);}void CToDoListWnd::OnUpdateViewExpandStartedtasks(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanExpandTasks(TDCEC_STARTED, TRUE));}void CToDoListWnd::OnViewCollapseStartedtasks() {	GetToDoCtrl().ExpandTasks(TDCEC_STARTED, FALSE);}void CToDoListWnd::OnUpdateViewCollapseStartedtasks(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanExpandTasks(TDCEC_STARTED, FALSE));}void CToDoListWnd::OnViewToggletaskexpanded() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.ExpandTasks(TDCEC_SELECTED, tdc.CanExpandTasks(TDCEC_SELECTED, TRUE));}void CToDoListWnd::OnUpdateViewToggletaskexpanded(CCmdUI* pCmdUI) {	const CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(tdc.CanExpandTasks(TDCEC_SELECTED, TRUE) || tdc.CanExpandTasks(TDCEC_SELECTED, FALSE));}void CToDoListWnd::OnWindow(UINT nCmdID) {	int nTDC = (int)(nCmdID - ID_WINDOW1);		if (nTDC < GetTDCCount())		SelectToDoCtrl(nTDC, (nTDC != GetSelToDoCtrl()), Prefs().GetNotifyDueByOnSwitch());}void CToDoListWnd::OnUpdateWindow(CCmdUI* pCmdUI) {	if (pCmdUI->m_pMenu)	{		ASSERT (ID_WINDOW1 == pCmdUI->m_nID);		const UINT MAXWINDOWS = 16;		int nWnd;				// delete existing tool entries first		for (nWnd = 0; nWnd < MAXWINDOWS; nWnd++)			pCmdUI->m_pMenu->DeleteMenu(ID_WINDOW1 + nWnd, MF_BYCOMMAND);				int nSel = GetSelToDoCtrl();		int nPos = 0, nTDCCount = GetTDCCount();		ASSERT (nTDCCount);		nTDCCount = min(nTDCCount, MAXWINDOWS);				for (nWnd = 0; nWnd < nTDCCount; nWnd++)		{			CFilteredToDoCtrl& tdc = GetToDoCtrl(nWnd);						CString sMenuItem;			sMenuItem.Format(_T("&%d (%s)"), (nPos + 1) % 10, tdc.GetFriendlyProjectName());						UINT nFlags = MF_BYPOSITION | MF_STRING | (nSel == nWnd ? MF_CHECKED : MF_UNCHECKED);			pCmdUI->m_pMenu->InsertMenu(pCmdUI->m_nIndex++, nFlags, ID_WINDOW1 + nWnd, sMenuItem);						nPos++;		}				// update end menu count		pCmdUI->m_nIndex--; // point to last menu added		pCmdUI->m_nIndexMax = pCmdUI->m_pMenu->GetMenuItemCount();				pCmdUI->m_bEnableChanged = TRUE;    // all the added items are enabled	}}#if _MSC_VER >= 1400void CToDoListWnd::OnActivateApp(BOOL bActive, DWORD dwThreadID)#elsevoid CToDoListWnd::OnActivateApp(BOOL bActive, HTASK hTask) #endif{	// don‘t activate when in the middle of loading	if (m_bReloading && !bActive)		return;#if _MSC_VER >= 1400	CFrameWnd::OnActivateApp(bActive, dwThreadID);#else	CFrameWnd::OnActivateApp(bActive, hTask);#endif		// don‘t do any further processing if closing    if (m_bClosing)        return; 	if (!bActive)	{		// save focus to restore when we next get activated		HWND hFocus = ::GetFocus();		if (hFocus)			m_hwndLastFocus = hFocus;		// save tasklists if required		if (Prefs().GetAutoSaveOnSwitchApp())			SaveAll(TDLS_FLUSH | TDLS_AUTOSAVE);	}	else	{		if (GetTDCCount() && (!m_hwndLastFocus || Prefs().GetAutoFocusTasklist()))			PostMessage(WM_APPRESTOREFOCUS, 0L, (LPARAM)GetToDoCtrl().GetSafeHwnd());				else if (m_hwndLastFocus)		{			// delay the restoration of focus else it gets lost			PostMessage(WM_APPRESTOREFOCUS, 0L, (LPARAM)m_hwndLastFocus);		}		UpdateCwd();	}}LRESULT CToDoListWnd::OnAppRestoreFocus(WPARAM /*wp*/, LPARAM lp){	HWND hWnd = (HWND)lp;	if (GetTDCCount() && hWnd == GetToDoCtrl().GetSafeHwnd())		GetToDoCtrl().SetFocusToTasks();	else		return (LRESULT)::SetFocus(hWnd);	return 0L;}void CToDoListWnd::UpdateCwd(){	// set cwd to active tasklist	if (GetTDCCount())	{		CString sFolder	= FileMisc::GetFolderFromFilePath(m_mgrToDoCtrls.GetFilePath(GetSelToDoCtrl()));		if (FileMisc::FolderExists(sFolder))			SetCurrentDirectory(sFolder);	}}BOOL CToDoListWnd::OnCommand(WPARAM wParam, LPARAM lParam) {	UpdateWindow();	return CFrameWnd::OnCommand(wParam, lParam);}void CToDoListWnd::OnEnable(BOOL bEnable) {	CFrameWnd::OnEnable(bEnable);		// save current focus because modal window is being shown	if (!bEnable)	{		HWND hFocus = ::GetFocus();		if (hFocus)			m_hwndLastFocus = hFocus;	}	// then restore it when we are enabled	else if (m_hwndLastFocus)	{		UpdateWindow();		PostMessage(WM_APPRESTOREFOCUS, 0L, (LPARAM)m_hwndLastFocus);	}}void CToDoListWnd::OnViewSorttasklisttabs() {	int nSel = m_mgrToDoCtrls.SortToDoCtrlsByName();	SelectToDoCtrl(nSel, FALSE);}void CToDoListWnd::OnUpdateViewSorttasklisttabs(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetTDCCount() > 1 && !Prefs().GetKeepTabsOrdered());}void CToDoListWnd::OnEditInctaskpercentdone() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.IncrementSelectedTaskPercentDone(TRUE);}void CToDoListWnd::OnUpdateEditInctaskpercentdone(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(nSelCount && !tdc.IsReadOnly());	}void CToDoListWnd::OnEditDectaskpercentdone() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.IncrementSelectedTaskPercentDone(FALSE);}void CToDoListWnd::OnUpdateEditDectaskpercentdone(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(nSelCount && !tdc.IsReadOnly());	}void CToDoListWnd::OnEditDectaskpriority() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.IncrementSelectedTaskPriority(FALSE);}void CToDoListWnd::OnUpdateEditDectaskpriority(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(nSelCount && !tdc.IsReadOnly());	}void CToDoListWnd::OnEditInctaskpriority() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.IncrementSelectedTaskPriority(TRUE);}void CToDoListWnd::OnUpdateEditInctaskpriority(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(nSelCount && !tdc.IsReadOnly());	}void CToDoListWnd::OnEditFlagtask() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.SetSelectedTaskFlag(!tdc.IsSelectedTaskFlagged());}void CToDoListWnd::OnUpdateEditFlagtask(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(nSelCount && !tdc.IsReadOnly());		pCmdUI->SetCheck(tdc.IsSelectedTaskFlagged() ? 1 : 0);}void CToDoListWnd::OnEditGotoDependency() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.GotoSelectedTaskDependency();}void CToDoListWnd::OnUpdateEditGotoDependency(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	CStringArray aDepends;	pCmdUI->Enable(tdc.GetSelectedTaskDependencies(aDepends) > 0);	}void CToDoListWnd::OnEditRecurrence() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.EditSelectedTaskRecurrence();	}void CToDoListWnd::OnUpdateEditRecurrence(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();	pCmdUI->Enable(nSelCount && !tdc.IsReadOnly());	}void CToDoListWnd::OnFileOpenarchive() {	CString sArchivePath = m_mgrToDoCtrls.GetArchivePath(GetSelToDoCtrl());	BOOL bArchiveExists = FileMisc::FileExists(sArchivePath);		if (bArchiveExists)		OpenTaskList(sArchivePath, FALSE);}void CToDoListWnd::OnUpdateFileOpenarchive(CCmdUI* pCmdUI) {	CString sArchivePath = m_mgrToDoCtrls.GetArchivePath(GetSelToDoCtrl());	BOOL bArchiveExists = FileMisc::FileExists(sArchivePath);		pCmdUI->Enable(bArchiveExists);}void CToDoListWnd::PrepareFilter(FTDCFILTER& filter) const{	if (filter.nShow != FS_CUSTOM)	{		// handle title filter option		switch (Prefs().GetTitleFilterOption())		{		case PUIP_MATCHONTITLECOMMENTS:			filter.nTitleOption = FT_FILTERONTITLECOMMENTS;			break;		case PUIP_MATCHONANYTEXT:			filter.nTitleOption = FT_FILTERONANYTEXT;			break;		case PUIP_MATCHONTITLE:		default:			filter.nTitleOption = FT_FILTERONTITLEONLY;			break;		}	}}void CToDoListWnd::OnViewShowfilterbar() {	m_bShowFilterBar = !m_bShowFilterBar;	m_filterBar.ShowWindow(m_bShowFilterBar ? SW_SHOW : SW_HIDE);	Resize();	Invalidate(TRUE);}void CToDoListWnd::OnUpdateViewShowfilterbar(CCmdUI* pCmdUI) {	pCmdUI->SetCheck(m_bShowFilterBar ? 1 : 0);}void CToDoListWnd::OnViewClearfilter() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		if (tdc.HasFilter() || tdc.HasCustomFilter())	{		tdc.ClearFilter();			// reenable the filter controls		//m_filterBar.RemoveCustomFilters();		m_filterBar.RefreshFilterControls(tdc);			RefreshFilterControls();		UpdateStatusbar();	}}void CToDoListWnd::OnUpdateViewClearfilter(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(tdc.HasFilter() || tdc.HasCustomFilter());}void CToDoListWnd::OnViewTogglefilter(){	CFilteredToDoCtrl& tdc = GetToDoCtrl();		tdc.ToggleFilter();	RefreshFilterControls();	UpdateStatusbar();	// reenable the filter controls	m_filterBar.SetCustomFilter(tdc.HasCustomFilter(), tdc.GetCustomFilterName());}void CToDoListWnd::OnUpdateViewTogglefilter(CCmdUI* pCmdUI){	CFilteredToDoCtrl& tdc = GetToDoCtrl();		pCmdUI->Enable(tdc.HasFilter() || tdc.HasLastFilter() || tdc.HasCustomFilter());}LRESULT CToDoListWnd::OnSelchangeFilter(WPARAM wp, LPARAM lp) {	FTDCFILTER* pFilter = (FTDCFILTER*)wp;	CString sCustom((LPCTSTR)lp);	ASSERT(pFilter);	CFilteredToDoCtrl& tdc = GetToDoCtrl();	if (pFilter->nShow == FS_CUSTOM)	{		SEARCHPARAMS params;		if (sCustom.IsEmpty())			m_findDlg.GetSearchParams(params);		else			m_findDlg.GetSearchParams(sCustom, params);		tdc.SetCustomFilter(params, sCustom);	}	else	{		PrepareFilter(*pFilter);		tdc.SetFilter(*pFilter);	}	m_filterBar.RefreshFilterControls(tdc);	UpdateStatusbar();	return 0L;}void CToDoListWnd::OnViewFilter() {	const CFilteredToDoCtrl& tdc = GetToDoCtrl();	CStringArray aCustom;	m_filterBar.GetCustomFilters(aCustom);		CTDLFilterDlg dialog(Prefs().GetMultiSelFilters());	if (dialog.DoModal(aCustom, tdc, m_aPriorityColors) == IDOK)	{		FTDCFILTER filter;		CString sCustom;				dialog.GetFilter(filter, sCustom);		OnSelchangeFilter((WPARAM)&filter, (LPARAM)(LPCTSTR)sCustom);	}}void CToDoListWnd::OnUpdateViewFilter(CCmdUI* pCmdUI) {	UNREFERENCED_PARAMETER(pCmdUI);	//	pCmdUI->Enable(!m_bShowFilterBar);}void CToDoListWnd::OnViewRefreshfilter() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	FTDCFILTER filterTDC, filter;	tdc.GetFilter(filterTDC);	m_filterBar.GetFilter(filter);	PrepareFilter(filter);		// if the filter has changed then set the new one else	// refresh the current one	if (filterTDC == filter)		tdc.RefreshFilter();		else	{		tdc.SetFilter(filter);			if (Prefs().GetExpandTasksOnLoad())			tdc.ExpandTasks(TDCEC_ALL);	}	UpdateStatusbar();}void CToDoListWnd::OnUpdateViewRefreshfilter(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	FTDCFILTER filterTDC, filter;	tdc.GetFilter(filterTDC);	m_filterBar.GetFilter(filter);		pCmdUI->Enable(tdc.HasFilter() || (filter != filterTDC) || tdc.HasCustomFilter());}void CToDoListWnd::OnTabctrlPreferences() {	DoPreferences(PREFPAGE_UI);}void CToDoListWnd::OnTasklistSelectColumns() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSel = GetSelToDoCtrl();	CTDCColumnIDArray aColumns, aDefault;	tdc.GetVisibleColumns(aColumns);	Prefs().GetDefaultColumns(aDefault);	CTDLColumnSelectionDlg dialog(aColumns, aDefault, TRUE);	if (dialog.DoModal() == IDOK)	{		dialog.GetVisibleColumns(aColumns);		tdc.SetVisibleColumns(aColumns);		m_filterBar.SetVisibleFilters(aColumns);		if (dialog.GetApplyActiveTasklist())			m_mgrToDoCtrls.SetHasOwnColumns(nSel, TRUE);		else		{			// update preferences			ASSERT(m_pPrefs);			m_pPrefs->SetDefaultColumns(aColumns);			// and flag other tasklists as requiring updates			m_mgrToDoCtrls.SetAllNeedPreferenceUpdate(TRUE, nSel);			m_mgrToDoCtrls.SetHasOwnColumns(nSel, FALSE);		}		// reload the menu if we dynamically alter it		if (Prefs().GetShowEditMenuAsColumns())			LoadMenubar();		Resize();	}}void CToDoListWnd::OnViewProjectname() {	m_bShowProjectName = !m_bShowProjectName;		// mark all tasklists as needing update	m_mgrToDoCtrls.SetAllNeedPreferenceUpdate(TRUE);		// then update active tasklist	GetToDoCtrl().SetStyle(TDCS_SHOWPROJECTNAME, m_bShowProjectName);	m_mgrToDoCtrls.SetNeedsPreferenceUpdate(GetSelToDoCtrl(), FALSE);}void CToDoListWnd::OnUpdateViewProjectname(CCmdUI* pCmdUI) {	pCmdUI->SetCheck(m_bShowProjectName ? 1 : 0);}void CToDoListWnd::OnEditOffsetdates() {	COffsetDatesDlg dialog;		if (dialog.DoModal() == IDOK)	{		ODD_UNITS nUnits;		int nAmount = dialog.GetOffsetAmount(nUnits);				if (!nAmount)			return;				DWORD dwWhat = dialog.GetOffsetWhat();		BOOL bSubtasks = dialog.GetOffsetSubtasks();				// translate units		int nTDCUnits = (nUnits == ODDU_DAYS) ? TDITU_DAYS :						((nUnits == ODDU_WEEKS) ? TDITU_WEEKS : TDITU_MONTHS);				// do the offsets		CFilteredToDoCtrl& tdc = GetToDoCtrl();				if (dwWhat & ODD_STARTDATE)			tdc.OffsetSelectedTaskDate(TDCD_START, nAmount, nTDCUnits, bSubtasks);				if (dwWhat & ODD_DUEDATE)			tdc.OffsetSelectedTaskDate(TDCD_DUE, nAmount, nTDCUnits, bSubtasks);				if (dwWhat & ODD_DONEDATE)			tdc.OffsetSelectedTaskDate(TDCD_DONE, nAmount, nTDCUnits, bSubtasks);	}}void CToDoListWnd::OnUpdateEditOffsetdates(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(nSelCount && !tdc.IsReadOnly());	}void CToDoListWnd::OnPrintpreview() {	DoPrint(TRUE);}void CToDoListWnd::OnShowTimelogfile() {	CString sLogPath = GetToDoCtrl().GetSelectedTaskTimeLogPath();		if (!sLogPath.IsEmpty())		FileMisc::Run(*this, sLogPath, NULL, SW_HIDE);}void CToDoListWnd::OnUpdateShowTimelogfile(CCmdUI* pCmdUI) {	const CPreferencesDlg& userPrefs = Prefs();	int nTasks = GetToDoCtrl().GetSelectedCount();	BOOL bEnable = FALSE;	if (userPrefs.GetLogTimeTracking() && 		(nTasks == 1 || !userPrefs.GetLogTaskTimeSeparately()))	{		CString sLogPath = GetToDoCtrl().GetSelectedTaskTimeLogPath();		bEnable = FileMisc::FileExists(sLogPath);	}		pCmdUI->Enable(bEnable);	}void CToDoListWnd::OnAddtimetologfile() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	DWORD dwTaskID = tdc.GetSelectedTaskID();	CString sTitle = tdc.GetSelectedTaskTitle();	CTDLAddLoggedTimeDlg dialog(dwTaskID, sTitle);	if (dialog.DoModal() == IDOK)		tdc.AddTimeToTaskLogFile(dwTaskID, dialog.GetLoggedTime(), dialog.GetWhen(), dialog.GetAddToTimeSpent());}void CToDoListWnd::OnUpdateAddtimetologfile(CCmdUI* pCmdUI) {	BOOL bEnable = (Prefs().GetLogTimeTracking() && GetToDoCtrl().GetSelectedCount() == 1);	pCmdUI->Enable(bEnable);	}LRESULT CToDoListWnd::OnToDoCtrlDoLengthyOperation(WPARAM wParam, LPARAM lParam){	if (wParam) // start op	{		m_sbProgress.BeginProgress(m_statusBar, (LPCTSTR)lParam);	}	else // end op	{		m_sbProgress.EndProgress();	}		return 0L;}BOOL CToDoListWnd::DoTaskLink(const CString& sPath, DWORD dwTaskID){	// handle no file path => active tasklist	if (sPath.IsEmpty())	{		ASSERT(dwTaskID);		GetToDoCtrl().SelectTask(dwTaskID);		return TRUE; // handled regardless of result	}	else	{		// build the full path to the file		// from the folder of the active tasklist		int nSelTDC = GetSelToDoCtrl();		CString sActivePath = m_mgrToDoCtrls.GetFilePath(nSelTDC);		CString sFolder = FileMisc::GetFolderFromFilePath(sActivePath);		CString sFile(sPath);		FileMisc::MakeFullPath(sFile, sFolder);		// do we have this tasklist ?		int nTDC = m_mgrToDoCtrls.FindToDoCtrl(sFile);		if (nTDC != -1)		{			if (SelectToDoCtrl(nTDC, (nTDC != nSelTDC)) && dwTaskID)				GetToDoCtrl().SelectTask(dwTaskID);			return TRUE; // handled regardless of result		}		else if (!Prefs().GetMultiInstance())		{			TDC_FILE nRet = OpenTaskList(sFile);						if (nRet == TDCO_SUCCESS)			{				if (dwTaskID)					GetToDoCtrl().SelectTask(dwTaskID);			}			else				HandleLoadTasklistError(nRet, sFile);			return TRUE; // handled regardless of result		}	}	// not handled	return FALSE;}LRESULT CToDoListWnd::OnToDoCtrlDoTaskLink(WPARAM wParam, LPARAM lParam){	DWORD dwTaskID = wParam;	CString sFile((LPCTSTR)lParam);		// can we handle it ?	if (DoTaskLink(sFile, dwTaskID))		return TRUE;	// Pass to our app startup code to look 	// for another instance who can handle it	CString sCommandline;			sCommandline.Format(_T("%s -l \"%s?%ld\""),						FileMisc::GetAppFileName(),						sFile,						dwTaskID);	return FileMisc::Run(*this, sCommandline);}LRESULT CToDoListWnd::OnTodoCtrlFailedLink(WPARAM /*wParam*/, LPARAM lParam){	LPCTSTR szLink = (LPCTSTR)lParam;	// if it‘s an Outlook link then prompt to install	// the Outlook URL handler	if (COutlookHelper::IsOutlookUrl(szLink))	{		// if the handler installs properly give the url another go		if (COutlookHelper::QueryInstallUrlHandler(IDS_QUERYINSTALLOUTLOOKHANDLER))			FileMisc::Run(*this, szLink);		return TRUE; // we handled it regardless	}	else // see if it‘s a task link	{		CString sFile;		DWORD dwTaskID = 0;		CFilteredToDoCtrl::ParseTaskLink(szLink, dwTaskID, sFile);		if (DoTaskLink(sFile, dwTaskID))			return TRUE; // we handled it	}	// all else	AfxMessageBox(IDS_COMMENTSGOTOERRMSG);	return 0L;}LRESULT CToDoListWnd::OnToDoCtrlTaskIsDone(WPARAM wParam, LPARAM lParam){	ASSERT (lParam);	CString sFile((LPCTSTR)lParam);		if (!sFile.IsEmpty())	{		// build the full path to the file		if (::PathIsRelative(sFile))		{			// append it to the folder containing the active tasklist			CString sPathName = m_mgrToDoCtrls.GetFilePath(GetSelToDoCtrl());			CString sDrive, sFolder;			FileMisc::SplitPath(sPathName, &sDrive, &sFolder);			FileMisc::MakePath(sFile, sDrive, sFolder, sFile);		}		// else its a full path already				int nTDC = m_mgrToDoCtrls.FindToDoCtrl(sFile);		if (nTDC != -1) // already loaded			return GetToDoCtrl(nTDC).IsTaskDone(wParam);		else		{			// we must load the tasklist ourselves			CTaskFile tasks;			if (tasks.Load(sFile))			{				HTASKITEM ht = tasks.FindTask(wParam);				return ht ? tasks.IsTaskDone(ht) : FALSE;			}		}	}		return 0L;}LRESULT CToDoListWnd::OnPowerBroadcast(WPARAM wp, LPARAM /*lp*/){	const CPreferencesDlg& userPrefs = Prefs();	switch (wp)	{	case PBT_APMSUSPEND:	case PBT_APMSTANDBY:	case PBT_APMQUERYSUSPEND:	case PBT_APMQUERYSTANDBY:		// Terminate all timers		SetTimer(TIMER_DUEITEMS, FALSE);		SetTimer(TIMER_READONLYSTATUS, FALSE);		SetTimer(TIMER_TIMESTAMPCHANGE, FALSE);		SetTimer(TIMER_CHECKOUTSTATUS, FALSE);		SetTimer(TIMER_AUTOSAVE, FALSE);		SetTimer(TIMER_TIMETRACKING, FALSE);		break;	case PBT_APMQUERYSUSPENDFAILED:	case PBT_APMQUERYSTANDBYFAILED:	case PBT_APMRESUMECRITICAL:	case PBT_APMRESUMESUSPEND: 	case PBT_APMRESUMESTANDBY:		// reset time tracking as required		if (!userPrefs.GetTrackHibernated())		{			int nCtrl = GetTDCCount();						while (nCtrl--)				GetToDoCtrl(nCtrl).ResetTimeTracking();		}		// restart timers		SetTimer(TIMER_DUEITEMS, TRUE);		SetTimer(TIMER_READONLYSTATUS, userPrefs.GetReadonlyReloadOption() != RO_NO);		SetTimer(TIMER_TIMESTAMPCHANGE, userPrefs.GetTimestampReloadOption() != RO_NO);		SetTimer(TIMER_AUTOSAVE, userPrefs.GetAutoSaveFrequency());		SetTimer(TIMER_CHECKOUTSTATUS, userPrefs.GetCheckoutOnCheckin() || userPrefs.GetAutoCheckinFrequency());		SetTimer(TIMER_TIMETRACKING, TRUE);		// check for updates		if (Prefs().GetAutoCheckForUpdates())			CheckForUpdates(FALSE);		break;	}	return TRUE; // allow }LRESULT CToDoListWnd::OnGetFont(WPARAM /*wp*/, LPARAM /*lp*/){	return (LRESULT)m_fontMain.GetSafeHandle();}void CToDoListWnd::OnViewStatusBar() {	m_bShowStatusBar = !m_bShowStatusBar;	m_statusBar.ShowWindow(m_bShowStatusBar ? SW_SHOW : SW_HIDE);		SendMessage(WM_SIZE, SIZE_RESTORED, 0L);	//Resize();	if (m_bShowStatusBar)		UpdateStatusbar();	else		UpdateCaption();}void CToDoListWnd::OnUpdateViewStatusBar(CCmdUI* pCmdUI) {	pCmdUI->SetCheck(m_bShowStatusBar ? 1 : 0) ;}BOOL CToDoListWnd::OnQueryOpen() {	if (CFrameWnd::OnQueryOpen())	{		// fail if the active tasklist is encrypted because we have to verify the password		// and we‘re not allowed to display a dialog in this message handler		if (!m_bQueryOpenAllow && GetToDoCtrl().IsEncrypted())		{			PostMessage(WM_TDL_RESTORE); 			return FALSE;		}				// all others		return TRUE;	}		return FALSE;}LRESULT CToDoListWnd::OnToDoListRestore(WPARAM /*wp*/, LPARAM /*lp*/){    ASSERT (IsIconic() && GetToDoCtrl().IsEncrypted()); // sanity check	    if (IsIconic())    {        if (VerifyToDoCtrlPassword())		{			CAutoFlag af(m_bQueryOpenAllow, TRUE);            ShowWindow(SW_RESTORE);		}    }	return 0L;}void CToDoListWnd::OnCopyTaskasLink() {	CopySelectedTasksToClipboard(TDCTC_ASLINK);}void CToDoListWnd::OnUpdateCopyTaskasLink(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().GetSelectedCount() == 1);}void CToDoListWnd::OnCopyTaskasDependency() {	CopySelectedTasksToClipboard(TDCTC_ASDEPENDS);}void CToDoListWnd::OnUpdateCopyTaskasDependency(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().GetSelectedCount() == 1);}void CToDoListWnd::OnCopyTaskasLinkFull() {	CopySelectedTasksToClipboard(TDCTC_ASLINKFULL);}void CToDoListWnd::OnUpdateCopyTaskasLinkFull(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().GetSelectedCount() == 1);}void CToDoListWnd::OnCopyTaskasDependencyFull() {	CopySelectedTasksToClipboard(TDCTC_ASDEPENDSFULL);}void CToDoListWnd::OnUpdateCopyTaskasDependencyFull(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().GetSelectedCount() == 1);}void CToDoListWnd::OnCopyTaskasPath() {	CopySelectedTasksToClipboard(TDCTC_ASPATH);}void CToDoListWnd::OnUpdateCopyTaskasPath(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().GetSelectedCount() == 1);}BOOL CToDoListWnd::PreCreateWindow(CREATESTRUCT& cs) {	if (CFrameWnd::PreCreateWindow(cs))	{		cs.dwExStyle &= ~WS_EX_CLIENTEDGE;		// Check if our class is already defined		LPCTSTR pszClassName = _T("ToDoListFrame");		WNDCLASS wndcls;		if (!::GetClassInfo(AfxGetInstanceHandle(), pszClassName, &wndcls))		{			// Get the current requested window class			VERIFY(GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wndcls));			// We want to register this info with our name			wndcls.lpszClassName = pszClassName;			// Need to preset the icon otherwise the function GetIconWndClass			// calling us will overwrite our class.			wndcls.hIcon = GraphicsMisc::LoadIcon(IDR_MAINFRAME);			// Register our class now and check the outcome			if (!::RegisterClass(&wndcls))			{				ASSERT(0);				return FALSE;			}		}		// Now use our class 		cs.lpszClass = pszClassName;		return TRUE;	}		// else	return FALSE;}void CToDoListWnd::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) {	CFrameWnd::OnWindowPosChanging(lpwndpos); }void CToDoListWnd::OnToolsCheckforupdates() {	CheckForUpdates(TRUE);}void CToDoListWnd::OnEditInsertdatetime() {	DoInsertDateAndTime(TRUE, TRUE);}void CToDoListWnd::OnEditInsertdate() {	DoInsertDateAndTime(TRUE, FALSE);}void CToDoListWnd::OnEditInserttime() {	DoInsertDateAndTime(FALSE, TRUE);}void CToDoListWnd::DoInsertDateAndTime(BOOL bDate, BOOL bTime) {	COleDateTime date = COleDateTime::GetCurrentTime();	const CPreferencesDlg& userPrefs = Prefs();	CString sInsert;	if (bDate) // date only or date and time	{		DWORD dwFmt = (bTime ? DHFD_TIME : 0);		if (userPrefs.GetShowWeekdayInDates())			dwFmt |= DHFD_DOW;								if (userPrefs.GetDisplayDatesInISO())			dwFmt |= DHFD_ISO;								sInsert = CDateHelper::FormatDate(date, dwFmt);	}	else // time only	{		if (userPrefs.GetDisplayDatesInISO())			sInsert = CTimeHelper::FormatISOTime(date.GetHour(), date.GetMinute(), date.GetSecond(), TRUE);		else			sInsert = CTimeHelper::Format24HourTime(date.GetHour(), date.GetMinute(), date.GetSecond(), TRUE);	}	// add trailing space	sInsert += ‘ ‘;	GetToDoCtrl().PasteText(sInsert);}void CToDoListWnd::OnUpdateEditInsertdatetime(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanPasteText());}void CToDoListWnd::OnUpdateEditInserttime(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanPasteText());}void CToDoListWnd::OnUpdateEditInsertdate(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().CanPasteText());}void CToDoListWnd::OnSysColorChange() {	CFrameWnd::OnSysColorChange();		InitMenuIconManager();	SetUITheme(m_sThemeFile);}void CToDoListWnd::UpdateSBPaneAndTooltip(UINT nIDPane, UINT nIDTextFormat, const CString& sValue, UINT nIDTooltip, TDC_COLUMN nTDCC){	const CFilteredToDoCtrl& tdc = GetToDoCtrl();	const CPreferencesDlg& userPrefs = Prefs();			CEnString sText, sTooltip;	if (!userPrefs.GetShowCtrlsAsColumns() || tdc.IsColumnShowing(nTDCC))	{		sText.Format(nIDTextFormat, sValue);		sTooltip.LoadString(nIDTooltip);	}	else	{		sText.Empty();		sTooltip.Empty();	}	int nPane = m_statusBar.CommandToIndex(nIDPane);	m_statusBar.SetPaneText(nPane, sText);	m_statusBar.SetPaneTooltipIndex(nPane, sTooltip);}void CToDoListWnd::UpdateStatusBarInfo(const CFilteredToDoCtrl& tdc, TDCSTATUSBARINFO& sbi) const{	sbi.nSelCount = tdc.GetSelectedCount();	sbi.dwSelTaskID = tdc.GetSelectedTaskID();	sbi.dCost = tdc.CalcSelectedTaskCost();	const CPreferencesDlg& userPrefs = Prefs();	userPrefs.GetDefaultTimeEst(sbi.nTimeEstUnits);	sbi.dTimeEst = tdc.CalcSelectedTaskTimeEstimate(sbi.nTimeEstUnits);	userPrefs.GetDefaultTimeSpent(sbi.nTimeSpentUnits);	sbi.dTimeSpent = tdc.CalcSelectedTaskTimeSpent(sbi.nTimeSpentUnits);}void CToDoListWnd::OnUpdateSBSelectionCount(CCmdUI* /*pCmdUI*/){	if (GetTDCCount())	{		CFilteredToDoCtrl& tdc = GetToDoCtrl();		// keep track of previous information to avoid unnecessary processing		static TDCSTATUSBARINFO sbiPrev;		TDCSTATUSBARINFO sbi;		UpdateStatusBarInfo(tdc, sbi);		if (sbi == sbiPrev)			return;		sbiPrev = sbi;		// number of selected tasks		CEnString sText;		if (sbi.nSelCount == 1)		{			ASSERT(sbi.dwSelTaskID);			sText.Format(ID_SB_SELCOUNTONE, sbi.dwSelTaskID);		}		else			sText.Format(ID_SB_SELCOUNT, sbi.nSelCount);		m_statusBar.SetPaneText(m_statusBar.CommandToIndex(ID_SB_SELCOUNT), sText);		// times		const CPreferencesDlg& userPrefs = Prefs();		// estimate		if (userPrefs.GetUseHMSTimeFormat())			sText = CTimeHelper().FormatTimeHMS(sbi.dTimeEst, sbi.nTimeEstUnits);		else			sText = CTimeHelper().FormatTime(sbi.dTimeEst, sbi.nTimeEstUnits, 2);		UpdateSBPaneAndTooltip(ID_SB_SELTIMEEST, ID_SB_SELTIMEEST, sText, IDS_SB_SELTIMEEST_TIP, TDCC_TIMEEST);		// spent		if (userPrefs.GetUseHMSTimeFormat())			sText = CTimeHelper().FormatTimeHMS(sbi.dTimeSpent, sbi.nTimeSpentUnits);		else			sText = CTimeHelper().FormatTime(sbi.dTimeSpent, sbi.nTimeSpentUnits, 2);		UpdateSBPaneAndTooltip(ID_SB_SELTIMESPENT, ID_SB_SELTIMESPENT, sText, IDS_SB_SELTIMESPENT_TIP, TDCC_TIMESPENT);		// cost		sText = Misc::Format(sbi.dCost, 2);		UpdateSBPaneAndTooltip(ID_SB_SELCOST, ID_SB_SELCOST, sText, IDS_SB_SELCOST_TIP, TDCC_COST);		// set tray tip too		UpdateTooltip();	}}void CToDoListWnd::OnUpdateSBTaskCount(CCmdUI* /*pCmdUI*/){	if (GetTDCCount())	{		CFilteredToDoCtrl& tdc = GetToDoCtrl();		UINT nVisibleTasks;		UINT nTotalTasks = tdc.GetTaskCount(&nVisibleTasks);		CEnString sText;		sText.Format(IDS_SB_TASKCOUNT, nVisibleTasks, nTotalTasks);		int nIndex = m_statusBar.CommandToIndex(ID_SB_TASKCOUNT);		m_statusBar.SetPaneText(nIndex, sText);		m_statusBar.SetPaneTooltipIndex(nIndex, CEnString(IDS_SB_TASKCOUNT_TIP));	}}void CToDoListWnd::OnEditSelectall() {	GetToDoCtrl().SelectAll();}void CToDoListWnd::OnUpdateEditSelectall(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetToDoCtrl().GetTaskCount());	}void CToDoListWnd::OnCloseallbutthis() {	int nThis = GetSelToDoCtrl();	int nCtrl = GetTDCCount();		// remove tasklists	while (nCtrl--)	{		if (nCtrl != nThis)		{			if (ConfirmSaveTaskList(nCtrl, TDLS_CLOSINGTASKLISTS) != TDCO_SUCCESS)				continue; // user cancelled			m_mgrToDoCtrls.RemoveToDoCtrl(nCtrl, TRUE);		}	}}void CToDoListWnd::OnUpdateCloseallbutthis(CCmdUI* pCmdUI) {	pCmdUI->Enable(GetTDCCount() > 1);}void CToDoListWnd::DoSendTasks(BOOL bSelected){	CTDLSendTasksDlg dialog(bSelected, GetToDoCtrl().GetView());	if (dialog.DoModal() == IDOK)	{		// get tasks		CFilteredToDoCtrl& tdc = GetToDoCtrl();		CTaskFile tasks;		GetTasks(tdc, FALSE, FALSE, dialog.GetTaskSelection(), tasks, NULL);		// package them up		CString sAttachment, sBody;		TD_SENDAS nSendAs = dialog.GetSendAs();		switch (nSendAs)		{		case TDSA_TASKLIST:			{				CString sFilename, sExt;				FileMisc::SplitPath(tdc.GetFilePath(), NULL, NULL, &sFilename, &sExt);								sAttachment = FileMisc::GetTempFileName(sFilename, sExt);								if (!tasks.Save(sAttachment))				{					// TODO					return;				}								sBody.LoadString(IDS_TASKLISTATTACHED);			}			break;					case TDSA_BODYTEXT:			sBody = m_mgrImportExport.ExportTaskListToText(&tasks);			break;		}				// form subject		CString sSubject = tdc.GetFriendlyProjectName();				// recipients		CStringArray aTo;		tdc.GetSelectedTaskAllocTo(aTo);		CString sTo = Misc::FormatArray(aTo, _T(";"));		// prefix with task name if necessary		if (dialog.GetTaskSelection().GetWantSelectedTasks() && tdc.GetSelectedCount() == 1)		{			sSubject = tdc.GetSelectedTaskTitle() + _T(" - ") + sSubject;		}		CSendFileTo().SendMail(*this, sTo, sSubject, sBody, sAttachment);	}}void CToDoListWnd::OnSendTasks() {	DoSendTasks(FALSE);}void CToDoListWnd::OnUpdateSendTasks(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(tdc.GetTaskCount());}void CToDoListWnd::OnSendSelectedTasks() {	DoSendTasks(TRUE);}void CToDoListWnd::OnUpdateSendSelectedTasks(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(tdc.GetTaskCount());}void CToDoListWnd::OnEditUndo() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.UndoLastAction(TRUE);	UpdateStatusbar();}void CToDoListWnd::OnUpdateEditUndo(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(tdc.CanUndoLastAction(TRUE));}void CToDoListWnd::OnEditRedo() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.UndoLastAction(FALSE);	UpdateStatusbar();}void CToDoListWnd::OnUpdateEditRedo(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(tdc.CanUndoLastAction(FALSE));}void CToDoListWnd::OnViewCycleTaskViews() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.SetNextView();	tdc.SetFocusToTasks();}void CToDoListWnd::OnUpdateViewCycleTaskViews(CCmdUI* pCmdUI) {	pCmdUI->Enable(m_nMaxState != TDCMS_MAXCOMMENTS);}void CToDoListWnd::OnViewToggleTreeandList() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	FTC_VIEW nView = tdc.GetView();	switch (nView)	{	case FTCV_TASKTREE:		nView = FTCV_TASKLIST;		break;	case FTCV_TASKLIST:	default:		nView = FTCV_TASKTREE;		break;	}	tdc.SetView(nView);	tdc.SetFocusToTasks();}void CToDoListWnd::OnUpdateViewToggleTreeandList(CCmdUI* pCmdUI) {	pCmdUI->Enable(m_nMaxState != TDCMS_MAXCOMMENTS);}void CToDoListWnd::OnViewToggletasksandcomments() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	if (!tdc.TasksHaveFocus())		tdc.SetFocusToTasks();	else		tdc.SetFocusToComments();}void CToDoListWnd::OnUpdateViewToggletasksandcomments(CCmdUI* pCmdUI) {	pCmdUI->Enable(m_nMaxState == TDCMS_NORMAL || 					(m_nMaxState == TDCMS_MAXTASKLIST && Prefs().GetShowCommentsAlways()));}void CToDoListWnd::OnUpdateQuickFind(CCmdUI* pCmdUI) {	pCmdUI->Enable(m_bShowToolbar);}void CToDoListWnd::OnQuickFind() {	if (m_bShowToolbar)		m_cbQuickFind.SetFocus();}void CToDoListWnd::OnQuickFindNext() {	if (!m_sQuickFind.IsEmpty())	{		if (!GetToDoCtrl().SelectTask(m_sQuickFind, TDC_SELECTNEXT))			GetToDoCtrl().SelectTask(m_sQuickFind, TDC_SELECTFIRST); // return to start	}}void CToDoListWnd::OnUpdateQuickFindNext(CCmdUI* pCmdUI) {	pCmdUI->Enable(!m_sQuickFind.IsEmpty());}LRESULT CToDoListWnd::OnQuickFindItemAdded(WPARAM /*wp*/, LPARAM /*lp*/){	// keep only the last 20 items	int nItem = m_cbQuickFind.GetCount();	while (nItem > 20)	{		nItem--;		m_cbQuickFind.DeleteString(nItem);	}	return 0L;}void CToDoListWnd::OnQuickFindPrev() {	if (!m_sQuickFind.IsEmpty())	{		if (!GetToDoCtrl().SelectTask(m_sQuickFind, TDC_SELECTPREV))			GetToDoCtrl().SelectTask(m_sQuickFind, TDC_SELECTLAST); // return to end	}}void CToDoListWnd::OnUpdateQuickFindPrev(CCmdUI* pCmdUI) {	pCmdUI->Enable(!m_sQuickFind.IsEmpty());}void CToDoListWnd::OnMove(int x, int y) {	CFrameWnd::OnMove(x, y);}void CToDoListWnd::OnEditSettaskicon() {	GetToDoCtrl().EditSelectedTaskIcon();}void CToDoListWnd::OnUpdateEditSettaskicon(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(nSelCount && !tdc.IsReadOnly());	}LRESULT CToDoListWnd::OnToDoCtrlReminder(WPARAM /*wp*/, LPARAM lp){	AF_NOREENTRANT_RET(0L) // macro helper	// ignore if we are showing a dialog	if (!IsWindowEnabled())		return 0L;	Show(FALSE);	CTDLShowReminderDlg dialog;	TDCREMINDER* pReminder = (TDCREMINDER*)lp;	int nRet = dialog.DoModal(*pReminder);		switch (nRet)	{	case IDSNOOZE:		{			double dNow = COleDateTime::GetCurrentTime();			if (pReminder->bRelative)			{				if (pReminder->nRelativeFromWhen == TDCR_DUEDATE)				{					// in case the user didn‘t handle the notification immediately we need					// to soak up any additional elapsed time in the snooze					COleDateTime dDue = pReminder->pTDC->GetTaskDate(pReminder->dwTaskID, TDCD_DUE);										pReminder->dDaysSnooze = (dNow - dDue + pReminder->dRelativeDaysLeadIn);				}				else // from start				{					// in case the user didn‘t handle the notification immediately we need					// to soak up any additional elapsed time in the snooze					COleDateTime dStart = pReminder->pTDC->GetTaskDate(pReminder->dwTaskID, TDCD_START);										pReminder->dDaysSnooze = (dNow - dStart + pReminder->dRelativeDaysLeadIn);				}			}			else // absolute			{				// in case the user didn‘t handle the notification immediately we need				// to soak up any additional elapsed time in the snooze				pReminder->dDaysSnooze = dNow - pReminder->dtAbsolute;			}								// then we add the user‘s snooze			pReminder->dDaysSnooze += dialog.GetSnoozeDays();		}		return 0L; // don‘t delete (default)	case IDGOTOTASK:		{			int nTDC = m_mgrToDoCtrls.FindToDoCtrl(pReminder->pTDC);			ASSERT(nTDC != -1);			SelectToDoCtrl(nTDC, TRUE);			GetToDoCtrl().SelectTask(pReminder->dwTaskID);		}		// fall thru	case IDCANCEL:	default:		// delete unless it‘s a recurring task in which case we 		// disable it so that it can later be copied when the 		// recurring task is completed		if (GetToDoCtrl().IsTaskRecurring(pReminder->dwTaskID))		{			pReminder->bEnabled = FALSE;			return 0L; // don‘t delete		}		// else		return 1L; // delete	}}LRESULT CToDoListWnd::OnToDoCtrlTaskHasReminder(WPARAM wParam, LPARAM lParam){	int nRem = m_reminders.FindReminder(wParam, (CFilteredToDoCtrl*)lParam, FALSE);	return (nRem != -1);}LRESULT CToDoListWnd::OnDoubleClkReminderCol(WPARAM /*wp*/, LPARAM /*lp*/){	OnEditSetReminder();	return 0L;}void CToDoListWnd::OnEditSetReminder() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	CTDLSetReminderDlg dialog;		CString sTitle = tdc.GetSelectedTaskTitle();		CDWordArray aTaskIDs;	int nNumSel = tdc.GetSelectedTaskIDs(aTaskIDs, TRUE);		if (nNumSel == 0)		return;		// get the first reminder as a reference	BOOL bNewReminder = TRUE;	TDCREMINDER rem;		for (int nTask = 0; nTask < nNumSel; nTask++)	{		DWORD dwTaskID = aTaskIDs[nTask];		int nRem = m_reminders.FindReminder(dwTaskID, &tdc);				if (nRem != -1)		{			m_reminders.GetReminder(nRem, rem);			bNewReminder = FALSE;			break;		}	}		// handle new task	if (bNewReminder)	{		rem.dwTaskID = aTaskIDs[0];		rem.pTDC = &tdc;	}		if (dialog.DoModal(rem, bNewReminder) == IDOK)	{		// apply reminder to selected tasks		for (int nTask = 0; nTask < nNumSel; nTask++)		{			rem.dwTaskID = aTaskIDs[nTask];			m_reminders.SetReminder(rem);		}				tdc.RedrawReminders();	}}void CToDoListWnd::OnUpdateEditSetReminder(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		BOOL bEnable = (tdc.GetSelectedCount() > 0) && !tdc.SelectedTasksAreAllDone();	pCmdUI->Enable(bEnable);}void CToDoListWnd::OnEditClearReminder() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();		CDWordArray aTaskIDs;	int nTask = tdc.GetSelectedTaskIDs(aTaskIDs, TRUE);		while (nTask--)	{		DWORD dwTaskID = aTaskIDs[nTask];		m_reminders.RemoveReminder(dwTaskID, &tdc);	}		tdc.RedrawReminders();}void CToDoListWnd::OnUpdateEditClearReminder(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	BOOL bEnable = FALSE;		// check at least one selected item has a reminder	CDWordArray aTaskIDs;	int nTask = tdc.GetSelectedTaskIDs(aTaskIDs, TRUE);		while (nTask--)	{		DWORD dwTaskID = aTaskIDs[nTask];				if (m_reminders.FindReminder(dwTaskID, &tdc) != -1)		{			bEnable = TRUE;			break;		}	}		pCmdUI->Enable(bEnable);}void CToDoListWnd::OnEditCleartaskicon() {	GetToDoCtrl().ClearSelectedTaskIcon();}void CToDoListWnd::OnUpdateEditCleartaskicon(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	int nSelCount = tdc.GetSelectedCount();		pCmdUI->Enable(nSelCount && !tdc.IsReadOnly() && tdc.SelectedTasksHaveIcons());	}void CToDoListWnd::OnSortMulti() {	TDSORTCOLUMNS sort;	CTDCColumnIDArray aColumns;	CTDCCustomAttribDefinitionArray aAttribDefs;	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.GetSortBy(sort);	tdc.GetVisibleColumns(aColumns);	tdc.GetCustomAttributeDefs(aAttribDefs);	CTDLMultiSortDlg dialog(sort, aColumns, aAttribDefs);	if (dialog.DoModal() == IDOK)	{		dialog.GetSortBy(sort);		tdc.MultiSort(sort);	}}void CToDoListWnd::OnUpdateSortMulti(CCmdUI* pCmdUI) {	pCmdUI->SetCheck(GetToDoCtrl().IsMultiSorting() ? 1 : 0);}void CToDoListWnd::OnToolsRemovefromsourcecontrol() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	if (tdc.RemoveFromSourceControl())	{		int nCtrl = GetSelToDoCtrl();		m_mgrToDoCtrls.UpdateToDoCtrlReadOnlyUIState(nCtrl);		m_mgrToDoCtrls.UpdateTabItemText(nCtrl);		m_mgrToDoCtrls.SetModifiedStatus(nCtrl, FALSE);		m_mgrToDoCtrls.RefreshLastModified(nCtrl);		m_mgrToDoCtrls.RefreshReadOnlyStatus(nCtrl);		m_mgrToDoCtrls.RefreshPathType(nCtrl);	}}void CToDoListWnd::OnUpdateToolsRemovefromsourcecontrol(CCmdUI* pCmdUI) {	int nCtrl = GetSelToDoCtrl();	BOOL bEnable = m_mgrToDoCtrls.IsSourceControlled(nCtrl);//	bEnable &= !Prefs().GetEnableSourceControl();//	bEnable &= m_mgrToDoCtrls.PathSupportsSourceControl(nCtrl);	if (bEnable)	{		// make sure no-one has the file checked out		CFilteredToDoCtrl& tdc = GetToDoCtrl();		bEnable &= !tdc.IsCheckedOut();	}	pCmdUI->Enable(bEnable);}void CToDoListWnd::OnViewShowTasklistTabbar() {	m_bShowTasklistBar = !m_bShowTasklistBar; 	Resize();	Invalidate(TRUE);}void CToDoListWnd::OnUpdateViewShowTasklistTabbar(CCmdUI* pCmdUI) {	pCmdUI->SetCheck(m_bShowTasklistBar ? 1 : 0);}void CToDoListWnd::OnViewShowTreeListTabbar() {	m_bShowTreeListBar = !m_bShowTreeListBar; 	GetToDoCtrl().SetStyle(TDCS_SHOWTREELISTBAR, m_bShowTreeListBar);	// refresh all the other tasklists	m_mgrToDoCtrls.SetAllNeedPreferenceUpdate(TRUE, GetSelToDoCtrl());}void CToDoListWnd::OnUpdateViewShowTreeListTabbar(CCmdUI* pCmdUI) {	pCmdUI->SetCheck(m_bShowTreeListBar ? 1 : 0);}void CToDoListWnd::OnFileChangePassword() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	if (!tdc.IsReadOnly() && tdc.IsEncrypted() && VerifyToDoCtrlPassword())	{		tdc.EnableEncryption(FALSE); // clears the password		tdc.EnableEncryption(TRUE); // forces it to be re-got	}}void CToDoListWnd::OnUpdateFileChangePassword(CCmdUI* pCmdUI) {	const CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(!tdc.IsReadOnly() && tdc.IsEncrypted());}void CToDoListWnd::OnTasklistCustomColumns() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	if (!tdc.IsReadOnly())	{		CTDLCustomAttributeDlg dialog(tdc, m_theme);		if (dialog.DoModal() == IDOK)		{			CTDCCustomAttribDefinitionArray aAttrib;			dialog.GetAttributes(aAttrib);			tdc.SetCustomAttributeDefs(aAttrib);		}	}}void CToDoListWnd::OnUpdateTasklistCustomcolumns(CCmdUI* pCmdUI) {	pCmdUI->Enable(!GetToDoCtrl().IsReadOnly());}void CToDoListWnd::OnEditClearAttribute() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	TDC_ATTRIBUTE nAttrib = MapColumnToAttribute(m_nContextColumnID);	tdc.ClearSelectedTaskAttribute(nAttrib);}void CToDoListWnd::OnUpdateEditClearAttribute(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	TDC_ATTRIBUTE nAttrib = MapColumnToAttribute(m_nContextColumnID);	pCmdUI->Enable(tdc.CanClearSelectedTaskAttribute(nAttrib));}void CToDoListWnd::OnEditClearFocusedAttribute() {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	tdc.ClearSelectedTaskFocusedAttribute();}void CToDoListWnd::OnUpdateEditClearFocusedAttribute(CCmdUI* pCmdUI) {	CFilteredToDoCtrl& tdc = GetToDoCtrl();	pCmdUI->Enable(tdc.CanClearSelectedTaskFocusedAttribute());}

  

ToDoList