todoctrlmgr.cpp

来自「管理项目进度工具的原代码」· C++ 代码 · 共 907 行 · 第 1/2 页

CPP
907
字号
void CToDoCtrlMgr::RestoreColumns(TDCITEM* pTDCI)
{
	CString sFilePath(pTDCI->pTDC->GetFilePath());

	if (!sFilePath.IsEmpty())
	{
		CString sKey;

		sFilePath.Replace('\\', '_');
		sKey.Format("FileStates\\%s\\Columns", sFilePath);

		CTDCColumnArray aColumns;
		int nItem = AfxGetApp()->GetProfileInt(sKey, "Count", -1);

		if (nItem < 0)
		{
			pTDCI->bHasOwnColumns = FALSE;
			nItem = Prefs().GetVisibleColumns(aColumns);
		}
		else
			pTDCI->bHasOwnColumns = TRUE;

		while (nItem--)
		{
			int nCol = AfxGetApp()->GetProfileInt(sKey, CEnString("Item%d", nItem), -1);
			
			if (nCol != -1)
				aColumns.Add((TDC_COLUMN&)nCol);
		}
		
		pTDCI->pTDC->SetVisibleColumns(aColumns);
	}
}

void CToDoCtrlMgr::SaveColumns(const TDCITEM* pTDCI) const
{
	CString sFilePath(pTDCI->pTDC->GetFilePath());
	
	if (!sFilePath.IsEmpty())
	{
		CString sKey;
		
		sFilePath.Replace('\\', '_');
		sKey.Format("FileStates\\%s\\Columns", sFilePath);
		
		if (pTDCI->bHasOwnColumns)
		{
			CTDCColumnArray aColumns;
			int nItem = pTDCI->pTDC->GetVisibleColumns(aColumns);
			
			AfxGetApp()->WriteProfileInt(sKey, "Count", nItem);
			
			while (nItem--)
				AfxGetApp()->WriteProfileInt(sKey, CEnString("Item%d", nItem), aColumns[nItem]);
		}
		else
			AfxGetApp()->WriteProfileInt(sKey, "Count", -1);
	}
}

time_t CToDoCtrlMgr::GetLastModified(int nIndex) const
{
	ASSERTVALIDINDEX(nIndex);

	return GetTDCItem(nIndex).tLastMod;
}

void CToDoCtrlMgr::MoveToDoCtrl(int nIndex, int nNumPlaces)
{
	ASSERTVALIDINDEX(nIndex);

	int nOrgCount = m_tabCtrl.GetItemCount();

	if (!CanMoveToDoCtrl(nIndex, nNumPlaces))
		return;

	// cache selection so we can restore it afterwards
	int nSel = GetSelToDoCtrl(), nNewSel = nSel;

	// work out what the new selection should be
	if (nIndex == nSel)
		nNewSel = (nIndex + nNumPlaces);

	else if (nIndex > nSel && (nIndex + nNumPlaces) <= nSel)
		nNewSel++;

	else if (nIndex < nSel && (nIndex + nNumPlaces) >= nSel)
		nNewSel--;

	// make copies of existing
	TCITEM tci;
	char szText[128];
	tci.mask = TCIF_TEXT | TCIF_IMAGE;
	tci.pszText = szText;
	tci.cchTextMax = 127;
		
	m_tabCtrl.GetItem(nIndex, &tci);
	TDCITEM tdci = GetTDCItem(nIndex);

	// remove and re-add
	RemoveToDoCtrl(nIndex);

	nIndex += nNumPlaces;

	m_aToDoCtrls.InsertAt(nIndex, tdci);
	m_tabCtrl.InsertItem(nIndex, &tci);

	// set selection
	m_tabCtrl.SetCurSel(nNewSel);

	ASSERT (nOrgCount == m_tabCtrl.GetItemCount());
}

BOOL CToDoCtrlMgr::CanMoveToDoCtrl(int nIndex, int nNumPlaces) const
{
	ASSERTVALIDINDEX(nIndex);

	nIndex += nNumPlaces;

	return (nIndex >= 0 && nIndex < GetCount());
}

CString CToDoCtrlMgr::GetArchivePath(LPCTSTR szFilePath) const
{
	CString sArchivePath, sFilePath(szFilePath);
	sFilePath.MakeLower();

	CEnString sDone(".%s", CEnString(IDS_TDC_DONE));
	
	if (!sFilePath.IsEmpty() && sFilePath.Find(sDone) == -1) // don't archive archives!
	{
		CString sDrive, sPath, sFName, sExt;

		FileMisc::SplitPath(sFilePath, &sDrive, &sPath, &sFName, &sExt);
		FileMisc::MakePath(sArchivePath, sDrive, sPath, sFName, sDone + sExt);
	}
	
	return sArchivePath;
}

