filteredtodoctrl.cpp

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

CPP
723
字号
		if (IsTaskDone(tasks, ht))
					return FALSE;
				
				else if (tasks.IsTaskDue(ht))
					return TRUE;
				// match exactly on 'none'
				else*/
		 if (m_filter.nPriority == FT_NOPRIORITY)
			return (tasks.GetTaskPriority(ht, FALSE) == FT_NOPRIORITY);
		else
			return (m_filter.nPriority <= tasks.GetTaskPriority(ht, FALSE));
	}

	// else match
	return TRUE;
}

BOOL CFilteredToDoCtrl::MatchRisk(const CTaskFile& tasks, HTASKITEM ht) const
{
	if (m_filter.nRisk != FT_ANYRISK)
	{
		/*
		if (IsTaskDone(tasks, ht))
					return FALSE;
				
				// match exactly on 'none'
				else*/
		 if (m_filter.nRisk == FT_NORISK)
			return (tasks.GetTaskRisk(ht, FALSE) == FT_NORISK);
		else
			return (m_filter.nRisk <= tasks.GetTaskRisk(ht, FALSE));
	}

	// else match
	return TRUE;
}

BOOL CFilteredToDoCtrl::MatchDueDate(const CTaskFile& tasks, HTASKITEM ht) const
{
	if (m_dateDue.m_dt > 0)
	{
		if (IsTaskDone(tasks, ht))
			return FALSE;
		else
		{
			COleDateTime dateDue = tasks.GetTaskDueDateOle(ht);
			return (dateDue.m_dt > 0 && dateDue <= m_dateDue);
		}
	}

	// else match
	return TRUE;
}

void CFilteredToDoCtrl::InitDueDate()
{
	switch (m_filter.nFilter)
	{
	case FT_ALL:
	case FT_DONE:
	case FT_NOTDONE:
		m_dateDue.m_dt = 0;
		break;

	case FT_DUETODAY:
		m_dateDue = CDateHelper::GetDate(DHD_TODAY);
		break;

	case FT_DUETOMORROW:
		m_dateDue = CDateHelper::GetDate(DHD_TOMORROW);
		break;

	case FT_DUEENDTHISWEEK:
		m_dateDue = CDateHelper::GetDate(DHD_ENDTHISWEEK);
		break;

	case FT_DUEENDNEXTWEEK: 
		m_dateDue = CDateHelper::GetDate(DHD_ENDNEXTWEEK);
		break;

	case FT_DUEENDTHISMONTH:
		m_dateDue = CDateHelper::GetDate(DHD_ENDTHISMONTH);
		break;

	case FT_DUEENDNEXTMONTH:
		m_dateDue = CDateHelper::GetDate(DHD_ENDNEXTMONTH);
		break;

	case FT_DUEENDTHISYEAR:
		m_dateDue = CDateHelper::GetDate(DHD_ENDTHISYEAR);
		break;

	case FT_DUEENDNEXTYEAR:
		m_dateDue = CDateHelper::GetDate(DHD_ENDNEXTYEAR);
		break;

	default:
		ASSERT(0);
		break;
	}
}

BOOL CFilteredToDoCtrl::IsTaskDone(const CTaskFile& tasks, HTASKITEM ht, BOOL bCheckParents) const
{
	if (!ht)
		return FALSE;

	if (tasks.IsTaskDone(ht))
		return TRUE;

	// check parents
	if (bCheckParents)
	{
		HTASKITEM htParent = tasks.GetTaskParent(ht);
		
		while (htParent)
		{
			if (tasks.IsTaskDone(htParent))
				return TRUE;

			htParent = tasks.GetTaskParent(htParent);
		}
	}

	// check children if needs be
	if (HasStyle(TDCS_TREATSUBCOMPLETEDASDONE))
	{
		HTASKITEM htChild = tasks.GetFirstTask(ht);

		if (htChild)
		{
			while (htChild)
			{
				if (!IsTaskDone(tasks, htChild, FALSE))
					return FALSE;

				htChild = tasks.GetNextTask(htChild);
			}

			// if we got here then all children and
			// children's children, etc are done
			return TRUE;
		}
	}

	// else not done
	return FALSE;
}

BOOL CFilteredToDoCtrl::DeleteSelectedTask(BOOL bWarnUser, BOOL bResetSel)
{
	if (!HasFilter())
		return CToDoCtrl::DeleteSelectedTask(bWarnUser, bResetSel);

	// 1. take a copy of the selected task IDs that also exist
	// in m_tasksHidden because we will have to delete those too. 
	CDWordArray aTaskIDs;
	POSITION pos = Selection().GetFirstItemPos();

	while (pos)
	{
		HTREEITEM hti = Selection().GetNextItem(pos);
		DWORD dwTaskID = GetTaskID(hti);

		if (m_tasksHidden.FindTask(dwTaskID))
			aTaskIDs.Add(dwTaskID);
	}

	// 2. let the base class do the visible deletion
	if (CToDoCtrl::DeleteSelectedTask(bWarnUser, bResetSel))
	{
		// 3. then we delete the duplicates
		for (int nID = 0; nID < aTaskIDs.GetSize(); nID++)
		{
			DWORD dwTaskID = aTaskIDs[nID];
			HTASKITEM ht = m_tasksHidden.FindTask(dwTaskID);

			if (ht)
				m_tasksHidden.DeleteTask(ht);
		}

		// 4. all done
		return TRUE;
	}

	return FALSE; // user cancelled
}

