Преглед изворни кода

start of multiple copy buffers

git-svn-id: svn://svn.code.sf.net/p/ditto-cp/code/trunk@364 595ec19a-5cb4-439b-94a8-42fb3063c22c
sabrogden пре 19 година
родитељ
комит
2c1ac8e1d7
11 измењених фајлова са 375 додато и 84 уклоњено
  1. 45 10
      CP_Main.cpp
  2. 11 2
      CP_Main.h
  3. 32 2
      CP_Main.vcproj
  4. 4 2
      Client.cpp
  5. 11 11
      Clip.cpp
  6. 40 1
      CopyThread.cpp
  7. 32 1
      DatabaseUtilities.cpp
  8. 132 0
      DittoCopyBuffer.cpp
  9. 30 0
      DittoCopyBuffer.h
  10. 36 53
      MainFrm.cpp
  11. 2 2
      MainFrm.h

+ 45 - 10
CP_Main.cpp

@@ -127,12 +127,12 @@ CCP_MainApp::CCP_MainApp()
 	m_pQuickPasteClip = NULL;
 	m_pQuickPasteClip = NULL;
 	m_bDittoHasFocus = false;
 	m_bDittoHasFocus = false;
 
 
-	::InitializeCriticalSection(&m_CriticalSection);
+	m_pDittoCopyBuffer = NULL;
 }
 }
 
 
 CCP_MainApp::~CCP_MainApp()
 CCP_MainApp::~CCP_MainApp()
 {
 {
-	::DeleteCriticalSection(&m_CriticalSection);
+	
 }
 }
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
@@ -438,23 +438,22 @@ void CCP_MainApp::SendPaste(bool bActivateTarget)
 		return;
 		return;
 	}
 	}
 
 
-	MSG KeyboardMsg;
-	while (::PeekMessage(&KeyboardMsg, NULL, 0, 0, PM_REMOVE))
-	{
-		::TranslateMessage(&KeyboardMsg);
-		::DispatchMessage(&KeyboardMsg);
-    }
+	PumpMessageEx();
 
 
-	Sleep(50);
+	Sleep(1);
 
 
 	keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
 	keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
 	keybd_event('V', 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
 	keybd_event('V', 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
 
 
-	Sleep(50);
+	Sleep(1);
+
+	PumpMessageEx();
 
 
 	keybd_event('V', 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
 	keybd_event('V', 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
 	keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
 	keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
 
 
+	PumpMessageEx();
+
 	Log(_T("END SendPaste"));
 	Log(_T("END SendPaste"));
 }
 }
 
 
@@ -630,6 +629,15 @@ long CCP_MainApp::SaveCopyClips()
 		//go ahead and send the clips out even though it won't be added for a bit
 		//go ahead and send the clips out even though it won't be added for a bit
 		count = 1;
 		count = 1;
 	}
 	}
+	else if(m_QuickPasteMode == DITTO_BUFFER_QUICK_PASTE && m_pDittoCopyBuffer != NULL)
+	{
+		m_pDittoCopyBuffer->EndCopy(pClips);
+		
+		ClearDittoCopyBuffer();
+
+		//go ahead and send the clips out even though it won't be added for a bit
+		count = 1;
+	}
 	else
 	else
 	{
 	{
 		count = pClips->AddToDB(true);
 		count = pClips->AddToDB(true);
@@ -1085,4 +1093,31 @@ int CCP_MainApp::ShowOptionsDlg()
 	}
 	}
 
 
 	return nRet;
 	return nRet;
+}
+
+void CCP_MainApp::CreateDittoCopyBuffer(long lCopyBuffer)
+{
+	m_pDittoCopyBuffer = new CDittoCopyBuffer();
+	if(m_pDittoCopyBuffer)
+	{
+		m_pDittoCopyBuffer->StartCopy(lCopyBuffer);
+	}
+}
+
+void CCP_MainApp::ClearDittoCopyBuffer()
+{
+	delete m_pDittoCopyBuffer;
+	m_pDittoCopyBuffer = NULL;
+
+	theApp.m_QuickPasteMode = CCP_MainApp::NONE_QUICK_PASTE;
+}
+
+void CCP_MainApp::PumpMessageEx()
+{
+	MSG KeyboardMsg;
+	while (::PeekMessage(&KeyboardMsg, NULL, 0, 0, PM_REMOVE))
+	{
+		::TranslateMessage(&KeyboardMsg);
+		::DispatchMessage(&KeyboardMsg);
+	}
 }
 }

