taskfile.cpp

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

CPP
1,983
字号
// TaskFile.cpp: implementation of the CTaskFile class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TaskFile.h"
#include "tdlschemadef.h"
#include "mergetodolist.h"
#include "tdcstruct.h"

#include "..\shared\timeedit.h"
#include "..\shared\datehelper.h"
#include "..\3rdparty\Base64Coder.h"
#include "..\shared\misc.h"
#include "..\shared\filemisc.h"

#include <math.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


// private class to load header
class CTFHeaderParse : public IXmlParse
{
public:
	CTFHeaderParse() : m_sTask(TDL_TASK) {}
	
	virtual BOOL Continue(LPCTSTR szItem, LPCTSTR /*szValue*/) const
	{
		return (m_sTask.CompareNoCase(szItem) != 0);
	}
	
protected:
	CString m_sTask;
};

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#define GET_TASK(t, h, r) { t = TaskFromHandle(h); if (!t) return r; }

CTaskFile::CTaskFile(LPCTSTR szPassword) : m_dwNextUniqueID(0),
#ifdef NO_TL_ENCRYPTDECRYPT
	CXmlFile(TDL_ROOT)
#else
	CXmlFileEx(TDL_ROOT, szPassword)
#endif
{
}

CTaskFile::~CTaskFile()
{
}

HRESULT CTaskFile::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
{
	*ppvObject = NULL;

	// compare riid against our supported version numbers
	if (IsEqualIID(riid, IID_TASKLIST2))
	{
		*ppvObject = reinterpret_cast<ITaskList2*>(this);
		AddRef();
	}
	else if (IsEqualIID(riid, IID_TASKLIST3))
	{
		*ppvObject = reinterpret_cast<ITaskList3*>(this);
		AddRef();
	}
	else if (IsEqualIID(riid, IID_TASKLIST4))
	{
		*ppvObject = reinterpret_cast<ITaskList4*>(this);
		AddRef();
	}
	else if (IsEqualIID(riid, IID_TASKLIST5))
	{
		*ppvObject = reinterpret_cast<ITaskList5*>(this);
		AddRef();
	}
	else if (IsEqualIID(riid, IID_TASKLIST6))
	{
		*ppvObject = reinterpret_cast<ITaskList6*>(this);
		AddRef();
	}
	
	return (*ppvObject ? S_OK : E_NOTIMPL);
}

#ifndef NO_TL_ENCRYPTDECRYPT

BOOL CTaskFile::Decrypt(LPCTSTR szPassword)
{
	BOOL bWasEncrypted = IsEncrypted();
	BOOL bResult = CXmlFileEx::Decrypt(szPassword);

	if (bResult && bWasEncrypted)
	{
		// fix corrupted tasklist where the root item has an ID
		CXmlItem* pXI = GetItem(TDL_TASKID);

		while (pXI)
		{
			DeleteItem(pXI);
			pXI = GetItem(TDL_TASKID);
		}

		m_dwNextUniqueID = (DWORD)GetItemValueI(TDL_NEXTUNIQUEID);

		if (m_dwNextUniqueID <= 0)
			m_dwNextUniqueID = 1; // always > 0

		BuildHandleMap();
	}

	return bResult;
}

#endif

BOOL CTaskFile::Load(LPCTSTR szFilePath, IXmlParse* pCallback, BOOL bDecrypt)
{
	
#ifdef NO_TL_ENCRYPTDECRYPT
	BOOL bRes = CXmlFile::Load(szFilePath, TDL_ROOT, pCallback);
#else
	BOOL bRes = CXmlFileEx::Load(szFilePath, TDL_ROOT, pCallback, bDecrypt);
#endif
	
	if (bRes)
	{
		m_dwNextUniqueID = (DWORD)GetItemValueI(TDL_NEXTUNIQUEID);
		
		if (m_dwNextUniqueID <= 0)
			m_dwNextUniqueID = 1; // always > 0
		
		BuildHandleMap();
	}
	
	return bRes;
}

BOOL CTaskFile::LoadHeader(LPCTSTR szFilePath)
{
	CTFHeaderParse tfhp;

	return Load(szFilePath, &tfhp, FALSE);
}

BOOL CTaskFile::LoadEx(IXmlParse* pCallback)
{
	BOOL bResult = XMLBASE::LoadEx(TDL_ROOT, pCallback);

#ifdef NO_TL_ENCRYPTDECRYPT
	if (bResult)
#else
	if (bResult && !IsEncrypted())
#endif
	{
		// fix corrupted tasklist where the root item has an ID
		CXmlItem* pXI = GetItem(TDL_TASKID);

		while (pXI)
		{
			DeleteItem(pXI);
			pXI = GetItem(TDL_TASKID);
		}

		m_dwNextUniqueID = (DWORD)GetItemValueI(TDL_NEXTUNIQUEID);

		if (m_dwNextUniqueID <= 0)
			m_dwNextUniqueID = 1; // always > 0

		BuildHandleMap();
	}

	return bResult;
}

BOOL CTaskFile::SaveEx()
{
	return XMLBASE::SaveEx();
}

