DeleteClipData.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  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. // CDeleteClipData dialog
  9. IMPLEMENT_DYNAMIC(CDeleteClipData, CDialog)
  10. CDeleteClipData::CDeleteClipData(CWnd* pParent /*=NULL*/)
  11. : CDialog(CDeleteClipData::IDD, pParent)
  12. , m_clipTitle(_T(""))
  13. , m_filterByClipTitle(FALSE)
  14. , m_filterByCreatedDate(FALSE)
  15. , m_filterByLastUsedDate(FALSE)
  16. , m_filterByClipboardFormat(FALSE)
  17. , m_createdDateStart(COleDateTime::GetCurrentTime())
  18. , m_createdDateEnd(COleDateTime::GetCurrentTime())
  19. , m_createdTimeStart(COleDateTime::GetCurrentTime())
  20. , m_createdTimeEnd(COleDateTime::GetCurrentTime())
  21. , m_usedTimeStart(COleDateTime::GetCurrentTime())
  22. , m_usedTimeEnd(COleDateTime::GetCurrentTime())
  23. , m_usedDateStart(COleDateTime::GetCurrentTime())
  24. , m_usedDateEnd(COleDateTime::GetCurrentTime())
  25. , m_databaseSize(_T(""))
  26. , m_selectedSize(_T(""))
  27. , m_toDeleteSize(_T(""))
  28. {
  29. }
  30. CDeleteClipData::~CDeleteClipData()
  31. {
  32. }
  33. void CDeleteClipData::DoDataExchange(CDataExchange* pDX)
  34. {
  35. CDialog::DoDataExchange(pDX);
  36. DDX_Control(pDX, IDC_LIST2, m_List);
  37. DDX_Text(pDX, IDC_EDIT_CLIP_TITLE, m_clipTitle);
  38. DDX_Check(pDX, IDC_CHECK_CLIP_TITLE, m_filterByClipTitle);
  39. DDX_Check(pDX, IDC_CHECK_CREATE_DATE, m_filterByCreatedDate);
  40. DDX_Check(pDX, IDC_CHECK_LAST_USE_DATE, m_filterByLastUsedDate);
  41. DDX_Check(pDX, IDC_CHECK_DATA_FORMAT, m_filterByClipboardFormat);
  42. DDX_Control(pDX, IDC_COMBO_DATA_FORMAT, m_clipboardFomatCombo);
  43. DDX_DateTimeCtrl(pDX, IDC_DATE_CREATE_START, m_createdDateStart);
  44. DDX_DateTimeCtrl(pDX, IDC_DATE_CREATE_END, m_createdDateEnd);
  45. DDX_DateTimeCtrl(pDX, IDC_TIME_CREATE_START, m_createdTimeStart);
  46. DDX_DateTimeCtrl(pDX, IDC_TIME_CREATE_END, m_createdTimeEnd);
  47. DDX_DateTimeCtrl(pDX, IDC_TIME_USE_START, m_usedTimeStart);
  48. DDX_DateTimeCtrl(pDX, IDC_TIME_USE_END, m_usedTimeEnd);
  49. DDX_DateTimeCtrl(pDX, IDC_DATE_USE_START, m_usedDateStart);
  50. DDX_DateTimeCtrl(pDX, IDC_DATE_USE_END, m_usedDateEnd);
  51. DDX_Text(pDX, IDC_STATIC_DB_SIZE, m_databaseSize);
  52. DDX_Text(pDX, IDC_STATIC_SELECTED_SIZE, m_selectedSize);
  53. DDX_Text(pDX, IDC_STATIC_TO_DELETE_SIZE, m_toDeleteSize);
  54. }
  55. BEGIN_MESSAGE_MAP(CDeleteClipData, CDialog)
  56. ON_WM_CLOSE()
  57. ON_WM_SIZE()
  58. ON_WM_NCDESTROY()
  59. ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CDeleteClipData::OnBnClickedButtonSearch)
  60. ON_NOTIFY(LVN_KEYDOWN, IDC_LIST2, &CDeleteClipData::OnLvnKeydownList2)
  61. ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, &CDeleteClipData::OnLvnItemchangedList2)
  62. ON_NOTIFY(HDN_GETDISPINFO, 0, &CDeleteClipData::OnHdnGetdispinfoList2)
  63. ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST2, &CDeleteClipData::OnLvnGetdispinfoList2)
  64. ON_BN_CLICKED(IDC_CHECK_CLIP_TITLE, &CDeleteClipData::OnBnClickedCheckClipTitle)
  65. ON_BN_CLICKED(IDC_BUTTON_APPLY, &CDeleteClipData::OnBnClickedButtonApply)
  66. ON_BN_CLICKED(IDCANCEL, &CDeleteClipData::OnBnClickedCancel)
  67. ON_WM_TIMER()
  68. END_MESSAGE_MAP()
  69. BOOL CDeleteClipData::OnInitDialog()
  70. {
  71. CDialog::OnInitDialog();
  72. //theApp.m_Language.UpdateGlobalHotKeys(this);
  73. m_Resize.SetParent(m_hWnd);
  74. m_Resize.AddControl(IDC_LIST2, DR_SizeHeight | DR_SizeWidth);
  75. m_Resize.AddControl(IDCANCEL, DR_MoveTop | DR_MoveLeft);
  76. m_Resize.AddControl(IDC_BUTTON_APPLY, DR_MoveTop | DR_MoveLeft);
  77. m_Resize.AddControl(IDC_STATIC_TO_DELETE_TEXT, DR_MoveTop);
  78. m_Resize.AddControl(IDC_STATIC_TO_DELETE_SIZE, DR_MoveTop);
  79. m_Resize.AddControl(IDC_STATIC_SELECTED_SIZE, DR_MoveTop);
  80. m_Resize.AddControl(IDC_STATIC_SELECTED_SIZE_TEXT, DR_MoveTop);
  81. m_Resize.AddControl(IDC_STATIC_DB_SIZE, DR_MoveTop);
  82. m_Resize.AddControl(IDC_STATIC_DB_SIZE_TEXT, DR_MoveTop);
  83. InitListCtrlCols();
  84. SetTimer(1, 500, 0);
  85. SetDbSize();
  86. return TRUE;
  87. }
  88. void CDeleteClipData::SetDbSize()
  89. {
  90. __int64 size = FileSize(GetDBName());
  91. const int MAX_FILE_SIZE_BUFFER = 255;
  92. TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
  93. StrFormatByteSize(size, szFileSize, MAX_FILE_SIZE_BUFFER);
  94. m_databaseSize = szFileSize;
  95. UpdateData(0);
  96. }
  97. void CDeleteClipData::InitListCtrlCols()
  98. {
  99. m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT);
  100. m_List.InsertColumn(0, theApp.m_Language.GetGlobalHotKeyString("Title", "Title"), LVCFMT_LEFT, 250);
  101. m_List.InsertColumn(1, theApp.m_Language.GetGlobalHotKeyString("Created", "Created"), LVCFMT_LEFT, 150);
  102. m_List.InsertColumn(2, theApp.m_Language.GetGlobalHotKeyString("Last Used", "Last Used"), LVCFMT_LEFT, 150);
  103. m_List.InsertColumn(3, theApp.m_Language.GetGlobalHotKeyString("Type", "Type"), LVCFMT_LEFT, 200);
  104. m_List.InsertColumn(4, theApp.m_Language.GetGlobalHotKeyString("Data Size", "Data Size"), LVCFMT_LEFT, 100);
  105. }
  106. void CDeleteClipData::LoadItems()
  107. {
  108. CWaitCursor wait;
  109. m_data.clear();
  110. m_filteredOut.clear();
  111. m_toDelete.clear();
  112. UpdateToDeleteSize();
  113. CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT Main.lID, Main.mText, Main.lDate, Main.lastPasteDate, "
  114. _T("Data.lID AS DataID, Data.strClipBoardFormat, length(Data.ooData) AS DataLength ")
  115. _T("FROM Data ")
  116. _T("INNER JOIN Main on Main.lID = Data.lParentID ")
  117. _T("ORDER BY length(ooData) DESC")));
  118. int row = 0;
  119. while (q.eof() == false)
  120. {
  121. CDeleteData data;
  122. data.m_lID = q.getIntField(_T("lID"));
  123. data.m_Desc = q.getStringField(_T("mText"));
  124. data.m_createdDateTime = q.getIntField(_T("lDate"));
  125. data.m_lastUsedDateTime = q.getIntField(_T("lastPasteDate"));
  126. data.m_clipboardFormat = q.getStringField(_T("strClipBoardFormat"));
  127. data.m_dataSize = q.getIntField(_T("DataLength"));
  128. data.m_DatalID = q.getIntField(_T("DataID"));
  129. m_data.push_back(data);
  130. row++;
  131. q.nextRow();
  132. }
  133. m_List.SetItemCountEx(row, 0);
  134. }
  135. //void CDeleteClipData::AddRow(CppSQLite3Query& q, int row)
  136. //{
  137. // LVITEM lvi;
  138. //
  139. // lvi.mask = LVIF_TEXT;
  140. // lvi.iItem = row;
  141. //
  142. // lvi.iSubItem = 0;
  143. // lvi.pszText = (LPTSTR) (LPCTSTR) (q.getStringField(_T("mText")));
  144. // m_List.InsertItem(&lvi);
  145. //
  146. // CTime created = q.getIntField(_T("lDate"));
  147. // COleDateTime dtTime(created.GetTime());
  148. //
  149. // CTime pasted = q.getIntField(_T("lastPasteDate"));
  150. // COleDateTime dtPastedTime(pasted.GetTime());
  151. //
  152. // m_List.SetItemText(row, 1, dtTime.Format());
  153. // m_List.SetItemText(row, 2, dtPastedTime.Format());
  154. // m_List.SetItemText(row, 3, q.getStringField(_T("strClipBoardFormat")));
  155. //
  156. // int dataLength = q.getIntField(_T("DataLength"));
  157. //
  158. // const int MAX_FILE_SIZE_BUFFER = 255;
  159. // TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
  160. // StrFormatByteSize(dataLength, szFileSize, MAX_FILE_SIZE_BUFFER);
  161. //
  162. // m_List.SetItemText(row, 4, szFileSize);
  163. //
  164. // m_List.SetItemData(row, ));
  165. //}
  166. void CDeleteClipData::SetNotifyWnd(HWND hWnd)
  167. {
  168. m_hWndParent = hWnd;
  169. }
  170. void CDeleteClipData::OnClose()
  171. {
  172. DestroyWindow();
  173. }
  174. void CDeleteClipData::OnSize(UINT nType, int cx, int cy)
  175. {
  176. CDialog::OnSize(nType, cx, cy);
  177. m_Resize.MoveControls(CSize(cx, cy));
  178. }
  179. void CDeleteClipData::OnNcDestroy()
  180. {
  181. CDialog::OnNcDestroy();
  182. ::PostMessage(m_hWndParent, WM_DELETE_CLIPS_CLOSED, 0, 0);
  183. }
  184. // CDeleteClipData message handlers
  185. void CDeleteClipData::OnBnClickedButtonSearch()
  186. {
  187. FilterItems();
  188. }
  189. void CDeleteClipData::FilterItems()
  190. {
  191. UpdateData();
  192. //First search the already filtered text, see if we need to add them back in
  193. std::vector<int> filteredRowsToDelete;
  194. std::vector<CDeleteData> addBackIn;
  195. INT_PTR count = m_filteredOut.size();
  196. for (int i = 0; i < count; i++)
  197. {
  198. CDeleteData data = m_filteredOut[i];
  199. if (MatchesFilter(&data))
  200. {
  201. addBackIn.push_back(data);
  202. filteredRowsToDelete.push_back(i);
  203. }
  204. }
  205. //next search the main list
  206. std::vector<int> rowsToDelete;
  207. count = m_data.size();
  208. for (int i = 0; i < count; i++)
  209. {
  210. CDeleteData data = m_data[i];
  211. if(MatchesFilter(&data) == false)
  212. {
  213. m_filteredOut.push_back(data);
  214. rowsToDelete.push_back(i);
  215. }
  216. }
  217. //Add back in the filtered out ones that now match
  218. count = addBackIn.size();
  219. for (int i = 0; i < count; i++)
  220. {
  221. CDeleteData data = addBackIn[i];
  222. m_data.push_back(data);
  223. }
  224. int toSelect = -1;
  225. //Remove from the main list the ones that don't match
  226. count = rowsToDelete.size();
  227. for (int i = count - 1; i >= 0; i--)
  228. {
  229. int row = rowsToDelete[i];
  230. toSelect = row;
  231. m_data.erase(m_data.begin() + row);
  232. }
  233. //Remove the rows that were filtered out but now match
  234. count = filteredRowsToDelete.size();
  235. for (int i = count - 1; i >= 0; i--)
  236. {
  237. int row = filteredRowsToDelete[i];
  238. m_filteredOut.erase(m_filteredOut.begin() + row);
  239. }
  240. if (toSelect > -1)
  241. {
  242. m_List.SetItemState(toSelect, LVIS_SELECTED, LVIS_SELECTED);
  243. }
  244. m_List.SetItemCountEx(m_data.size(), 0);
  245. }
  246. bool CDeleteClipData::MatchesFilter(CDeleteData *pdata)
  247. {
  248. if(m_filterByClipTitle &&
  249. m_clipTitle != _T("") &&
  250. pdata->m_Desc != _T(""))
  251. {
  252. if(pdata->m_Desc.MakeLower().Find(m_clipTitle.MakeLower()) == -1)
  253. {
  254. return false;
  255. }
  256. }
  257. return true;
  258. }
  259. void CDeleteClipData::OnLvnKeydownList2(NMHDR *pNMHDR, LRESULT *pResult)
  260. {
  261. LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
  262. // TODO: Add your control notification handler code here
  263. switch(pLVKeyDow->wVKey)
  264. {
  265. case VK_DELETE:
  266. DeleteSelectedRows();
  267. break;
  268. }
  269. *pResult = 0;
  270. }
  271. void CDeleteClipData::DeleteSelectedRows()
  272. {
  273. POSITION pos = m_List.GetFirstSelectedItemPosition();
  274. std::vector<int> rowsToDelete;
  275. if (pos != NULL)
  276. {
  277. while (pos)
  278. {
  279. int row = m_List.GetNextSelectedItem(pos);
  280. rowsToDelete.push_back(row);
  281. }
  282. }
  283. int toSelect = -1;
  284. INT_PTR count = rowsToDelete.size();
  285. for (int i = count-1; i >= 0; i--)
  286. {
  287. int row = rowsToDelete[i];
  288. toSelect = row;
  289. m_toDelete.push_back(m_data[row]);
  290. m_data.erase(m_data.begin() + row);
  291. }
  292. if(toSelect > -1)
  293. {
  294. m_List.SetItemState(toSelect, LVIS_SELECTED, LVIS_SELECTED);
  295. }
  296. UpdateToDeleteSize();
  297. m_List.SetItemCountEx(m_data.size(), 0);
  298. }
  299. void CDeleteClipData::UpdateToDeleteSize()
  300. {
  301. __int64 toDeleteDataSize = 0;
  302. INT_PTR count = m_toDelete.size();
  303. for (int i = 0; i < count; i++)
  304. {
  305. CDeleteData data = m_toDelete[i];
  306. toDeleteDataSize += data.m_dataSize;
  307. }
  308. const int MAX_FILE_SIZE_BUFFER = 255;
  309. TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
  310. StrFormatByteSize(toDeleteDataSize, szFileSize, MAX_FILE_SIZE_BUFFER);
  311. m_toDeleteSize = szFileSize;
  312. UpdateData(0);
  313. }
  314. void CDeleteClipData::OnLvnItemchangedList2(NMHDR *pNMHDR, LRESULT *pResult)
  315. {
  316. LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
  317. POSITION pos = m_List.GetFirstSelectedItemPosition();
  318. __int64 selectedDataSize = 0;
  319. if (pos != NULL)
  320. {
  321. while (pos)
  322. {
  323. INT_PTR row = m_List.GetNextSelectedItem(pos);
  324. if(row >= 0 && row < m_data.size())
  325. {
  326. selectedDataSize += m_data[row].m_dataSize;
  327. }
  328. }
  329. }
  330. const int MAX_FILE_SIZE_BUFFER = 255;
  331. TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
  332. StrFormatByteSize(selectedDataSize, szFileSize, MAX_FILE_SIZE_BUFFER);
  333. m_selectedSize = szFileSize;
  334. UpdateData(0);
  335. *pResult = 0;
  336. }
  337. void CDeleteClipData::OnHdnGetdispinfoList2(NMHDR *pNMHDR, LRESULT *pResult)
  338. {
  339. LPNMHDDISPINFO pDispInfo = reinterpret_cast<LPNMHDDISPINFO>(pNMHDR);
  340. if (pDispInfo->mask &LVIF_TEXT)
  341. {
  342. switch (pDispInfo->iItem)
  343. {
  344. case 0:
  345. break;
  346. }
  347. }
  348. *pResult = 0;
  349. }
  350. void CDeleteClipData::OnLvnGetdispinfoList2(NMHDR *pNMHDR, LRESULT *pResult)
  351. {
  352. NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
  353. if (pDispInfo->item.mask & LVIF_TEXT)
  354. {
  355. switch (pDispInfo->item.iSubItem)
  356. {
  357. case 0:
  358. {
  359. lstrcpyn(pDispInfo->item.pszText, m_data[pDispInfo->item.iItem].m_Desc, pDispInfo->item.cchTextMax);
  360. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  361. }
  362. break;
  363. case 1:
  364. {
  365. COleDateTime dtTime(m_data[pDispInfo->item.iItem].m_createdDateTime.GetTime());
  366. lstrcpyn(pDispInfo->item.pszText, dtTime.Format(), pDispInfo->item.cchTextMax);
  367. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  368. }
  369. break;
  370. case 2:
  371. {
  372. COleDateTime dtTime(m_data[pDispInfo->item.iItem].m_lastUsedDateTime.GetTime());
  373. lstrcpyn(pDispInfo->item.pszText, dtTime.Format(), pDispInfo->item.cchTextMax);
  374. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  375. }
  376. break;
  377. case 3:
  378. {
  379. lstrcpyn(pDispInfo->item.pszText, m_data[pDispInfo->item.iItem].m_clipboardFormat, pDispInfo->item.cchTextMax);
  380. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  381. }
  382. break;
  383. case 4:
  384. {
  385. const int MAX_FILE_SIZE_BUFFER = 255;
  386. TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
  387. StrFormatByteSize(m_data[pDispInfo->item.iItem].m_dataSize, szFileSize, MAX_FILE_SIZE_BUFFER);
  388. lstrcpyn(pDispInfo->item.pszText, szFileSize, pDispInfo->item.cchTextMax);
  389. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  390. }
  391. break;
  392. }
  393. }
  394. *pResult = 0;
  395. }
  396. void CDeleteClipData::OnBnClickedCheckClipTitle()
  397. {
  398. UpdateData();
  399. ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT_CLIP_TITLE), m_filterByClipTitle);
  400. ::SetFocus(::GetDlgItem(m_hWnd, IDC_EDIT_CLIP_TITLE));
  401. }
  402. void CDeleteClipData::OnBnClickedButtonApply()
  403. {
  404. if(MessageBox(_T("Delete items? This cannot be undone!"), _T(""), MB_YESNO|MB_ICONWARNING) == IDYES)
  405. {
  406. ApplyDelete();
  407. }
  408. }
  409. void CDeleteClipData::ApplyDelete()
  410. {
  411. CWaitCursor wait;
  412. INT_PTR count = m_toDelete.size();
  413. for (int i = 0; i < count; i++)
  414. {
  415. CDeleteData data = m_toDelete[i];
  416. try
  417. {
  418. int deleteCount = theApp.m_db.execDMLEx(_T("DELETE FROM Data where lID = %d"), data.m_DatalID);
  419. //If there are no more children for this clip then delete the parent
  420. int parentDeleteCount = theApp.m_db.execDMLEx(_T("DELETE FROM Main where lID IN ")
  421. _T("(")
  422. _T("SELECT Main.lID ")
  423. _T("FROM Main ")
  424. _T("LEFT OUTER JOIN Data on Data.lParentID = Main.lID ")
  425. _T("WHERE bIsGroup = 0 AND Main.lID = %d ")
  426. _T("Group by Main.lID ")
  427. _T("having Count(Data.lID) = 0 ")
  428. _T(")"), data.m_lID);
  429. }
  430. CATCH_SQLITE_EXCEPTION
  431. }
  432. SetDbSize();
  433. LoadItems();
  434. FilterItems();
  435. }
  436. void CDeleteClipData::OnBnClickedCancel()
  437. {
  438. DestroyWindow();
  439. }
  440. void CDeleteClipData::OnTimer(UINT_PTR nIDEvent)
  441. {
  442. switch(nIDEvent)
  443. {
  444. case 1:
  445. LoadItems();
  446. KillTimer(1);
  447. break;
  448. }
  449. CDialog::OnTimer(nIDEvent);
  450. }