+ 11 - 2
CP_Main.h

@@ -22,6 +22,8 @@
 #include "ProcessPaste.h"
 #include "ProcessPaste.h"
 #include "MultiLanguage.h"
 #include "MultiLanguage.h"
 #include "CopyThread.h"
 #include "CopyThread.h"
+#include "ClipboardSaveRestore.h"
+#include "DittoCopyBuffer.h"
 
 
 #include "sqlite\CppSQLite3.h"
 #include "sqlite\CppSQLite3.h"
 
 
@@ -149,7 +151,6 @@ public:
 
 
 	//Socket Info
 	//Socket Info
 	SOCKET	m_sSocket;
 	SOCKET	m_sSocket;
-	CRITICAL_SECTION m_CriticalSection;
 	void	StartStopServerThread();
 	void	StartStopServerThread();
 	void	StopServerThread();
 	void	StopServerThread();
 
 
@@ -169,13 +170,21 @@ public:
 	//Mulitlange Support
 	//Mulitlange Support
 	CMultiLanguage m_Language;
 	CMultiLanguage m_Language;
 
 
-	enum eQuickPasteMode{NONE_QUICK_PASTE, ADDING_QUICK_PASTE, PASTING_QUICK_PASTE};
+	enum eQuickPasteMode{NONE_QUICK_PASTE, ADDING_QUICK_PASTE, PASTING_QUICK_PASTE, DITTO_BUFFER_QUICK_PASTE};
 
 
 	eQuickPasteMode m_QuickPasteMode;
 	eQuickPasteMode m_QuickPasteMode;
 	CClipList* m_pQuickPasteClip;
 	CClipList* m_pQuickPasteClip;
 
 
+	void CreateDittoCopyBuffer(long lCopyBuffer);
+	void ClearDittoCopyBuffer();
+	
 	bool m_bDittoHasFocus;
 	bool m_bDittoHasFocus;
 
 
+	void PumpMessageEx();
+
+protected:
+	CDittoCopyBuffer *m_pDittoCopyBuffer;
+
 // Overrides
 // Overrides
 	// ClassWizard generated virtual function overrides
 	// ClassWizard generated virtual function overrides
 	//{{AFX_VIRTUAL(CCP_MainApp)
 	//{{AFX_VIRTUAL(CCP_MainApp)

+ 32 - 2
CP_Main.vcproj

@@ -795,6 +795,33 @@
 						BasicRuntimeChecks="3"/>
 						BasicRuntimeChecks="3"/>
 				</FileConfiguration>
 				</FileConfiguration>
 			</File>
 			</File>
+			<File
+				RelativePath=".\DittoCopyBuffer.cpp">
+				<FileConfiguration
+					Name="Release|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Unicode Release|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Unicode Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+				</FileConfiguration>
+			</File>
 			<File
 			<File
 				RelativePath=".\DittoRulerRichEditCtrl.cpp">
 				RelativePath=".\DittoRulerRichEditCtrl.cpp">
 			</File>
 			</File>
@@ -2633,6 +2660,9 @@
 			<File
 			<File
 				RelativePath="DialogResizer.h">
 				RelativePath="DialogResizer.h">
 			</File>
 			</File>
+			<File
+				RelativePath=".\DittoCopyBuffer.h">
+			</File>
 			<File
 			<File
 				RelativePath=".\DittoRulerRichEditCtrl.h">
 				RelativePath=".\DittoRulerRichEditCtrl.h">
 			</File>
 			</File>
@@ -2897,7 +2927,7 @@
 				</FileConfiguration>
 				</FileConfiguration>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="Debug\focus.dll">
