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_Pasting(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(FALSE))
  24. {
  25. if(bCut)
  26. {
  27. theApp.m_activeWnd.SendCut();
  28. }
  29. else
  30. {
  31. theApp.m_activeWnd.SendCopy(CopyReasonEnum::COPY_TO_BUFFER);
  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_SavedClipboard.Clear();
  55. pBuffer->m_bActive = false;
  56. }
  57. }
  58. return 0;
  59. }
  60. bool CDittoCopyBuffer::EndCopy(long lID)
  61. {
  62. if(m_lCurrentDittoBuffer < 0 || m_lCurrentDittoBuffer >= 10)
  63. {
  64. Log(_T("tried to save copy buffer but copy buffer is empty"));
  65. return false;
  66. }
  67. if(m_bActive == false)
  68. {
  69. Log(_T("Current buffer is not active can't save copy buffer to db"));
  70. return false;
  71. }
  72. m_ActiveTimer.SetEvent();
  73. m_bActive = false;
  74. Log(StrF(_T("Start - Ditto EndCopy buffer = %d"), m_lCurrentDittoBuffer));
  75. bool bRet = false;
  76. //put the data that we stored at the start of this action back on the standard clipboard
  77. m_SavedClipboard.Restore();
  78. if(PutClipOnDittoCopyBuffer(lID, m_lCurrentDittoBuffer))
  79. {
  80. Log(StrF(_T("Ditto end copy, saved clip successfully Clip ID = %d"), lID));
  81. bRet = true;
  82. }
  83. else
  84. {
  85. Log(StrF(_T("Ditto end copy, ERROR associating clip to Copy buffer ID = %d"), lID));
  86. }
  87. return bRet;
  88. }
  89. bool CDittoCopyBuffer::PutClipOnDittoCopyBuffer(long lClipId, long lBuffer)
  90. {
  91. try
  92. {
  93. //enclose in brackets so the query closes before we update below
  94. {
  95. CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID FROM CopyBuffers WHERE lCopyBuffer = %d"), lBuffer);
  96. if(q.eof())
  97. {
  98. theApp.m_db.execDMLEx(_T("INSERT INTO CopyBuffers VALUES(NULL, -1, %d);"), lBuffer);
  99. }
  100. }
  101. theApp.m_db.execDMLEx(_T("UPDATE CopyBuffers SET lClipID = %d WHERE lCopyBuffer = %d"), lClipId, lBuffer);
  102. CCopyBufferItem Item;
  103. g_Opt.GetCopyBufferItem(lBuffer, Item);
  104. if(Item.m_bPlaySoundOnCopy)
  105. {
  106. PlaySound(_T("ding.wav"), NULL, SND_FILENAME|SND_ASYNC);
  107. }
  108. return true;
  109. }
  110. CATCH_SQLITE_EXCEPTION
  111. return false;
  112. }
  113. bool CDittoCopyBuffer::PastCopyBuffer(long lCopyBuffer)
  114. {
  115. //Can't paste while another is still active
  116. if(WaitForSingleObject(m_Pasting, 1) == WAIT_TIMEOUT)
  117. {
  118. Log(_T("Copy Buffer pasted to fast"));
  119. return false;
  120. }
  121. m_RestoreTimer.ResetEvent();
  122. m_Pasting.ResetEvent();
  123. bool bRet = false;
  124. Log(StrF(_T("Start - PastCopyBuffer buffer = %d"), m_lCurrentDittoBuffer));
  125. try
  126. {
  127. CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT Main.lID FROM Main ")
  128. _T("INNER JOIN CopyBuffers ON CopyBuffers.lClipID = Main.lID ")
  129. _T("WHERE CopyBuffers.lCopyBuffer = %d"), lCopyBuffer);
  130. if(q.eof() == false)
  131. {
  132. m_pClipboard = new CClipboardSaveRestoreCopyBuffer;
  133. if(m_pClipboard)
  134. {
  135. //Save the clipboard,
  136. //then put the new data on the clipboard
  137. //then send a paste
  138. //then wait a little and restore the original clipboard data
  139. if(m_pClipboard->Save(false))
  140. {
  141. theApp.m_pMainFrame->PasteOrShowGroup(q.getIntField(_T("lID")), -1, FALSE, TRUE, false);
  142. m_pClipboard->m_lRestoreDelay = g_Opt.GetDittoRestoreClipboardDelay();
  143. Log(StrF(_T("PastCopyBuffer sent paste, starting thread to restore clipboard, Delay = %d"), m_pClipboard->m_lRestoreDelay));
  144. AfxBeginThread(CDittoCopyBuffer::DelayRestoreClipboard, (LPVOID)this, THREAD_PRIORITY_LOWEST);
  145. bRet = true;
  146. }
  147. else
  148. {
  149. Log(_T("PastCopyBuffer failed to save clipboard"));
  150. }
  151. }
  152. }
  153. }
  154. CATCH_SQLITE_EXCEPTION
  155. if(bRet == false)
  156. m_Pasting.SetEvent();
  157. return bRet;
  158. }
  159. void CDittoCopyBuffer::EndRestoreThread()
  160. {
  161. //Tell the thread to stop waiting and restore the clipboard
  162. m_RestoreTimer.SetEvent();
  163. //make sure it's ended
  164. WaitForSingleObject(m_Pasting, 5000);
  165. }
  166. UINT CDittoCopyBuffer::DelayRestoreClipboard(LPVOID pParam)
  167. {
  168. CDittoCopyBuffer *pBuffer = (CDittoCopyBuffer*)pParam;
  169. if(pBuffer)
  170. {
  171. CClipboardSaveRestoreCopyBuffer *pLocalClipboard = pBuffer->m_pClipboard;
  172. DWORD dRes = WaitForSingleObject(pBuffer->m_RestoreTimer, pLocalClipboard->m_lRestoreDelay);
  173. if(GetKeyState(VK_SHIFT) & 0x8000)
  174. {
  175. Log(_T("Shift key is down not restoring clipbard, custom Buffer on normal clipboard"));
  176. }
  177. else
  178. {
  179. if(pLocalClipboard->Restore())
  180. {
  181. Log(_T("CDittoCopyBuffer::DelayRestoreClipboard Successfully"));
  182. }
  183. else
  184. {
  185. Log(_T("CDittoCopyBuffer::DelayRestoreClipboard Failed to restore"));
  186. }
  187. }
  188. delete pLocalClipboard;
  189. pLocalClipboard = NULL;
  190. pBuffer->m_Pasting.SetEvent();
  191. }
  192. return TRUE;
  193. }