DittoCopyBuffer.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "stdafx.h"
  2. #include ".\dittocopybuffer.h"
  3. #include "CP_Main.h"
  4. #include <Mmsystem.h> //play sound
  5. CEvent CDittoCopyBuffer::m_ActiveTimer(TRUE, TRUE);
  6. CEvent CDittoCopyBuffer::m_RestoreTimer(TRUE, TRUE);
  7. CEvent CDittoCopyBuffer::m_RestoreActive(TRUE, TRUE);
  8. CDittoCopyBuffer CDittoCopyBuffer::m_Singleton;
  9. CDittoCopyBuffer::CDittoCopyBuffer()
  10. {
  11. m_bActive = false;
  12. m_dwLastPaste = 0;
  13. }
  14. CDittoCopyBuffer::~CDittoCopyBuffer(void)
  15. {
  16. }
  17. bool CDittoCopyBuffer::StartCopy(long lCopyBuffer, bool bCut)
  18. {
  19. Log(StrF(_T("Start of Ditto Copy buffer = %d"), lCopyBuffer));
  20. m_ActiveTimer.SetEvent();
  21. EndRestoreThread();
  22. m_bActive = true;
  23. m_lCurrentDittoBuffer = lCopyBuffer;
  24. m_SavedClipboard.Save();
  25. if(bCut)
  26. {
  27. theApp.SendCut();
  28. }
  29. else
  30. {
  31. theApp.SendCopy();
  32. }
  33. AfxBeginThread(CDittoCopyBuffer::StartCopyTimer, (LPVOID)this, THREAD_PRIORITY_LOWEST);
  34. return true;
  35. }
  36. UINT CDittoCopyBuffer::StartCopyTimer(LPVOID pParam)
  37. {
  38. m_ActiveTimer.ResetEvent();
  39. CDittoCopyBuffer *pBuffer = (CDittoCopyBuffer*)pParam;
  40. if(pBuffer)
  41. {
  42. DWORD dRes = WaitForSingleObject(m_ActiveTimer, 1500);
  43. if(dRes == WAIT_TIMEOUT)
  44. {
  45. pBuffer->m_bActive = false;
  46. }
  47. }
  48. return 0;
  49. }
  50. bool CDittoCopyBuffer::EndCopy(CClipList *pClips)
  51. {
  52. if(m_lCurrentDittoBuffer < 0 || m_lCurrentDittoBuffer >= 10)
  53. {
  54. Log(_T("tried to save copy buffer but copy buffer is empty"));
  55. return false;
  56. }
  57. m_ActiveTimer.SetEvent();
  58. m_bActive = false;
  59. Log(StrF(_T("Start - Ditto EndCopy buffer = %d"), m_lCurrentDittoBuffer));
  60. bool bRet = false;
  61. if(pClips)
  62. {
  63. m_SavedClipboard.Restore();
  64. try
  65. {
  66. CClip *pClip = pClips->GetHead();
  67. if(pClip)
  68. {
  69. int nCount = pClips->AddToDB(true);
  70. if(nCount > 0)
  71. {
  72. long lID = pClips->GetTail()->m_ID;
  73. theApp.OnCopyCompleted(lID, nCount);
  74. //enclose in brackets so the query closes before we update below
  75. {
  76. CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID FROM CopyBuffers WHERE lCopyBuffer = %d"), m_lCurrentDittoBuffer);
  77. if(q.eof())
  78. {
  79. theApp.m_db.execDMLEx(_T("INSERT INTO CopyBuffers VALUES(NULL, -1, %d);"), m_lCurrentDittoBuffer);
  80. }
  81. }
  82. theApp.m_db.execDMLEx(_T("UPDATE CopyBuffers SET lClipID = %d WHERE lCopyBuffer = %d"), lID, m_lCurrentDittoBuffer);
  83. bRet = true;
  84. Log(StrF(_T("Ditto end copy, saved clip successfully Clip ID = %d"), lID));
  85. PlaySound(_T("ding.wav"), NULL, SND_FILENAME|SND_ASYNC);
  86. }
  87. else
  88. {
  89. Log(_T("Error saving Ditto Buffer to Database"));
  90. }
  91. }
  92. else
  93. {
  94. Log(_T("Error getting clip from cliplist"));
  95. }
  96. }
  97. catch (CppSQLite3Exception& e)
  98. {
  99. Log(StrF(_T("SQLITE Exception %d - %s"), e.errorCode(), e.errorMessage()));
  100. ASSERT(FALSE);
  101. }
  102. }
  103. else
  104. {
  105. Log(_T("Ditto Buffer Ditto did not receive a copy"));
  106. }
  107. return bRet;
  108. }
  109. bool CDittoCopyBuffer::PastCopyBuffer(long lCopyBuffer)
  110. {
  111. DWORD dNow = GetTickCount();
  112. if(((dNow - m_dwLastPaste) < 500) || (dNow < m_dwLastPaste))
  113. {
  114. Log(_T("Copy Buffer pasted to fast"));
  115. return false;
  116. }
  117. m_dwLastPaste = GetTickCount();
  118. bool bRet = false;
  119. Log(StrF(_T("Start - PastCopyBuffer buffer = %d"), m_lCurrentDittoBuffer));
  120. try
  121. {
  122. CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT Main.lID FROM Main ")
  123. _T("INNER JOIN CopyBuffers ON CopyBuffers.lClipID = Main.lID ")
  124. _T("WHERE CopyBuffers.lCopyBuffer = %d"), lCopyBuffer);
  125. if(q.eof() == false)
  126. {
  127. CClipboardSaveRestoreCopyBuffer *pClipboard = new CClipboardSaveRestoreCopyBuffer;
  128. if(pClipboard)
  129. {
  130. EndRestoreThread();
  131. if(pClipboard->Save())
  132. {
  133. CProcessPaste paste;
  134. paste.m_bSendPaste = true;
  135. paste.m_bActivateTarget = false;
  136. paste.GetClipIDs().Add(q.getIntField(_T("lID")));
  137. paste.DoPaste();
  138. pClipboard->m_lRestoreDelay = g_Opt.GetDittoRestoreClipboardDelay();
  139. Log(StrF(_T("PastCopyBuffer sent paste, starting thread to restore clipboard, Delay = %d"), pClipboard->m_lRestoreDelay));
  140. AfxBeginThread(CDittoCopyBuffer::DelayRestoreClipboard, (LPVOID)pClipboard, THREAD_PRIORITY_LOWEST);
  141. bRet = true;
  142. }
  143. else
  144. {
  145. Log(_T("PastCopyBuffer failed to save clipboard"));
  146. }
  147. }
  148. }
  149. }
  150. CATCH_SQLITE_EXCEPTION
  151. return bRet;
  152. }
  153. void CDittoCopyBuffer::EndRestoreThread()
  154. {
  155. //Tell the thread to stop waiting and restore the clipboard
  156. m_RestoreTimer.SetEvent();
  157. //make sure it's ended
  158. WaitForSingleObject(m_RestoreActive, 5000);
  159. }
  160. UINT CDittoCopyBuffer::DelayRestoreClipboard(LPVOID pParam)
  161. {
  162. m_RestoreTimer.ResetEvent();
  163. m_RestoreActive.ResetEvent();
  164. CClipboardSaveRestoreCopyBuffer *pClipboard = (CClipboardSaveRestoreCopyBuffer*)pParam;
  165. if(pClipboard)
  166. {
  167. DWORD dRes = WaitForSingleObject(m_RestoreTimer, pClipboard->m_lRestoreDelay);
  168. if(GetKeyState(VK_SHIFT) & 0x8000)
  169. {
  170. Log(_T("Shift key is down not restoring clipbard, custom Buffer on normal clipboard"));
  171. }
  172. else
  173. {
  174. pClipboard->Restore();
  175. }
  176. delete pClipboard;
  177. pClipboard = NULL;
  178. }
  179. m_RestoreActive.SetEvent();
  180. return TRUE;
  181. }