+				RelativePath="Release\focus.dll">
 				<FileConfiguration
 				<FileConfiguration
 					Name="Release|Win32"
 					Name="Release|Win32"
 					ExcludedFromBuild="TRUE">
 					ExcludedFromBuild="TRUE">
@@ -2924,7 +2954,7 @@
 				</FileConfiguration>
 				</FileConfiguration>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="Release\focus.dll">
+				RelativePath="Debug\focus.dll">
 				<FileConfiguration
 				<FileConfiguration
 					Name="Release|Win32"
 					Name="Release|Win32"
 					ExcludedFromBuild="TRUE">
 					ExcludedFromBuild="TRUE">

+ 4 - 2
Client.cpp

@@ -90,15 +90,17 @@ BOOL SendToFriend(CSendToFriendInfo &Info)
 	return TRUE;
 	return TRUE;
 }
 }
 
 
+CCriticalSection SendClientCritSection;
 UINT  SendClientThread(LPVOID pParam)
 UINT  SendClientThread(LPVOID pParam)
 {	
 {	
-	EnterCriticalSection(&theApp.m_CriticalSection);
+	SendClientCritSection.Lock();
 
 
 	LogSendRecieveInfo("@@@@@@@@@@@@@@@ - START OF SendClientThread - @@@@@@@@@@@@@@@");
 	LogSendRecieveInfo("@@@@@@@@@@@@@@@ - START OF SendClientThread - @@@@@@@@@@@@@@@");
 
 
 	CClipList *pClipList = (CClipList*)pParam;
 	CClipList *pClipList = (CClipList*)pParam;
 	if(pClipList == NULL)
 	if(pClipList == NULL)
 	{
 	{
+		SendClientCritSection.Unlock();
 		LogSendRecieveInfo("ERROR if(pClipList == NULL)");
 		LogSendRecieveInfo("ERROR if(pClipList == NULL)");
 		return FALSE;
 		return FALSE;
 	}
 	}
@@ -167,7 +169,7 @@ UINT  SendClientThread(LPVOID pParam)
 	
 	
 	LogSendRecieveInfo("@@@@@@@@@@@@@@@ - END OF SendClientThread - @@@@@@@@@@@@@@@");
 	LogSendRecieveInfo("@@@@@@@@@@@@@@@ - END OF SendClientThread - @@@@@@@@@@@@@@@");
 
 
-	LeaveCriticalSection(&theApp.m_CriticalSection);
+	SendClientCritSection.Unlock();
 
 
 	return TRUE;
 	return TRUE;
 }
 }

+ 11 - 11
Clip.cpp

@@ -185,6 +185,7 @@ void CClip::Clear()
 	m_lShortCut = 0;
 	m_lShortCut = 0;
 	m_bIsGroup = FALSE;
 	m_bIsGroup = FALSE;
 	m_csQuickPaste = "";
 	m_csQuickPaste = "";
+	
 	EmptyFormats();
 	EmptyFormats();
 }
 }
 
 
