DeleteClipData.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  1. // DeleteClipData.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "CP_Main.h"
  5. #include "DeleteClipData.h"
  6. #include "afxdialogex.h"
  7. #include "Misc.h"
  8. #include "ProgressWnd.h"
  9. #include <algorithm>
  10. #include "../Shared/TextConvert.h"
  11. #include "../resource.h"
  12. #include "CopyProperties.h"
  13. #include "DimWnd.h"
  14. // CDeleteClipData dialog
  15. IMPLEMENT_DYNAMIC(CDeleteClipData, CDialog)
  16. CDeleteClipData::CDeleteClipData(CWnd* pParent /*=NULL*/)
  17. : CDialog(CDeleteClipData::IDD, pParent)
  18. , m_pDescriptionWindow(nullptr)
  19. , m_clipTitle(_T(""))
  20. , m_filterByClipTitle(FALSE)
  21. , m_filterByCreatedDate(FALSE)
  22. , m_filterByLastUsedDate(FALSE)
  23. , m_filterByClipboardFormat(FALSE)
  24. , m_createdDateStart(COleDateTime::GetCurrentTime())
  25. , m_createdDateEnd(COleDateTime::GetCurrentTime())
  26. , m_createdTimeStart(COleDateTime::GetCurrentTime())
  27. , m_createdTimeEnd(COleDateTime::GetCurrentTime())
  28. , m_usedTimeStart(COleDateTime::GetCurrentTime())
  29. , m_usedTimeEnd(COleDateTime::GetCurrentTime())
  30. , m_usedDateStart(COleDateTime::GetCurrentTime())
  31. , m_usedDateEnd(COleDateTime::GetCurrentTime())
  32. , m_databaseSize(_T(""))
  33. , m_selectedSize(_T(""))
  34. , m_selectedCount(_T(""))
  35. {
  36. m_applyingDelete = false;
  37. m_cancelDelete = false;
  38. }
  39. CDeleteClipData::~CDeleteClipData()
  40. {
  41. }
  42. void CDeleteClipData::DoDataExchange(CDataExchange* pDX)
  43. {
  44. CDialog::DoDataExchange(pDX);
  45. DDX_Control(pDX, IDC_LIST2, m_clipList);
  46. DDX_Text(pDX, IDC_EDIT_CLIP_TITLE, m_clipTitle);
  47. DDX_Check(pDX, IDC_CHECK_CLIP_TITLE, m_filterByClipTitle);
  48. DDX_Check(pDX, IDC_CHECK_CREATE_DATE, m_filterByCreatedDate);
  49. DDX_Check(pDX, IDC_CHECK_LAST_USE_DATE, m_filterByLastUsedDate);
  50. DDX_Check(pDX, IDC_CHECK_DATA_FORMAT, m_filterByClipboardFormat);
  51. DDX_Control(pDX, IDC_COMBO_DATA_FORMAT, m_clipboardFomatCombo);
  52. DDX_DateTimeCtrl(pDX, IDC_DATE_CREATE_START, m_createdDateStart);
  53. DDX_DateTimeCtrl(pDX, IDC_DATE_CREATE_END, m_createdDateEnd);
  54. DDX_DateTimeCtrl(pDX, IDC_TIME_CREATE_START, m_createdTimeStart);
  55. DDX_DateTimeCtrl(pDX, IDC_TIME_CREATE_END, m_createdTimeEnd);
  56. DDX_DateTimeCtrl(pDX, IDC_TIME_USE_START, m_usedTimeStart);
  57. DDX_DateTimeCtrl(pDX, IDC_TIME_USE_END, m_usedTimeEnd);
  58. DDX_DateTimeCtrl(pDX, IDC_DATE_USE_START, m_usedDateStart);
  59. DDX_DateTimeCtrl(pDX, IDC_DATE_USE_END, m_usedDateEnd);
  60. DDX_Text(pDX, IDC_STATIC_DB_SIZE, m_databaseSize);
  61. DDX_Text(pDX, IDC_STATIC_SELECTED_SIZE, m_selectedSize);
  62. DDX_Text(pDX, IDC_STATIC_SELECTED_COUNT, m_selectedCount);
  63. }
  64. BEGIN_MESSAGE_MAP(CDeleteClipData, CDialog)
  65. ON_WM_CLOSE()
  66. ON_WM_SIZE()
  67. ON_WM_NCDESTROY()
  68. ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CDeleteClipData::OnBnClickedButtonSearch)
  69. ON_NOTIFY(LVN_KEYDOWN, IDC_LIST2, &CDeleteClipData::OnLvnKeydownList2)
  70. ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, &CDeleteClipData::OnLvnItemchangedList2)
  71. ON_NOTIFY(HDN_GETDISPINFO, 0, &CDeleteClipData::OnHdnGetdispinfoList2)
  72. ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST2, &CDeleteClipData::OnLvnGetdispinfoList2)
  73. ON_BN_CLICKED(IDC_CHECK_CLIP_TITLE, &CDeleteClipData::OnBnClickedCheckClipTitle)
  74. ON_BN_CLICKED(IDC_BUTTON_APPLY, &CDeleteClipData::OnBnClickedButtonApply)
  75. ON_BN_CLICKED(IDCLOSE, &CDeleteClipData::OnBnClickedClose)
  76. ON_WM_TIMER()
  77. ON_BN_CLICKED(IDC_CHECK_CREATE_DATE, &CDeleteClipData::OnBnClickedCheckCreateDate)
  78. ON_BN_CLICKED(IDC_CHECK_LAST_USE_DATE, &CDeleteClipData::OnBnClickedCheckLastUseDate)
  79. ON_BN_CLICKED(IDC_CHECK_DATA_FORMAT, &CDeleteClipData::OnBnClickedCheckDataFormat)
  80. ON_NOTIFY(HDN_ITEMCLICK, 0, &CDeleteClipData::OnLvnColumnclickList2)
  81. ON_WM_CONTEXTMENU()
  82. END_MESSAGE_MAP()
  83. BOOL CDeleteClipData::OnInitDialog()
  84. {
  85. CDialog::OnInitDialog();
  86. theApp.m_Language.UpdateDeleteClipData(this);
  87. m_Resize.SetParent(m_hWnd);
  88. m_Resize.AddControl(IDC_LIST2, DR_SizeHeight | DR_SizeWidth);
  89. m_Resize.AddControl(IDCLOSE, DR_MoveTop | DR_MoveLeft);
  90. m_Resize.AddControl(IDC_BUTTON_APPLY, DR_MoveTop | DR_MoveLeft);
  91. m_Resize.AddControl(IDC_STATIC_TO_DELETE_TEXT, DR_MoveTop);
  92. m_Resize.AddControl(IDC_STATIC_TO_DELETE_SIZE, DR_MoveTop);
  93. m_Resize.AddControl(IDC_STATIC_SELECTED_SIZE, DR_MoveTop);
  94. m_Resize.AddControl(IDC_STATIC_SELECTED_SIZE_TEXT, DR_MoveTop);
  95. m_Resize.AddControl(IDC_STATIC_DB_SIZE, DR_MoveTop);
  96. m_Resize.AddControl(IDC_STATIC_DB_SIZE_TEXT, DR_MoveTop);
  97. m_Resize.AddControl(IDC_BUTTON_SEARCH, DR_MoveLeft);
  98. m_Resize.AddControl(IDC_STATIC_GROUP_SEARCH, DR_SizeWidth);
  99. InitListCtrlCols();
  100. SetTimer(1, 500, 0);
  101. SetDbSize();
  102. return TRUE;
  103. }
  104. void CDeleteClipData::SetDbSize()
  105. {
  106. __int64 size = FileSize(GetDBName());
  107. const int MAX_FILE_SIZE_BUFFER = 255;
  108. TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
  109. StrFormatByteSize(size, szFileSize, MAX_FILE_SIZE_BUFFER);
  110. m_databaseSize = szFileSize;
  111. UpdateData(0);
  112. }
  113. void CDeleteClipData::InitListCtrlCols()
  114. {
  115. m_clipList.SetExtendedStyle(LVS_EX_FULLROWSELECT);
  116. m_clipList.InsertColumn(0, theApp.m_Language.GetDeleteClipDataString("Title", "Title"), LVCFMT_LEFT, 350);
  117. m_clipList.InsertColumn(1, theApp.m_Language.GetDeleteClipDataString("QuickPasteText", "Quick Paste Text"), LVCFMT_LEFT, 200);
  118. m_clipList.InsertColumn(2, theApp.m_Language.GetDeleteClipDataString("Created", "Created"), LVCFMT_LEFT, 150);
  119. m_clipList.InsertColumn(3, theApp.m_Language.GetDeleteClipDataString("LastUsed", "Last Used"), LVCFMT_LEFT, 150);
  120. m_clipList.InsertColumn(4, theApp.m_Language.GetDeleteClipDataString("Format", "Format"), LVCFMT_LEFT, 150);
  121. m_clipList.InsertColumn(5, theApp.m_Language.GetDeleteClipDataString("DataSize", "Data Size"), LVCFMT_LEFT, 100);
  122. }
  123. void CDeleteClipData::LoadItems()
  124. {
  125. CWaitCursor wait;
  126. m_data.clear();
  127. m_filteredOut.clear();
  128. if (m_clipboardFomatCombo.GetCount() == 0)
  129. {
  130. CppSQLite3Query qFormats = theApp.m_db.execQueryEx(_T("select DISTINCT(strClipBoardFormat) from Data"));
  131. while (qFormats.eof() == false)
  132. {
  133. CString format = qFormats.getStringField(_T("strClipBoardFormat"));
  134. m_clipboardFomatCombo.AddString(format);
  135. qFormats.nextRow();
  136. }
  137. }
  138. CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT Main.lID, Main.mText, Main.lDate, Main.lastPasteDate, Main.QuickPasteText, Data.lID AS DataID, Data.strClipBoardFormat, length(Data.ooData) AS DataLength ")
  139. _T("FROM Data ")
  140. _T("INNER JOIN Main on Main.lID = Data.lParentID ")
  141. _T("ORDER BY length(ooData) DESC"));
  142. int row = 0;
  143. while (q.eof() == false)
  144. {
  145. CDeleteData data;
  146. data.m_lID = q.getIntField(_T("lID"));
  147. data.m_Desc = q.getStringField(_T("mText"));
  148. data.m_createdDateTime = q.getInt64Field(_T("lDate"));
  149. data.m_lastUsedDateTime = q.getInt64Field(_T("lastPasteDate"));
  150. data.m_clipboardFormat = q.getStringField(_T("strClipBoardFormat"));
  151. data.m_dataSize = q.getIntField(_T("DataLength"));
  152. data.m_DatalID = q.getIntField(_T("DataID"));
  153. data.m_quickPasteText = q.getStringField(_T("QuickPasteText"));
  154. m_data.push_back(data);
  155. row++;
  156. q.nextRow();
  157. }
  158. m_clipList.SetItemCountEx(row, 0);
  159. }
  160. void CDeleteClipData::SetNotifyWnd(HWND hWnd)
  161. {
  162. m_hWndParent = hWnd;
  163. }
  164. void CDeleteClipData::OnClose()
  165. {
  166. if (m_applyingDelete)
  167. {
  168. return;
  169. }
  170. CloseDescriptionWindow();
  171. DestroyWindow();
  172. }
  173. void CDeleteClipData::CloseDescriptionWindow()
  174. {
  175. if (m_pDescriptionWindow != nullptr)
  176. {
  177. m_pDescriptionWindow->CloseWindow();
  178. m_pDescriptionWindow->DestroyWindow();
  179. delete m_pDescriptionWindow;
  180. m_pDescriptionWindow = nullptr;
  181. }
  182. }
  183. void CDeleteClipData::OnSize(UINT nType, int cx, int cy)
  184. {
  185. CDialog::OnSize(nType, cx, cy);
  186. m_Resize.MoveControls(CSize(cx, cy));
  187. }
  188. void CDeleteClipData::OnNcDestroy()
  189. {
  190. CDialog::OnNcDestroy();
  191. ::PostMessage(m_hWndParent, WM_DELETE_CLIPS_CLOSED, 0, 0);
  192. }
  193. // CDeleteClipData message handlers
  194. void CDeleteClipData::OnBnClickedButtonSearch()
  195. {
  196. FilterItems();
  197. }
  198. void CDeleteClipData::FilterItems()
  199. {
  200. if (m_pDescriptionWindow != nullptr)
  201. {
  202. m_pDescriptionWindow->Hide();
  203. }
  204. UpdateData();
  205. //First search the already filtered text, see if we need to add them back in
  206. std::vector<int> filteredRowsToDelete;
  207. std::vector<CDeleteData> addBackIn;
  208. INT_PTR count = m_filteredOut.size();
  209. for (int i = 0; i < count; i++)
  210. {
  211. CDeleteData data = m_filteredOut[i];
  212. if (MatchesFilter(&data))
  213. {
  214. addBackIn.push_back(data);
  215. filteredRowsToDelete.push_back(i);
  216. }
  217. }
  218. //next search the main list
  219. std::vector<int> rowsToDelete;
  220. count = m_data.size();
  221. for (int i = 0; i < count; i++)
  222. {
  223. CDeleteData data = m_data[i];
  224. if(MatchesFilter(&data) == false)
  225. {
  226. m_filteredOut.push_back(data);
  227. rowsToDelete.push_back(i);
  228. }
  229. }
  230. //Add back in the filtered out ones that now match
  231. count = addBackIn.size();
  232. for (int i = 0; i < count; i++)
  233. {
  234. CDeleteData data = addBackIn[i];
  235. m_data.push_back(data);
  236. }
  237. int toSelect = -1;
  238. //Remove from the main list the ones that don't match
  239. count = rowsToDelete.size();
  240. for (INT_PTR i = count - 1; i >= 0; i--)
  241. {
  242. int row = rowsToDelete[i];
  243. toSelect = row;
  244. m_data.erase(m_data.begin() + row);
  245. }
  246. //Remove the rows that were filtered out but now match
  247. count = filteredRowsToDelete.size();
  248. for (INT_PTR i = count - 1; i >= 0; i--)
  249. {
  250. int row = filteredRowsToDelete[i];
  251. m_filteredOut.erase(m_filteredOut.begin() + row);
  252. }
  253. if (toSelect > -1)
  254. {
  255. m_clipList.SetItemState(toSelect, LVIS_SELECTED, LVIS_SELECTED);
  256. }
  257. m_clipList.SetItemCountEx((int)m_data.size(), 0);
  258. }
  259. bool CDeleteClipData::MatchesFilter(CDeleteData *pdata)
  260. {
  261. if(m_filterByClipTitle &&
  262. m_clipTitle != _T("") &&
  263. pdata->m_Desc != _T(""))
  264. {
  265. if(pdata->m_Desc.MakeLower().Find(m_clipTitle.MakeLower()) == -1)
  266. {
  267. return false;
  268. }
  269. }
  270. if (m_filterByCreatedDate)
  271. {
  272. CTime dateStart = CTime(m_createdDateStart.GetYear(), m_createdDateStart.GetMonth(), m_createdDateStart.GetDay(), m_createdTimeStart.GetHour(), m_createdTimeStart.GetMinute(), m_createdTimeStart.GetSecond());
  273. CTime dateEnd = CTime(m_createdDateEnd.GetYear(), m_createdDateEnd.GetMonth(), m_createdDateEnd.GetDay(), m_createdTimeEnd.GetHour(), m_createdTimeEnd.GetMinute(), m_createdTimeEnd.GetSecond());
  274. if (pdata->m_createdDateTime >= dateStart && pdata->m_createdDateTime <= dateEnd)
  275. {
  276. return true;
  277. }
  278. else
  279. {
  280. return false;
  281. }
  282. }
  283. if (m_filterByLastUsedDate)
  284. {
  285. CTime dateStart = CTime(m_usedDateStart.GetYear(), m_usedDateStart.GetMonth(), m_usedDateStart.GetDay(), m_usedTimeStart.GetHour(), m_usedTimeStart.GetMinute(), m_usedTimeStart.GetSecond());
  286. CTime dateEnd = CTime(m_usedDateEnd.GetYear(), m_usedDateEnd.GetMonth(), m_usedDateEnd.GetDay(), m_usedTimeEnd.GetHour(), m_usedTimeEnd.GetMinute(), m_usedTimeEnd.GetSecond());
  287. if (pdata->m_lastUsedDateTime >= dateStart && pdata->m_lastUsedDateTime <= dateEnd)
  288. {
  289. return true;
  290. }
  291. else
  292. {
  293. return false;
  294. }
  295. }
  296. if (m_filterByClipboardFormat)
  297. {
  298. CString str1;
  299. int n = m_clipboardFomatCombo.GetLBTextLen(m_clipboardFomatCombo.GetCurSel());
  300. m_clipboardFomatCombo.GetLBText(m_clipboardFomatCombo.GetCurSel(), str1.GetBuffer(n));
  301. str1.ReleaseBuffer();
  302. if (pdata->m_clipboardFormat == str1)
  303. {
  304. return true;
  305. }
  306. else
  307. {
  308. return false;
  309. }
  310. }
  311. return true;
  312. }
  313. void CDeleteClipData::OnLvnKeydownList2(NMHDR *pNMHDR, LRESULT *pResult)
  314. {
  315. LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
  316. // TODO: Add your control notification handler code here
  317. switch(pLVKeyDow->wVKey)
  318. {
  319. case VK_DELETE:
  320. this->ApplyDelete();
  321. break;
  322. case VK_RETURN:
  323. {
  324. if (GetKeyState(VK_MENU) & 0x8000) // Check if Alt is also pressed
  325. {
  326. ShowClipPropertiesWindow();
  327. *pResult = 1;
  328. }
  329. }
  330. break;
  331. case VK_F3:
  332. {
  333. CreateAndShowDescriptionWindow();
  334. *pResult = 1;
  335. }
  336. break;
  337. case 'N':
  338. {
  339. int nSelItem = m_clipList.GetNextItem(-1, LVNI_SELECTED);
  340. if (nSelItem != -1 && nSelItem < m_clipList.GetItemCount() - 1)
  341. {
  342. SelectRow(nSelItem + 1);
  343. CreateAndShowDescriptionWindow();
  344. }
  345. *pResult = 1;
  346. }
  347. break;
  348. case 'P':
  349. {
  350. int nSelItem = m_clipList.GetNextItem(-1, LVNI_SELECTED);
  351. if (nSelItem != -1 && nSelItem > 0)
  352. {
  353. SelectRow(nSelItem - 1);
  354. CreateAndShowDescriptionWindow();
  355. }
  356. *pResult = 1;
  357. }
  358. break;
  359. default:
  360. *pResult = 0;
  361. break;
  362. }
  363. }
  364. void CDeleteClipData::OnLvnItemchangedList2(NMHDR *pNMHDR, LRESULT *pResult)
  365. {
  366. LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
  367. POSITION pos = m_clipList.GetFirstSelectedItemPosition();
  368. __int64 selectedDataSize = 0;
  369. int selectedCount = 0;
  370. bool setDescriptionWindowText = false;
  371. if (pos != nullptr)
  372. {
  373. while (pos)
  374. {
  375. INT_PTR row = m_clipList.GetNextSelectedItem(pos);
  376. if(row >= 0 && row < (INT_PTR)m_data.size())
  377. {
  378. selectedDataSize += m_data[row].m_dataSize;
  379. selectedCount++;
  380. if (setDescriptionWindowText == false &&
  381. m_pDescriptionWindow != nullptr &&
  382. m_pDescriptionWindow->IsWindowVisible())
  383. {
  384. SetDescriptionWindowText(row);
  385. CRect r;
  386. m_pDescriptionWindow->GetWindowRectEx(r);
  387. CPoint pt;
  388. pt = r.TopLeft();
  389. m_pDescriptionWindow->Show(pt);
  390. setDescriptionWindowText = true;
  391. }
  392. }
  393. }
  394. }
  395. const int MAX_FILE_SIZE_BUFFER = 255;
  396. TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
  397. StrFormatByteSize(selectedDataSize, szFileSize, MAX_FILE_SIZE_BUFFER);
  398. m_selectedSize = szFileSize;
  399. CString count;
  400. count.Format(_T("%d"), selectedCount);
  401. m_selectedCount = count;
  402. UpdateData(0);
  403. *pResult = 0;
  404. }
  405. void CDeleteClipData::OnHdnGetdispinfoList2(NMHDR *pNMHDR, LRESULT *pResult)
  406. {
  407. LPNMHDDISPINFO pDispInfo = reinterpret_cast<LPNMHDDISPINFO>(pNMHDR);
  408. if (pDispInfo->mask &LVIF_TEXT)
  409. {
  410. switch (pDispInfo->iItem)
  411. {
  412. case 0:
  413. break;
  414. }
  415. }
  416. *pResult = 0;
  417. }
  418. void CDeleteClipData::OnLvnGetdispinfoList2(NMHDR *pNMHDR, LRESULT *pResult)
  419. {
  420. NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
  421. if (pDispInfo->item.mask & LVIF_TEXT)
  422. {
  423. if (pDispInfo->item.iItem >= 0 && pDispInfo->item.iItem < m_data.size())
  424. {
  425. switch (pDispInfo->item.iSubItem)
  426. {
  427. case 0:
  428. {
  429. lstrcpyn(pDispInfo->item.pszText, m_data[pDispInfo->item.iItem].m_Desc, pDispInfo->item.cchTextMax);
  430. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  431. }
  432. break;
  433. case 1:
  434. {
  435. lstrcpyn(pDispInfo->item.pszText, m_data[pDispInfo->item.iItem].m_quickPasteText, pDispInfo->item.cchTextMax);
  436. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  437. }
  438. break;
  439. case 2:
  440. {
  441. COleDateTime dtTime(m_data[pDispInfo->item.iItem].m_createdDateTime.GetTime());
  442. lstrcpyn(pDispInfo->item.pszText, dtTime.Format(), pDispInfo->item.cchTextMax);
  443. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  444. }
  445. break;
  446. case 3:
  447. {
  448. COleDateTime dtTime(m_data[pDispInfo->item.iItem].m_lastUsedDateTime.GetTime());
  449. lstrcpyn(pDispInfo->item.pszText, dtTime.Format(), pDispInfo->item.cchTextMax);
  450. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  451. }
  452. break;
  453. case 4:
  454. {
  455. lstrcpyn(pDispInfo->item.pszText, m_data[pDispInfo->item.iItem].m_clipboardFormat, pDispInfo->item.cchTextMax);
  456. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  457. }
  458. break;
  459. case 5:
  460. {
  461. const int MAX_FILE_SIZE_BUFFER = 255;
  462. TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
  463. StrFormatByteSize(m_data[pDispInfo->item.iItem].m_dataSize, szFileSize, MAX_FILE_SIZE_BUFFER);
  464. lstrcpyn(pDispInfo->item.pszText, szFileSize, pDispInfo->item.cchTextMax);
  465. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  466. }
  467. break;
  468. }
  469. }
  470. }
  471. *pResult = 0;
  472. }
  473. void CDeleteClipData::OnBnClickedCheckClipTitle()
  474. {
  475. UpdateData();
  476. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT_CLIP_TITLE), m_filterByClipTitle);
  477. ::SetFocus(::GetDlgItem(m_hWnd, IDC_EDIT_CLIP_TITLE));
  478. }
  479. void CDeleteClipData::OnBnClickedButtonApply()
  480. {
  481. ApplyDelete();
  482. }
  483. void CDeleteClipData::ApplyDelete()
  484. {
  485. if (m_applyingDelete)
  486. return;
  487. if (MessageBox(_T("Delete selected items? This cannot be undone!"), _T(""), MB_OKCANCEL | MB_ICONWARNING) == IDOK)
  488. {
  489. m_clipList.EnableWindow(FALSE);
  490. m_applyingDelete = true;
  491. m_cancelDelete = false;
  492. CWaitCursor wait;
  493. try
  494. {
  495. theApp.m_db.execDML(_T("PRAGMA auto_vacuum = 2"));
  496. POSITION pos = m_clipList.GetFirstSelectedItemPosition();
  497. std::vector<int> rowsToDelete;
  498. if (pos != nullptr)
  499. {
  500. while (pos)
  501. {
  502. int row = m_clipList.GetNextSelectedItem(pos);
  503. rowsToDelete.push_back(row);
  504. }
  505. }
  506. CProgressWnd progress;
  507. progress.Create(this, _T("Deleting clip items"), TRUE);
  508. progress.SetRange(0, (int)rowsToDelete.size() + 4);
  509. progress.SetText(_T("Deleting selected items"));
  510. progress.SetStep(1);
  511. INT_PTR count = rowsToDelete.size();
  512. for (INT_PTR i = count - 1; i >= 0; i--)
  513. {
  514. progress.PeekAndPump();
  515. if (m_cancelDelete || progress.Cancelled())
  516. {
  517. break;
  518. }
  519. progress.StepIt();
  520. int row = rowsToDelete[i];
  521. CDeleteData data = m_data[row];
  522. try
  523. {
  524. //Sleep(100);
  525. int deleteCount = theApp.m_db.execDMLEx(_T("DELETE FROM Data where lID = %d"), data.m_DatalID);
  526. //If there are no more children for this clip then delete the parent
  527. int parentDeleteCount = theApp.m_db.execDMLEx(_T("DELETE FROM Main where lID IN ")
  528. _T("(")
  529. _T("SELECT Main.lID ")
  530. _T("FROM Main ")
  531. _T("LEFT OUTER JOIN Data on Data.lParentID = Main.lID ")
  532. _T("WHERE bIsGroup = 0 AND Main.lID = %d ")
  533. _T("Group by Main.lID ")
  534. _T("having Count(Data.lID) = 0 ")
  535. _T(")"), data.m_lID);
  536. m_data.erase(m_data.begin() + row);
  537. }
  538. CATCH_SQLITE_EXCEPTION
  539. }
  540. progress.StepIt();
  541. progress.SetText(_T("Shrinking database"));
  542. try
  543. {
  544. for(int i = 0; i < 100; i++)
  545. {
  546. int toDeleteCount = theApp.m_db.execScalar(_T("SELECT COUNT(clipID) FROM MainDeletes"));
  547. if(toDeleteCount <= 0)
  548. break;
  549. RemoveOldEntries(false);
  550. }
  551. }
  552. CATCH_SQLITE_EXCEPTION
  553. theApp.m_db.execDML(_T("PRAGMA auto_vacuum = 1"));
  554. theApp.m_db.execQuery(_T("VACUUM"));
  555. progress.StepIt();
  556. progress.SetText(_T("Refreshing database size"));
  557. SetDbSize();
  558. progress.StepIt();
  559. progress.SetText(_T("Reloading list"));
  560. //LoadItems();
  561. progress.StepIt();
  562. progress.SetText(_T("Applying filter"));
  563. FilterItems();
  564. m_clipList.SetItemCountEx((int)m_data.size(), 0);
  565. }
  566. CATCH_SQLITE_EXCEPTION
  567. m_applyingDelete = false;
  568. m_clipList.EnableWindow();
  569. }
  570. }
  571. void CDeleteClipData::OnBnClickedClose()
  572. {
  573. if (m_applyingDelete)
  574. {
  575. m_cancelDelete = true;
  576. return;
  577. }
  578. CloseDescriptionWindow();
  579. DestroyWindow();
  580. }
  581. void CDeleteClipData::OnTimer(UINT_PTR nIDEvent)
  582. {
  583. switch(nIDEvent)
  584. {
  585. case 1:
  586. LoadItems();
  587. KillTimer(1);
  588. break;
  589. }
  590. CDialog::OnTimer(nIDEvent);
  591. }
  592. void CDeleteClipData::OnBnClickedCheckCreateDate()
  593. {
  594. UpdateData();
  595. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_DATE_CREATE_START), m_filterByCreatedDate);
  596. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_TIME_CREATE_START), m_filterByCreatedDate);
  597. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_DATE_CREATE_END), m_filterByCreatedDate);
  598. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_TIME_CREATE_END), m_filterByCreatedDate);
  599. ::SetFocus(::GetDlgItem(m_hWnd, IDC_DATE_CREATE_START));
  600. }
  601. void CDeleteClipData::OnBnClickedCheckLastUseDate()
  602. {
  603. UpdateData();
  604. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_DATE_USE_START), m_filterByLastUsedDate);
  605. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_TIME_USE_START), m_filterByLastUsedDate);
  606. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_DATE_USE_END), m_filterByLastUsedDate);
  607. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_TIME_USE_END), m_filterByLastUsedDate);
  608. ::SetFocus(::GetDlgItem(m_hWnd, IDC_DATE_USE_START));
  609. }
  610. void CDeleteClipData::OnBnClickedCheckDataFormat()
  611. {
  612. UpdateData();
  613. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_COMBO_DATA_FORMAT), m_filterByClipboardFormat);
  614. ::SetFocus(::GetDlgItem(m_hWnd, IDC_COMBO_DATA_FORMAT));
  615. }
  616. static bool SortByTitleDesc(const CDeleteData& a1, const CDeleteData& a2)
  617. {
  618. return a1.m_Desc > a2.m_Desc;
  619. }
  620. static bool SortByQuickPaste(const CDeleteData& a1, const CDeleteData& a2)
  621. {
  622. return a1.m_quickPasteText > a2.m_quickPasteText;
  623. }
  624. static bool SortByCreatedDateDesc(const CDeleteData& a1, const CDeleteData& a2)
  625. {
  626. return a1.m_createdDateTime > a2.m_createdDateTime;
  627. }
  628. static bool SortByLastUsedDateDesc(const CDeleteData& a1, const CDeleteData& a2)
  629. {
  630. return a1.m_lastUsedDateTime > a2.m_lastUsedDateTime;
  631. }
  632. static bool SortByFormatDesc(const CDeleteData& a1, const CDeleteData& a2)
  633. {
  634. return a1.m_clipboardFormat > a2.m_clipboardFormat;
  635. }
  636. static bool SortByDataSizeDesc(const CDeleteData& a1, const CDeleteData& a2)
  637. {
  638. return a1.m_dataSize > a2.m_dataSize;
  639. }
  640. static bool SortByTitleAsc(const CDeleteData& a1, const CDeleteData& a2)
  641. {
  642. return a1.m_Desc < a2.m_Desc;
  643. }
  644. static bool SortByCreatedDateAsc(const CDeleteData& a1, const CDeleteData& a2)
  645. {
  646. return a1.m_createdDateTime < a2.m_createdDateTime;
  647. }
  648. static bool SortByLastUsedDateAsc(const CDeleteData& a1, const CDeleteData& a2)
  649. {
  650. return a1.m_lastUsedDateTime < a2.m_lastUsedDateTime;
  651. }
  652. static bool SortByFormatAsc(const CDeleteData& a1, const CDeleteData& a2)
  653. {
  654. return a1.m_clipboardFormat < a2.m_clipboardFormat;
  655. }
  656. static bool SortByDataSizeAsc(const CDeleteData& a1, const CDeleteData& a2)
  657. {
  658. return a1.m_dataSize < a2.m_dataSize;
  659. }
  660. bool desc = true;
  661. void CDeleteClipData::OnLvnColumnclickList2(NMHDR *pNMHDR, LRESULT *pResult)
  662. {
  663. HD_NOTIFY *phdn = (HD_NOTIFY *)pNMHDR;
  664. switch (phdn->iItem)
  665. {
  666. case 0:
  667. if(desc)
  668. std::sort(m_data.begin(), m_data.end(), SortByTitleDesc);
  669. else
  670. std::sort(m_data.begin(), m_data.end(), SortByTitleAsc);
  671. break;
  672. case 1:
  673. if (desc)
  674. std::sort(m_data.begin(), m_data.end(), SortByQuickPaste);
  675. else
  676. std::sort(m_data.begin(), m_data.end(), SortByQuickPaste);
  677. break;
  678. case 2:
  679. if(desc)
  680. std::sort(m_data.begin(), m_data.end(), SortByCreatedDateDesc);
  681. else
  682. std::sort(m_data.begin(), m_data.end(), SortByCreatedDateAsc);
  683. break;
  684. case 3:
  685. if(desc)
  686. std::sort(m_data.begin(), m_data.end(), SortByLastUsedDateDesc);
  687. else
  688. std::sort(m_data.begin(), m_data.end(), SortByLastUsedDateAsc);
  689. break;
  690. case 4:
  691. if(desc)
  692. std::sort(m_data.begin(), m_data.end(), SortByFormatDesc);
  693. else
  694. std::sort(m_data.begin(), m_data.end(), SortByFormatAsc);
  695. break;
  696. case 5:
  697. if(desc)
  698. std::sort(m_data.begin(), m_data.end(), SortByDataSizeDesc);
  699. else
  700. std::sort(m_data.begin(), m_data.end(), SortByDataSizeAsc);
  701. break;
  702. }
  703. desc = !desc;
  704. m_clipList.SetItemCountEx((int)m_data.size(), 0);
  705. *pResult = 0;
  706. }
  707. BOOL CDeleteClipData::PreTranslateMessage(MSG* pMsg)
  708. {
  709. if (pMsg->message == WM_KEYDOWN)
  710. {
  711. if (pMsg->wParam == VK_RETURN)
  712. {
  713. FilterItems();
  714. return TRUE; // Do not process further
  715. }
  716. else if (pMsg->wParam == VK_ESCAPE)
  717. {
  718. if (m_pDescriptionWindow != nullptr)
  719. {
  720. m_pDescriptionWindow->Hide();
  721. return TRUE;
  722. }
  723. }
  724. }
  725. return CDialog::PreTranslateMessage(pMsg);
  726. }
  727. void CDeleteClipData::SelectRow(int selectedRow)
  728. {
  729. RemoveAllSelection();
  730. SetCaret(selectedRow);
  731. SetSelection(selectedRow);
  732. ListView_SetSelectionMark(m_clipList.GetSafeHwnd(), selectedRow);
  733. m_clipList.EnsureVisible(selectedRow, FALSE);
  734. }
  735. void CDeleteClipData::RemoveAllSelection()
  736. {
  737. POSITION pos = m_clipList.GetFirstSelectedItemPosition();
  738. while (pos)
  739. {
  740. SetSelection(m_clipList.GetNextSelectedItem(pos), FALSE);
  741. }
  742. }
  743. BOOL CDeleteClipData::SetCaret(int nRow, BOOL bFocus)
  744. {
  745. if (bFocus)
  746. return m_clipList.SetItemState(nRow, LVIS_FOCUSED, LVIS_FOCUSED);
  747. else
  748. return m_clipList.SetItemState(nRow, ~LVIS_FOCUSED, LVIS_FOCUSED);
  749. }
  750. BOOL CDeleteClipData::SetSelection(int nRow, BOOL bSelect)
  751. {
  752. if (bSelect)
  753. return m_clipList.SetItemState(nRow, LVIS_SELECTED, LVIS_SELECTED);
  754. else
  755. return m_clipList.SetItemState(nRow, ~LVIS_SELECTED, LVIS_SELECTED);
  756. }
  757. void CDeleteClipData::CreateAndShowDescriptionWindow()
  758. {
  759. if (m_pDescriptionWindow == nullptr)
  760. {
  761. m_pDescriptionWindow = new CToolTipEx;
  762. m_pDescriptionWindow->Create(this);
  763. m_pDescriptionWindow->SetNotifyWnd(GetParent());
  764. }
  765. POSITION pos = m_clipList.GetFirstSelectedItemPosition();
  766. if (pos != nullptr)
  767. {
  768. INT_PTR row = m_clipList.GetNextSelectedItem(pos);
  769. if (row >= 0 && row < (INT_PTR)m_data.size())
  770. {
  771. SetDescriptionWindowText(row);
  772. CRect rc;
  773. this->GetWindowRect(rc);
  774. CPoint pt;
  775. pt = CPoint(rc.right, rc.top);
  776. m_pDescriptionWindow->Show(pt);
  777. }
  778. }
  779. }
  780. void CDeleteClipData::SetDescriptionWindowText(INT_PTR row)
  781. {
  782. m_pDescriptionWindow->SetGdiplusBitmap(NULL);
  783. m_pDescriptionWindow->SetRTFText("");
  784. m_pDescriptionWindow->SetToolTipText(_T(""));
  785. m_pDescriptionWindow->SetFolderPath(_T(""));
  786. m_pDescriptionWindow->SetToolTipText(m_data[row].m_Desc);
  787. CClip selectedClip;
  788. selectedClip.LoadMainTable(m_data[row].m_lID);
  789. selectedClip.LoadFormats(m_data[row].m_lID, false, false, m_data[row].m_DatalID);
  790. CString clipData;
  791. COleDateTime time(selectedClip.m_Time.GetTime());
  792. clipData += "Added: " + time.Format();
  793. COleDateTime modified(selectedClip.m_lastPasteDate.GetTime());
  794. clipData += _T(" | Last Used: ") + modified.Format();
  795. if(selectedClip.m_dontAutoDelete > 0)
  796. {
  797. clipData += _T(" | Never Auto Delete");
  798. }
  799. CString csQuickPaste = selectedClip.m_csQuickPaste;
  800. if (csQuickPaste.IsEmpty() == FALSE)
  801. {
  802. clipData += _T(" | Quick Paste = ");
  803. clipData += csQuickPaste;
  804. }
  805. int shortCut = selectedClip.m_shortCut;
  806. if (shortCut > 0)
  807. {
  808. clipData += _T(" | ");
  809. clipData += CHotKey::GetHotKeyDisplayStatic(shortCut);
  810. BOOL globalShortCut = selectedClip.m_globalShortCut;
  811. if (globalShortCut)
  812. {
  813. clipData += _T(" - Global Shortcut Key");
  814. }
  815. }
  816. if (theApp.m_GroupID > 0)
  817. {
  818. int sticky = selectedClip.m_stickyClipGroupOrder;
  819. if (sticky != INVALID_STICKY)
  820. {
  821. clipData += _T(" | ");
  822. clipData += _T(" - Sticky In Group");
  823. }
  824. }
  825. else
  826. {
  827. int sticky = selectedClip.m_stickyClipOrder;
  828. if (sticky != INVALID_STICKY)
  829. {
  830. clipData += _T(" | ");
  831. clipData += _T(" - Sticky");
  832. }
  833. }
  834. int parentId = selectedClip.m_parentId;
  835. if (parentId > 0)
  836. {
  837. CString folder = FolderPath(parentId);
  838. m_pDescriptionWindow->SetFolderPath(folder);
  839. }
  840. m_pDescriptionWindow->SetClipData(clipData);
  841. IClipFormat* format = selectedClip.Clips()->FindFormatEx(CF_UNICODETEXT);
  842. if (format != nullptr)
  843. {
  844. m_pDescriptionWindow->SetToolTipText(format->GetAsCString());
  845. }
  846. if (format == NULL)
  847. {
  848. format = selectedClip.Clips()->FindFormatEx(CF_TEXT);
  849. if (format != nullptr)
  850. {
  851. CString cs(format->GetAsCStringA());
  852. m_pDescriptionWindow->SetToolTipText(cs);
  853. }
  854. }
  855. if (format == nullptr)
  856. {
  857. IClipFormat* format = selectedClip.Clips()->FindFormatEx(GetFormatID(CF_RTF));
  858. if (format != nullptr)
  859. {
  860. m_pDescriptionWindow->SetRTFText(format->GetAsCStringA());
  861. }
  862. }
  863. if (format == nullptr)
  864. {
  865. IClipFormat* format = selectedClip.Clips()->FindFormatEx(GetFormatID(_T("HTML Format")));
  866. if (format != nullptr)
  867. {
  868. CString html = CTextConvert::Utf8ToUnicode(format->GetAsCStringA());
  869. m_pDescriptionWindow->SetHtmlText(html);
  870. }
  871. }
  872. if (format == nullptr)
  873. {
  874. IClipFormat* format = selectedClip.Clips()->FindFormatEx(CF_DIB);
  875. if (format != nullptr)
  876. {
  877. m_pDescriptionWindow->SetGdiplusBitmap(format->CreateGdiplusBitmap());
  878. }
  879. }
  880. if (format == nullptr)
  881. {
  882. IClipFormat* format = selectedClip.Clips()->FindFormatEx(theApp.m_PNG_Format);
  883. if (format != nullptr)
  884. {
  885. m_pDescriptionWindow->SetGdiplusBitmap(format->CreateGdiplusBitmap());
  886. }
  887. }
  888. }
  889. void CDeleteClipData::OnContextMenu(CWnd* pWnd, CPoint point)
  890. {
  891. CMenu menu;
  892. menu.LoadMenu(IDR_MENU_DELETE_CLIP_DATA); // Load your context menu from resource
  893. CMenu* pContextMenu = menu.GetSubMenu(0); // Get the first submenu
  894. if (pContextMenu != nullptr)
  895. {
  896. int nID = pContextMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, point.x, point.y, this);
  897. switch (nID)
  898. {
  899. case ID__VIEWFULLDESCRIPTION:
  900. {
  901. CreateAndShowDescriptionWindow();
  902. }
  903. break;
  904. case ID__SAVETOFILE:
  905. {
  906. int row = m_clipList.GetNextItem(-1, LVNI_SELECTED);
  907. if (row >= 0 && row < (INT_PTR)m_data.size())
  908. {
  909. SaveClipDataItemToFile(m_data[row]);
  910. }
  911. }
  912. break;
  913. case ID__PROPERTIES:
  914. {
  915. ShowClipPropertiesWindow();
  916. }
  917. break;
  918. }
  919. }
  920. }
  921. void CDeleteClipData::ShowClipPropertiesWindow()
  922. {
  923. int row = m_clipList.GetNextItem(-1, LVNI_SELECTED);
  924. if (row >= 0 && row < (INT_PTR)m_data.size())
  925. {
  926. CDimWnd dimmer(this);
  927. CCopyProperties props(m_data[row].m_lID, this);
  928. props.DoModal();
  929. }
  930. }
  931. void CDeleteClipData::SaveClipDataItemToFile(CDeleteData item)
  932. {
  933. bool ret = false;
  934. CString extension = _T("");
  935. CString filter = _T("");
  936. if (item.m_clipboardFormat == _T("PNG"))
  937. {
  938. extension = _T("png");
  939. filter = _T("PNG Files (*.png)\0*.png\0\0");
  940. }
  941. else if (item.m_clipboardFormat == _T("CF_DIB"))
  942. {
  943. extension = _T(".bmp");
  944. filter = _T("Bitmap Files (*.bmp)\0*.bmp\0\0");
  945. }
  946. else if (item.m_clipboardFormat == _T("CF_UNICODETEXT") || item.m_clipboardFormat == _T("CF_TEXT"))
  947. {
  948. extension = _T(".txt");
  949. filter = _T("Text Files (*.txt)\0*.txt\0\0");
  950. }
  951. else if (item.m_clipboardFormat == _T("Rich Text Format"))
  952. {
  953. extension = _T(".rtf");
  954. filter = _T("Rich Text Files (*.rtf)\0*.rtf\0\0");
  955. }
  956. else
  957. {
  958. return;
  959. }
  960. OPENFILENAME ofn;
  961. TCHAR szFile[400];
  962. TCHAR szDir[400];
  963. memset(&szFile, 0, sizeof(szFile));
  964. memset(szDir, 0, sizeof(szDir));
  965. memset(&ofn, 0, sizeof(ofn));
  966. CString csInitialDir = CGetSetOptions::GetLastImportDir();
  967. STRCPY(szDir, csInitialDir);
  968. ofn.lStructSize = sizeof(OPENFILENAME);
  969. ofn.hwndOwner = m_hWnd;
  970. ofn.lpstrFile = szFile;
  971. ofn.nMaxFile = sizeof(szFile);
  972. CString x = _T("Exported Ditto Clips (.txt)\0*.txt\0\0");
  973. ofn.lpstrFilter = filter;
  974. ofn.nFilterIndex = 1;
  975. ofn.lpstrFileTitle = nullptr;
  976. ofn.nMaxFileTitle = 0;
  977. ofn.lpstrInitialDir = szDir;
  978. ofn.lpstrDefExt = extension;
  979. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR;
  980. if (GetSaveFileName(&ofn))
  981. {
  982. using namespace nsPath;
  983. CString startingFilePath = ofn.lpstrFile;
  984. CPath path(ofn.lpstrFile);
  985. CString csPath = path.GetPath();
  986. CString csExt = path.GetExtension();
  987. path.RemoveExtension();
  988. CString csFileName = path.GetName();
  989. CClip selectedClip;
  990. selectedClip.LoadFormats(item.m_lID, false, false, item.m_DatalID);
  991. if (item.m_clipboardFormat == _T("PNG"))
  992. {
  993. selectedClip.WriteImageToFile(ofn.lpstrFile);
  994. }
  995. else if (item.m_clipboardFormat == _T("CF_DIB"))
  996. {
  997. selectedClip.WriteImageToFile(ofn.lpstrFile);
  998. }
  999. else if (item.m_clipboardFormat == _T("CF_UNICODETEXT"))
  1000. {
  1001. selectedClip.WriteTextToFile(ofn.lpstrFile, TRUE, FALSE, FALSE);
  1002. }
  1003. else if (item.m_clipboardFormat == _T("CF_TEXT"))
  1004. {
  1005. selectedClip.WriteTextToFile(ofn.lpstrFile, FALSE, TRUE, FALSE);
  1006. }
  1007. else if (item.m_clipboardFormat == _T("Rich Text Format"))
  1008. {
  1009. selectedClip.WriteTextToFile(ofn.lpstrFile, FALSE, FALSE, TRUE);
  1010. }
  1011. }
  1012. }
  1013. void CDeleteClipData::OnCancel()
  1014. {
  1015. //don't close on escape key
  1016. }