| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- // ProcessCopy.cpp: implementation of the CProcessCopy class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "AccessToSqlite.h"
- #include "..\UnicodeMacros.h"
- #include "Clip.h"
- #include "..\Crc32Dynamic.h"
- #include <Mmsystem.h>
- #define CATCH_SQLITE_EXCEPTION \
- catch (CppSQLite3Exception& e) \
- { \
- Log(StrF(_T("SQLITE Exception %d - %s"), e.errorCode(), e.errorMessage())); \
- ASSERT(!e.errorMessage()); \
- } \
- #define CATCH_SQLITE_EXCEPTION_AND_RETURN(bRet) \
- catch (CppSQLite3Exception& e) \
- { \
- Log(StrF(_T("SQLITE Exception %d - %s"), e.errorCode(), e.errorMessage())); \
- ASSERT(!e.errorMessage()); \
- return bRet; \
- } \
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- /*----------------------------------------------------------------------------*\
- CClipFormat - holds the data of one clip format.
- \*----------------------------------------------------------------------------*/
- CClipFormat::CClipFormat(CLIPFORMAT cfType, HGLOBAL hgData)
- {
- m_cfType = cfType;
- m_hgData = hgData;
- bDeleteData = true;
- }
- CClipFormat::~CClipFormat()
- {
- Free();
- }
- void CClipFormat::Clear()
- {
- m_cfType = 0;
- m_hgData = 0;
- }
- void CClipFormat::Free()
- {
- if(bDeleteData)
- {
- if(m_hgData)
- {
- m_hgData = ::GlobalFree( m_hgData );
- m_hgData = NULL;
- }
- }
- }
- /*----------------------------------------------------------------------------*\
- CClipFormats - holds an array of CClipFormat
- \*----------------------------------------------------------------------------*/
- // returns a pointer to the CClipFormat in this array which matches the given type
- // or NULL if that type doesn't exist in this array.
- CClipFormat* CClipFormats::FindFormat(UINT cfType)
- {
- CClipFormat* pCF;
- int count = (int)GetSize();
- for(int i=0; i < count; i++)
- {
- pCF = &ElementAt(i);
- if(pCF->m_cfType == cfType)
- return pCF;
- }
- return NULL;
- }
- /*----------------------------------------------------------------------------*\
- CClip - holds multiple CClipFormats and CopyClipboard() statistics
- \*----------------------------------------------------------------------------*/
- DWORD CClip::m_LastAddedCRC = 0;
- long CClip::m_LastAddedID = -1;
- CClip::CClip() :
- m_ID(0),
- m_CRC(0),
- m_lParent(-1),
- m_lDontAutoDelete(FALSE),
- m_lShortCut(0),
- m_bIsGroup(FALSE)
- {
- }
- CClip::~CClip()
- {
- EmptyFormats();
- }
- void CClip::Clear()
- {
- m_ID = -1;
- m_Time = 0;
- m_Desc = "";
- m_CRC = 0;
- m_lParent = -1;
- m_lDontAutoDelete = FALSE;
- m_lShortCut = 0;
- m_bIsGroup = FALSE;
- m_csQuickPaste = "";
- EmptyFormats();
- }
- const CClip& CClip::operator=(const CClip &clip)
- {
- const CClipFormat* pCF;
- m_ID = clip.m_ID;
- m_Time = clip.m_Time;
- m_CRC = clip.m_CRC;
- m_lParent = clip.m_lParent;
- m_lDontAutoDelete = clip.m_lDontAutoDelete;
- m_lShortCut = clip.m_lShortCut;
- m_bIsGroup = clip.m_bIsGroup;
- m_csQuickPaste = clip.m_csQuickPaste;
- int nCount = (int)clip.m_Formats.GetSize();
-
- for(int i = 0; i < nCount; i++)
- {
- pCF = &clip.m_Formats.GetData()[i];
- LPVOID pvData = GlobalLock(pCF->m_hgData);
- if(pvData)
- {
- AddFormat(pCF->m_cfType, pvData, (UINT)GlobalSize(pCF->m_hgData));
- }
- GlobalUnlock(pCF->m_hgData);
- }
- //Set this after since in could get the wrong description in AddFormat
- m_Desc = clip.m_Desc;
- return *this;
- }
- void CClip::EmptyFormats()
- {
- // free global memory in m_Formats
- for(int i = (int)m_Formats.GetSize()-1; i >= 0; i--)
- {
- m_Formats[i].Free();
- m_Formats.RemoveAt( i );
- }
- }
- // Adds a new Format to this Clip by copying the given data.
- bool CClip::AddFormat(CLIPFORMAT cfType, void* pData, UINT nLen)
- {
- ASSERT(pData && nLen);
- HGLOBAL hGlobal = NewGlobalP(pData, nLen);
- ASSERT(hGlobal);
- // update the Clip statistics
- m_Time = m_Time.GetCurrentTime();
-
- CClipFormat format(cfType,hGlobal);
- CClipFormat *pFormat;
-
- pFormat = m_Formats.FindFormat(cfType);
- // if the format type already exists as part of this clip, replace the data
- if(pFormat)
- {
- pFormat->Free();
- pFormat->m_hgData = format.m_hgData;
- }
- else
- {
- m_Formats.Add(format);
- }
-
- format.m_hgData = 0; // now owned by m_Formats
- return true;
- }
- bool CClip::AddToDB(bool bCheckForDuplicates)
- {
- bool bResult;
-
- m_CRC = GenerateCRC();
-
- bResult = false;
- if(AddToMainTable())
- {
- bResult = AddToDataTable();
- }
- // should be emptied by AddToDataTable
- ASSERT(m_Formats.GetSize() == 0);
-
- return bResult;
- }
- DWORD CClip::GenerateCRC()
- {
- CClipFormat* pCF;
- DWORD dwCRC = 0xFFFFFFFF;
- CCrc32Dynamic *pCrc32 = new CCrc32Dynamic;
- if(pCrc32)
- {
- //Generate a CRC value for all copied data
- int nSize = (int)m_Formats.GetSize();
- for(int i = 0; i < nSize ; i++)
- {
- pCF = & m_Formats.ElementAt(i);
-
- const unsigned char *Data = (const unsigned char *)GlobalLock(pCF->m_hgData);
- if(Data)
- {
- pCrc32->GenerateCrc32((const LPBYTE)Data, (DWORD)GlobalSize(pCF->m_hgData), dwCRC);
- }
- GlobalUnlock(pCF->m_hgData);
- }
- dwCRC = ~dwCRC;
- delete pCrc32;
- }
- return dwCRC;
- }
- // assigns m_ID
- bool CClip::AddToMainTable()
- {
- try
- {
- m_Desc.Replace(_T("'"), _T("''"));
- m_csQuickPaste.Replace(_T("'"), _T("''"));
- CString cs;
- cs.Format(_T("insert into Main values(NULL, %d, '%s', %d, %d, %d, %d, %d, '%s');"),
- (long)m_Time.GetTime(),
- m_Desc,
- m_lShortCut,
- m_lDontAutoDelete,
- m_CRC,
- m_bIsGroup,
- m_lParent,
- m_csQuickPaste);
- theApp.m_db.execDML(cs);
- m_ID = (long)theApp.m_db.lastRowId();
- m_LastAddedCRC = m_CRC;
- m_LastAddedID = m_ID;
- }
- CATCH_SQLITE_EXCEPTION_AND_RETURN(false)
-
- return true;
- }
- // Empties m_Formats as it saves them to the Data Table.
- bool CClip::AddToDataTable()
- {
- CClipFormat* pCF;
- try
- {
- CppSQLite3Statement stmt = theApp.m_db.compileStatement(_T("insert into Data values (NULL, ?, ?, ?);"));
-
- for(int i = (int)m_Formats.GetSize()-1; i >= 0 ; i--)
- {
- pCF = & m_Formats.ElementAt(i);
-
- stmt.bind(1, m_ID);
- stmt.bind(2, GetFormatName(pCF->m_cfType));
- const unsigned char *Data = (const unsigned char *)GlobalLock(pCF->m_hgData);
- if(Data)
- {
- stmt.bind(3, Data, (int)GlobalSize(pCF->m_hgData));
- }
- GlobalUnlock(pCF->m_hgData);
-
- stmt.execDML();
- stmt.reset();
- m_Formats.RemoveAt(i);
- }
- }
- CATCH_SQLITE_EXCEPTION_AND_RETURN(false)
-
- return true;
- }
- // changes m_Time to be later than the latest clip entry in the db
- // ensures that pClip's time is not older than the last clip added
- // old times can happen on fast copies (<1 sec).
- void CClip::MakeLatestTime()
- {
- try
- {
- CppSQLite3Query q = theApp.m_db.execQuery(_T("SELECT lDate FROM Main ORDER BY lDate DESC LIMIT 1"));
- if(q.eof() == false)
- {
- long lLatestDate = q.getIntField(_T("lDate"));
- if(m_Time.GetTime() <= lLatestDate)
- {
- m_Time = lLatestDate + 1;
- }
- }
- }
- CATCH_SQLITE_EXCEPTION
- }
- BOOL CClip::LoadMainTable(long lID)
- {
- try
- {
- CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT * FROM Main WHERE lID = %d"), lID);
- if(q.eof() == false)
- {
- m_Time = q.getIntField(_T("lDate"));
- m_Desc = q.getStringField(_T("mText"));
- m_CRC = q.getIntField(_T("CRC"));
- m_lParent = q.getIntField(_T("lParentID"));
- m_lDontAutoDelete = q.getIntField(_T("lDontAutoDelete"));
- m_lShortCut = q.getIntField(_T("lShortCut"));
- m_bIsGroup = q.getIntField(_T("bIsGroup"));
- }
- }
- CATCH_SQLITE_EXCEPTION_AND_RETURN(FALSE)
- return TRUE;
- }
- // STATICS
- // Allocates a Global containing the requested Clip Format Data
- HGLOBAL CClip::LoadFormat(long lID, UINT cfType)
- {
- HGLOBAL hGlobal = 0;
- try
- {
- CString csSQL;
-
- csSQL.Format(
- _T("SELECT Data.ooData FROM Data ")
- _T("INNER JOIN Main ON Main.lID = Data.lParentID ")
- _T("WHERE Main.lID = %d ")
- _T("AND Data.strClipBoardFormat = \'%s\'"),
- lID,
- GetFormatName(cfType));
- CppSQLite3Query q = theApp.m_db.execQuery(csSQL);
- if(q.eof() == false)
- {
- int nDataLen = 0;
- const unsigned char *cData = q.getBlobField(0, nDataLen);
- if(cData == NULL)
- {
- return false;
- }
- hGlobal = NewGlobalP((LPVOID)cData, nDataLen);
- }
- }
- CATCH_SQLITE_EXCEPTION
-
- return hGlobal;
- }
- bool CClip::LoadFormats(long lID, bool bOnlyLoad_CF_TEXT)
- {
- CClipFormat cf;
- HGLOBAL hGlobal = 0;
- m_Formats.RemoveAll();
- try
- {
- //Open the data table for all that have the parent id
- //Order by Data.lID so that when generating CRC it's always in the same order as the first time
- //we generated it
- CString csSQL;
- csSQL.Format(
- _T("SELECT strClipBoardFormat, ooData FROM Data ")
- _T("INNER JOIN Main ON Main.lID = Data.lParentID ")
- _T("WHERE Main.lID = %d ORDER BY Data.lID desc"), lID);
- CppSQLite3Query q = theApp.m_db.execQuery(csSQL);
- while(q.eof() == false)
- {
- cf.m_cfType = GetFormatID(q.getStringField(_T("strClipBoardFormat")));
-
- if(bOnlyLoad_CF_TEXT)
- {
- if(cf.m_cfType != CF_TEXT && cf.m_cfType != CF_UNICODETEXT)
- {
- q.nextRow();
- continue;
- }
- }
- int nDataLen = 0;
- const unsigned char *cData = q.getBlobField(1, nDataLen);
- if(cData != NULL)
- {
- hGlobal = NewGlobalP((LPVOID)cData, nDataLen);
- }
-
- cf.m_hgData = hGlobal;
- m_Formats.Add(cf);
- q.nextRow();
- }
- // formats owns all the data
- cf.m_hgData = 0;
- }
- CATCH_SQLITE_EXCEPTION_AND_RETURN(false)
-
- return m_Formats.GetSize() > 0;
- }
- void CClip::LoadTypes(long lID, CClipTypes& types)
- {
- types.RemoveAll();
- try
- {
- CString csSQL;
- // get formats for Clip "lID" (Main.lID) using the corresponding Main.lDataID
-
- //Order by Data.lID so that when generating CRC it's always in the same order as the first time
- //we generated it
- csSQL.Format(
- _T("SELECT strClipBoardFormat FROM Data ")
- _T("INNER JOIN Main ON Main.lID = Data.lParentID ")
- _T("WHERE Main.lID = %d ORDER BY Data.lID desc"), lID);
- CppSQLite3Query q = theApp.m_db.execQuery(csSQL);
- while(q.eof() == false)
- {
- types.Add(GetFormatID(q.getStringField(0)));
- q.nextRow();
- }
- }
- CATCH_SQLITE_EXCEPTION
- }
|