DittoCopyBuffer.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #include "stdafx.h"
  2. #include ".\dittocopybuffer.h"
  3. #include "CP_Main.h"
  4. #include <Mmsystem.h> //play sound
  5. CDittoCopyBuffer::CDittoCopyBuffer() :
  6. m_ActiveTimer(TRUE, TRUE),
  7. m_RestoreTimer(TRUE, TRUE),
  8. m_RestoreActive(TRUE, TRUE)
  9. {
  10. m_bActive = false;
  11. m_dwLastPaste = 0;
  12. }
  13. CDittoCopyBuffer::~CDittoCopyBuffer(void)
  14. {
  15. }
  16. bool CDittoCopyBuffer::StartCopy(long lCopyBuffer, bool bCut)
  17. {
  18. Log(StrF(_T("Start of Ditto Copy buffer = %d"), lCopyBuffer));
  19. //Tell the timer thread to exit
  20. m_ActiveTimer.SetEvent();
  21. //Make sure the end copy thread has exited
  22. EndRestoreThread();
  23. if(m_SavedClipboard.Save())
  24. {
  25. if(bCut)
  26. {
  27. theApp.SendCut();
  28. }
  29. else
  30. {
  31. theApp.SendCopy();
  32. }
  33. //Create a thread to track if they have copied anything, if thread has exited before they have
  34. //copied something then the copy buffer copy is canceled
  35. AfxBeginThread(CDittoCopyBuffer::StartCopyTimer, (LPVOID)this, THREAD_PRIORITY_LOWEST);
  36. m_bActive = true;
  37. m_lCurrentDittoBuffer = lCopyBuffer;
  38. }
  39. else
  40. {
  41. Log(_T("Start of Ditto Failed to save buffer"));
  42. }
  43. return true;
  44. }
  45. UINT CDittoCopyBuffer::StartCopyTimer(LPVOID pParam)
  46. {
  47. CDittoCopyBuffer *pBuffer = (CDittoCopyBuffer*)pParam;
  48. if(pBuffer)
  49. {
  50. pBuffer->m_ActiveTimer.ResetEvent();
  51. DWORD dRes = WaitForSingleObject(pBuffer->m_ActiveTimer, 1500);
  52. if(dRes == WAIT_TIMEOUT)
  53. {
  54. pBuffer->m_bActive = false;
  55. }
  56. }
  57. return 0;
  58. }
  59. bool CDittoCopyBuffer::EndCopy(long lID)
  60. {
  61. if(m_lCurrentDittoBuffer < 0 || m_lCurrentDittoBuffer >= 10)
  62. {
  63. Log(_T("tried to save copy buffer but copy buffer is empty"));
  64. return false;
  65. }
  66. if(m_bActive == false)
  67. {
  68. Log(_T("Current buffer is not active can't save copy buffer to db"));
  69. return false;
  70. }
  71. m_ActiveTimer.SetEvent();
  72. m_bActive = false;
  73. Log(StrF(_T("Start - Ditto EndCopy buffer = %d"), m_lCurrentDittoBuffer));
  74. bool bRet = false;
  75. //put the data that we stored at the start of this action back on the standard clipboard
  76. m_SavedClipboard.Restore();
  77. if(PutClipOnDittoCopyBuffer(lID, m_lCurrentDittoBuffer))
  78. {
  79. Log(StrF(_T("Ditto end copy, saved clip successfully Clip ID = %d"), lID));
  80. bRet = true;
  81. }
  82. else
  83. {
  84. Log(StrF(_T("Ditto end copy, ERROR associating clip to Copy buffer ID = %d"), lID));
  85. }
  86. return bRet;
  87. }
  88. bool CDittoCopyBuffer::PutClipOnDittoCopyBuffer(long lClipId, long lBuffer)
  89. {
  90. try
  91. {
  92. //enclose in brackets so the query closes before we update below
  93. {
  94. CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID FROM CopyBuffers WHERE lCopyBuffer = %d"), lBuffer);
  95. if(q.eof())
  96. {
  97. theApp.m_db.execDMLEx(_T("INSERT INTO CopyBuffers VALUES(NULL, -1, %d);"), lBuffer);
  98. }
  99. }
  100. theApp.m_db.execDMLEx(_T("UPDATE CopyBuffers SET lClipID = %d WHERE lCopyBuffer = %d"), lClipId, lBuffer);
  101. CCopyBufferItem Item;
  102. g_Opt.GetCopyBufferItem(lBuffer, Item);
  103. if(Item.m_bPlaySoundOnCopy)
  104. {
  105. PlaySound(_T("ding.wav"), NULL, SND_FILENAME|SND_ASYNC);
  106. }
  107. return true;
  108. }
  109. CATCH_SQLITE_EXCEPTION
  110. return false;
  111. }
  112. bool CDittoCopyBuffer::PastCopyBuffer(long lCopyBuffer)
  113. {
  114. //Can't paste while another is still active
  115. if(WaitForSingleObject(m_RestoreActive, 1) == WAIT_TIMEOUT)
  116. {
  117. Log(_T("Copy Buffer pasted to fast"));
  118. return false;
  119. }
  120. bool bRet = false;
  121. Log(StrF(_T("Start - PastCopyBuffer buffer = %d"), m_lCurrentDittoBuffer));
  122. try
  123. {
  124. CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT Main.lID FROM Main ")
  125. _T("INNER JOIN CopyBuffers ON CopyBuffers.lClipID = Main.lID ")
  126. _T("WHERE CopyBuffers.lCopyBuffer = %d"), lCopyBuffer);
  127. if(q.eof() == false)
  128. {
  129. m_pClipboard = new CClipboardSaveRestoreCopyBuffer;
  130. if(m_pClipboard)
  131. {
  132. //Save the clipboard,
  133. //then put the new data on the clipboard
  134. //then send a paste
  135. //then wait a little and restore the original clipboard data
  136. if(m_pClipboard->Save())
  137. {
  138. CProcessPaste paste;
  139. paste.m_bSendPaste = true;
  140. paste.m_bActivateTarget = false;
  141. paste.GetClipIDs().Add(q.getIntField(_T("lID")));
  142. paste.DoPaste();
  143. m_pClipboard->m_lRestoreDelay = g_Opt.GetDittoRestoreClipboardDelay();
  144. Log(StrF(_T("PastCopyBuffer sent paste, starting thread to restore clipboard, Delay = %d"), m_pClipboard->m_lRestoreDelay));
  145. AfxBeginThread(CDittoCopyBuffer::DelayRestoreClipboard, (LPVOID)this, THREAD_PRIORITY_LOWEST);
  146. bRet = true;
  147. }
  148. else
  149. {
  150. Log(_T("PastCopyBuffer failed to save clipboard"));
  151. }
  152. }
  153. }
  154. }
  155. CATCH_SQLITE_EXCEPTION
  156. return bRet;
  157. }
  158. void CDittoCopyBuffer::EndRestoreThread()
  159. {
  160. //Tell the thread to stop waiting and restore the clipboard
  161. m_RestoreTimer.SetEvent();
  162. //make sure it's ended
  163. WaitForSingleObject(m_RestoreActive, 5000);
  164. }
  165. UINT CDittoCopyBuffer::DelayRestoreClipboard(LPVOID pParam)
  166. {
  167. CDittoCopyBuffer *pBuffer = (CDittoCopyBuffer*)pParam;
  168. if(pBuffer)
  169. {
  170. pBuffer->m_RestoreTimer.ResetEvent();
  171. pBuffer->m_RestoreActive.ResetEvent();
  172. CClipboardSaveRestoreCopyBuffer *pLocalClipboard = pBuffer->m_pClipboard;
  173. DWORD dRes = WaitForSingleObject(pBuffer->m_RestoreTimer, pLocalClipboard->m_lRestoreDelay);
  174. if(GetKeyState(VK_SHIFT) & 0x8000)
  175. {
  176. Log(_T("Shift key is down not restoring clipbard, custom Buffer on normal clipboard"));
  177. }
  178. else
  179. {
  180. if(pLocalClipboard->Restore())
  181. {
  182. Log(_T("CDittoCopyBuffer::DelayRestoreClipboard Successfully"));
  183. }
  184. else
  185. {
  186. Log(_T("CDittoCopyBuffer::DelayRestoreClipboard Failed to restore"));
  187. }
  188. }
  189. delete pLocalClipboard;
  190. pLocalClipboard = NULL;
  191. pBuffer->m_RestoreActive.SetEvent();
  192. }
  193. return TRUE;
  194. }