@@ -491,18 +492,15 @@ bool CClip::AddToDB(bool bCheckForDuplicates)
 			int nID = FindDuplicate();
 			int nID = FindDuplicate();
 			if(nID >= 0)
 			if(nID >= 0)
 			{
 			{
-				m_csQuickPaste.Replace(_T("'"), _T("''"));
-
-				if(m_csQuickPaste.IsEmpty())
+				CString csQuickPasteSQL;
+				if(m_csQuickPaste.IsEmpty() == FALSE)
 				{
 				{
-					theApp.m_db.execDMLEx(_T("UPDATE Main SET lDate = %d where lID = %d;"), 
-											(long)m_Time.GetTime(), nID);
-				}
-				else
-				{		
-					theApp.m_db.execDMLEx(_T("UPDATE Main SET lDate = %d, QuickPasteText = '%s' where lID = %d;"), 
-											(long)m_Time.GetTime(), m_csQuickPaste, nID);
+					m_csQuickPaste.Replace(_T("'"), _T("''"));
+					csQuickPasteSQL.Format(_T(", QuickPasteText = '%s'"), m_csQuickPaste);
 				}
 				}
+
+				theApp.m_db.execDMLEx(_T("UPDATE Main SET lDate = %d%s where lID = %d;"), 
+										(long)m_Time.GetTime(), csQuickPasteSQL, nID);
 				
 				
 				EmptyFormats();
 				EmptyFormats();
 
 
@@ -597,7 +595,7 @@ bool CClip::AddToMainTable()
 		m_csQuickPaste.Replace(_T("'"), _T("''"));
 		m_csQuickPaste.Replace(_T("'"), _T("''"));
 
 
 		CString cs;
 		CString cs;
-		cs.Format(_T("insert into Main values(NULL, %d, '%s', %d, %d, %d, %d, %d, '%s');"),
+		cs.Format(_T("INSERT into Main values(NULL, %d, '%s', %d, %d, %d, %d, %d, '%s');"),
 							(long)m_Time.GetTime(),
 							(long)m_Time.GetTime(),
 							m_Desc,
 							m_Desc,
 							m_lShortCut,
 							m_lShortCut,
@@ -632,6 +630,7 @@ bool CClip::ModifyMainTable()
 			_T("lParentID = %d, ")
 			_T("lParentID = %d, ")
 			_T("lDontAutoDelete = %d, ")
 			_T("lDontAutoDelete = %d, ")
 			_T("QuickPasteText = '%s' ")
 			_T("QuickPasteText = '%s' ")
+			_T("CopyBuffer = %d ")
 			_T("WHERE lID = %d;"), 
 			_T("WHERE lID = %d;"), 
 			m_lShortCut, 
 			m_lShortCut, 
 			m_Desc, 
 			m_Desc, 
@@ -717,6 +716,7 @@ BOOL CClip::LoadMainTable(long lID)
 			m_lShortCut = q.getIntField(_T("lShortCut"));
 			m_lShortCut = q.getIntField(_T("lShortCut"));
 			m_bIsGroup = q.getIntField(_T("bIsGroup"));
 			m_bIsGroup = q.getIntField(_T("bIsGroup"));
 			m_csQuickPaste = q.getStringField(_T("QuickPasteText"));
 			m_csQuickPaste = q.getStringField(_T("QuickPasteText"));
+
 			m_ID = lID;
 			m_ID = lID;
 		}
 		}
 	}
 	}

+ 40 - 1
CopyThread.cpp

@@ -73,7 +73,46 @@ void CCopyThread::OnClipboardChange()
 		return;
 		return;
 	
 	
 	CClip* pClip = new CClip;
 	CClip* pClip = new CClip;
-	bool bResult = pClip->LoadFromClipboard(m_LocalConfig.m_pSupportedTypes);
+
+	CClipTypes* pSupportedTypes = m_LocalConfig.m_pSupportedTypes;
+	bool bDeleteMemory = false;
+
+	//If we are copying from a Ditto Buffer then save all to the database, so when we paste this it will paste 
+	//just like you were using Ctrl-V
+	if(theApp.m_QuickPasteMode == CCP_MainApp::DITTO_BUFFER_QUICK_PASTE)
+	{
+		pSupportedTypes = new CClipTypes;
+		if(pSupportedTypes)
+		{
+			bDeleteMemory = true;
+			COleDataObject oleData;
+
+			if(oleData.AttachClipboard())
+			{
+				oleData.BeginEnumFormats();
+
+				FORMATETC format;
+				while(oleData.GetNextFormat(&format))
+				{
+					pSupportedTypes->Add(format.cfFormat);
+				}
+
+				oleData.Release();
+			}
+		}
+		else
+		{
+			pSupportedTypes = m_LocalConfig.m_pSupportedTypes;
+		}
+	}
+
+	bool bResult = pClip->LoadFromClipboard(pSupportedTypes);
+
+	if(bDeleteMemory)
+	{
+		delete pSupportedTypes;
+		pSupportedTypes = NULL;
+	}
 	
 	
 	if(!bResult)
 	if(!bResult)
 	{
 	{

+ 32 - 1
DatabaseUtilities.cpp

@@ -230,6 +230,26 @@ BOOL ValidDB(CString csPath, BOOL bUpgrade)
  		{
  		{
  			e.errorCode();
  			e.errorCode();
  		}
  		}
+
+		//This was added later so try to add each time and catch the exception here
+		try
+		{
+			db.execQuery(_T("SELECT lID, lClipID, lCopyBuffer FROM CopyBuffers"));
+		}
+		catch(CppSQLite3Exception& e)
+		{
+			e.errorCode();
+
+			db.execDML(_T("CREATE TABLE CopyBuffers(")
+				_T("lID INTEGER PRIMARY KEY AUTOINCREMENT, ")
+				_T("lClipID INTEGER,")
+				_T("lCopyBuffer INTEGER)"));
+
+			db.execDML(_T("CREATE TRIGGER delete_copy_buffer_trigger BEFORE DELETE ON Main FOR EACH ROW\n")
+				_T("BEGIN\n")
+				_T("DELETE FROM CopyBuffers WHERE lClipID = old.lID;\n")
+				_T("END\n"));
+		}
 	}
 	}
 	CATCH_SQLITE_EXCEPTION_AND_RETURN(FALSE)
 	CATCH_SQLITE_EXCEPTION_AND_RETURN(FALSE)
 
 
