StringsCategoryViewDialog.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. // StringsCategoryViewDialog.cpp : implementation file
  19. //
  20. #include "stdafx.h"
  21. #include "leveledit.h"
  22. #include "stringscategoryviewdialog.h"
  23. #include "translateobj.h"
  24. #include "translatedb.h"
  25. #include "tdbcategory.h"
  26. #include "editstringdialog.h"
  27. #include "editstringtwiddlerdialog.h"
  28. #include "utils.h"
  29. #include "stringlibrarydialog.h"
  30. #include "stringtwiddler.h"
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36. /////////////////////////////////////////////////////////////////////////////
  37. // Local prototypes
  38. /////////////////////////////////////////////////////////////////////////////
  39. static int CALLBACK StringEntrySortCompareFn (LPARAM param1, LPARAM param2, LPARAM sort_info);
  40. /////////////////////////////////////////////////////////////////////////////
  41. //
  42. // StringsCategoryViewDialogClass
  43. //
  44. /////////////////////////////////////////////////////////////////////////////
  45. StringsCategoryViewDialogClass::StringsCategoryViewDialogClass (CWnd *pParent)
  46. : SelectedObjectID (0),
  47. CategoryID (0),
  48. IsInitialized (false),
  49. ShouldUpdateVersionNumber (false),
  50. CurrentColSort (COL_ID),
  51. AscendingSort (true),
  52. CallbackObject (NULL),
  53. EditMode (EDIT_MODE_STRING),
  54. CDialog(StringsCategoryViewDialogClass::IDD, pParent)
  55. {
  56. //{{AFX_DATA_INIT(StringsCategoryViewDialogClass)
  57. // NOTE: the ClassWizard will add member initialization here
  58. //}}AFX_DATA_INIT
  59. Columns.Add (COL_ID);
  60. Columns.Add (COL_TEXT);
  61. ColumnSettings[COL_ID].id = COL_ID;
  62. ColumnSettings[COL_ID].name = "ID";
  63. ColumnSettings[COL_ID].width = 0.33F;
  64. ColumnSettings[COL_TEXT].id = COL_TEXT;
  65. ColumnSettings[COL_TEXT].name = "English Test";
  66. ColumnSettings[COL_TEXT].width = 0.66F;
  67. return ;
  68. }
  69. /////////////////////////////////////////////////////////////////////////////
  70. //
  71. // DoDataExchange
  72. //
  73. /////////////////////////////////////////////////////////////////////////////
  74. void
  75. StringsCategoryViewDialogClass::DoDataExchange (CDataExchange *pDX)
  76. {
  77. CDialog::DoDataExchange(pDX);
  78. //{{AFX_DATA_MAP(StringsCategoryViewDialogClass)
  79. DDX_Control(pDX, IDC_STRING_LIST, m_ListCtrl);
  80. //}}AFX_DATA_MAP
  81. return ;
  82. }
  83. BEGIN_MESSAGE_MAP(StringsCategoryViewDialogClass, CDialog)
  84. //{{AFX_MSG_MAP(StringsCategoryViewDialogClass)
  85. ON_NOTIFY(LVN_COLUMNCLICK, IDC_STRING_LIST, OnColumnclickStringList)
  86. ON_NOTIFY(NM_DBLCLK, IDC_STRING_LIST, OnDblclkStringList)
  87. ON_NOTIFY(LVN_DELETEITEM, IDC_STRING_LIST, OnDeleteitemStringList)
  88. ON_NOTIFY(LVN_KEYDOWN, IDC_STRING_LIST, OnKeydownStringList)
  89. ON_WM_SIZE()
  90. ON_NOTIFY(LVN_ITEMCHANGED, IDC_STRING_LIST, OnItemchangedStringList)
  91. //}}AFX_MSG_MAP
  92. END_MESSAGE_MAP()
  93. /////////////////////////////////////////////////////////////////////////////
  94. //
  95. // Remove_Column
  96. //
  97. /////////////////////////////////////////////////////////////////////////////
  98. void
  99. StringsCategoryViewDialogClass::Remove_Column (int col_id)
  100. {
  101. for (int index = 0; index < Columns.Count (); index ++) {
  102. //
  103. // If this is the column we were looking for, remove
  104. // it from list
  105. //
  106. if (Columns[index] == col_id) {
  107. Columns.Delete (index);
  108. break;
  109. }
  110. }
  111. return ;
  112. }
  113. /////////////////////////////////////////////////////////////////////////////
  114. //
  115. // Set_Column_Width
  116. //
  117. /////////////////////////////////////////////////////////////////////////////
  118. void
  119. StringsCategoryViewDialogClass::Set_Column_Width (int col_id, float width)
  120. {
  121. ColumnSettings[col_id].width = width;
  122. return ;
  123. }
  124. /////////////////////////////////////////////////////////////////////////////
  125. //
  126. // Create
  127. //
  128. /////////////////////////////////////////////////////////////////////////////
  129. void
  130. StringsCategoryViewDialogClass::Create (CWnd *parent_wnd)
  131. {
  132. CDialog::Create (StringsCategoryViewDialogClass::IDD, parent_wnd);
  133. return ;
  134. }
  135. /////////////////////////////////////////////////////////////////////////////
  136. //
  137. // OnInitDialog
  138. //
  139. /////////////////////////////////////////////////////////////////////////////
  140. BOOL
  141. StringsCategoryViewDialogClass::OnInitDialog (void)
  142. {
  143. CDialog::OnInitDialog ();
  144. //
  145. // Set the extended styles for the list control
  146. //
  147. m_ListCtrl.SetExtendedStyle (m_ListCtrl.GetExtendedStyle () | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
  148. //
  149. // Configure the columns
  150. //
  151. for (int index = 0; index < Columns.Count (); index ++) {
  152. m_ListCtrl.InsertColumn (index, ColumnSettings[index].name);
  153. }
  154. Update_Controls ();
  155. m_ListCtrl.GetClientRect (CurrListRect);
  156. //
  157. // Add an entry to the end that the user can double-click on to insert
  158. // new strings.
  159. //
  160. if (EditMode != EDIT_MODE_NONE) {
  161. m_ListCtrl.InsertItem (0, "");
  162. }
  163. //
  164. // Get the list of strings from the database and insert them into the list control
  165. //
  166. for ( TDBObjClass *object = TranslateDBClass::Get_First_Object (CategoryID);
  167. object != NULL;
  168. object = TranslateDBClass::Get_Next_Object (CategoryID, object))
  169. {
  170. //
  171. // Insert a copy of this object into the list control
  172. //
  173. Insert_New_Entry (object->Clone ());
  174. }
  175. //
  176. // Sort the list
  177. //
  178. m_ListCtrl.SortItems (StringEntrySortCompareFn, MAKELONG (CurrentColSort, AscendingSort));
  179. Resize_Controls ();
  180. //
  181. // Handle the default selection
  182. //
  183. if (m_ListCtrl.GetItemCount () > 0) {
  184. int item_index = -1;
  185. //
  186. // Try to find the object that is supposed to be selected
  187. //
  188. TDBObjClass *sel_object = TranslateDBClass::Find_Object (SelectedObjectID);
  189. if (sel_object != NULL) {
  190. item_index = Find_Entry (sel_object);
  191. }
  192. //
  193. // Select the object if possible, otherwise select the first entry
  194. //
  195. if (item_index >= 0) {
  196. m_ListCtrl.SetItemState (item_index, LVIS_SELECTED, LVIS_SELECTED);
  197. m_ListCtrl.EnsureVisible (item_index, FALSE);
  198. } else {
  199. m_ListCtrl.SetItemState (0, LVIS_SELECTED, LVIS_SELECTED);
  200. }
  201. }
  202. IsInitialized = true;
  203. return TRUE;
  204. }
  205. /////////////////////////////////////////////////////////////////////////////
  206. //
  207. // Update_Controls
  208. //
  209. /////////////////////////////////////////////////////////////////////////////
  210. void
  211. StringsCategoryViewDialogClass::Update_Controls (void)
  212. {
  213. //
  214. // Size the columns
  215. //
  216. CRect rect;
  217. m_ListCtrl.GetClientRect (&rect);
  218. int width = rect.Width () - ::GetSystemMetrics (SM_CXVSCROLL);
  219. //
  220. // Configure the columns
  221. //
  222. for (int index = 0; index < Columns.Count (); index ++) {
  223. m_ListCtrl.SetColumnWidth (index, ColumnSettings[index].width * width);
  224. }
  225. return ;
  226. }
  227. /////////////////////////////////////////////////////////////////////////////
  228. //
  229. // Find_Entry
  230. //
  231. /////////////////////////////////////////////////////////////////////////////
  232. int
  233. StringsCategoryViewDialogClass::Find_Entry (TDBObjClass *object)
  234. {
  235. int object_index = -1;
  236. //
  237. // Loop over all the objects in the list control
  238. //
  239. for (int index = 0; index < m_ListCtrl.GetItemCount (); index ++) {
  240. TDBObjClass *curr_object = (TDBObjClass *)m_ListCtrl.GetItemData (index);
  241. //
  242. // Is this the object we're looking for?
  243. //
  244. if (curr_object != NULL && curr_object->Get_ID () == object->Get_ID ()) {
  245. object_index = index;
  246. break;
  247. }
  248. }
  249. return object_index;
  250. }
  251. /////////////////////////////////////////////////////////////////////////////
  252. //
  253. // OnDblclkStringList
  254. //
  255. /////////////////////////////////////////////////////////////////////////////
  256. void
  257. StringsCategoryViewDialogClass::OnDblclkStringList
  258. (
  259. NMHDR * pNMHDR,
  260. LRESULT * pResult
  261. )
  262. {
  263. (*pResult) = 0;
  264. //
  265. // Don't do anything if we aren't in edit mode
  266. //
  267. if (EditMode == EDIT_MODE_NONE) {
  268. return ;
  269. }
  270. TDBObjClass *object = NULL;
  271. //
  272. // Peek into the selected item to get the translation object associated with it
  273. //
  274. int selected_item = m_ListCtrl.GetNextItem (-1, LVNI_SELECTED | LVNI_ALL);
  275. if (selected_item >= 0) {
  276. object = (TDBObjClass *)m_ListCtrl.GetItemData (selected_item);
  277. }
  278. //
  279. // See if this is a string twiddler
  280. //
  281. StringTwiddlerClass *twiddler = NULL;
  282. if (object != NULL) {
  283. twiddler = object->As_StringTwiddlerClass ();
  284. }
  285. //
  286. // Determine which dialog to show
  287. //
  288. bool show_edit_string = true;
  289. if (EditMode == EDIT_MODE_TWIDDLER && object == NULL) {
  290. show_edit_string = false;
  291. } else if (twiddler != NULL) {
  292. show_edit_string = false;
  293. }
  294. //
  295. // Show a dialog to the user
  296. //
  297. if (show_edit_string) {
  298. //
  299. // Let the user edit this entry
  300. //
  301. EditStringDialogClass dialog (this);
  302. dialog.Set_Translate_Object (object);
  303. if (dialog.DoModal () == IDOK) {
  304. //
  305. // Either add a new entry to the list control, or update the
  306. // text of an existing entry
  307. //
  308. if (object == NULL) {
  309. TDBObjClass *new_object = dialog.Get_Translate_Object ();
  310. new_object->Set_Category_ID (CategoryID);
  311. TranslateDBClass::Add_Object (new_object);
  312. Insert_New_Entry (new_object->Clone ());
  313. } else {
  314. Upate_Entry (selected_item);
  315. }
  316. }
  317. } else {
  318. EditStringTwiddlerDialogClass dialog (this);
  319. dialog.Set_Twiddler (twiddler);
  320. if (dialog.DoModal () == IDOK) {
  321. //
  322. // Either add a new entry to the list control, or update the
  323. // text of an existing entry
  324. //
  325. if (object == NULL) {
  326. StringTwiddlerClass *new_object = dialog.Get_Twiddler ();
  327. new_object->Set_Category_ID (CategoryID);
  328. TranslateDBClass::Add_Object (new_object);
  329. Insert_New_Entry (new_object->Clone ());
  330. } else {
  331. Upate_Entry (selected_item);
  332. }
  333. }
  334. }
  335. //
  336. // Force a repaint
  337. //
  338. InvalidateRect (NULL, TRUE);
  339. UpdateWindow ();
  340. return ;
  341. }
  342. /////////////////////////////////////////////////////////////////////////////
  343. //
  344. // OnColumnclickStringList
  345. //
  346. /////////////////////////////////////////////////////////////////////////////
  347. void
  348. StringsCategoryViewDialogClass::OnColumnclickStringList
  349. (
  350. NMHDR * pNMHDR,
  351. LRESULT * pResult
  352. )
  353. {
  354. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  355. (*pResult) = 0;
  356. if (CurrentColSort == pNMListView->iSubItem) {
  357. AscendingSort = !AscendingSort;
  358. } else {
  359. CurrentColSort = pNMListView->iSubItem;
  360. AscendingSort = true;
  361. }
  362. m_ListCtrl.SortItems (StringEntrySortCompareFn, MAKELONG (CurrentColSort, AscendingSort));
  363. return ;
  364. }
  365. /////////////////////////////////////////////////////////////////////////////
  366. //
  367. // StringEntrySortCompareFn
  368. //
  369. /////////////////////////////////////////////////////////////////////////////
  370. int CALLBACK
  371. StringEntrySortCompareFn (LPARAM param1, LPARAM param2, LPARAM sort_info)
  372. {
  373. int retval = 0;
  374. TDBObjClass *object1 = (TDBObjClass *)param1;
  375. TDBObjClass *object2 = (TDBObjClass *)param2;
  376. LONG column_id = LOWORD (sort_info);
  377. BOOL ascending = HIWORD (sort_info);
  378. if (object1 != NULL && object2 != NULL) {
  379. //
  380. // Determine the order based on which column the user clicked on
  381. //
  382. if (column_id == StringsCategoryViewDialogClass::COL_ID) {
  383. retval = ::lstrcmpi (object1->Get_ID_Desc (), object2->Get_ID_Desc ());
  384. } else if (column_id == StringsCategoryViewDialogClass::COL_TEXT) {
  385. retval = ::lstrcmpi (object1->Get_English_String (), object2->Get_English_String ());
  386. }
  387. }
  388. //
  389. // Invert the sort if necessary
  390. //
  391. if (ascending != TRUE) {
  392. retval = -retval;
  393. }
  394. return retval;
  395. }
  396. /////////////////////////////////////////////////////////////////////////////
  397. //
  398. // Upate_Entry
  399. //
  400. /////////////////////////////////////////////////////////////////////////////
  401. void
  402. StringsCategoryViewDialogClass::Upate_Entry (int index)
  403. {
  404. if (index < 0) {
  405. return ;
  406. }
  407. //
  408. // Update this list control entry
  409. //
  410. TDBObjClass *object = (TDBObjClass *)m_ListCtrl.GetItemData (index);
  411. if (object != NULL) {
  412. //
  413. // Update each column
  414. //
  415. for (int col_index = 0; col_index < Columns.Count (); col_index ++) {
  416. //
  417. // Determine what information to update
  418. //
  419. if (ColumnSettings[col_index].id == COL_ID) {
  420. m_ListCtrl.SetItemText (index, col_index, object->Get_ID_Desc ());
  421. } else if (ColumnSettings[col_index].id == COL_TEXT) {
  422. m_ListCtrl.SetItemText (index, col_index, object->Get_English_String ());
  423. }
  424. }
  425. }
  426. return ;
  427. }
  428. /////////////////////////////////////////////////////////////////////////////
  429. //
  430. // Insert_New_Entry
  431. //
  432. /////////////////////////////////////////////////////////////////////////////
  433. void
  434. StringsCategoryViewDialogClass::Insert_New_Entry (TDBObjClass *object)
  435. {
  436. if (object == NULL) {
  437. return ;
  438. }
  439. //
  440. // Ensure the new object has the right category
  441. //
  442. object->Set_Category_ID (CategoryID);
  443. //
  444. // Insert an item into the list control to represent this string
  445. //
  446. int last_index = max (m_ListCtrl.GetItemCount () - 1, 0);
  447. int item_index = m_ListCtrl.InsertItem (last_index, object->Get_ID_Desc ());
  448. if (item_index >= 0) {
  449. //
  450. // Update each column
  451. //
  452. for (int col_index = 0; col_index < Columns.Count (); col_index ++) {
  453. //
  454. // Determine what information to update
  455. //
  456. if (ColumnSettings[col_index].id == COL_ID) {
  457. m_ListCtrl.SetItemText (item_index, col_index, object->Get_ID_Desc ());
  458. } else if (ColumnSettings[col_index].id == COL_TEXT) {
  459. m_ListCtrl.SetItemText (item_index, col_index, object->Get_English_String ());
  460. }
  461. }
  462. m_ListCtrl.SetItemData (item_index, (DWORD)object);
  463. }
  464. return ;
  465. }
  466. /////////////////////////////////////////////////////////////////////////////
  467. //
  468. // OnDeleteitemStringList
  469. //
  470. /////////////////////////////////////////////////////////////////////////////
  471. void
  472. StringsCategoryViewDialogClass::OnDeleteitemStringList
  473. (
  474. NMHDR * pNMHDR,
  475. LRESULT * pResult
  476. )
  477. {
  478. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  479. (*pResult) = 0;
  480. //
  481. // Free the associated translation object
  482. //
  483. TDBObjClass *object = (TDBObjClass *)m_ListCtrl.GetItemData (pNMListView->iItem);
  484. SAFE_DELETE (object);
  485. m_ListCtrl.SetItemData (pNMListView->iItem, 0L);
  486. return ;
  487. }
  488. /////////////////////////////////////////////////////////////////////////////
  489. //
  490. // OnKeydownStringList
  491. //
  492. /////////////////////////////////////////////////////////////////////////////
  493. void
  494. StringsCategoryViewDialogClass::OnKeydownStringList
  495. (
  496. NMHDR * pNMHDR,
  497. LRESULT * pResult
  498. )
  499. {
  500. LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
  501. (*pResult) = 0;
  502. //
  503. // Don't do anything if we aren't in edit mode
  504. //
  505. if (EditMode == EDIT_MODE_NONE) {
  506. return ;
  507. }
  508. if (pLVKeyDow->wVKey == VK_DELETE) {
  509. //
  510. // Delete all the selected items (except for the last item)
  511. //
  512. int index = -1;
  513. while ((index = m_ListCtrl.GetNextItem (-1, LVNI_SELECTED | LVNI_ALL)) >= 0) {
  514. if (index < m_ListCtrl.GetItemCount () - 1) {
  515. m_ListCtrl.DeleteItem (index);
  516. ShouldUpdateVersionNumber = true;
  517. } else {
  518. break;
  519. }
  520. }
  521. } else if (::GetKeyState (VK_CONTROL) < 0) {
  522. if (CallbackObject != NULL) {
  523. //
  524. // Check to see if the user pressed the copy or paste keys
  525. //
  526. switch (pLVKeyDow->wVKey)
  527. {
  528. case 'x':
  529. case 'X':
  530. CallbackObject->On_Cut ();
  531. break;
  532. case 'v':
  533. case 'V':
  534. CallbackObject->On_Paste ();
  535. break;
  536. }
  537. }
  538. }
  539. return ;
  540. }
  541. /////////////////////////////////////////////////////////////////////////////
  542. //
  543. // Resize_Controls
  544. //
  545. /////////////////////////////////////////////////////////////////////////////
  546. void
  547. StringsCategoryViewDialogClass::Resize_Controls (void)
  548. {
  549. if (IsInitialized == false) {
  550. return ;
  551. }
  552. //
  553. // Get the current client rectangle of the list control
  554. //
  555. CRect new_list_rect;
  556. GetClientRect (&new_list_rect);
  557. int old_width = CurrListRect.Width ();
  558. //
  559. // Resize each column so its the same percentage size as it was before
  560. //
  561. for (int col_index = 0; col_index < Columns.Count (); col_index ++) {
  562. float col_per = (float)m_ListCtrl.GetColumnWidth (col_index) / (float)old_width;
  563. int new_width = int(new_list_rect.Width () * col_per);
  564. m_ListCtrl.SetColumnWidth (col_index, new_width);
  565. }
  566. CurrListRect = new_list_rect;
  567. //
  568. // Get the window bounding rectangle
  569. //
  570. CRect rect;
  571. GetClientRect (&rect);
  572. //
  573. // Resize the list control
  574. //
  575. m_ListCtrl.SetWindowPos (NULL, rect.left, rect.top, rect.Width (), rect.Height (),
  576. SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE);
  577. return ;
  578. }
  579. /////////////////////////////////////////////////////////////////////////////
  580. //
  581. // Apply_Changes
  582. //
  583. /////////////////////////////////////////////////////////////////////////////
  584. void
  585. StringsCategoryViewDialogClass::Apply_Changes (void)
  586. {
  587. //
  588. // Don't do anything if we aren't in edit mode
  589. //
  590. if (EditMode == EDIT_MODE_NONE) {
  591. return ;
  592. }
  593. //
  594. // Add all the objects from the list control into the database
  595. //
  596. int count = m_ListCtrl.GetItemCount ();
  597. for (int index = 0; index < count; index ++) {
  598. TDBObjClass *object = (TDBObjClass *)m_ListCtrl.GetItemData (index);
  599. if (object != NULL) {
  600. TranslateDBClass::Add_Object (object->Clone ());
  601. }
  602. }
  603. return ;
  604. }
  605. /////////////////////////////////////////////////////////////////////////////
  606. //
  607. // OnSize
  608. //
  609. /////////////////////////////////////////////////////////////////////////////
  610. void
  611. StringsCategoryViewDialogClass::OnSize (UINT nType, int cx, int cy)
  612. {
  613. CDialog::OnSize (nType, cx, cy);
  614. Resize_Controls ();
  615. return ;
  616. }
  617. /////////////////////////////////////////////////////////////////////////////
  618. //
  619. // Cut
  620. //
  621. /////////////////////////////////////////////////////////////////////////////
  622. void
  623. StringsCategoryViewDialogClass::Cut
  624. (
  625. DynamicVectorClass <TDBObjClass *> & entry_list,
  626. bool sel_only
  627. )
  628. {
  629. m_ListCtrl.SetRedraw (false);
  630. //
  631. // Enable the selected flag if we only want to cut the current selection set.
  632. //
  633. int flags = LVNI_ALL;
  634. if (sel_only) {
  635. flags |= LVNI_SELECTED;
  636. }
  637. //
  638. // Remove all selected entries from the list control and add them to the list
  639. //
  640. int index = -1;
  641. while ((index = m_ListCtrl.GetNextItem (-1, flags)) != -1) {
  642. TDBObjClass *object = (TDBObjClass *)m_ListCtrl.GetItemData (index);
  643. if (object != NULL) {
  644. entry_list.Add (object->Clone ());
  645. m_ListCtrl.DeleteItem (index);
  646. } else if (m_ListCtrl.GetItemCount () == 1) {
  647. break;
  648. }
  649. }
  650. m_ListCtrl.SetRedraw (true);
  651. return ;
  652. }
  653. /////////////////////////////////////////////////////////////////////////////
  654. //
  655. // Paste
  656. //
  657. /////////////////////////////////////////////////////////////////////////////
  658. void
  659. StringsCategoryViewDialogClass::Paste (DynamicVectorClass <TDBObjClass *> &entry_list)
  660. {
  661. m_ListCtrl.SetRedraw (false);
  662. //
  663. // Add a new entry for each object
  664. //
  665. for (int index = 0; index < entry_list.Count (); index ++) {
  666. TDBObjClass *object = entry_list[index];
  667. TDBObjClass *our_copy = object->Clone ();
  668. our_copy->Set_Category_ID (CategoryID);
  669. Insert_New_Entry (our_copy);
  670. }
  671. //
  672. // Resort the list
  673. //
  674. m_ListCtrl.SortItems (StringEntrySortCompareFn, MAKELONG (CurrentColSort, AscendingSort));
  675. m_ListCtrl.SetRedraw (true);
  676. return ;
  677. }
  678. /////////////////////////////////////////////////////////////////////////////
  679. //
  680. // Get_Selection
  681. //
  682. /////////////////////////////////////////////////////////////////////////////
  683. int
  684. StringsCategoryViewDialogClass::Get_Selection (void)
  685. {
  686. //
  687. // Check to see if we need to update the cached selection ID
  688. //
  689. if (::IsWindow (m_hWnd)) {
  690. //
  691. // Find the selected item
  692. //
  693. int index = m_ListCtrl.GetNextItem (-1, LVNI_SELECTED | LVNI_ALL);
  694. if (index != -1) {
  695. //
  696. // Store the selected item's object id
  697. //
  698. TDBObjClass *object = (TDBObjClass *)m_ListCtrl.GetItemData (index);
  699. if (object != NULL) {
  700. SelectedObjectID = object->Get_ID ();
  701. }
  702. } else {
  703. SelectedObjectID = 0;
  704. }
  705. }
  706. return SelectedObjectID;
  707. }
  708. /////////////////////////////////////////////////////////////////////////////
  709. //
  710. // OnItemchangedStringList
  711. //
  712. /////////////////////////////////////////////////////////////////////////////
  713. void
  714. StringsCategoryViewDialogClass::OnItemchangedStringList
  715. (
  716. NMHDR * pNMHDR,
  717. LRESULT * pResult
  718. )
  719. {
  720. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  721. (*pResult) = 0;
  722. if (IsInitialized && (pNMListView->uChanged & LVIF_STATE)) {
  723. //
  724. // This will force the cached selection data to be updated
  725. //
  726. Get_Selection ();
  727. //
  728. // Notify the owner (if necessary)
  729. //
  730. if (CallbackObject != NULL) {
  731. CallbackObject->On_Selection_Changed (SelectedObjectID);
  732. }
  733. }
  734. return ;
  735. }