GroupTree.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. // GroupTree.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "cp_main.h"
  5. #include "GroupTree.h"
  6. #include ".\grouptree.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CGroupTree
  14. CGroupTree::CGroupTree()
  15. {
  16. m_lSelectedFolderID = -1;
  17. m_bShowCounts = true;
  18. }
  19. CGroupTree::~CGroupTree()
  20. {
  21. }
  22. BEGIN_MESSAGE_MAP(CGroupTree, CTreeCtrl)
  23. //{{AFX_MSG_MAP(CGroupTree)
  24. ON_WM_CREATE()
  25. ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
  26. ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnKeydown)
  27. //}}AFX_MSG_MAP
  28. ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnTvnEndlabeledit)
  29. ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnTvnBeginlabeledit)
  30. END_MESSAGE_MAP()
  31. /////////////////////////////////////////////////////////////////////////////
  32. // CGroupTree message handlers
  33. BOOL CGroupTree::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
  34. {
  35. // TODO: Add your specialized code here and/or call the base class
  36. dwStyle = dwStyle | TVS_EDITLABELS | TVS_SHOWSELALWAYS;
  37. return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
  38. }
  39. int CGroupTree::OnCreate(LPCREATESTRUCT lpCreateStruct)
  40. {
  41. if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
  42. return -1;
  43. CImageList iml;
  44. iml.Create(18, 16, ILC_COLOR8, 0, 1);
  45. m_bmClosedFolder.LoadBitmap(IDB_CLOSED_FOLDER);
  46. iml.Add(&m_bmClosedFolder, RGB(255, 0, 0));
  47. m_bmOpenFolder.LoadBitmap(IDB_OPEN_FOLDER);
  48. iml.Add(&m_bmOpenFolder, RGB(255, 0, 0));
  49. SetImageList(&iml, TVSIL_NORMAL);
  50. iml.Detach();
  51. m_DropTarget.Register(this);
  52. m_DropTarget.SetDropTarget(this);
  53. return 0;
  54. }
  55. void CGroupTree::FillTree()
  56. {
  57. DeleteAllItems();
  58. CString cs;
  59. cs.Format(_T("Root (%d)"), GetGroupCount(-1));
  60. HTREEITEM hItem = InsertItem(cs, TVI_ROOT);
  61. SetItemData(hItem, -1);
  62. SetItemState(hItem, TVIS_EXPANDED, TVIS_EXPANDED);
  63. if(m_lSelectedFolderID < 0)
  64. SelectItem(hItem);
  65. FillTree(-1, hItem);
  66. }
  67. void CGroupTree::FillTree(long lParentID, HTREEITEM hParent)
  68. {
  69. try
  70. {
  71. CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID, mText FROM Main WHERE bIsGroup = 1 AND lParentID = %d"), lParentID);
  72. if(q.eof() == false)
  73. {
  74. HTREEITEM hItem;
  75. CString cs;
  76. while(!q.eof())
  77. {
  78. int nGroupID = q.getIntField(_T("lID"));
  79. if(m_bShowCounts)
  80. {
  81. cs.Format(_T("%s (%d)"), q.getStringField(_T("mText")), GetGroupCount(nGroupID));
  82. }
  83. else
  84. {
  85. cs.Format(_T("%s"), q.getStringField(_T("mText")));
  86. }
  87. if(nGroupID == m_lSelectedFolderID)
  88. {
  89. hItem = InsertItem(cs, 1, 1, hParent);
  90. SelectItem(hItem);
  91. }
  92. else
  93. {
  94. hItem = InsertItem(cs, 0, 0, hParent);
  95. }
  96. SetItemData(hItem, nGroupID);
  97. FillTree(nGroupID, hItem);
  98. q.nextRow();
  99. }
  100. }
  101. }
  102. CATCH_SQLITE_EXCEPTION
  103. }
  104. void CGroupTree::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
  105. {
  106. HTREEITEM hItem = GetNextItem(TVI_ROOT, TVGN_CARET);
  107. if(hItem)
  108. SendToParent(hItem);
  109. *pResult = 1;
  110. }
  111. long CGroupTree::GetSelectedGroup()
  112. {
  113. HTREEITEM hItem = GetNextItem(TVI_ROOT, TVGN_CARET);
  114. if(hItem)
  115. return (long)GetItemData(hItem);
  116. return -1;
  117. }
  118. void CGroupTree::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult)
  119. {
  120. TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR;
  121. switch(pTVKeyDown->wVKey)
  122. {
  123. case VK_RETURN:
  124. {
  125. HTREEITEM hItem = GetNextItem(TVI_ROOT, TVGN_CARET);
  126. if(hItem)
  127. SendToParent(hItem);
  128. break;
  129. }
  130. case VK_F2:
  131. {
  132. HTREEITEM hItem = GetNextItem(TVI_ROOT, TVGN_CARET);
  133. if(hItem)
  134. EditLabel(hItem);
  135. }
  136. break;
  137. }
  138. *pResult = 1;
  139. }
  140. void CGroupTree::SendToParent(HTREEITEM Item)
  141. {
  142. long lID = -1;
  143. if(Item != NULL)
  144. lID = GetItemData(Item);
  145. ::PostMessage(m_NotificationWnd, NM_GROUP_TREE_MESSAGE, lID, 0);
  146. RefreshTreeItem(Item);
  147. }
  148. HTREEITEM CGroupTree::AddNode(CString csText, long lID)
  149. {
  150. HTREEITEM hItem;
  151. HTREEITEM hParent = GetNextItem(TVI_ROOT, TVGN_CARET);
  152. if(hParent == NULL)
  153. return NULL;
  154. hItem = InsertItem(csText, 1, 1, hParent);
  155. SelectItem(hItem);
  156. SetItemData(hItem, lID);
  157. return hItem;
  158. }
  159. int CGroupTree::GetGroupCount(long lGroupID)
  160. {
  161. long lCount = 0;
  162. try
  163. {
  164. lCount = theApp.m_db.execScalarEx(_T("SELECT COUNT(lID) FROM Main WHERE lParentID = %d"), lGroupID);
  165. }
  166. CATCH_SQLITE_EXCEPTION
  167. return lCount;
  168. }
  169. void CGroupTree::OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult)
  170. {
  171. LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
  172. *pResult = 0;
  173. long lID = GetItemData(pTVDispInfo->item.hItem);
  174. if((lID < 0 && lID != NEW_GROUP_ID) || pTVDispInfo->item.pszText == NULL)
  175. {
  176. if(lID == NEW_GROUP_ID)
  177. DeleteItem(pTVDispInfo->item.hItem);
  178. return;
  179. }
  180. if(lID == NEW_GROUP_ID)
  181. {
  182. HTREEITEM hParent = GetParentItem(pTVDispInfo->item.hItem);
  183. long lParentID = -1;
  184. if(hParent != NULL)
  185. lParentID = GetItemData(hParent);
  186. lID = NewGroupID(lParentID, pTVDispInfo->item.pszText);
  187. if(lID >= 0)
  188. {
  189. SetItemData(pTVDispInfo->item.hItem, lID);
  190. }
  191. else
  192. {
  193. DeleteItem(pTVDispInfo->item.hItem);
  194. return;
  195. }
  196. }
  197. CClip clip;
  198. if(clip.LoadMainTable(lID))
  199. {
  200. clip.m_Desc = pTVDispInfo->item.pszText;
  201. if(clip.ModifyMainTable())
  202. {
  203. CString cs;
  204. cs.Format(_T("%s (%d)"), pTVDispInfo->item.pszText, GetGroupCount(lID));
  205. SetItemText(pTVDispInfo->item.hItem, cs);
  206. }
  207. }
  208. }
  209. void CGroupTree::OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult)
  210. {
  211. LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
  212. long lID = GetItemData(pTVDispInfo->item.hItem);
  213. if(lID < 0 && lID != NEW_GROUP_ID)
  214. {
  215. *pResult = 1;
  216. return;
  217. }
  218. if(m_bShowCounts)
  219. {
  220. CString csText = GetItemText(pTVDispInfo->item.hItem);
  221. if(csText.ReverseFind(')') == csText.GetLength()-1)
  222. {
  223. int nPos = csText.ReverseFind('(');
  224. csText = csText.Left(nPos);
  225. csText = csText.Trim();
  226. CEdit* pEdit = GetEditControl();
  227. if (pEdit != NULL)
  228. {
  229. pEdit->SetWindowText(csText);
  230. }
  231. }
  232. }
  233. // TODO: Add your control notification handler code here
  234. *pResult = 0;
  235. }
  236. void CGroupTree::RefreshTreeItem(HTREEITEM Item)
  237. {
  238. CString csText = GetItemText(Item);
  239. if(csText.ReverseFind(')') == csText.GetLength()-1)
  240. {
  241. int nPos = csText.ReverseFind('(');
  242. csText = csText.Left(nPos);
  243. csText = csText.Trim();
  244. }
  245. CString csItemText;
  246. long lGroupID = GetItemData(Item);
  247. csItemText.Format(_T("%s (%d)"), csText, GetGroupCount(lGroupID));
  248. SetItemText(Item, csItemText);
  249. }
  250. DROPEFFECT CGroupTree::DragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
  251. {
  252. return DragOver(pDataObject, dwKeyState, point);
  253. }
  254. DROPEFFECT CGroupTree::DragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
  255. {
  256. if(pDataObject->IsDataAvailable(theApp.m_DittoIdsFormat) == false)
  257. return DROPEFFECT_NONE;
  258. HTREEITEM hItem = HitTest(point);
  259. SelectDropTarget(hItem);
  260. return DROPEFFECT_MOVE;
  261. }
  262. BOOL CGroupTree::Drop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
  263. {
  264. HTREEITEM hItem = HitTest(point);
  265. long lGroupID = GetItemData(hItem);
  266. CClipIDs Clips;
  267. HGLOBAL hData = pDataObject->GetGlobalData(theApp.m_DittoIdsFormat);
  268. if(hData)
  269. {
  270. int *pData = (int*)GlobalLock(hData);
  271. if(pData)
  272. {
  273. int nItems = GlobalSize(hData) / sizeof(int);
  274. for(int nPos = 0; nPos < nItems; nPos++)
  275. {
  276. Clips.Add(pData[nPos]);
  277. }
  278. GlobalUnlock(hData);
  279. }
  280. }
  281. if(Clips.GetCount() > 0)
  282. {
  283. Clips.MoveTo(lGroupID);
  284. RefreshTreeItem(hItem);
  285. ::SendMessage(m_NotificationWnd, WM_REFRESH_VIEW, 1, 0);
  286. }
  287. SelectDropTarget(NULL);
  288. SelectItem(hItem);
  289. return FALSE;
  290. }
  291. void CGroupTree::DragLeave()
  292. {
  293. SelectDropTarget(NULL);
  294. }