@@ -252,7 +272,7 @@ BOOL CreateDB(CString csPath)
 								_T("CRC INTEGER, ")
 								_T("CRC INTEGER, ")
 								_T("bIsGroup INTEGER, ")
 								_T("bIsGroup INTEGER, ")
 								_T("lParentID INTEGER, ")
 								_T("lParentID INTEGER, ")
-								_T("QuickPasteText TEXT);"));
+								_T("QuickPasteText TEXT)"));
 
 
 		db.execDML(_T("CREATE TABLE Data(")
 		db.execDML(_T("CREATE TABLE Data(")
 							_T("lID INTEGER PRIMARY KEY AUTOINCREMENT, ")
 							_T("lID INTEGER PRIMARY KEY AUTOINCREMENT, ")
@@ -272,6 +292,17 @@ BOOL CreateDB(CString csPath)
 						_T("BEGIN\n")
 						_T("BEGIN\n")
 							_T("DELETE FROM Data WHERE lParentID = old.lID;\n")
 							_T("DELETE FROM Data WHERE lParentID = old.lID;\n")
 						_T("END\n"));
 						_T("END\n"));
+
+		db.execDML(_T("CREATE TABLE CopyBuffers(")
+			_T("lID INTEGER PRIMARY KEY AUTOINCREMENT, ")
+			_T("lClipID INTEGER, ")
+			_T("lCopyBuffer INTEGER)"));
+
+		db.execDML(_T("CREATE TRIGGER delete_copy_buffer_trigger BEFORE DELETE ON Main FOR EACH ROW\n")
+			_T("BEGIN\n")
+			_T("DELETE FROM CopyBuffers WHERE lClipID = old.lID;\n")
+			_T("END\n"));
+
 		db.close();
 		db.close();
 	}
 	}
 	CATCH_SQLITE_EXCEPTION_AND_RETURN(FALSE)
 	CATCH_SQLITE_EXCEPTION_AND_RETURN(FALSE)

+ 132 - 0
DittoCopyBuffer.cpp