BOOL CTaskFile::Copy(const CTaskFile& tasks)
{
	XMLBASE::Copy(tasks);
	BuildHandleMap();

	return TRUE;
}

BOOL CTaskFile::Copy(const ITaskList* pTasks)
{
	Reset();
	m_dwNextUniqueID = 1;

	// copy top level tasks
	return CopyTask(NULL, pTasks, NULL);
}

BOOL CTaskFile::CopyTask(HTASKITEM hSrcTask, const ITaskList* pSrcTasks, HTASKITEM hDestParent)
{
	HTASKITEM hDestTask = NULL; // our root

	if (hSrcTask) // NULL if src root
	{
		hDestTask = NewTask(pSrcTasks->GetTaskTitle(hSrcTask), hDestParent);
		ASSERT (hDestTask);

		if (!hDestTask)
			return FALSE;

		// the rest of the attributes
		SetTaskComments(hDestTask, pSrcTasks->GetTaskComments(hSrcTask));
		SetTaskAllocatedTo(hDestTask, pSrcTasks->GetTaskAllocatedTo(hSrcTask));
		SetTaskAllocatedBy(hDestTask, pSrcTasks->GetTaskAllocatedBy(hSrcTask));
		SetTaskCategory(hDestTask, pSrcTasks->GetTaskCategory(hSrcTask));
		SetTaskStatus(hDestTask, pSrcTasks->GetTaskStatus(hSrcTask));
		SetTaskFileReferencePath(hDestTask, pSrcTasks->GetTaskFileReferencePath(hSrcTask));
		SetTaskColor(hDestTask, pSrcTasks->GetTaskColor(hSrcTask));
		SetTaskPriority(hDestTask, pSrcTasks->GetTaskPriority(hSrcTask, FALSE));
		SetTaskPercentDone(hDestTask, pSrcTasks->GetTaskPercentDone(hSrcTask, FALSE));
		SetTaskLastModified(hDestTask, pSrcTasks->GetTaskLastModified(hSrcTask));
		SetTaskDoneDate(hDestTask, pSrcTasks->GetTaskDoneDate(hSrcTask));
		SetTaskDueDate(hDestTask, pSrcTasks->GetTaskDueDate(hSrcTask));
		SetTaskStartDate(hDestTask, pSrcTasks->GetTaskStartDate(hSrcTask));
		SetTaskFlag(hDestTask, pSrcTasks->IsTaskFlagged(hSrcTask));

		char cUnits;
		double dTime;
		
		dTime = pSrcTasks->GetTaskTimeEstimate(hSrcTask, cUnits, FALSE);
		SetTaskTimeEstimate(hDestTask, dTime, cUnits);
		dTime = pSrcTasks->GetTaskTimeSpent(hSrcTask, cUnits, FALSE);
		SetTaskTimeSpent(hDestTask, dTime, cUnits);

		const ITaskList2* pTL2 = GetITLInterface<ITaskList2>(pSrcTasks, IID_TASKLIST2);

		if (pTL2)
		{
			SetTaskCreatedBy(hDestTask, pTL2->GetTaskCreatedBy(hSrcTask));
			SetTaskCreationDate(hDestTask, pTL2->GetTaskCreationDate(hSrcTask));
		}

		const ITaskList3* pTL3 = GetITLInterface<ITaskList3>(pSrcTasks, IID_TASKLIST3);

		if (pTL3)
		{
			SetTaskRisk(hDestTask, pTL3->GetTaskRisk(hSrcTask, FALSE));
			SetTaskExternalID(hDestTask, pTL3->GetTaskExternalID(hSrcTask));
		}

		const ITaskList4* pTL4 = GetITLInterface<ITaskList4>(pSrcTasks, IID_TASKLIST4);

		if (pTL4)
		{
			SetTaskDependency(hDestTask, pTL4->GetTaskDependency(hSrcTask));
		}

		const ITaskList6* pTL6 = GetITLInterface<ITaskList6>(pSrcTasks, IID_TASKLIST6);

		if (pTL6)
		{
			SetTaskVersion(hDestTask, pTL6->GetTaskVersion(hSrcTask));
		}
	}

	// children
	HTASKITEM hSrcChildTask = pSrcTasks->GetFirstTask(hSrcTask);

	while (hSrcChildTask)
	{
		if (!CopyTask(hSrcChildTask, pSrcTasks, hDestTask))
			return FALSE;

		hSrcChildTask = pSrcTasks->GetNextTask(hSrcChildTask);
	}

	return TRUE;
}

#ifndef NO_TL_MERGE
int CTaskFile::Merge(const CTaskFile& tasks, BOOL bByID, BOOL bMoveExist)
{
	CMergeToDoList mtdl(bByID ? TDLM_BYID : TDLM_BYTITLE, 
						bMoveExist ? TDLM_MOVE : TDLM_LEAVE);

	int nMerge = mtdl.Merge(tasks.Root(), Root());
	BuildHandleMap();

	// update next uniqueID
	SetNextUniqueID(mtdl.GetNextID());

	return nMerge;
}