BOOL CFilteredToDoCtrl::SelectedTasksHaveChildren() const
{
	if (CToDoCtrl::SelectedTasksHaveChildren())
		return TRUE;

	// else lookup selected tasks in m_tasksHidden and if
	// they exist check if they have children
	POSITION pos = Selection().GetFirstItemPos();

	while (pos)
	{
		HTREEITEM hti = Selection().GetNextItem(pos);
		DWORD dwTaskID = GetTaskID(hti);

		HTASKITEM ht = m_tasksHidden.FindTask(dwTaskID);

		if (ht && m_tasksHidden.GetFirstTask(ht))
			return TRUE;
	}

	// else
	return FALSE;
}

TODOITEM* CFilteredToDoCtrl::NewTask()
{
	TODOITEM* pTDI = CToDoCtrl::NewTask();

	// fiddle with the default attributes so that the task 
	// will not be filtered out by the current filter
	if (HasFilter())
	{
		if (m_filter.nRisk != FT_ANYRISK)
			pTDI->nRisk = max(pTDI->nRisk, m_filter.nRisk);

		if (m_filter.nPriority != FT_ANYPRIORITY)
			pTDI->nPriority = max(pTDI->nPriority, m_filter.nPriority);

		if (!m_filter.sAllocBy.IsEmpty() && pTDI->sAllocBy.IsEmpty())
			pTDI->sAllocBy = m_filter.sAllocBy;

		if (!m_filter.MatchAllocTo(pTDI->aAllocTo))
		{
			// if any category will match then set it to the first
			if (m_filter.HasFlag(FT_ANYALLOCTO))
			{
				pTDI->aAllocTo.RemoveAll();

				if (m_filter.aAllocTo.GetSize())
					pTDI->aAllocTo.Add(m_filter.aAllocTo[0]);
			}
			else // set it to all the filter cats
				pTDI->aAllocTo.Copy(m_filter.aAllocTo);
		}

		if (!m_filter.sStatus.IsEmpty() && pTDI->sStatus.IsEmpty())
			pTDI->sStatus = m_filter.sStatus;

		if (!m_filter.MatchCategories(pTDI->aCategories))
		{
			// if any category will match then set it to the first
			if (m_filter.HasFlag(FT_ANYCATEGORY))
			{
				pTDI->aCategories.RemoveAll();

				if (m_filter.aCategories.GetSize())
					pTDI->aCategories.Add(m_filter.aCategories[0]);
			}
			else // set it to all the filter cats
				pTDI->aCategories.Copy(m_filter.aCategories);
		}

		// if the filter is FT_DONE then complete the task
		if (m_filter.nFilter == FT_DONE)
		{
			pTDI->dateDone = floor(COleDateTime::GetCurrentTime());
		}
		// else if due, set due today
		else if (m_filter.nFilter != FT_ALL && m_filter.nFilter != FT_NOTDONE)
		{
			pTDI->dateDue = floor(COleDateTime::GetCurrentTime());
		}
	}

	return pTDI;
}

HTREEITEM CFilteredToDoCtrl::NewTask(LPCTSTR szText, TDC_INSERTWHERE nWhere, 
									BOOL bSelect, BOOL bEditText)
{
	return CToDoCtrl::NewTask(szText, nWhere, bSelect, bEditText);
}

void CFilteredToDoCtrl::SetModified(BOOL bMod, TDC_ATTRIBUTE nAttrib)
{
	if (bMod && ModNeedsRefilter(nAttrib))
		RefreshFilter();

	CToDoCtrl::SetModified(bMod, nAttrib);
}

BOOL CFilteredToDoCtrl::ModNeedsRefilter(TDC_ATTRIBUTE nModType)
{
	if (HasStyle(TDCS_REFILTERONMODIFY))
	{
		switch (nModType)
		{
		case TDCA_PRIORITY:		return (m_filter.nPriority != -1);
		case TDCA_RISK:			return (m_filter.nRisk != -1);
			
		case TDCA_ALLOCBY:		return (!m_filter.sAllocBy.IsEmpty());
		case TDCA_STATUS:		return (!m_filter.sStatus.IsEmpty());

		case TDCA_CATEGORY:		return (m_filter.aCategories.GetSize());
		case TDCA_ALLOCTO:		return (m_filter.aAllocTo.GetSize());

		case TDCA_PERCENT:
		case TDCA_DONEDATE:		return (m_filter.nFilter == FT_DONE ||
										m_filter.nFilter == FT_NOTDONE);
			
		case TDCA_DUEDATE:		return (m_filter.nFilter != FT_DONE &&
										m_filter.nFilter != FT_NOTDONE &&
										m_filter.nFilter != FT_ALL);
		}
	}

	// all else
	return FALSE;
}

BOOL CFilteredToDoCtrl::IsTaskDone(DWORD dwTaskID) const
{
	// check task has not been filtered out
	if (m_data.GetTask(dwTaskID))
		return CToDoCtrl::IsTaskDone(dwTaskID);

	// else look it up in the filtered out tasks
	HTASKITEM ht = m_tasksHidden.FindTask(dwTaskID);

	if (ht)
		return m_tasksHidden.IsTaskDone(ht);

	// else
	return FALSE; // not found
}

BOOL CFilteredToDoCtrl::HasTask(DWORD dwTaskID)
{
	// check task has not been filtered out
	if (m_data.GetTask(dwTaskID))
		return TRUE;

	// else look it up in the filtered out tasks
	return (NULL != m_tasksHidden.FindTask(dwTaskID));
}

BOOL CFilteredToDoCtrl::SelectTask(DWORD dwTaskID)
{
	// check task has not been filtered out
	if (m_data.GetTask(dwTaskID))
		return CToDoCtrl::SelectTask(dwTaskID);

	// else look it up in the filtered out tasks
	if (m_tasksHidden.FindTask(dwTaskID))
	{
		// TODO
		return TRUE;
	}

	// else
	return FALSE;
}

⌨️ 快捷键说明

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