@@ -0,0 +1,132 @@
+#include "stdafx.h"
+#include ".\dittocopybuffer.h"
+#include "CP_Main.h"
+
+CDittoCopyBuffer::CDittoCopyBuffer()
+{
+}
+
+CDittoCopyBuffer::~CDittoCopyBuffer(void)
+{
+}
+
+
+bool CDittoCopyBuffer::StartCopy(long lCopyBuffer)
+{
+	m_lCurrentDittoBuffer = lCopyBuffer;
+	m_SavedClipboard.Save();
+	theApp.SendCopy();
+
+	return true;
+}
+
+bool CDittoCopyBuffer::EndCopy(CClipList *pClips)
+{
+	if(m_lCurrentDittoBuffer < 0 || m_lCurrentDittoBuffer >= 10)
+	{
+		Log(_T("tried to save copy buffer but copy buffer is empty"));
+		return false;
+	}
+
+	m_SavedClipboard.Restore();
+
+	bool bRet = false;
+
+	if(pClips)
+	{
+		try
+		{	
+			CClip *pClip = pClips->GetHead();
+			if(pClip)
+			{
+				int nCount = pClips->AddToDB(true);
+				if(nCount > 0)
+				{
+					long lID = pClips->GetTail()->m_ID;
+					theApp.OnCopyCompleted(lID, nCount);
+
+					//enclose in brackets so the query closes before we update below
+					{
+						CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID FROM CopyBuffers WHERE lCopyBuffer = %d"), m_lCurrentDittoBuffer);
+						if(q.eof())
+						{
+							theApp.m_db.execDMLEx(_T("INSERT INTO CopyBuffers VALUES(NULL, -1, %d);"), m_lCurrentDittoBuffer);
+						}
+					}
+
+					theApp.m_db.execDMLEx(_T("UPDATE CopyBuffers SET lClipID = %d WHERE lCopyBuffer = %d"), lID, m_lCurrentDittoBuffer);
+
+					bRet = true;
+				}
+				else
+				{
+					Log(_T("Error saving Ditto Buffer to Database"));
+				}
+			}
+			else
+			{
+				Log(_T("Error getting clip from cliplist"));
+			}
+		}
+		catch (CppSQLite3Exception& e)
+		{
+			Log(StrF(_T("SQLITE Exception %d - %s"), e.errorCode(), e.errorMessage()));
+			ASSERT(FALSE);
+		}	
+	}
+	else
+	{
+		Log(_T("Ditto Buffer Ditto did not receive a copy"));
+	}
+
+	return bRet;
+}
+
+bool CDittoCopyBuffer::PastCopyBuffer(long lCopyBuffer)
+{
+	bool bRet = false;
+
+	try
+	{
+		CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT Main.lID FROM Main ")
+													_T("INNER JOIN CopyBuffers ON CopyBuffers.lClipID = Main.lID ")
+													_T("WHERE CopyBuffers.lCopyBuffer = %d"), lCopyBuffer);
+
+		if(q.eof() == false)
+		{
+			CClipboardSaveRestoreCopyBuffer *pClipboard = new CClipboardSaveRestoreCopyBuffer;
+			if(pClipboard)
+			{
+				pClipboard->Save();
+
+				CProcessPaste paste;
+				paste.m_bSendPaste = true;
+				paste.m_bActivateTarget = false;
+				paste.GetClipIDs().Add(q.getIntField(_T("lID")));
+				paste.DoPaste();
+
+				pClipboard->m_lRestoreDelay = g_Opt.GetDittoRestoreClipboardDelay();
+
+				AfxBeginThread(CDittoCopyBuffer::DelayRestoreClipboard, (LPVOID)pClipboard, THREAD_PRIORITY_LOWEST);
+
+				bRet = true;
+			}
+		}
+	}
+	CATCH_SQLITE_EXCEPTION
+
+	return bRet;
+}
+
+UINT CDittoCopyBuffer::DelayRestoreClipboard(LPVOID pParam)
+{
+	CClipboardSaveRestoreCopyBuffer *pClipboard = (CClipboardSaveRestoreCopyBuffer*)pParam;
+
+	if(pClipboard)
+	{
+		Sleep(pClipboard->m_lRestoreDelay);
+		pClipboard->Restore();
+	}
+
+	return TRUE;
+}

+ 30 - 0
DittoCopyBuffer.h

@@ -0,0 +1,30 @@
+#pragma once
+
+#include "ClipboardSaveRestore.h"
+
+class CClipboardSaveRestoreCopyBuffer : public CClipboardSaveRestore
+{
+public:
+	CClipboardSaveRestoreCopyBuffer()
+	{
+		m_lRestoreDelay = 0;
+	}
+	long m_lRestoreDelay;
+};
+
+class CDittoCopyBuffer
+{
+public:
+	CDittoCopyBuffer();
+	~CDittoCopyBuffer(void);
+
+	bool StartCopy(long lCopyBuffer);
+	bool EndCopy(CClipList *pClips);
+
+	bool PastCopyBuffer(long lCopyBuffer);
+	static UINT DelayRestoreClipboard(LPVOID pParam);
+
+protected:
+	long m_lCurrentDittoBuffer;
+	CClipboardSaveRestore m_SavedClipboard;
+};