CString CToDoCtrlMgr::GetArchivePath(int nIndex) const
{
	ASSERTVALIDINDEX(nIndex);

	const CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);

	return GetArchivePath(tdc.GetFilePath());
}

int CToDoCtrlMgr::ArchiveDoneTasks(int nIndex)
{
	ASSERTVALIDINDEX(nIndex);

	CFilteredToDoCtrl& tdc = GetToDoCtrl(nIndex);

	TDC_ARCHIVE nRemove = TDC_REMOVENONE;
	
	if (Prefs().GetRemoveArchivedTasks())
	{
		if (Prefs().GetRemoveOnlyOnAbsoluteCompletion())
			nRemove = TDC_REMOVEIFSIBLINGSANDSUBTASKSCOMPLETE;
		else
			nRemove = TDC_REMOVEALL;
	}
	
	return tdc.ArchiveDoneTasks(GetArchivePath(tdc.GetFilePath()), nRemove,
								!Prefs().GetDontRemoveFlagged());
}

int CToDoCtrlMgr::SortToDoCtrlsByName()
{
	int nSel = GetSelToDoCtrl();

	if (!AreToDoCtrlsSorted())
	{
		// save off current selection 
		CFilteredToDoCtrl* pTDC = &GetToDoCtrl(nSel);

		qsort(m_aToDoCtrls.GetData(), m_aToDoCtrls.GetSize(), sizeof(TDCITEM), SortProc);

		nSel = -1;

		// redo the tab text
		for (int nTDC = 0; nTDC < GetCount(); nTDC++)
		{
			UpdateTabItemText(nTDC);

			// check if this was the selected item
			if (pTDC == &GetToDoCtrl(nTDC))
				nSel = nTDC;
		}

		// set selection
		ASSERT (nSel != -1);
	}

	return nSel;
}

int CToDoCtrlMgr::SortProc(const void* v1, const void* v2)
{
	TDCITEM* pTDCI1 = (TDCITEM*)v1;
	TDCITEM* pTDCI2 = (TDCITEM*)v2;

	CString sName1 = pTDCI1->GetFriendlyProjectName();
	CString sName2 = pTDCI2->GetFriendlyProjectName();

	return sName1.CompareNoCase(sName2);
}

BOOL CToDoCtrlMgr::AreToDoCtrlsSorted() const
{
	if (GetCount() <= 1)
		return TRUE;

	// check that each item is 'less' than the next
	CString sPrev = GetTDCItem(0).GetFriendlyProjectName();

	for (int nTDC = 1; nTDC < GetCount(); nTDC++)
	{
		CString sTDC = GetTDCItem(nTDC).GetFriendlyProjectName();

		if (sPrev.CompareNoCase(sTDC) > 0)
			return FALSE;

		sPrev = sTDC;
	}

	return TRUE;
}

CString CToDoCtrlMgr::UpdateTabItemText(int nIndex)
{
	if (nIndex < 0)
	{
		nIndex = GetSelToDoCtrl();
		
		if (nIndex < 0)
			return "";
	}
	
	TDCITEM& tdci = GetTDCItem(nIndex);
	
	// project name
	CString sProjectName = tdci.GetFriendlyProjectName();

	// double up ampersands to avoid unexpected underlining
	sProjectName.Replace("&", "&&");

	if (tdci.pTDC->IsModified() && !tdci.pTDC->IsReadOnly())
		sProjectName += "*";
	
	// appropriate icon
	int nImage = IM_NONE;

	if (!tdci.bLoaded)
		nImage = IM_NOTLOADED;
	
	else if (tdci.bLastStatusReadOnly > 0)
		nImage = IM_READONLY;
	
	else if (PathSupportsSourceControl(nIndex))
        nImage = tdci.pTDC->IsCheckedOut() ? IM_CHECKEDOUT : IM_CHECKEDIN;
	
	else if (tdci.pTDC->IsReadOnly())
		nImage = IM_READONLY;
	
    // update tab array
	TCITEM tci;
	tci.mask = TCIF_TEXT | TCIF_IMAGE;
	tci.pszText = (LPTSTR)(LPCTSTR)sProjectName;
	tci.iImage = nImage;
	
	m_tabCtrl.SetItem(nIndex, &tci);

	// remove doubled-up ampersands
	sProjectName.Replace("&&", "&");
	
	return sProjectName;
}

CString CToDoCtrlMgr::GetTabItemText(int nIndex) const
{
	ASSERTVALIDINDEX(nIndex);

	TCITEM tci;
	CString sText;
	
	tci.mask = TCIF_TEXT;
	tci.pszText = sText.GetBuffer(128);
	tci.cchTextMax = 127;
		
	m_tabCtrl.GetItem(nIndex, &tci);

	sText.ReleaseBuffer();
	sText.Replace("&&", "&"); // remove doubled-up ampersands

	return sText;
}

