DiagramEntityContainer.cpp
Upload User: kairuinn
Upload Date: 2009-02-07
Package Size: 2922k
Code Size: 38k
Category:

Graph program

Development Platform:

Visual C++

  1. /* ==========================================================================
  2. Class : CDiagramEntityContainer
  3. Author : Johan Rosengren, Abstrakt Mekanik AB
  4. Date : 2004-03-29
  5. Purpose : "CDiagramEntityContainer" contains the data for a 
  6. "CDiagramEditor". It manages mass operations such as 
  7. copying, pasting and undo. It is completely separated 
  8. from "CDiagramEditor" to allow the package to be used 
  9. in a doc/view app. This is also the reason why some 
  10. functionality is accessible in both this class and 飊
  11. "CDiagramEditor".
  12. Description : The class contains a "CObArray" with the instances of 
  13. "CDiagramEntity"-derived classes that is the current data 
  14. for an editor. It also contains a pointer to a 
  15. "CDiagramClipboardHandler"-instance that works as the 
  16. 'clipboard' for an editor. Furthermore, It contains an
  17. "CObArray" of "CObArray"s that is the undo stack.
  18. The Undo-functionality is implemented as a simple FILO-stack 
  19. of "CObArray" pointers. Before any change that should be 
  20. undoable, "Snapshot" is called to add new entries to 
  21. the Undo-stack. This is normally managed by the editor, 
  22. and need only be done manually for added functionality.
  23. Note that the "CDiagramEntityContainer" should normally 
  24. not call "Snapshot" itself - in the case of, for example, 
  25. additions to "m_objs", the container can not and should 
  26. not know if it is an undoable operation.
  27. Usage : Normally, this class need not be derived from. A 
  28. "CDiagramEditor" needs an instance of 
  29. "CDiagramEntityContainer" to hold the object data. This 
  30. instance can either be external, as for a doc/view app 
  31. where the container belongs to the document, or 
  32. internal, as for a dialog application where the editor 
  33. will manage all of the data. In the first case, a 
  34. "CDiagramEntityContainer" member should be declared in 
  35. the document class, and a pointer to it submitted to 
  36. the "Create"-call of the "CDiagramEditor" (or by calling 
  37. "CDiagramEditor::SetCDiagramEntityContainer"). In the 
  38. second case, nothing special need to be done - the 
  39. "CDiagramEntityContainer" will be created during the 
  40. "CDiagramEditor::Create" call automatically if no pointer 
  41. is submitted.
  42. The container is not using the Windows clipboard 
  43. (because of instantiation questions on derived 
  44. entities), but rather an external clipboard handler 
  45. derived from "CDiagramClipboardHandler". This handler is 
  46. set calling "SetClipboardHandler", and several containers 
  47. can share the same handler. If no clipboard handler is 
  48. set, a default internal one will be used.
  49. "CDiagramEntityContainer" manages all data internally, 
  50. all internal objects are deleted in the class "dtor".
  51.    ========================================================================
  52. Changes : 19/4 2004 Made RemoveAt virtual.
  53. 20/4 2004 Made several Undo- and Copy/Paste functions 
  54. virtual. Added array accessors for derived 
  55. classes. Moved the member function Find to 
  56. protected.
  57. 30/4 2004 Copy/paste-handling removed to a separate 
  58. class to allow several containers to share 
  59. the same clipboard.
  60. 30/4 2004 Changed c-style casts to static_cast
  61.    ========================================================================
  62. 20/5 2004 Made GetAt virtual
  63. 30/5 2004 RemoveAll, added check to see if there are 
  64. any items in the object array.
  65. 30/5 2004 Made RemoveAll access data container objects 
  66. directly, to avoid chained deletes in 
  67. derived classes.
  68.    ========================================================================
  69. 26/6 2004 Added group handling (Unruled Boy).
  70. 3/7  2004 Made Add and Remove virtual
  71. 3/7  2004 Added a GetSelectCount
  72.    ========================================================================
  73. 4/8  2004 Added SelectAll and UnselectAll
  74.    ========================================================================
  75. 11/12 2004 Made UnselectAll virtual (Grisha Vinevich)
  76.    ========================================================================
  77. 22/1  2005 Added PopUndo function to pop the latest 
  78. undo item from the stack
  79. Made IsUndoPossible const.
  80.    ========================================================================*/
  81. #include "stdafx.h"
  82. #include "DiagramEntityContainer.h"
  83. #include "DiagramEntity.h"
  84. #include "Tokenizer.h"
  85. #include "GroupFactory.h"
  86. #ifdef _DEBUG
  87. #define new DEBUG_NEW
  88. #undef THIS_FILE
  89. static char THIS_FILE[] = __FILE__;
  90. #endif
  91. #pragma warning( disable : 4706 )
  92. /////////////////////////////////////////////////////////////////////////////
  93. // CDiagramEntityContainer construction/destruction/initialization
  94. CDiagramEntityContainer::CDiagramEntityContainer( int printer_mode, 
  95.  const CSize*  page_sizes,CDiagramClipboardHandler* clip )
  96. /* ============================================================
  97. Function : CDiagramEntityContainer::CDiagramEntityContainer
  98. Description : Constructor
  99. Access : Public
  100. Return : void
  101. Parameters : none
  102. Usage :
  103.    ============================================================*/
  104. {
  105. m_clip = clip;
  106. m_thumb_stor = NULL;
  107. SetUndoStackSize( 0 );
  108. Clear();
  109. SetVirtualSize( CSize( 0, 0 ) );
  110. m_printer_mode = printer_mode;
  111. if (page_sizes)
  112. {
  113. m_page_sizes.cx = page_sizes->cx;
  114. m_page_sizes.cy = page_sizes->cy;
  115. }
  116. else
  117. {
  118. m_page_sizes.cx = 0;
  119. m_page_sizes.cy = 0;
  120. }
  121. }
  122. CDiagramEntityContainer::~CDiagramEntityContainer()
  123. /* ============================================================
  124. Function : CDiagramEntityContainer::~CDiagramEntityContainer
  125. Description : Destructor
  126. Access : Public
  127. Return : void
  128. Parameters : none
  129. Usage :
  130.    ============================================================*/
  131. {
  132. Clear();
  133. }
  134. void CDiagramEntityContainer::Clear()
  135. /* ============================================================
  136. Function : CDiagramEntityContainer::Clear
  137. Description : Removes all data from the data and undo.
  138. Access : Public
  139. Return : void
  140. Parameters : none
  141. Usage : Call to remove data from the container. The 
  142. Paste-array will be kept.
  143.    ============================================================*/
  144. {
  145. RemoveAll();
  146. ClearUndo();
  147. SetModified( FALSE );
  148. }
  149. CString CDiagramEntityContainer::GetString() const
  150. /* ============================================================
  151. Function : CDiagramEntityContainer::GetString
  152. Description : Returns a string representation of the 
  153. virtual paper size
  154. Access : Public
  155. Return : CString - Resulting string
  156. Parameters : none
  157. Usage : Call to get a string representing the paper 
  158. size of the container. The format is 
  159. "paper:x,y;" where "x" and "y" are the 
  160. horisontal and vertical sizes.
  161.    ============================================================*/
  162. {
  163. CString str;
  164. str.Format( _T( "paper:%i,%i;" ), GetVirtualSize().cx, GetVirtualSize().cy );
  165. return str;
  166. }
  167. BOOL CDiagramEntityContainer::FromString( const CString& str )
  168. /* ============================================================
  169. Function : CDiagramEntityContainer::FromString
  170. Description : Sets the virtual paper size from a string.
  171. Access : Public
  172. Return : BOOL - "TRUE" if the string 
  173. represented a 
  174. paper.
  175. Parameters : const CString& str - The string 
  176. representation.
  177. Usage : Call to set the paper size of the container 
  178. from a string. The format is "paper:x,y;" 
  179. where "x" and "y" are the horisontal and 
  180. vertical sizes.
  181.    ============================================================*/
  182. {
  183. BOOL result = FALSE;
  184. CTokenizer main( str, _T( ":" ) );
  185. CString header;
  186. CString data;
  187. if( main.GetSize() == 2 )
  188. {
  189. main.GetAt( 0, header );
  190. main.GetAt( 1, data );
  191. header.TrimLeft();
  192. header.TrimRight();
  193. data.TrimLeft();
  194. data.TrimRight();
  195. if( header == _T( "paper" ) )
  196. {
  197. CTokenizer tok( data.Left( data.GetLength() - 1 ) );
  198. int size = tok.GetSize();
  199. if( size == 2 )
  200. {
  201. int right;
  202. int bottom;
  203. tok.GetAt(0, right );
  204. tok.GetAt(1, bottom );
  205. SetVirtualSize( CSize( right, bottom ) );
  206. result = TRUE;
  207. }
  208. }
  209. }
  210. return result;
  211. }
  212. void CDiagramEntityContainer::Export( CStringArray& stra, UINT format ) const
  213. /* ============================================================
  214. Function : CDiagramEntityContainer::Export
  215. Description : Exports all objects to format format.
  216. Access : Public
  217. Return : void
  218. Parameters : CStringArray& stra - "CStingArray" that 
  219. will be filled with 
  220. data on return. 
  221. UINT format - Format to save to.
  222. Usage : Call to export the contents of the container 
  223. to a "CStringArray". "Export" will - of course - 
  224. have to be defined for the derived objects.
  225.    ============================================================*/
  226. {
  227. int max = GetSize();
  228. for( int t = 0 ; t < max ; t++ )
  229. {
  230. CDiagramEntity* obj = GetAt( t );
  231. stra.Add( obj->Export( format ) );
  232. }
  233. }
  234. /////////////////////////////////////////////////////////////////////////////
  235. // CDiagramEntityContainer data access
  236. int CDiagramEntityContainer::GetSize() const
  237. /* ============================================================
  238. Function : CDiagramEntityContainer::GetSize
  239. Description : Returns the number of objects in the data
  240. container.
  241. Access : Public
  242. Return : int - The number of objects.
  243. Parameters : none
  244. Usage : Call to get the number of objects currently 
  245. in the data array of the container.
  246.    ============================================================*/
  247. {
  248. return m_objs.GetSize();
  249. }
  250. void CDiagramEntityContainer::Add( CDiagramEntity* obj )
  251. /* ============================================================
  252. Function : CDiagramEntityContainer::Add
  253. Description : Add an object to the data.
  254. Access : Public
  255. Return : void
  256. Parameters : CDiagramEntity* obj - The object to add.
  257. Usage : Call to add a new object to the container.
  258.    ============================================================*/
  259. {
  260. obj->SetParent( this );
  261. m_objs.Add( obj );
  262. SetModified( TRUE );
  263. }
  264. CDiagramEntity* CDiagramEntityContainer::GetAt( int index ) const
  265. /* ============================================================
  266. Function : CDiagramEntityContainer::GetAt
  267. Description : Gets the object at position "index".
  268. Access : Public
  269. Return : CDiagramEntity* - The object or "NULL" if 
  270. out of range.
  271. Parameters : int index - The index to get data 
  272. from
  273. Usage : Call to get a specific object from the 
  274. container.
  275.    ============================================================*/
  276. {
  277. CDiagramEntity* result = NULL;
  278. if( index < m_objs.GetSize() && index >= 0 )
  279. result = static_cast< CDiagramEntity* >( m_objs.GetAt( index ) );
  280. return result;
  281. }
  282. void CDiagramEntityContainer::SetAt( int index, CDiagramEntity* obj )
  283. /* ============================================================
  284. Function : CDiagramEntityContainer::SetAt
  285. Description : Sets an object at position "index".
  286. Access : Public
  287. Return : void
  288. Parameters : int index - Index to set data 
  289. at.
  290. CDiagramEntity* obj - Object to set.
  291. Usage : Internal function. Used by "Swap".
  292.    ============================================================*/
  293. {
  294. m_objs.SetAt( index, obj );
  295. SetModified( TRUE );
  296. }
  297. void CDiagramEntityContainer::RemoveAt( int index )
  298. /* ============================================================
  299. Function : CDiagramEntityContainer::RemoveAt
  300. Description : Removes the object at index.
  301. Access : Public
  302. Return : void
  303. Parameters : int index - The index of the object 
  304. to remove.
  305. Usage : Call to remove a specific object. Memory is 
  306. freed.
  307.    ============================================================*/
  308. {
  309. CDiagramEntity* obj = GetAt( index );
  310. if( obj )
  311. {
  312. delete obj;
  313. m_objs.RemoveAt( index );
  314. SetModified( TRUE );
  315. }
  316. }
  317. void CDiagramEntityContainer::RemoveAll()
  318. /* ============================================================
  319. Function : CDiagramEntityContainer::RemoveAll
  320. Description : Removes all data objects
  321. Access : Public
  322. Return : void
  323. Parameters : none
  324. Usage : Call to remove all data objects in the 
  325. container. Undo- and paste arrays are not 
  326. emptied.
  327. Allocated memory is released. Undo and 
  328. paste not deleted.
  329.    ============================================================*/
  330. {
  331. int max = m_objs.GetSize();
  332. if( max )
  333. {
  334. for( int t = 0 ; t < max ; t++ )
  335. {
  336. CDiagramEntity* obj = static_cast< CDiagramEntity* >( m_objs.GetAt( t ) );
  337. delete obj;
  338. }
  339. m_objs.RemoveAll();
  340. SetModified( TRUE );
  341. }
  342. }
  343. void CDiagramEntityContainer::RemoveAllSelected()
  344. /* ============================================================
  345. Function : CDiagramEntityContainer::RemoveAllSelected
  346. Description : Removes all selected objects
  347. Access : Public
  348. Return : void
  349. Parameters : none
  350. Usage : Call to remove all selected objects from the 
  351. container. Releases allocated data
  352.    ============================================================*/
  353. {
  354. int max = m_objs.GetSize() - 1;
  355. for( int t = max ; t >= 0 ; t-- )
  356. if( GetAt( t )->IsSelected() )
  357. RemoveAt( t );
  358. if (m_thumb_stor)
  359. m_thumb_stor->InvalidateThumbnailer();
  360. }
  361. /////////////////////////////////////////////////////////////////////////////
  362. // CDiagramEntityContainer property access
  363. void CDiagramEntityContainer::SetVirtualSize( CSize size )
  364. /* ============================================================
  365. Function : CDiagramEntityContainer::SetVirtualSize
  366. Description : Sets the current virtual paper size.
  367. Access : Public
  368. Return : void
  369. Parameters : CSize size - The size to set
  370. Usage : Call to set the paper size. Note that 
  371. "SetModified( TRUE )" might have to be called 
  372. as well.
  373.    ============================================================*/
  374. {
  375. m_virtualSize = size;
  376. }
  377. CSize CDiagramEntityContainer::GetVirtualSize() const
  378. /* ============================================================
  379. Function : CDiagramEntityContainer::GetVirtualSize
  380. Description : Gets the virtual paper size.
  381. Access : Public
  382. Return : CSize - The current size
  383. Parameters : none
  384. Usage : Call to get the current paper size.
  385.    ============================================================*/
  386. {
  387. return m_virtualSize;
  388. }
  389. BOOL CDiagramEntityContainer::IsModified() const
  390. /* ============================================================
  391. Function : CDiagramEntityContainer::IsModified
  392. Description : Returns the state of the modified-flag.
  393. Access : Public
  394. Return : BOOL - "TRUE" if data is changed
  395. Parameters : none
  396. Usage : Call to see if data is modified.
  397.    ============================================================*/
  398. {
  399. return m_dirty;
  400. }
  401. void CDiagramEntityContainer::SetModified( BOOL dirty )
  402. /* ============================================================
  403. Function : CDiagramEntityContainer::SetModified
  404. Description : Sets the state of the modified flag
  405. Access : Public
  406. Return : void
  407. Parameters : BOOL dirty - "TRUE" if data is changed.
  408. Usage : Call to mark the data as modified.
  409.    ============================================================*/
  410. {
  411. m_dirty = dirty;
  412. }
  413. /////////////////////////////////////////////////////////////////////////////
  414. // CDiagramEntityContainer single object handlers
  415. void CDiagramEntityContainer::Remove( CDiagramEntity* obj )
  416. /* ============================================================
  417. Function : CDiagramEntityContainer::Remove
  418. Description : Removes the object.
  419. Access : Public
  420. Return : void
  421. Parameters : CDiagramEntity* obj - The object to 
  422. remove.
  423. Usage : Call to remove "obj" - if it exists - from the 
  424. container. Allocated memory is released.
  425.    ============================================================*/
  426. {
  427. int index = Find( obj );
  428. if( index != -1 )
  429. RemoveAt( index );
  430. if (m_thumb_stor)
  431. m_thumb_stor->InvalidateThumbnailer();
  432. }
  433. void CDiagramEntityContainer::Duplicate( CDiagramEntity* obj )
  434. /* ============================================================
  435. Function : CDiagramEntityContainer::Duplicate
  436. Description : Duplicates the object and adds the new 
  437. one 10 pixels offset down and right.
  438. Access : Public
  439. Return : void
  440. Parameters : CDiagramEntity* obj - The object to 
  441. duplicate.
  442. Usage : Call to create a copy of the selected 
  443. element.
  444.    ============================================================*/
  445. {
  446. int index = Find( obj );
  447. if( index != -1 )
  448. {
  449. CDiagramEntity* newobj = obj->Clone();
  450. newobj->SetRect( newobj->GetLeft() + 10, newobj->GetTop() + 10, newobj->GetRight() + 10, newobj->GetBottom() + 10 );
  451. Add( newobj );
  452. if (m_thumb_stor)
  453. m_thumb_stor->InvalidateThumbnailer();
  454. }
  455. }
  456. void CDiagramEntityContainer::Cut( CDiagramEntity* obj )
  457. /* ============================================================
  458. Function : CDiagramEntityContainer::Cut
  459. Description : Cuts out the object and puts it into the 
  460. 'clipboard'
  461. Access : Public
  462. Return : void
  463. Parameters : CDiagramEntity* obj - The object to cut.
  464. Usage : Call in response to a Cut-command. See also 
  465. the functions for copy/paste below.
  466.    ============================================================*/
  467. {
  468. Copy( obj );
  469. Remove( obj );
  470. }
  471. void CDiagramEntityContainer::Copy( CDiagramEntity* obj )
  472. /* ============================================================
  473. Function : CDiagramEntityContainer::Copy
  474. Description : Copies the object to the 'clipboard'.
  475. Access : Public
  476. Return : void
  477. Parameters : CDiagramEntity* obj - The object to copy.
  478. Usage : Call in response to a Copy-command. Note 
  479. that obj will only be copied to the 
  480. clipboard, not the screen. See also the 
  481. functions for copy/paste below.
  482.    ============================================================*/
  483. {
  484. ASSERT( obj );
  485. if( m_clip == NULL )
  486. m_clip = &m_internalClip;
  487. if( obj )
  488. m_clip->Copy( obj );
  489. }
  490. void CDiagramEntityContainer::Up( CDiagramEntity* obj )
  491. /* ============================================================
  492. Function : CDiagramEntityContainer::Up
  493. Description : Moves the object one step up in the z-
  494. order.
  495. Access : Public
  496. Return : void
  497. Parameters : CDiagramEntity* obj - The object to move.
  498. Usage : Call to move "obj" in the z-order.
  499.    ============================================================*/
  500. {
  501. int index = Find( obj );
  502. Swap( index, index + 1);
  503. }
  504. void CDiagramEntityContainer::Down( CDiagramEntity* obj )
  505. /* ============================================================
  506. Function : CDiagramEntityContainer::Down
  507. Description : Moves the object one step down in the z-
  508. order.
  509. Access : Public
  510. Return : void
  511. Parameters : CDiagramEntity* obj - The object to move.
  512. Usage : Call to move "obj" in the z-order.
  513.    ============================================================*/
  514. {
  515. int index = Find( obj );
  516. Swap( index, index - 1);
  517. }
  518. void CDiagramEntityContainer::Front( CDiagramEntity* obj )
  519. /* ============================================================
  520. Function : CDiagramEntityContainer::Front
  521. Description : Moves "obj" to the top of the z-order.
  522. Access : Public
  523. Return : void
  524. Parameters : CDiagramEntity* obj - The object to move.
  525. Usage : Call to move "obj" in the z-order.
  526.    ============================================================*/
  527. {
  528. int index = Find( obj );
  529. m_objs.RemoveAt( index );
  530. m_objs.Add( obj );
  531. SetModified( TRUE );
  532. }
  533. void CDiagramEntityContainer::Bottom( CDiagramEntity* obj )
  534. /* ============================================================
  535. Function : CDiagramEntityContainer::Bottom
  536. Description : Moves "obj" to the bottom of the z-order.
  537. Access : Public
  538. Return : void
  539. Parameters : CDiagramEntity* obj - The object to move.
  540. Usage : Call to move "obj" in the z-order.
  541.    ============================================================*/
  542. {
  543. int index = Find( obj );
  544. m_objs.RemoveAt( index );
  545. m_objs.InsertAt( 0, obj );
  546. SetModified( TRUE );
  547. }
  548. /////////////////////////////////////////////////////////////////////////////
  549. // CDiagramEntityContainer copy/paste is implemented as separate class.
  550. void CDiagramEntityContainer::SetClipboardHandler( CDiagramClipboardHandler* clip )
  551. /* ============================================================
  552. Function : CDiagramEntityContainer::SetClipboardHandler
  553. Description : Sets the container clipboard class.
  554. Access : Public
  555. Return : void
  556. Parameters : CDiagramClipboardHandler* clip - A pointer
  557. to the
  558. class
  559. Usage : Call to set the clipboard handler for this 
  560. container. The same clipboard handler 
  561. instance can be used for several containers 
  562. to allow several editors (in an MDI-
  563. application) to share the same clipboard.
  564.    ============================================================*/
  565. {
  566. m_clip = clip;
  567. }
  568. CDiagramClipboardHandler* CDiagramEntityContainer::GetClipboardHandler()
  569. /* ============================================================
  570. Function : CDiagramEntityContainer::GetClipboardHandler
  571. Description : Returns a pointer to the current clipboard 
  572. handler.
  573. Access : Public
  574. Return : CDiagramClipboardHandler* - Current handler.
  575. Parameters : none
  576. Usage : Call to get a pointer to the current handler.
  577.    ============================================================*/
  578. {
  579. return m_clip;
  580. }
  581. void CDiagramEntityContainer::CopyAllSelected()
  582. /* ============================================================
  583. Function : CDiagramEntityContainer::CopyAllSelected
  584. Description : Clones all selected object to the paste 
  585. array.
  586. Access : Public
  587. Return : void
  588. Parameters : none
  589. Usage : Call to copy all selected objects to the 
  590. clipboard. "Paste" will put them on screen.
  591.    ============================================================*/
  592. {
  593. if( m_clip == NULL )
  594. m_clip = &m_internalClip;
  595. m_clip->CopyAllSelected( this );
  596. }
  597. int CDiagramEntityContainer::ObjectsInPaste()
  598. /* ============================================================
  599. Function : CDiagramEntityContainer::ObjectsInPaste
  600. Description : Returns the number of objects in the paste 
  601. array.
  602. Access : Public
  603. Return : int - The number of objects.
  604. Parameters : none
  605. Usage : Call to get the number of objects in the 
  606. clipboard.
  607.    ============================================================*/
  608. {
  609. if( m_clip == NULL )
  610. m_clip = &m_internalClip;
  611. return m_clip->ObjectsInPaste();
  612. }
  613. void CDiagramEntityContainer::ClearPaste()
  614. /* ============================================================
  615. Function : CDiagramEntityContainer::ClearPaste
  616. Description : Clears the paste-array.
  617. Access : Public
  618. Return : void
  619. Parameters : none
  620. Usage : Call to clear the clipboard. All memory is 
  621. released.
  622.    ============================================================*/
  623. {
  624. if( m_clip == NULL )
  625. m_clip = &m_internalClip;
  626. m_clip->ClearPaste();
  627. }
  628. void CDiagramEntityContainer::Paste()
  629. /* ============================================================
  630. Function : CDiagramEntityContainer::Paste
  631. Description : Clones the contents of the paste array 
  632. into the container data array.
  633. Access : Public
  634. Return : void
  635. Parameters : none
  636. Usage : Call to paste the contents of the clipboard 
  637. to screen.
  638.    ============================================================*/
  639. {
  640. if( m_clip == NULL )
  641. m_clip = &m_internalClip;
  642. m_clip->Paste( this );
  643. if (m_thumb_stor)
  644. m_thumb_stor->InvalidateThumbnailer();
  645. }
  646. /////////////////////////////////////////////////////////////////////////////
  647. // CDiagramEntityContainer message handling
  648. void CDiagramEntityContainer::SendMessageToObjects( int command, BOOL selected, CDiagramEntity* sender, IThumbnailerStorage* from )
  649. /* ============================================================
  650. Function : CDiagramEntityContainer::SendMessageToObjects
  651. Description : Sends "command" to objects. 
  652. Access : Public
  653. Return : void
  654. Parameters : int command - The command to send.
  655. BOOL selected - If "TRUE", the command 
  656. will only be sent to 
  657. selected objects, 
  658. otherwise, it will be 
  659. sent to all objects.
  660. CDiagramEntity* sender - Original sender 
  661. or "NULL" if not 
  662. an object.
  663. Usage : Call this member to send messages to 
  664. (selected) objects in the range "CMD_START" 
  665. to "CMD_END" inclusively (defined in 
  666. DiagramEntity.h). Calls the object "DoCommand".
  667.    ============================================================*/
  668. {
  669. BOOL stop = FALSE;
  670. int max = m_objs.GetSize();
  671. for( int t = 0 ; t < max ; t++ )
  672. {
  673. CDiagramEntity* obj = GetAt( t );
  674. if( !stop && ( !selected || obj->IsSelected() ) )
  675. {
  676. stop = obj->DoMessage( command, sender, from );
  677. SetModified( TRUE );
  678. }
  679. }
  680. }
  681. /////////////////////////////////////////////////////////////////////////////
  682. // CDiagramEntityContainer private helpers
  683. int CDiagramEntityContainer::Find( CDiagramEntity* testobj )
  684. /* ============================================================
  685. Function : CDiagramEntityContainer::Find
  686. Description : Finds the index of object "testobj" in the 
  687. data array.
  688. Access : Protected
  689. Return : int - Index of the 
  690. object or -1 
  691. if not found.
  692. Parameters : CDiagramEntity* testobj - Object to find.
  693. Usage : Internal function. 
  694.    ============================================================*/
  695. {
  696. int index = -1;
  697. CDiagramEntity* obj;
  698. int count = 0;
  699. while( ( obj = GetAt( count ) ) )
  700. {
  701. if( obj == testobj )
  702. index = count;
  703. count++;
  704. }
  705. return index;
  706. }
  707. void CDiagramEntityContainer::Swap( int index1, int index2 )
  708. /* ============================================================
  709. Function : CDiagramEntityContainer::Swap
  710. Description : Swaps the elements at "index1" and "index2".
  711. Access : Private
  712. Return : void
  713. Parameters : int index1 - First object to swap
  714. int index2 - Second object to swap
  715. Usage : Internal function. Used to move objects up 
  716. or down in the z-order.
  717.    ============================================================*/
  718. {
  719. int max = m_objs.GetSize();
  720. if( index1 >= 0 && index1 < max && index2 >= 0 && index2 < max )
  721. {
  722. CDiagramEntity* obj1 = GetAt( index1 );
  723. CDiagramEntity* obj2 = GetAt( index2 );
  724. SetAt( index1, obj2 );
  725. SetAt( index2, obj1 );
  726. }
  727. }
  728. void CDiagramEntityContainer::Undo()
  729. /* ============================================================
  730. Function : CDiagramEntityContainer::Undo
  731. Description : Sets the container data to the last entry 
  732. in the undo stack.
  733. Access : Public
  734. Return : void
  735. Parameters : none
  736. Usage : Call to undo the last operation
  737.    ============================================================*/
  738. {
  739. if( m_undo.GetSize() )
  740. {
  741. // We remove all current data
  742. RemoveAll();
  743. // We get the last entry from the undo-stack
  744. // and clone it into the container data
  745. CUndoItem* undo = static_cast< CUndoItem* >( m_undo.GetAt( m_undo.GetUpperBound() ) );
  746. int count = ( undo->arr ).GetSize();
  747. for( int t = 0 ; t < count ; t++ )
  748. {
  749. CDiagramEntity* obj = static_cast< CDiagramEntity* >( ( undo->arr ).GetAt( t ) );
  750. Add( obj->Clone() );
  751. }
  752. // Set the saved virtual size as well
  753. SetVirtualSize( undo->pt );
  754. // We remove the entry from the undo-stack
  755. delete undo;
  756. m_undo.RemoveAt( m_undo.GetUpperBound() );
  757. if (m_thumb_stor)
  758. m_thumb_stor->InvalidateThumbnailer();
  759. }
  760. }
  761. void CDiagramEntityContainer::Snapshot()
  762. /* ============================================================
  763. Function : CDiagramEntityContainer::Snapshot
  764. Description : Copies the current state of the data to 
  765. the undo-stack.
  766. Access : Public
  767. Return : void
  768. Parameters : none
  769. Usage : Call to add the current state to the undo-stack. 
  770. If the undo stack has a maximum size and 
  771. the stack will grow above the stack limit, 
  772. the first undo array will be removed.
  773.    ============================================================*/
  774. {
  775. if( m_maxstacksize > 0 && m_undo.GetSize() == m_maxstacksize )
  776. {
  777. delete m_undo.GetAt( 0 );
  778. m_undo.RemoveAt( 0 );
  779. }
  780. CUndoItem* undo = new CUndoItem;
  781. while( !undo && m_undo.GetSize() )
  782. {
  783. // We seem - however unlikely -
  784. // to be out of memory.
  785. // Remove first element in
  786. // undo-stack and try again
  787. delete m_undo.GetAt( 0 );
  788. m_undo.RemoveAt( 0 );
  789. undo = new CUndoItem;
  790. }
  791. if( undo )
  792. {
  793. // Save current virtual size
  794. undo->pt = GetVirtualSize();
  795. // Save all objects
  796. int count = m_objs.GetSize();
  797. for( int t = 0 ; t < count ; t++ )
  798. ( undo->arr ).Add( GetAt( t )->Clone() );
  799. // Add to undo stack
  800. m_undo.Add( undo );
  801. }
  802. }
  803. void CDiagramEntityContainer::ClearUndo()
  804. /* ============================================================
  805. Function : CDiagramEntityContainer::ClearUndo
  806. Description : Remove all undo arrays from the undo stack
  807. Access : Public
  808. Return : void
  809. Parameters : none
  810. Usage : Call to clear the undo-stack. All memory will 
  811. be deleted.
  812.    ============================================================*/
  813. {
  814. int count = m_undo.GetSize() - 1;
  815. for( int t = count ; t >= 0 ; t-- )
  816. {
  817. CUndoItem* undo = static_cast< CUndoItem* >( m_undo.GetAt( t ) );
  818. // Remove the stack entry itself.
  819. delete undo;
  820. }
  821. m_undo.RemoveAll();
  822. }
  823. BOOL CDiagramEntityContainer::IsUndoPossible() const
  824. /* ============================================================
  825. Function : CDiagramEntityContainer::IsUndoPossible
  826. Description : Check if it is possible to undo.
  827. Access : Public
  828. Return : BOOL - "TRUE" if undo is possible.
  829. Parameters : none
  830. Usage : Use this call for command enabling
  831.    ============================================================*/
  832. {
  833. return m_undo.GetSize();
  834. }
  835. void CDiagramEntityContainer::SetUndoStackSize( int maxstacksize )
  836. /* ============================================================
  837. Function : CDiagramEntityContainer::SetUndoStackSize
  838. Description : Sets the size of the undo stack.
  839. Access : Public
  840. Return : void
  841. Parameters : int maxstacksize - New size. -1 means 
  842. no limit, 0 no undo.
  843. Usage : Call to set the max undo stack size.
  844.    ============================================================*/
  845. {
  846. m_maxstacksize = maxstacksize;
  847. }
  848. int CDiagramEntityContainer::GetUndoStackSize() const
  849. /* ============================================================
  850. Function : CDiagramEntityContainer::GetUndoStackSize
  851. Description : Returns the size of the undo-stack
  852. Access : Public
  853. Return : int - Current size
  854. Parameters : none
  855. Usage : Call to get the max undo stack size.
  856.    ============================================================*/
  857. {
  858. return m_maxstacksize;
  859. }
  860. void CDiagramEntityContainer::PopUndo()
  861. /* ============================================================
  862. Function : CUMLEntityContainer::PopUndo
  863. Description : Pops the undo stack (removes the last stack
  864. item)
  865. Access : Public
  866. Return : void
  867. Parameters : none
  868. Usage : Call do undo the last Snapshot
  869.    ============================================================*/
  870. {
  871. int size = m_undo.GetSize();
  872. if( size )
  873. {
  874. delete m_undo.GetAt( size - 1 );
  875. m_undo.RemoveAt( size - 1 );
  876. }
  877. }
  878. CObArray* CDiagramEntityContainer::GetData() 
  879. /* ============================================================
  880. Function : CDiagramEntityContainer::GetData
  881. Description : Accessor for the internal data array
  882. Access : Public
  883. Return : CObArray* - A pointer to the internal 
  884. data array.
  885. Parameters : none
  886. Usage : Call to access the internal data array. To 
  887. be used in derived classes.
  888.    ============================================================*/
  889. return &m_objs; 
  890. }
  891. CObArray* CDiagramEntityContainer::GetPaste()
  892. /* ============================================================
  893. Function : CDiagramEntityContainer::GetPaste
  894. Description : Accessor for the internal paste array
  895. Access : Protected
  896. Return : CObArray* - A pointer to the paste 
  897. array
  898. Parameters : none
  899. Usage : Call to access the internal paste array. To 
  900. be used in derived classes.
  901.    ============================================================*/
  902. CObArray* arr = NULL;
  903. if( m_clip )
  904. arr = m_clip->GetData();
  905. return arr;
  906. }
  907. CObArray* CDiagramEntityContainer::GetUndo()
  908. /* ============================================================
  909. Function : CDiagramEntityContainer::GetUndo
  910. Description : Accessor for the internal undo array
  911. Access : Protected
  912. Return : CObArray* - A pointer to the undo 
  913. array
  914. Parameters : none
  915. Usage : Call to access the internal undo array. To 
  916. be used in derived classes.
  917.    ============================================================*/
  918. return &m_undo;
  919. }
  920. void CDiagramEntityContainer::Group()
  921. /* ============================================================
  922. Function : CDiagramEntityContainer::Group
  923. Description : Groups the currently selected objects into 
  924. the same group.
  925. Access : Public
  926. Return : void
  927. Parameters : none
  928. Usage : Call to group all selected items into the 
  929. same group.
  930. Grouped objects can be moved as a 
  931. single entity. Technically, when one object 
  932. in a group is selected, all other objects 
  933. are also selected automatically.
  934.    ============================================================*/
  935. {
  936. CDiagramEntity* obj;
  937. int count = 0;
  938. int group = CGroupFactory::GetNewGroup();
  939. while( ( obj = GetAt( count ) ) )
  940. {
  941. if( obj->IsSelected() )
  942. obj->SetGroup( group );
  943. count++;
  944. }
  945. }
  946. void CDiagramEntityContainer::Ungroup()
  947. /* ============================================================
  948. Function : CDiagramEntityContainer::Ungroup
  949. Description : Ungroups the currently selected objects.
  950. Access : Public
  951. Return : void
  952. Parameters : none
  953. Usage : Call to ungroup all selected items. 
  954. Grouped objects can be moved as a 
  955. single entity. Technically, when one object 
  956. in a group is selected, all other objects 
  957. are also selected automatically.
  958.    ============================================================*/
  959. {
  960. CDiagramEntity* obj;
  961. int count = 0;
  962. while( ( obj = GetAt( count ) ) )
  963. {
  964. if( obj->IsSelected() )
  965. obj->SetGroup( 0 );
  966. count++;
  967. }
  968. }
  969. CSize CDiagramEntityContainer::GetTotalSize()
  970. /* ============================================================
  971. Function : CDiagramEntityContainer::GetTotalSize
  972. Description : Gets the minimum bounding size for the 
  973. objects in the container.
  974. Access :
  975. Return : CSize - Minimum bounding size
  976. Parameters : none
  977. Usage : Call to get the screen size of the objects 
  978. in the container.
  979.    ============================================================*/
  980. {
  981. CPoint start = GetStartPoint();
  982. double width = 0;
  983. double height = 0;
  984. CDiagramEntity* obj;
  985. int count = 0;
  986. while( ( obj = GetAt( count ) ) )
  987. {
  988. width = max( width, obj->GetLeft() );
  989. width = max( width, obj->GetRight() );
  990. height = max( height, obj->GetTop() );
  991. height = max( height, obj->GetBottom() );
  992. count++;
  993. }
  994. return CSize( round( width - start.x ), round( height - start.y ) );
  995. }
  996. CPoint CDiagramEntityContainer::GetStartPoint()
  997. /* ============================================================
  998. Function : CDiagramEntityContainer::GetStartPoint
  999. Description : Gets the starting screen position of the 
  1000. objects in the container (normally the 
  1001. top-left corner of the top-left object).
  1002. Access :
  1003. Return : CPoint - Top-left position of the 
  1004. objects.
  1005. Parameters : none
  1006. Usage : Call to get the starting point on screen of 
  1007. the objects.
  1008.    ============================================================*/
  1009. {
  1010. double startx = 2000.0;
  1011. double starty = 2000.0;
  1012. CDiagramEntity* obj;
  1013. int count = 0;
  1014. while( ( obj = GetAt( count ) ) )
  1015. {
  1016. startx = min( startx, obj->GetLeft() );
  1017. startx = min( startx, obj->GetRight() );
  1018. starty = min( starty, obj->GetTop() );
  1019. starty = min( starty, obj->GetBottom() );
  1020. count++;
  1021. }
  1022. return CPoint( round( startx ), round( starty ) );
  1023. }
  1024. int CDiagramEntityContainer::GetSelectCount() const
  1025. /* ============================================================
  1026. Function : int CDiagramEntityContainer::GetSelectCount
  1027. Description : Gets the number of currently selected 
  1028. objects in the container.
  1029. Access :
  1030. Return : int - Currently selected objects.
  1031. Parameters : none
  1032. Usage : Call to get the number of selected objects.
  1033.    ============================================================*/
  1034. {
  1035. int max = GetSize();
  1036. int count = 0;
  1037. for( int t = 0 ; t < max ; t++ )
  1038. if( GetAt( t )->IsSelected() )
  1039. count++;
  1040. return count;
  1041. }
  1042. void CDiagramEntityContainer::SelectAll()
  1043. {
  1044. int max = GetSize();
  1045. for( int t = 0 ; t < max ; t++ )
  1046. GetAt( t )->Select( TRUE );
  1047. }
  1048. void CDiagramEntityContainer::UnselectAll()
  1049. {
  1050. int max = GetSize();
  1051. for( int t = 0 ; t < max ; t++ )
  1052. GetAt( t )->Select( FALSE );
  1053. }
  1054. #pragma warning( default : 4706 )