todoctrlmgr.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 907 行 · 第 1/2 页
CPP
907 行
// CToDoCtrlMgr.cpp : implementation file
//
#include "stdafx.h"
#include "ToDolist.h"
#include "ToDoCtrlMgr.h"
#include "tdstringres.h"
#include "..\shared\holdredraw.h"
#include "..\shared\enstring.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CToDoCtrlMgr dialog
enum { IM_NONE = -1, IM_READONLY, IM_CHECKEDIN, IM_CHECKEDOUT, IM_NOTLOADED };
#define ASSERTVALIDINDEX(i) { ASSERT (i >= 0 && i < GetCount()); }
CToDoCtrlMgr::CToDoCtrlMgr(CTabCtrl& tabCtrl) : m_tabCtrl(tabCtrl)
{
}
CToDoCtrlMgr::~CToDoCtrlMgr()
{
}
void CToDoCtrlMgr::SetPrefs(const CPreferencesDlg* pPrefs)
{
m_pPrefs = pPrefs;
}
const CPreferencesDlg& CToDoCtrlMgr::Prefs() const
{
ASSERT (m_pPrefs);
return *m_pPrefs;
}
CFilteredToDoCtrl& CToDoCtrlMgr::GetToDoCtrl(int nIndex)
{
ASSERTVALIDINDEX(nIndex);
return *(m_aToDoCtrls[nIndex].pTDC);
}
const CFilteredToDoCtrl& CToDoCtrlMgr::GetToDoCtrl(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
return *(m_aToDoCtrls[nIndex].pTDC);
}
CToDoCtrlMgr::TDCITEM& CToDoCtrlMgr::GetTDCItem(int nIndex)
{
ASSERTVALIDINDEX(nIndex);
return m_aToDoCtrls[nIndex];
}
const CToDoCtrlMgr::TDCITEM& CToDoCtrlMgr::GetTDCItem(int nIndex) const
{
// hack to get around const problem
CToDoCtrlMgr* pThis = const_cast<CToDoCtrlMgr*>(this);
return pThis->m_aToDoCtrls[nIndex];
}
CString CToDoCtrlMgr::GetFilePath(int nIndex, BOOL bStrict) const
{
ASSERTVALIDINDEX(nIndex);
CString sPath = GetToDoCtrl(nIndex).GetFilePath();
if (sPath.IsEmpty() && !bStrict)
{
TCITEM tci;
char szText[51];
tci.mask = TCIF_TEXT;
tci.cchTextMax = 50;
tci.pszText = szText;
m_tabCtrl.GetItem(nIndex, &tci);
sPath = tci.pszText;
FileMisc::ValidateFilename(sPath);
}
return sPath;
}
CString CToDoCtrlMgr::GetFriendlyProjectName(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
return m_aToDoCtrls[nIndex].GetFriendlyProjectName();
}
void CToDoCtrlMgr::ClearFilePath(int nIndex)
{
ASSERTVALIDINDEX(nIndex);
GetToDoCtrl(nIndex).ClearFilePath();
}
BOOL CToDoCtrlMgr::IsFilePathEmpty(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
return GetFilePath(nIndex).IsEmpty();
}
TDCM_PATHTYPE CToDoCtrlMgr::GetFilePathType(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
// we do it this way because of const
return m_aToDoCtrls[nIndex].GetPathType();
}
TDCM_PATHTYPE CToDoCtrlMgr::RefreshPathType(int nIndex)
{
ASSERTVALIDINDEX(nIndex);
TDCITEM& tdci = GetTDCItem(nIndex);
tdci.RefreshPathType();
return tdci.nPathType;
}
BOOL CToDoCtrlMgr::IsPristine(int nIndex) const
{
return IsFilePathEmpty(nIndex) && !GetModifiedStatus(nIndex);
}
BOOL CToDoCtrlMgr::IsLoaded(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
return GetTDCItem(nIndex).bLoaded;
}
void CToDoCtrlMgr::SetLoaded(int nIndex, BOOL bLoaded)
{
ASSERTVALIDINDEX(nIndex);
GetTDCItem(nIndex).bLoaded = bLoaded;
}
BOOL CToDoCtrlMgr::RefreshLastModified(int nIndex)
{
ASSERTVALIDINDEX(nIndex);
TDCITEM& tdci = GetTDCItem(nIndex);
time_t timeNow = FileMisc::GetLastModified(tdci.pTDC->GetFilePath());
time_t timePrev = tdci.tLastMod;
tdci.tLastMod = timeNow;
// if the tasklist is checked out then always return FALSE because
// noone else should be able to modify it (by any means).
if (tdci.pTDC->IsCheckedOut())
return FALSE;
// else
return (timeNow > 0 && timePrev > 0 && timeNow != timePrev);
}
BOOL CToDoCtrlMgr::RefreshReadOnlyStatus(int nIndex)
{
ASSERTVALIDINDEX(nIndex);
TDCITEM& tdci = GetTDCItem(nIndex);
BOOL bReadOnlyNow = CDriveInfo::IsReadonlyPath(tdci.pTDC->GetFilePath()) > 0;
BOOL bReadOnlyPrev = tdci.bLastStatusReadOnly;
GetTDCItem(nIndex).bLastStatusReadOnly = bReadOnlyNow;
return (bReadOnlyNow != -1 && bReadOnlyPrev != -1 && bReadOnlyNow != bReadOnlyPrev);
}
int CToDoCtrlMgr::GetReadOnlyStatus(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
return GetTDCItem(nIndex).bLastStatusReadOnly;
}
void CToDoCtrlMgr::SetDueItemStatus(int nIndex, TDCM_DUESTATUS nStatus)
{
ASSERTVALIDINDEX(nIndex);
GetTDCItem(nIndex).nDueStatus = nStatus;
}
TDCM_DUESTATUS CToDoCtrlMgr::GetDueItemStatus(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
return GetTDCItem(nIndex).nDueStatus;
}
int CToDoCtrlMgr::GetLastCheckoutStatus(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
return GetTDCItem(nIndex).bLastCheckoutSuccess;
}
void CToDoCtrlMgr::SetLastCheckoutStatus(int nIndex, BOOL bStatus)
{
ASSERTVALIDINDEX(nIndex);
GetTDCItem(nIndex).bLastCheckoutSuccess = bStatus;
}
int CToDoCtrlMgr::CanCheckOut(int nIndex) const
{
return (CanCheckInOut(nIndex) && !GetToDoCtrl(nIndex).IsCheckedOut());
}
int CToDoCtrlMgr::CanCheckIn(int nIndex) const
{
return (CanCheckInOut(nIndex) && GetToDoCtrl(nIndex).IsCheckedOut());
}
int CToDoCtrlMgr::CanCheckInOut(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
if (!Prefs().GetEnableSourceControl())
return FALSE;
const CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);
BOOL bCanCheckInOut = (tdc.CompareFileFormat() != TDCFF_NEWER);
if (bCanCheckInOut)
{
bCanCheckInOut &= PathSupportsSourceControl(nIndex);
if (bCanCheckInOut)
bCanCheckInOut &= !GetReadOnlyStatus(nIndex);
}
return bCanCheckInOut;
}
void CToDoCtrlMgr::SetModifiedStatus(int nIndex, BOOL bMod)
{
ASSERTVALIDINDEX(nIndex);
GetTDCItem(nIndex).bModified = bMod;
}
BOOL CToDoCtrlMgr::GetModifiedStatus(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
return GetTDCItem(nIndex).bModified;
}
void CToDoCtrlMgr::RefreshModifiedStatus(int nIndex)
{
ASSERTVALIDINDEX(nIndex);
TDCITEM& tdci = GetTDCItem(nIndex);
tdci.bModified = tdci.pTDC->IsModified();
}
void CToDoCtrlMgr::UpdateToDoCtrlReadOnlyUIState(int nIndex)
{
ASSERTVALIDINDEX(nIndex);
CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);
UpdateToDoCtrlReadOnlyUIState(tdc);
}
void CToDoCtrlMgr::UpdateToDoCtrlReadOnlyUIState(CFilteredToDoCtrl& tdc)
{
LPCTSTR szPath = tdc.GetFilePath();
BOOL bReadOnly = CDriveInfo::IsReadonlyPath(szPath) > 0;
if (!bReadOnly)
bReadOnly = (tdc.CompareFileFormat() == TDCFF_NEWER);
if (!bReadOnly)
bReadOnly = (PathSupportsSourceControl(szPath) && !tdc.IsCheckedOut());
if (!bReadOnly && !Prefs().GetEnableSourceControl())
bReadOnly = tdc.IsSourceControlled();
tdc.SetReadonly(bReadOnly);
}
int CToDoCtrlMgr::RemoveToDoCtrl(int nIndex, BOOL bDelete)
{
ASSERTVALIDINDEX(nIndex);
int nSel = GetSelToDoCtrl(), nNewSel = -1;
CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);
TDCITEM& tdci = GetTDCItem(nIndex);
// save state first
SaveColumns(&tdci);
SaveFilter(&tdc);
if (bDelete)
{
// checkin as our final task
if (Prefs().GetCheckinOnClose() && PathSupportsSourceControl(nIndex))
tdc.CheckIn();
}
m_aToDoCtrls.RemoveAt(nIndex);
m_tabCtrl.DeleteItem(nIndex);
// set new selection as close to previous as possible
// *before* deleting the tasklist
if (GetCount())
{
if (nIndex <= nSel)
nNewSel = max(0, nSel - 1);
else
nNewSel = nSel;
m_tabCtrl.SetCurSel(nNewSel);
}
if (bDelete)
{
tdc.DestroyWindow();
delete &tdc;
}
return nNewSel;
}
int CToDoCtrlMgr::AddToDoCtrl(CFilteredToDoCtrl* pCtrl, BOOL bLoaded)
{
static int nNextIndex = 0;
TDCITEM tdci(pCtrl, nNextIndex++, bLoaded);
// restore previous state
if (Prefs().GetRestoreTasklistFilters())
RestoreFilter(pCtrl);
RestoreColumns(&tdci);
// add to tab
int nSel = m_aToDoCtrls.Add(tdci);
m_tabCtrl.InsertItem(nSel, "");
UpdateTabItemText(nSel);
RefreshPathType(nSel);
return nSel;
}
void CToDoCtrlMgr::RestoreFilter(CFilteredToDoCtrl* pCtrl)
{
CString sFilePath(pCtrl->GetFilePath());
if (!sFilePath.IsEmpty())
{
CString sKey;
sFilePath.Replace('\\', '_');
sKey.Format("FileStates\\%s\\Filter", sFilePath);
FTDCFILTER filter;
filter.nFilter = (FILTER_TYPE)AfxGetApp()->GetProfileInt(sKey, "Filter", FT_ALL);
filter.nPriority = AfxGetApp()->GetProfileInt(sKey, "Priority", FT_ANYPRIORITY);
filter.nRisk = AfxGetApp()->GetProfileInt(sKey, "Risk", FT_ANYRISK);
filter.sAllocBy = AfxGetApp()->GetProfileString(sKey, "AllocBy");
filter.sStatus = AfxGetApp()->GetProfileString(sKey, "Status");
// cats
filter.SetFlag(FT_ANYCATEGORY, AfxGetApp()->GetProfileInt(sKey, "AnyCategory", FALSE));
CString sCategory = AfxGetApp()->GetProfileString(sKey, "Category");
Misc::ParseIntoArray(sCategory, filter.aCategories, TRUE);
// alloc to
filter.SetFlag(FT_ANYALLOCTO, AfxGetApp()->GetProfileInt(sKey, "AnyAllocTo", FALSE));
CString sAllocTo = AfxGetApp()->GetProfileString(sKey, "AllocTo");
Misc::ParseIntoArray(sAllocTo, filter.aAllocTo, TRUE);
pCtrl->SetFilter(filter);
}
}
void CToDoCtrlMgr::SaveFilter(const CFilteredToDoCtrl* pCtrl) const
{
CString sFilePath(pCtrl->GetFilePath());
if (!sFilePath.IsEmpty())
{
CString sKey;
sFilePath.Replace('\\', '_');
sKey.Format("FileStates\\%s\\Filter", sFilePath);
FTDCFILTER filter;
pCtrl->GetFilter(filter);
AfxGetApp()->WriteProfileInt(sKey, "Filter", filter.nFilter);
AfxGetApp()->WriteProfileInt(sKey, "Priority", filter.nPriority);
AfxGetApp()->WriteProfileInt(sKey, "Risk", filter.nRisk);
AfxGetApp()->WriteProfileString(sKey, "AllocBy", filter.sAllocBy);
AfxGetApp()->WriteProfileString(sKey, "Status", filter.sStatus);
AfxGetApp()->WriteProfileString(sKey, "AllocTo", Misc::FormatArray(filter.aAllocTo));
AfxGetApp()->WriteProfileInt(sKey, "AnyAllocTo", filter.HasFlag(FT_ANYALLOCTO));
AfxGetApp()->WriteProfileString(sKey, "Category", Misc::FormatArray(filter.aCategories));
AfxGetApp()->WriteProfileInt(sKey, "AnyCategory", filter.HasFlag(FT_ANYCATEGORY));
}
}
void CToDoCtrlMgr::RefreshColumns(int nIndex, CTDCColumnArray& aColumns /*out*/)
{
ASSERTVALIDINDEX(nIndex);
// if the todoctrl does not have its own columns we use the default
// preferences set else we return it's own set.
if (!HasOwnColumns(nIndex))
{
Prefs().GetVisibleColumns(aColumns);
GetToDoCtrl(nIndex).SetVisibleColumns(aColumns);
}
else
GetToDoCtrl(nIndex).GetVisibleColumns(aColumns);
}
BOOL CToDoCtrlMgr::HasOwnColumns(int nIndex) const
{
ASSERTVALIDINDEX(nIndex);
return GetTDCItem(nIndex).bHasOwnColumns;
}
void CToDoCtrlMgr::SetHasOwnColumns(int nIndex, BOOL bHas)
{
ASSERTVALIDINDEX(nIndex);
GetTDCItem(nIndex).bHasOwnColumns = bHas;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?