CString CToDoCtrlMgr::GetTabItemTooltip(int nIndex) const
{
	ASSERTVALIDINDEX(nIndex);

	TCITEM tci;
	tci.mask = TCIF_IMAGE;

	m_tabCtrl.GetItem(nIndex, &tci);

	switch (tci.iImage)
	{
	case IM_READONLY:	return CEnString(IDS_TABTIP_READONLY);
	case IM_CHECKEDIN:	return CEnString(IDS_TABTIP_CHECKEDIN);
	case IM_CHECKEDOUT: return CEnString(IDS_TABTIP_CHECKEDOUT);
	case IM_NOTLOADED:	return CEnString(IDS_TABTIP_NOTLOADED);

	case IM_NONE:
	default:
		break;
	}

	return "";
}

BOOL CToDoCtrlMgr::PathTypeSupportsSourceControl(TDCM_PATHTYPE nType) const
{
	switch (nType)
    {
    case TDCM_FIXED:          
    case TDCM_REMOTE:         
        break;
		
    default: // everything else
        return FALSE;
    }
	
	BOOL bEnableSourceControl = Prefs().GetEnableSourceControl();
	BOOL bLanOnly = Prefs().GetSourceControlLanOnly();
	
    return (bEnableSourceControl && (!bLanOnly || nType == TDCM_REMOTE));
}

BOOL CToDoCtrlMgr::PathSupportsSourceControl(LPCTSTR szPath) const
{
    int nType = CDriveInfo::GetPathType(szPath);

	return PathTypeSupportsSourceControl(TDCITEM::TranslatePathType(nType));
}

BOOL CToDoCtrlMgr::PathSupportsSourceControl(int nIndex) const
{
	TDCM_PATHTYPE nType = GetFilePathType(nIndex);
	
	return PathTypeSupportsSourceControl(nType);
}

BOOL CToDoCtrlMgr::IsSourceControlled(int nIndex) const
{
	ASSERTVALIDINDEX(nIndex);
	
	return GetToDoCtrl(nIndex).IsSourceControlled();
}

void CToDoCtrlMgr::SetNeedsPreferenceUpdate(int nIndex, BOOL bNeed)
{
	ASSERTVALIDINDEX(nIndex);
	
	GetTDCItem(nIndex).bNeedPrefUpdate = bNeed;
}

BOOL CToDoCtrlMgr::GetNeedsPreferenceUpdate(int nIndex) const
{
	ASSERTVALIDINDEX(nIndex);
	
	return GetTDCItem(nIndex).bNeedPrefUpdate;
}

void CToDoCtrlMgr::SetAllNeedPreferenceUpdate(BOOL bNeed, int nExcept)
{
	for (int nIndex = 0; nIndex < m_aToDoCtrls.GetSize(); nIndex++)
	{
		if (nIndex != nExcept)
			GetTDCItem(nIndex).bNeedPrefUpdate = bNeed;
	}
}

int CToDoCtrlMgr::FindToDoCtrl(LPCTSTR szFilePath) const
{
	if (!szFilePath || GetFileAttributes(szFilePath) != 0xffffffff)
	{
		int nCtrl = GetCount();
	
		while (nCtrl--)
		{
			if (GetFilePath(nCtrl).CompareNoCase(szFilePath) == 0)
				return nCtrl;
		}
	}

	return -1;
}

int CToDoCtrlMgr::FindToDoCtrl(const CFilteredToDoCtrl* pTDC) const
{
	int nCtrl = GetCount();
	
	while (nCtrl--)
	{
		if (pTDC == GetTDCItem(nCtrl).pTDC)
			return nCtrl;
	}

	return -1;
}

void CToDoCtrlMgr::PreparePopupMenu(CMenu& menu, UINT nID1, int nMax) const
{
	//fabio_2005
	int nTDC = 0;
	for (nTDC = 0; nTDC < GetCount() && nTDC < nMax; nTDC++)
	{
		CString sTaskList = GetFriendlyProjectName(nTDC);

		menu.ModifyMenu(nID1 + nTDC, MF_BYCOMMAND, nID1 + nTDC, sTaskList);
	}

	// delete any unused items
	for (; nTDC < nMax; nTDC++)
		menu.RemoveMenu(nID1 + nTDC, MF_BYCOMMAND);

}

BOOL CToDoCtrlMgr::HasTasks(int nIndex) const
{
	ASSERTVALIDINDEX(nIndex);
	
	return GetToDoCtrl(nIndex).GetTaskCount();
}

BOOL CToDoCtrlMgr::AnyHasTasks() const
{
	int nCtrl = GetCount();
	
	while (nCtrl--)
	{
		if (HasTasks(nCtrl))
			return TRUE;
	}
	
	return FALSE;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?