+ 36 - 53
MainFrm.cpp

@@ -13,6 +13,7 @@
 #include "HyperLink.h"
 #include "HyperLink.h"
 #include "tinyxml.h"
 #include "tinyxml.h"
 #include "Path.h"
 #include "Path.h"
+#include "DittoCopyBuffer.h"
 
 
 #ifdef _DEBUG
 #ifdef _DEBUG
 #define new DEBUG_NEW
 #define new DEBUG_NEW
@@ -252,66 +253,19 @@ LRESULT CMainFrame::OnHotKey(WPARAM wParam, LPARAM lParam)
 	{
 	{
 		if(theApp.m_QuickPasteMode == CCP_MainApp::NONE_QUICK_PASTE)
 		if(theApp.m_QuickPasteMode == CCP_MainApp::NONE_QUICK_PASTE)
 		{
 		{
-			theApp.m_QuickPasteMode = CCP_MainApp::ADDING_QUICK_PASTE;
-
-			theApp.SendCopy();
-
-			m_pTypingToolTip = new CToolTipEx;
-			m_pTypingToolTip->Create(this);
-
-			csTypeToolTipTitle = theApp.m_Language.GetString("Named_Copy_Title", "Ditto - Named Copy");
-
-			m_pTypingToolTip->SetToolTipText(csTypeToolTipTitle);
-
-			CRect rcScreen;
-			GetMonitorRect(0, &rcScreen);
-
-			m_ToolTipPoint = GetFocusedCaretPos();
-			if(m_ToolTipPoint.x < 0 || m_ToolTipPoint.y < 0)
-			{
-				CRect cr;
-				::GetWindowRect(theApp.m_hTargetWnd, cr);
-				m_ToolTipPoint = cr.CenterPoint();
-			}
-			m_ToolTipPoint.Offset(-15, 15);
-			m_pTypingToolTip->Show(m_ToolTipPoint);
-
-			//If they don't type anything for 2 seconds stop looking
-			SetTimer(STOP_LOOKING_FOR_KEYBOARD, 20000, NULL);
+			theApp.m_QuickPasteMode = CCP_MainApp::DITTO_BUFFER_QUICK_PASTE;
+			
+			theApp.CreateDittoCopyBuffer(1);
 
 
-			MonitorKeyboardChanges(m_hWnd, WM_FOCUS_CHANGED+1);
-			SetCaptureKeys(true);
+			SetTimer(END_DITTO_BUFFER_CLIPBOARD_TIMER, 2000, NULL);
 		}
 		}
 	}
 	}
 	else if(!g_Opt.m_bU3 && wParam == theApp.m_pNamedPaste->m_Atom)
 	else if(!g_Opt.m_bU3 && wParam == theApp.m_pNamedPaste->m_Atom)
 	{
 	{
 		if(theApp.m_QuickPasteMode == CCP_MainApp::NONE_QUICK_PASTE)
 		if(theApp.m_QuickPasteMode == CCP_MainApp::NONE_QUICK_PASTE)
 		{
 		{
-			theApp.m_QuickPasteMode = CCP_MainApp::PASTING_QUICK_PASTE;
-
-			m_pTypingToolTip = new CToolTipEx;
-			m_pTypingToolTip->Create(this);
-
-			csTypeToolTipTitle = theApp.m_Language.GetString("Named_Paste_Title", "Ditto - Named Paste");
-			m_pTypingToolTip->SetToolTipText(csTypeToolTipTitle);
-
-			CRect rcScreen;
-
-			m_ToolTipPoint = GetFocusedCaretPos();
-			if(m_ToolTipPoint.x < 0 || m_ToolTipPoint.y < 0)
-			{
-				CRect cr;
-				::GetWindowRect(theApp.m_hTargetWnd, cr);
-				m_ToolTipPoint = cr.CenterPoint();
-			}
-			m_ToolTipPoint.Offset(-15, 15);
-			m_pTypingToolTip->Show(m_ToolTipPoint);
-			
-			//If they don't type anything for 2 seconds stop looking
-			SetTimer(STOP_LOOKING_FOR_KEYBOARD, 20000, NULL);
-
-			MonitorKeyboardChanges(m_hWnd, WM_FOCUS_CHANGED+1);
-			SetCaptureKeys(true);
+			CDittoCopyBuffer Past;
+			Past.PastCopyBuffer(1);
 		}
 		}
 	}
 	}
 	else if(wParam == theApp.m_pPosOne->m_Atom)
 	else if(wParam == theApp.m_pPosOne->m_Atom)
