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 + -
显示快捷键?