1
0

OleClipSource.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. #include "stdafx.h"
  2. #include "CP_Main.h"
  3. #include "OleClipSource.h"
  4. #include "shared/TextConvert.h"
  5. #include "CF_HDropAggregator.h"
  6. #include "CF_UnicodeTextAggregator.h"
  7. #include "CF_TextAggregator.h"
  8. #include "richtextaggregator.h"
  9. #include "htmlformataggregator.h"
  10. #include "Shared\Tokenizer.h"
  11. #include <random>
  12. #include "Client.h"
  13. #include "sqlite\unicode\unistr.h"
  14. #include "sqlite\unicode\uchar.h"
  15. /*------------------------------------------------------------------*\
  16. COleClipSource
  17. \*------------------------------------------------------------------*/
  18. //IMPLEMENT_DYNAMIC(COleClipSource, COleDataSource)
  19. COleClipSource::COleClipSource()
  20. {
  21. m_bLoadedFormats = false;
  22. m_convertToHDROPOnDelayRender = false;
  23. }
  24. COleClipSource::~COleClipSource()
  25. {
  26. }
  27. BOOL COleClipSource::DoDelayRender()
  28. {
  29. CClipTypes types;
  30. m_ClipIDs.GetTypes(types);
  31. bool foundHDrop = false;
  32. INT_PTR count = types.GetSize();
  33. for(int i=0; i < count; i++)
  34. {
  35. DelayRenderData(types[i]);
  36. if (types[i] == CF_HDROP)
  37. {
  38. foundHDrop = true;
  39. }
  40. }
  41. if (foundHDrop == false)
  42. {
  43. DelayRenderData(CF_HDROP);
  44. m_convertToHDROPOnDelayRender = true;
  45. }
  46. return count > 0;
  47. }
  48. BOOL COleClipSource::DoImmediateRender()
  49. {
  50. if(m_bLoadedFormats)
  51. return TRUE;
  52. m_bLoadedFormats = true;
  53. if(m_pasteOptions.m_pPasteFormats != NULL)
  54. {
  55. return PutFormatOnClipboard(m_pasteOptions.m_pPasteFormats) > 0;
  56. }
  57. INT_PTR count = m_ClipIDs.GetSize();
  58. if(count <= 0)
  59. return 0;
  60. CClip clip;
  61. if(count > 1)
  62. {
  63. CStringA SepA = CTextConvert::ConvertToChar(g_Opt.GetMultiPasteSeparator());
  64. CCF_TextAggregator CFText(SepA);
  65. if(m_ClipIDs.AggregateData(CFText, CF_TEXT, g_Opt.m_bMultiPasteReverse))
  66. {
  67. CClipFormat cf(CF_TEXT, CFText.GetHGlobal());
  68. clip.m_Formats.Add(cf);
  69. //clip.m_Formats now owns the global data
  70. cf.m_autoDeleteData = false;
  71. }
  72. CStringW SepW = CTextConvert::ConvertToUnicode(g_Opt.GetMultiPasteSeparator());
  73. CCF_UnicodeTextAggregator CFUnicodeText(SepW);
  74. if(m_ClipIDs.AggregateData(CFUnicodeText, CF_UNICODETEXT, g_Opt.m_bMultiPasteReverse))
  75. {
  76. CClipFormat cf(CF_UNICODETEXT, CFUnicodeText.GetHGlobal());
  77. clip.m_Formats.Add(cf);
  78. //clip.m_Formats now owns the global data
  79. cf.m_autoDeleteData = false;
  80. }
  81. if ((m_pasteOptions.LimitFormatsToText()) &&
  82. clip.m_Formats.GetCount() == 0)
  83. {
  84. CCF_HDropAggregator HDrop;
  85. if (m_ClipIDs.AggregateData(HDrop, CF_HDROP, g_Opt.m_bMultiPasteReverse))
  86. {
  87. CClipFormat cf(CF_UNICODETEXT, HDrop.GetHGlobalAsString());
  88. clip.m_Formats.Add(cf);
  89. //clip.m_Formats now owns the global data
  90. cf.m_autoDeleteData = false;
  91. }
  92. }
  93. else if (m_pasteOptions.LimitFormatsToText() == false)
  94. {
  95. CCF_HDropAggregator HDrop;
  96. if(m_ClipIDs.AggregateData(HDrop, CF_HDROP, g_Opt.m_bMultiPasteReverse))
  97. {
  98. CClipFormat cf(CF_HDROP, HDrop.GetHGlobal());
  99. clip.m_Formats.Add(cf);
  100. //clip.m_Formats now owns the global data
  101. cf.m_autoDeleteData = false;
  102. }
  103. CRichTextAggregator RichText(SepA);
  104. if(m_ClipIDs.AggregateData(RichText, theApp.m_RTFFormat, g_Opt.m_bMultiPasteReverse))
  105. {
  106. CClipFormat cf(theApp.m_RTFFormat, RichText.GetHGlobal());
  107. clip.m_Formats.Add(cf);
  108. //clip.m_Formats now owns the global data
  109. cf.m_autoDeleteData = false;
  110. }
  111. CHTMLFormatAggregator Html(SepA);
  112. if(m_ClipIDs.AggregateData(Html, theApp.m_HTML_Format, g_Opt.m_bMultiPasteReverse))
  113. {
  114. CClipFormat cf(theApp.m_HTML_Format, Html.GetHGlobal());
  115. clip.m_Formats.Add(cf);
  116. //clip.m_Formats now owns the global data
  117. cf.m_autoDeleteData = false;
  118. }
  119. }
  120. }
  121. if (count >= 1 && clip.m_Formats.GetCount() == 0)
  122. {
  123. clip.LoadFormats(m_ClipIDs[0], m_pasteOptions.LimitFormatsToText(), m_pasteOptions.IncludeRTFForTextOnly());
  124. }
  125. if (m_pasteOptions.LimitFormatsToText())
  126. {
  127. PlainTextFilter(clip);
  128. }
  129. if(m_pasteOptions.m_pasteUpperCase ||
  130. m_pasteOptions.m_pasteLowerCase)
  131. {
  132. DoUpperLowerCase(clip, m_pasteOptions.m_pasteUpperCase);
  133. }
  134. else if(m_pasteOptions.m_pasteCapitalize)
  135. {
  136. Capitalize(clip);
  137. }
  138. else if(m_pasteOptions.m_pasteSentenceCase)
  139. {
  140. SentenceCase(clip);
  141. }
  142. else if(m_pasteOptions.m_pasteRemoveLineFeeds)
  143. {
  144. RemoveLineFeeds(clip);
  145. }
  146. else if(m_pasteOptions.m_pasteAddOneLineFeed)
  147. {
  148. AddLineFeeds(clip, 1);
  149. }
  150. else if (m_pasteOptions.m_pasteAddTwoLineFeeds)
  151. {
  152. AddLineFeeds(clip, 2);
  153. }
  154. else if (m_pasteOptions.m_pasteTypoglycemia)
  155. {
  156. Typoglycemia(clip);
  157. }
  158. return PutFormatOnClipboard(&clip.m_Formats) > 0;
  159. }
  160. void COleClipSource::DoUpperLowerCase(CClip &clip, bool upper)
  161. {
  162. IClipFormat *unicodeTextFormat = clip.m_Formats.FindFormatEx(CF_UNICODETEXT);
  163. if (unicodeTextFormat != NULL)
  164. {
  165. HGLOBAL data = unicodeTextFormat->Data();
  166. wchar_t * stringData = (wchar_t *) GlobalLock(data);
  167. int size = (int) GlobalSize(data);
  168. icu::UnicodeString s = stringData;
  169. GlobalUnlock(data);
  170. //free the old text we are going to replace it below with an upper case version
  171. unicodeTextFormat->Free();
  172. icu::UnicodeString val;
  173. if (upper)
  174. {
  175. val = s.toUpper();
  176. }
  177. else
  178. {
  179. val = s.toLower();
  180. }
  181. long lLen = val.length();
  182. HGLOBAL hGlobal = NewGlobalP((LPVOID)val.getTerminatedBuffer(), ((lLen+1) * sizeof(wchar_t)));
  183. val.releaseBuffer();
  184. unicodeTextFormat->Data(hGlobal);
  185. }
  186. IClipFormat *asciiTextFormat = clip.m_Formats.FindFormatEx(CF_TEXT);
  187. if (asciiTextFormat != NULL)
  188. {
  189. HGLOBAL data = asciiTextFormat->Data();
  190. char * stringData = (char *) GlobalLock(data);
  191. int size = (int) GlobalSize(data);
  192. CStringA cs(stringData);
  193. GlobalUnlock(data);
  194. //free the old text we are going to replace it below with an upper case version
  195. asciiTextFormat->Free();
  196. CString val;
  197. if (upper)
  198. {
  199. val = cs.MakeUpper();
  200. }
  201. else
  202. {
  203. val = cs.MakeLower();
  204. }
  205. long lLen = val.GetLength();
  206. HGLOBAL hGlobal = NewGlobalP(val.GetBuffer(lLen), lLen + sizeof(char));
  207. val.ReleaseBuffer();
  208. asciiTextFormat->Data(hGlobal);
  209. }
  210. }
  211. void COleClipSource::Capitalize(CClip &clip)
  212. {
  213. IClipFormat *unicodeTextFormat = clip.m_Formats.FindFormatEx(CF_UNICODETEXT);
  214. if (unicodeTextFormat != NULL)
  215. {
  216. HGLOBAL data = unicodeTextFormat->Data();
  217. wchar_t * stringData = (wchar_t *) GlobalLock(data);
  218. int size = (int) GlobalSize(data);
  219. CString cs(stringData);
  220. GlobalUnlock(data);
  221. //free the old text we are going to replace it below with an upper case version
  222. unicodeTextFormat->Free();
  223. icu::UnicodeString temp = cs;
  224. CString val = temp.toLower().getTerminatedBuffer();
  225. long len = val.GetLength();
  226. if (len > 0)
  227. {
  228. wchar_t * pText = val.GetBuffer();
  229. pText[0] = u_toupper(pText[0]);
  230. bool capitalize = false;
  231. for (int i = 1; i < len; i++)
  232. {
  233. wchar_t item = pText[i];
  234. if (item == ' ')
  235. {
  236. capitalize = true;
  237. }
  238. else if (capitalize)
  239. {
  240. pText[i] = u_toupper(item);
  241. capitalize = false;
  242. }
  243. }
  244. }
  245. val.ReleaseBuffer();
  246. HGLOBAL hGlobal = NewGlobalP(val.GetBuffer(), ((len + 1) * sizeof(wchar_t)));
  247. unicodeTextFormat->Data(hGlobal);
  248. }
  249. //my change
  250. //test
  251. //second test
  252. IClipFormat *asciiTextFormat = clip.m_Formats.FindFormatEx(CF_TEXT);
  253. if (asciiTextFormat != NULL)
  254. {
  255. HGLOBAL data = asciiTextFormat->Data();
  256. char * stringData = (char *) GlobalLock(data);
  257. int size = (int) GlobalSize(data);
  258. CStringA cs(stringData);
  259. GlobalUnlock(data);
  260. //free the old text we are going to replace it below with an upper case version
  261. asciiTextFormat->Free();
  262. CStringA val = cs.MakeLower();
  263. long len = val.GetLength();
  264. if (len > 0)
  265. {
  266. char * pText = val.GetBuffer();
  267. pText[0] = toupper(pText[0]);
  268. bool capitalize = false;
  269. for (int i = 1; i < len; i++)
  270. {
  271. wchar_t item = pText[i];
  272. if (item == ' ')
  273. {
  274. capitalize = true;
  275. }
  276. else if (capitalize)
  277. {
  278. pText[i] = toupper(item);
  279. capitalize = false;
  280. }
  281. }
  282. }
  283. val.ReleaseBuffer();
  284. HGLOBAL hGlobal = NewGlobalP(val.GetBuffer(), (len + 1));
  285. asciiTextFormat->Data(hGlobal);
  286. }
  287. }
  288. void COleClipSource::SentenceCase(CClip &clip)
  289. {
  290. IClipFormat *unicodeTextFormat = clip.m_Formats.FindFormatEx(CF_UNICODETEXT);
  291. if (unicodeTextFormat != NULL)
  292. {
  293. HGLOBAL data = unicodeTextFormat->Data();
  294. wchar_t * stringData = (wchar_t *) GlobalLock(data);
  295. int size = (int) GlobalSize(data);
  296. CString cs(stringData);
  297. GlobalUnlock(data);
  298. //free the old text we are going to replace it below with an upper case version
  299. unicodeTextFormat->Free();
  300. icu::UnicodeString temp = cs;
  301. CString val = temp.toLower().getTerminatedBuffer();
  302. long len = val.GetLength();
  303. if (len > 0)
  304. {
  305. wchar_t * pText = val.GetBuffer();
  306. pText[0] = u_toupper(pText[0]);
  307. bool capitalize = false;
  308. for (int i = 1; i < len; i++)
  309. {
  310. wchar_t item = pText[i];
  311. if (item == '.' ||
  312. item == '!' ||
  313. item == '?')
  314. {
  315. capitalize = true;
  316. }
  317. else if (capitalize && item != ' ')
  318. {
  319. pText[i] = u_toupper(item);
  320. capitalize = false;
  321. }
  322. }
  323. }
  324. val.ReleaseBuffer();
  325. HGLOBAL hGlobal = NewGlobalP(val.GetBuffer(), ((len + 1) * sizeof(wchar_t)));
  326. unicodeTextFormat->Data(hGlobal);
  327. }
  328. IClipFormat *asciiTextFormat = clip.m_Formats.FindFormatEx(CF_TEXT);
  329. if (asciiTextFormat != NULL)
  330. {
  331. HGLOBAL data = asciiTextFormat->Data();
  332. char * stringData = (char *) GlobalLock(data);
  333. int size = (int) GlobalSize(data);
  334. CStringA cs(stringData);
  335. GlobalUnlock(data);
  336. //free the old text we are going to replace it below with an upper case version
  337. asciiTextFormat->Free();
  338. CStringA val = cs.MakeLower();
  339. long len = val.GetLength();
  340. if (len > 0)
  341. {
  342. char * pText = val.GetBuffer();
  343. pText[0] = toupper(pText[0]);
  344. bool capitalize = false;
  345. for (int i = 1; i < len; i++)
  346. {
  347. wchar_t item = pText[i];
  348. if (item == '.' ||
  349. item == '!' ||
  350. item == '?')
  351. {
  352. capitalize = true;
  353. }
  354. else if (capitalize && item != ' ')
  355. {
  356. pText[i] = toupper(item);
  357. capitalize = false;
  358. }
  359. }
  360. }
  361. val.ReleaseBuffer();
  362. HGLOBAL hGlobal = NewGlobalP(val.GetBuffer(), (len + 1));
  363. asciiTextFormat->Data(hGlobal);
  364. }
  365. }
  366. void COleClipSource::PlainTextFilter(CClip &clip)
  367. {
  368. bool foundText = false;
  369. INT_PTR hDropIndex = -1;
  370. INT_PTR count = clip.m_Formats.GetCount();
  371. for (INT_PTR i = 0; i < count; i++)
  372. {
  373. CClipFormat *pCF = &clip.m_Formats.ElementAt(i);
  374. if (pCF->m_cfType == CF_TEXT ||
  375. pCF->m_cfType == CF_UNICODETEXT)
  376. {
  377. foundText = true;
  378. }
  379. else if (pCF->m_cfType == CF_HDROP)
  380. {
  381. hDropIndex = i;
  382. }
  383. }
  384. if (foundText &&
  385. hDropIndex > -1)
  386. {
  387. clip.m_Formats.RemoveAt(hDropIndex);
  388. }
  389. else if (foundText == false &&
  390. hDropIndex > -1)
  391. {
  392. CCF_HDropAggregator HDrop;
  393. if (m_ClipIDs.AggregateData(HDrop, CF_HDROP, g_Opt.m_bMultiPasteReverse))
  394. {
  395. clip.m_Formats.RemoveAt(hDropIndex);
  396. CClipFormat format(CF_UNICODETEXT, HDrop.GetHGlobalAsString());
  397. clip.m_Formats.Add(format);
  398. format.m_autoDeleteData = false; //owned by m_DelayRenderedFormats
  399. }
  400. }
  401. }
  402. void COleClipSource::RemoveLineFeeds(CClip &clip)
  403. {
  404. IClipFormat *pUnicodeText = clip.m_Formats.FindFormatEx(CF_UNICODETEXT);
  405. if (pUnicodeText != NULL)
  406. {
  407. wchar_t *stringData = (wchar_t *) GlobalLock(pUnicodeText->Data());
  408. if (stringData != NULL)
  409. {
  410. CStringW string(stringData);
  411. GlobalUnlock(pUnicodeText->Data());
  412. pUnicodeText->Free();
  413. int count = string.Replace(_T("\r\n"), _T(" "));
  414. count = string.Replace(_T("\r"), _T(" "));
  415. count = string.Replace(_T("\n"), _T(" "));
  416. HGLOBAL hGlobal = NewGlobalP(string.GetBuffer(), ((string.GetLength() + 1) * sizeof(wchar_t)));
  417. pUnicodeText->Data(hGlobal);
  418. }
  419. }
  420. IClipFormat *pAsciiText = clip.m_Formats.FindFormatEx(CF_TEXT);
  421. if (pAsciiText != NULL)
  422. {
  423. char *stringData = (char *) GlobalLock(pAsciiText->Data());
  424. if (stringData != NULL)
  425. {
  426. CStringA string(stringData);
  427. GlobalUnlock(pAsciiText->Data());
  428. pAsciiText->Free();
  429. int count = string.Replace("\r\n", " ");
  430. count = string.Replace("\r", " ");
  431. count = string.Replace("\n", " ");
  432. HGLOBAL hGlobal = NewGlobalP(string.GetBuffer(), ((string.GetLength() + 1)));
  433. pAsciiText->Data(hGlobal);
  434. }
  435. }
  436. IClipFormat *pRTFFormat = clip.m_Formats.FindFormatEx(theApp.m_RTFFormat);
  437. if (pRTFFormat != NULL)
  438. {
  439. char *stringData = (char *) GlobalLock(pRTFFormat->Data());
  440. if (stringData != NULL)
  441. {
  442. CStringA string(stringData);
  443. GlobalUnlock(pRTFFormat->Data());
  444. pRTFFormat->Free();
  445. int count = string.Replace("\\par\r\n", " ");
  446. int count2 = string.Replace("\\par ", " ");
  447. int count3 = string.Replace("\\line ", " ");
  448. HGLOBAL hGlobal = NewGlobalP(string.GetBuffer(), ((string.GetLength() + 1)));
  449. pRTFFormat->Data(hGlobal);
  450. }
  451. }
  452. }
  453. void COleClipSource::AddLineFeeds(CClip &clip, int count)
  454. {
  455. IClipFormat *pUnicodeText = clip.m_Formats.FindFormatEx(CF_UNICODETEXT);
  456. if (pUnicodeText != NULL)
  457. {
  458. wchar_t *stringData = (wchar_t *) GlobalLock(pUnicodeText->Data());
  459. if (stringData != NULL)
  460. {
  461. CStringW string(stringData);
  462. GlobalUnlock(pUnicodeText->Data());
  463. pUnicodeText->Free();
  464. for(int i = 0; i < count; i++)
  465. {
  466. string += _T("\r\n");
  467. }
  468. HGLOBAL hGlobal = NewGlobalP(string.GetBuffer(), ((string.GetLength() + 1) * sizeof(wchar_t)));
  469. pUnicodeText->Data(hGlobal);
  470. }
  471. }
  472. IClipFormat *pAsciiText = clip.m_Formats.FindFormatEx(CF_TEXT);
  473. if (pAsciiText != NULL)
  474. {
  475. char *stringData = (char *) GlobalLock(pAsciiText->Data());
  476. if (stringData != NULL)
  477. {
  478. CStringA string(stringData);
  479. GlobalUnlock(pAsciiText->Data());
  480. pAsciiText->Free();
  481. for (int i = 0; i < count; i++)
  482. {
  483. string += _T("\r\n");
  484. }
  485. HGLOBAL hGlobal = NewGlobalP(string.GetBuffer(), ((string.GetLength() + 1)));
  486. pAsciiText->Data(hGlobal);
  487. }
  488. }
  489. IClipFormat *pRTFFormat = clip.m_Formats.FindFormatEx(theApp.m_RTFFormat);
  490. if (pRTFFormat != NULL)
  491. {
  492. char *stringData = (char *) GlobalLock(pRTFFormat->Data());
  493. if (stringData != NULL)
  494. {
  495. CStringA string(stringData);
  496. GlobalUnlock(pRTFFormat->Data());
  497. pRTFFormat->Free();
  498. for (int i = 0; i < count; i++)
  499. {
  500. int pos = string.ReverseFind('}');
  501. if (pos >= 0)
  502. {
  503. int count = string.Insert(pos, "\\par\r\n");
  504. }
  505. }
  506. HGLOBAL hGlobal = NewGlobalP(string.GetBuffer(), ((string.GetLength() + 1)));
  507. pRTFFormat->Data(hGlobal);
  508. }
  509. }
  510. }
  511. void COleClipSource::Typoglycemia(CClip &clip)
  512. {
  513. IClipFormat *unicodeTextFormat = clip.m_Formats.FindFormatEx(CF_UNICODETEXT);
  514. if (unicodeTextFormat != NULL)
  515. {
  516. HGLOBAL data = unicodeTextFormat->Data();
  517. wchar_t * stringData = (wchar_t *) GlobalLock(data);
  518. int size = (int) GlobalSize(data);
  519. CString cs(stringData);
  520. GlobalUnlock(data);
  521. //free the old text we are going to replace it below with an upper case version
  522. unicodeTextFormat->Free();
  523. CString newString;
  524. CTokenizer token(cs, _T(' '));
  525. CString word;
  526. while (token.Next(word))
  527. {
  528. if(word.GetLength() > 3)
  529. {
  530. int end = word.GetLength();
  531. for (int i = end-1; i >= 0; i--)
  532. {
  533. if(word[i] == _T('.') ||
  534. word[i] == _T('!') ||
  535. word[i] == _T('?'))
  536. {
  537. end--;
  538. }
  539. else
  540. {
  541. break;
  542. }
  543. }
  544. if (end > 3)
  545. {
  546. std::uniform_int_distribution<int> dist(1, end - 2);
  547. std::random_device rd;
  548. for (int i = 1; i < end - 1; i++)
  549. {
  550. int newPos = dist(rd);
  551. CString cs;
  552. cs.Format(_T("pos: %d, rnd: %d\r\n"), i, newPos);
  553. OutputDebugString(cs);
  554. TCHAR temp = word.GetAt(i);
  555. word.SetAt(i, word.GetAt(newPos));
  556. word.SetAt(newPos, temp);
  557. }
  558. }
  559. newString += word;
  560. }
  561. else
  562. {
  563. newString += word;
  564. }
  565. newString += _T(' ');
  566. }
  567. long len = newString.GetLength();
  568. HGLOBAL hGlobal = NewGlobalP(newString.GetBuffer(), ((len + 1) * sizeof(wchar_t)));
  569. unicodeTextFormat->Data(hGlobal);
  570. }
  571. }
  572. INT_PTR COleClipSource::PutFormatOnClipboard(CClipFormats *pFormats)
  573. {
  574. Log(_T("Start of put format on clipboard"));
  575. CClipFormat* pCF;
  576. INT_PTR count = pFormats->GetSize();
  577. bool bDelayedRenderCF_HDROP = false;
  578. INT_PTR i = 0;
  579. //see if the html format is in the list
  580. //if it is the list we will not paste CF_TEXT
  581. for(i = 0; i < count; i++)
  582. {
  583. pCF = &pFormats->ElementAt(i);
  584. if(pCF->m_cfType == theApp.m_RemoteCF_HDROP)
  585. {
  586. bDelayedRenderCF_HDROP = true;
  587. }
  588. }
  589. for(i = 0; i < count; i++)
  590. {
  591. pCF = &pFormats->ElementAt(i);
  592. if(bDelayedRenderCF_HDROP)
  593. {
  594. if(pCF->m_cfType == CF_HDROP)
  595. {
  596. LogSendRecieveInfo("Added delayed cf_hdrop to clipboard");
  597. DelayRenderData(pCF->m_cfType);
  598. }
  599. continue;
  600. }
  601. wchar_t * stringData = (wchar_t *) GlobalLock(pCF->m_hgData);
  602. int size = (int) GlobalSize(pCF->m_hgData);
  603. CString cs(stringData);
  604. GlobalUnlock(pCF->m_hgData);
  605. Log(StrF(_T("Setting clipboard type: %s to the clipboard"), GetFormatName(pCF->m_cfType)));
  606. CacheGlobalData(pCF->m_cfType, pCF->m_hgData);
  607. pCF->m_hgData = 0; // OLE owns it now
  608. }
  609. pFormats->RemoveAll();
  610. m_bLoadedFormats = true;
  611. Log(_T("End of put format on clipboard"));
  612. return count;
  613. }
  614. BOOL COleClipSource::OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal)
  615. {
  616. static bool bInHere = false;
  617. if(bInHere)
  618. {
  619. return FALSE;
  620. }
  621. bInHere = true;
  622. HGLOBAL hData = NULL;
  623. CClipFormat *pFind = m_DelayRenderedFormats.FindFormat(lpFormatEtc->cfFormat);
  624. if(pFind)
  625. {
  626. if(pFind->m_hgData)
  627. {
  628. hData = NewGlobalH(pFind->m_hgData, GlobalSize(pFind->m_hgData));
  629. }
  630. }
  631. else
  632. {
  633. LogSendRecieveInfo("Delayed Render, getting data from remote machine");
  634. CClip clip;
  635. if(m_ClipIDs.GetCount() > 0)
  636. {
  637. clip.LoadFormats(m_ClipIDs[0]);
  638. CClipFormat *pDittoDelayCF_HDROP = clip.m_Formats.FindFormat(theApp.m_RemoteCF_HDROP);
  639. CClipFormat *pCF_HDROP = clip.m_Formats.FindFormat(CF_HDROP);
  640. if(pDittoDelayCF_HDROP && pCF_HDROP)
  641. {
  642. CDittoCF_HDROP *pData = (CDittoCF_HDROP*)GlobalLock(pDittoDelayCF_HDROP->m_hgData);
  643. if(pData)
  644. {
  645. CString csComputerName;
  646. CString csIP;
  647. CTextConvert::ConvertFromUTF8(pData->m_cIP, csIP);
  648. CTextConvert::ConvertFromUTF8(pData->m_cComputerName, csComputerName);
  649. GlobalUnlock(pDittoDelayCF_HDROP->m_hgData);
  650. CClient cl;
  651. hData = cl.RequestCopiedFiles(*pCF_HDROP, csIP, csComputerName);
  652. }
  653. }
  654. else
  655. {
  656. hData = m_ClipIDs.Render(lpFormatEtc->cfFormat);
  657. if (m_convertToHDROPOnDelayRender &&
  658. hData == NULL &&
  659. lpFormatEtc->cfFormat == CF_HDROP)
  660. {
  661. hData = ConvertToFileDrop();
  662. }
  663. }
  664. }
  665. //Add to a cache of already rendered data
  666. //Windows seems to call this function multiple times
  667. //so only the first time do we need to go get the data
  668. HGLOBAL hCopy = NULL;
  669. if(hData)
  670. {
  671. hCopy = NewGlobalH(hData, GlobalSize(hData));
  672. }
  673. CClipFormat format(lpFormatEtc->cfFormat, hCopy);
  674. m_DelayRenderedFormats.Add(format);
  675. format.m_autoDeleteData = false; //owned by m_DelayRenderedFormats
  676. }
  677. BOOL bRet = FALSE;
  678. if(hData)
  679. {
  680. // if phGlobal is null, we can just give the allocated mem
  681. // else, our data must fit within the GlobalSize(*phGlobal)
  682. if(*phGlobal == 0)
  683. {
  684. *phGlobal = hData;
  685. }
  686. else
  687. {
  688. SIZE_T len = min(::GlobalSize(*phGlobal), ::GlobalSize(hData));
  689. if(len)
  690. {
  691. CopyToGlobalHH(*phGlobal, hData, len);
  692. }
  693. ::GlobalFree(hData);
  694. }
  695. bRet = TRUE;
  696. }
  697. bInHere = false;
  698. return bRet;
  699. }
  700. HGLOBAL COleClipSource::ConvertToFileDrop()
  701. {
  702. CString path = CGetSetOptions::GetPath(PATH_DRAG_FILES);
  703. CreateDirectory(path, NULL);
  704. CFileRecieve fileList;
  705. int dragId = CGetSetOptions::GetDragId();
  706. int origDragId = dragId;
  707. for (int i = 0; i < m_ClipIDs.GetCount(); i++)
  708. {
  709. CClip fileClip;
  710. fileClip.LoadFormats(m_ClipIDs[i]);
  711. CClipFormat *unicodeText = fileClip.m_Formats.FindFormat(CF_UNICODETEXT);
  712. if (unicodeText)
  713. {
  714. CString file;
  715. file.Format(_T("%stext_%d.txt"), path, dragId++);
  716. fileClip.WriteTextToFile(file, TRUE, FALSE, FALSE);
  717. fileList.AddFile(file);
  718. }
  719. else
  720. {
  721. CClipFormat *asciiText = fileClip.m_Formats.FindFormat(CF_TEXT);
  722. if (asciiText)
  723. {
  724. CString file;
  725. file.Format(_T("%stext_%d.txt"), path, dragId++);
  726. fileClip.WriteTextToFile(file, FALSE, TRUE, FALSE);
  727. fileList.AddFile(file);
  728. }
  729. else
  730. {
  731. CClipFormat *bitmap = fileClip.m_Formats.FindFormat(CF_DIB);
  732. if (bitmap)
  733. {
  734. CString file;
  735. file.Format(_T("%simage_%d.png"), path, dragId++);
  736. LPVOID pvData = GlobalLock(bitmap->m_hgData);
  737. ULONG size = (ULONG) GlobalSize(bitmap->m_hgData);
  738. WriteCF_DIBToFile(file, pvData, size);
  739. GlobalUnlock(bitmap->m_hgData);
  740. fileList.AddFile(file);
  741. }
  742. }
  743. }
  744. }
  745. if(dragId != origDragId)
  746. {
  747. CGetSetOptions::SetDragId(dragId);
  748. }
  749. HGLOBAL hData = fileList.CreateCF_HDROPBuffer();
  750. return hData;
  751. }