int CTaskFile::Merge(LPCTSTR szTaskFilePath, BOOL bByID, BOOL bMoveExist)
{
	CMergeToDoList mtdl(bByID ? TDLM_BYID : TDLM_BYTITLE, 
						bMoveExist ? TDLM_MOVE : TDLM_LEAVE);
	
	int nMerge = mtdl.Merge(szTaskFilePath, Root());
	BuildHandleMap();

	// update next uniqueID
	SetNextUniqueID(mtdl.GetNextID());

	return nMerge;
}
#endif

void CTaskFile::SortTasksByID()
{
	SortItemsI(TDL_TASK, TDL_TASKID);
}

void CTaskFile::SortTasksByPos()
{
	SortItemsI(TDL_TASK, TDL_TASKPOS);
}

DWORD CTaskFile::GetNextUniqueID() const
{
	return m_dwNextUniqueID;
}

void CTaskFile::BuildHandleMap()
{
	m_mapHandles.RemoveAll();

	AddTaskToMap(GetItem(TDL_TASK), TRUE); // first top level item
}

void CTaskFile::AddTaskToMap(CXmlItem* pXITask, BOOL bRecurse)
{
	if (pXITask)
	{
		// sanity check
		ASSERT (pXITask->NameIs(TDL_TASK));
		
		m_mapHandles[(HTASKITEM)pXITask] = pXITask;

		if (bRecurse)
		{
			// next item
			AddTaskToMap(pXITask->GetSibling(), TRUE);

			// children
			// note: we only need do the first child
			AddTaskToMap(pXITask->GetItem(TDL_TASK), TRUE);
		}
	}
}

void CTaskFile::RemoveTaskFromMap(CXmlItem* pXITask)
{
	if (pXITask)
	{
		// sanity check
		ASSERT (pXITask->NameIs(TDL_TASK));
		
		m_mapHandles.RemoveKey((HTASKITEM)pXITask);

		// children
		CXmlItem* pXIChild = pXITask->GetItem(TDL_TASK);

		while (pXIChild)
		{
			RemoveTaskFromMap(pXIChild);
			pXIChild = pXIChild->GetSibling();
		}
	}
}

CXmlItem* CTaskFile::TaskFromHandle(HTASKITEM hTask) const
{
#ifdef _DEBUG
	CXmlItem* pXITask = NULL;

	if (hTask)
		m_mapHandles.Lookup(hTask, pXITask);

	return pXITask;
#else
	return static_cast<CXmlItem*>(hTask);
#endif
}

bool CTaskFile::IsArchive() const
{
	return (NULL != GetItem(TDL_ARCHIVE));
}

bool CTaskFile::IsCheckedOut() const
{
	return (Misc::GetComputerName() == GetCheckOutTo());
}	

bool CTaskFile::IsSourceControlled() const
{
	return (NULL != GetItem(TDL_CHECKEDOUTTO));
}

const char* CTaskFile::GetProjectName() const
{
	return GetItemValue(TDL_PROJECTNAME);
}

const char* CTaskFile::GetReportTitle() const
{
	return GetItemValue(TDL_REPORTTITLE);
}

const char* CTaskFile::GetHtmlCharSet() const
{
	return GetItemValue(TDL_CHARSET);
}

const char* CTaskFile::GetAttribute(const char* szAttrib) const
{
	return GetItemValue(szAttrib);
}

const char* CTaskFile::GetReportDate() const
{
	return GetItemValue(TDL_REPORTDATE);
}

const char* CTaskFile::GetCheckOutTo() const
{
	return GetItemValue(TDL_CHECKEDOUTTO);
}	

unsigned long CTaskFile::GetFileFormat() const
{
	return GetItemValueI(TDL_FILEFORMAT);
}

unsigned long CTaskFile::GetFileVersion() const
{
	return GetItemValueI(TDL_FILEVERSION);
}
	
time_t CTaskFile::GetLastModified() const
{
	COleDateTime date(GetItemValueF(TDL_LASTMODIFIED));

	tm time = { date.GetHour(), 
		        0, 
				date.GetDay(), 
				date.GetMinute(), 
				date.GetMonth(), 
				date.GetSecond(), 
				0, 
				0, 
				date.GetYear() - 1900 };

	return mktime(&time);
}

BOOL CTaskFile::SetEarliestDueDate(const COleDateTime& date)
{
	return (NULL != SetItemValue(TDL_TASKEARLIESTDUEDATE, date.m_dt));
}

BOOL CTaskFile::GetEarliestDueDate(COleDateTime& date) const
{
	const CXmlItem* pXItem = GetItem(TDL_TASKEARLIESTDUEDATE);

	if (!pXItem)
		return FALSE;

	date.m_dt = pXItem->GetValueF();
	return TRUE;
}

BOOL CTaskFile::SetCommentsType(LPCTSTR szID)
{
	return (SetItemValue(TDL_COMMENTSTYPE, szID) != NULL);
}

CString CTaskFile::GetCommentsType() const
{
	return GetItemValue(TDL_COMMENTSTYPE);
}

bool CTaskFile::SetProjectName(const char* szName)
{
	return (NULL != SetItemValue(TDL_PROJECTNAME, szName));
}

⌨️ 快捷键说明

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