@@ -389,6 +343,30 @@ void CMainFrame::DoFirstTenPositionsPaste(int nPos)
 	CATCH_SQLITE_EXCEPTION
 	CATCH_SQLITE_EXCEPTION
 }
 }
 
 
+void CMainFrame::DoDittoCopyBufferPaste(int nCopyBuffer)
+{
+	try
+	{	
+		CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID FROM Main WHERE CopyBuffer = %d"), nCopyBuffer);
+
+		if(q.eof() == false)
+		{	
+			//Don't move these to the top
+			BOOL bItWas = g_Opt.m_bUpdateTimeOnPaste;
+			g_Opt.m_bUpdateTimeOnPaste = FALSE;
+
+			CProcessPaste paste;
+			paste.GetClipIDs().Add(q.getIntField(_T("lID")));
+			paste.m_bActivateTarget = false;
+			paste.DoPaste();
+			theApp.OnPasteCompleted();
+
+			g_Opt.m_bUpdateTimeOnPaste = bItWas;
+		}
+	}
+	CATCH_SQLITE_EXCEPTION
+}
+
 void CMainFrame::OnTimer(UINT nIDEvent) 
 void CMainFrame::OnTimer(UINT nIDEvent) 
 {
 {
 	switch(nIDEvent)
 	switch(nIDEvent)
@@ -467,6 +445,11 @@ void CMainFrame::OnTimer(UINT nIDEvent)
 	case REMOVE_OLD_REMOTE_COPIES:
 	case REMOVE_OLD_REMOTE_COPIES:
 		AfxBeginThread(CMainFrame::RemoteOldRemoteFilesThread, NULL);
 		AfxBeginThread(CMainFrame::RemoteOldRemoteFilesThread, NULL);
 		break;
 		break;
+
+	case END_DITTO_BUFFER_CLIPBOARD_TIMER:
+		KillTimer(END_DITTO_BUFFER_CLIPBOARD_TIMER);
+		theApp.ClearDittoCopyBuffer();
+		break;
 	}
 	}
 
 
 	CFrameWnd::OnTimer(nIDEvent);
 	CFrameWnd::OnTimer(nIDEvent);

+ 2 - 2
MainFrm.h

@@ -23,7 +23,7 @@
 #define STOP_MONITORING_KEYBOARD_TIMER	7
 #define STOP_MONITORING_KEYBOARD_TIMER	7
 #define STOP_LOOKING_FOR_KEYBOARD		8
 #define STOP_LOOKING_FOR_KEYBOARD		8
 #define REMOVE_OLD_REMOTE_COPIES		9
 #define REMOVE_OLD_REMOTE_COPIES		9
-
+#define END_DITTO_BUFFER_CLIPBOARD_TIMER	10
 
 
 class CMainFrame : public CFrameWnd
 class CMainFrame : public CFrameWnd
 {
 {
@@ -65,7 +65,7 @@ public:
 	CPoint m_ToolTipPoint;
 	CPoint m_ToolTipPoint;
 	CAlphaBlend m_Transparency;
 	CAlphaBlend m_Transparency;
 
 
-
+	void DoDittoCopyBufferPaste(int nCopyBuffer);
 	void DoFirstTenPositionsPaste(int nPos);
 	void DoFirstTenPositionsPaste(int nPos);
 	void StopLookingForKeystrokes(bool bInitAppVaribles);
 	void StopLookingForKeystrokes(bool bInitAppVaribles);
 	bool PasteQuickPasteEntry(CString csQuickPaste);
 	bool PasteQuickPasteEntry(CString csQuickPaste);