#include "stdafx.h" #include "CP_Main.h" #include ".\clip_importexport.h" #include "shared/TextConvert.h" #include "sqlite/CppSQLite3.h" #include "zlib/zlib.h" #include "Misc.h" #define CURRENT_EXPORT_VERSION 1 CClip_ImportExport::CClip_ImportExport(void) : m_importCount(0) { } CClip_ImportExport::~CClip_ImportExport(void) { } bool CClip_ImportExport::ExportToSqliteDB(CppSQLite3DB &db) { bool bRet = false; try { //Add to Main Table m_Desc.Replace(_T("'"), _T("''")); db.execDMLEx(_T("insert into Main values(NULL, %d, '%s');"), CURRENT_EXPORT_VERSION, m_Desc); long lId = (long)db.lastRowId(); //Add to Data table CClipFormat* pCF; CppSQLite3Statement stmt = db.compileStatement(_T("insert into Data values (NULL, ?, ?, ?, ?);")); for(INT_PTR i = m_Formats.GetSize()-1; i >= 0 ; i--) { pCF = & m_Formats.ElementAt(i); stmt.bind(1, lId); stmt.bind(2, GetFormatName(pCF->m_cfType)); INT_PTR originalSize = GlobalSize(pCF->m_hgData); stmt.bind(3, (int)originalSize); const unsigned char *Data = (const unsigned char *)GlobalLock(pCF->m_hgData); if(Data) { //First compress the data INT_PTR zippedSize = compressBound((ULONG)originalSize); Bytef *pZipped = new Bytef[zippedSize]; if(pZipped) { INT_PTR zipReturn = compress(pZipped, (uLongf *)&zippedSize, (const Bytef *)Data, (ULONG)originalSize); if(zipReturn == Z_OK) { stmt.bind(4, pZipped, (int)zippedSize); } delete []pZipped; pZipped = NULL; } } GlobalUnlock(pCF->m_hgData); stmt.execDML(); stmt.reset(); m_Formats.RemoveAt(i); } bRet = true; } CATCH_SQLITE_EXCEPTION_AND_RETURN(false) return bRet; } bool CClip_ImportExport::ImportFromSqliteDB(CppSQLite3DB &db, bool bAddToDB, bool bPutOnClipboard) { bool bRet = false; CStringA csCF_TEXT; CStringW csCF_UNICODETEXT; try { CppSQLite3Query q = db.execQuery(_T("Select * from Main order by lId DESC")); while(q.eof() == false) { Clear(); int nVersion = q.getIntField(_T("lVersion")); if(nVersion == 1) { if(ImportFromSqliteV1(db, q)) { if(bAddToDB) { MakeLatestOrder(); AddToDB(true); bRet = true; } else if(bPutOnClipboard) { bRet = true; } } } m_importCount++; //If putting on the clipboard and there are multiple //then append cf_text and cf_unicodetext if(bPutOnClipboard) { Append_CF_TEXT_AND_CF_UNICODETEXT(csCF_TEXT, csCF_UNICODETEXT); } q.nextRow(); } if(bRet && bAddToDB) { theApp.RefreshView(); } else if(bRet && m_importCount == 1 && bPutOnClipboard) { PlaceFormatsOnclipboard(); } else if(bRet && bPutOnClipboard) { PlaceCF_TEXT_AND_CF_UNICODETEXT_OnClipboard(csCF_TEXT, csCF_UNICODETEXT); } } CATCH_SQLITE_EXCEPTION_AND_RETURN(false) return bRet; } bool CClip_ImportExport::PlaceCF_TEXT_AND_CF_UNICODETEXT_OnClipboard(CStringA &csCF_TEXT, CStringW &csCF_UNICODETEXT) { bool bRet = false; if(OpenClipboard(theApp.m_MainhWnd)) { EmptyClipboard(); if(csCF_TEXT.IsEmpty() == FALSE) { long lLen = csCF_TEXT.GetLength(); HGLOBAL hGlobal = NewGlobalP(csCF_TEXT.GetBuffer(lLen), lLen+1); csCF_TEXT.ReleaseBuffer(); SetClipboardData(CF_TEXT, hGlobal); bRet = true; } if(csCF_UNICODETEXT.IsEmpty() == FALSE) { long lLen = csCF_UNICODETEXT.GetLength() * sizeof(wchar_t); HGLOBAL hGlobal = NewGlobalP(csCF_UNICODETEXT.GetBuffer(lLen), lLen+1); csCF_UNICODETEXT.ReleaseBuffer(); SetClipboardData(CF_UNICODETEXT, hGlobal); bRet = true; } CloseClipboard(); } else { Log(_T("Error opening clipboard")); } return bRet; } bool CClip_ImportExport::PlaceFormatsOnclipboard() { bool bRet = false; if(OpenClipboard(theApp.m_MainhWnd)) { EmptyClipboard(); INT_PTR formatCount = m_Formats.GetSize(); for(int i = 0; i < formatCount; i++) { CClipFormat *pCF; pCF = &m_Formats.ElementAt(i); LPVOID Data = (LPVOID)GlobalLock(pCF->m_hgData); if(Data) { HGLOBAL hGlobal = NewGlobalP(Data, GlobalSize(pCF->m_hgData)); if(hGlobal) { SetClipboardData(pCF->m_cfType, hGlobal); } GlobalUnlock(pCF->m_hgData); } } CloseClipboard(); bRet = true; } else { Log(_T("PlaceFormatsOnclipboard::Error opening clipboard")); } return bRet; } bool CClip_ImportExport::ImportFromSqliteV1(CppSQLite3DB &db, CppSQLite3Query &qMain) { try { //Load the Main Table m_Desc = qMain.getStringField(_T("mText")); long lID = qMain.getIntField(_T("lID")); //Load the data Table CClipFormat cf; HGLOBAL hGlobal = 0; m_Formats.RemoveAll(); CString csSQL; csSQL.Format( _T("SELECT Data.* FROM Data ") _T("INNER JOIN Main ON Main.lID = Data.lParentID ") _T("WHERE Main.lID = %d ORDER BY Data.lID desc"), lID); CppSQLite3Query qData = db.execQuery(csSQL); while(qData.eof() == false) { cf.m_cfType = GetFormatID(qData.getStringField(_T("strClipBoardFormat"))); long lOriginalSize = qData.getIntField(_T("lOriginalSize")); int nDataLen = 0; const unsigned char *cData = qData.getBlobField(_T("ooData"), nDataLen); if(cData != NULL) { Bytef *pUnZippedData = new Bytef[lOriginalSize]; if(pUnZippedData) { //the data in the exported file is compressed so uncompress it now int nRet = uncompress(pUnZippedData, (uLongf *)&lOriginalSize, (Bytef *)cData, nDataLen); if(nRet == Z_OK) { cf.m_hgData = NewGlobalP(pUnZippedData, lOriginalSize); if(cf.m_hgData) { m_Formats.Add(cf); cf.m_hgData = NULL; //m_format owns m_hgData now } else { Log(StrF(_T("Error allocating NewGlobalP size = %d"), lOriginalSize)); ASSERT(FALSE); } } else { Log(_T("Error uncompressing data from zlib")); ASSERT(FALSE); } delete []pUnZippedData; pUnZippedData = NULL; } else { Log(StrF(_T("Error allocating memory to unzip size = %d"), lOriginalSize)); ASSERT(FALSE); } } qData.nextRow(); } } CATCH_SQLITE_EXCEPTION_AND_RETURN(false) return m_Formats.GetSize() > 0; } bool CClip_ImportExport::Append_CF_TEXT_AND_CF_UNICODETEXT(CStringA &csCF_TEXT, CStringW &csCF_UNICODETEXT) { bool bRet = false; CClipFormat *pCF; INT_PTR count = m_Formats.GetSize(); for(int i = 0; i < count; i++) { pCF = &m_Formats.ElementAt(i); switch(pCF->m_cfType) { case CF_TEXT: { if(csCF_TEXT.IsEmpty() == FALSE) csCF_TEXT += "\r\n"; csCF_TEXT += pCF->GetAsCStringA(); bRet = true; } break; case CF_UNICODETEXT: { if(csCF_UNICODETEXT.IsEmpty() == FALSE) csCF_UNICODETEXT += _T("\r\n"); csCF_UNICODETEXT += pCF->GetAsCString();; bRet = true; } break; } } return bRet; }