home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWPart / FWCmd.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  12.6 KB  |  475 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWCmd.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWCMD_H
  13. #include "FWCmd.h"
  14. #endif
  15.  
  16. // ----- Framework Includes -----
  17.  
  18. #ifndef FWPART_H
  19. #include "FWPart.h"
  20. #endif
  21.  
  22. #ifndef FWFRAME_H
  23. #include "FWFrame.h"
  24. #endif
  25.  
  26. #ifndef FWSELECT_H
  27. #include "FWSelect.h"
  28. #endif
  29.  
  30. #ifndef FWPRESEN_H
  31. #include "FWPresen.h"
  32. #endif
  33.  
  34. // ----- OS Layer -----
  35.  
  36. #ifndef FWMENUS_K
  37. #include "FWMenus.k"
  38. #endif
  39.  
  40. #ifndef FWRESACC_H
  41. #include "FWResAcc.h"
  42. #endif
  43.  
  44. #ifndef FWRESTYP_H
  45. #include "FWResTyp.h"
  46. #endif
  47.  
  48. #ifndef SLODFSTR_K
  49. #include "SLODFStr.k"
  50. #endif
  51.  
  52. #ifndef SLODFSTR_H
  53. #include "SLODFStr.h"
  54. #endif
  55.  
  56. #ifndef FWSESION_H
  57. #include "FWSesion.h"
  58. #endif
  59.  
  60. // ----- Foundation Layer -----
  61.  
  62. #ifndef FWCFMRES_H
  63. #include "FWCFMRes.h"
  64. #endif
  65.  
  66. #ifndef FWMEMMGR_H
  67. #include "FWMemMgr.h"
  68. #endif
  69.  
  70. #ifndef FWSTRS_H
  71. #include "FWStrs.h"
  72. #endif
  73.  
  74. #ifndef FWBNDSTR_H
  75. #include "FWBndStr.h"
  76. #endif
  77.  
  78. // ----- OpenDoc Includes -----
  79.  
  80. // for ODIText
  81. #ifndef _ITEXT_
  82. #include "IText.h"
  83. #endif
  84.  
  85. #ifndef SOM_Module_OpenDoc_Commands_defined
  86. #include <CmdDefs.xh>
  87. #endif
  88.  
  89. #ifndef SOM_ODPart_xh
  90. #include "Part.xh"
  91. #endif
  92.  
  93. #ifndef SOM_ODFrame_xh
  94. #include "Frame.xh"
  95. #endif
  96.  
  97. #ifndef SOM_ODStorageUnit_xh
  98. #include <StorageU.xh>
  99. #endif
  100.  
  101. // ----- Platform Includes -----
  102.  
  103. #if defined(FW_BUILD_MAC) && !defined(__SCRIPT__)
  104. #include <Script.h>
  105. #endif
  106.  
  107. #if defined(FW_BUILD_WIN32S) && !defined(__WINNT_H)
  108. #include <winnt.h>
  109. #endif
  110.  
  111.  
  112. //========================================================================================
  113. //    Runtime Info
  114. //========================================================================================
  115.  
  116. #ifdef FW_BUILD_MAC
  117. #pragma segment odfcommands
  118. #endif
  119.  
  120. FW_DEFINE_AUTO(FW_CCommand)
  121.  
  122. //========================================================================================
  123. // FW_CCommand class
  124. //========================================================================================
  125.  
  126. //----------------------------------------------------------------------------------------
  127. // FW_CCommand constructor
  128. //----------------------------------------------------------------------------------------
  129.  
  130. FW_CCommand::FW_CCommand(Environment* ev,
  131.                          ODCommandID id,
  132.                          FW_CFrame* frame,
  133.                          FW_Boolean canUndo) :
  134.     fCommandID(id),
  135.     fCanUndo(canUndo),
  136.     fCausesChange(TRUE),
  137.     fActionType(kODSingleAction),
  138.     fPart(NULL),
  139.     fFrame(frame),        
  140.     fUndoString(NULL),
  141.     fRedoString(NULL),
  142.     fHasAddedAction(false)
  143. {
  144.     FW_ASSERT(fFrame);
  145.     
  146.     fPart = fFrame->GetPart(ev);
  147.     fPart->GetODPart(ev)->Acquire(ev);
  148.  
  149.     // [HLX] ATTENTION: Because secondary frames may have disappeared during Undo
  150.     // we need to use the source frame
  151.     fSourceFrame = fFrame->GetSourceFrame(ev);
  152.  
  153.     fPresentation = fFrame->GetPresentation(ev);
  154.  
  155.     FW_END_CONSTRUCTOR
  156. }
  157.  
  158. //----------------------------------------------------------------------------------------
  159. // FW_CCommand destructor
  160. //----------------------------------------------------------------------------------------
  161.  
  162. FW_CCommand::~FW_CCommand()
  163. {
  164.     FW_START_DESTRUCTOR
  165.  
  166.     FW_SOMEnvironment ev;    
  167.     fPart->GetODPart(ev)->Release(ev);
  168.  
  169.     PrivDisposeUndoStrings();
  170. }
  171.  
  172. //----------------------------------------------------------------------------------------
  173. // FW_CCommand::PrivDisposeUndoStrings
  174. //----------------------------------------------------------------------------------------
  175.  
  176. void FW_CCommand::PrivDisposeUndoStrings()
  177. {
  178.     if (fUndoString)
  179.         ::DisposeIText(fUndoString);
  180.     if (fRedoString)
  181.         ::DisposeIText(fRedoString);
  182.     
  183.     fUndoString = fRedoString = NULL;
  184. }
  185.  
  186. //----------------------------------------------------------------------------------------
  187. // FW_CCommand::Execute
  188. //----------------------------------------------------------------------------------------
  189. //    Note: Execute returns true if the command is on the undo stack. It returns false if the
  190. //    command has been deleted because it was not undoable
  191.  
  192. FW_Boolean FW_CCommand::Execute(Environment* ev, FW_Boolean deleteIfNotUndoable)
  193. {
  194.     FW_Boolean wasDone = FALSE;
  195.     FW_Boolean isOnUndoStack = TRUE;
  196.     FW_VOLATILE(wasDone);
  197.     
  198.     FW_TRY
  199.     {
  200.         this->DoIt(ev);
  201.         wasDone = TRUE;
  202.     
  203.         if (GetCausesChange(ev))
  204.             PropagateChanges(ev);
  205.             
  206.         if (GetCanUndo(ev))
  207.             AddAction(ev, fActionType, (octet*) &this, sizeof(FW_CCommand*), GetUndoString(ev), GetRedoString(ev));
  208.     }
  209.     FW_CATCH_BEGIN
  210.     FW_CATCH_EVERYTHING()
  211.     {
  212.         if (!wasDone)
  213.         {
  214.             CommitDone(ev);
  215.             delete this;
  216.             FW_THROW_SAME();
  217.         }
  218.         
  219.         // Don't rethrow if the command was completed
  220.         SetCanUndo(ev, FALSE);
  221.     }
  222.     FW_CATCH_END
  223.     
  224.     // If the command has not been added to the action stack then kill it
  225.  
  226.     if (!HasAddedAction(ev))
  227.     {
  228.         CommitDone(ev);
  229.         if (deleteIfNotUndoable)
  230.             delete this;
  231.         isOnUndoStack = FALSE;
  232.     }
  233.     
  234.     return isOnUndoStack;
  235. }
  236.  
  237. //----------------------------------------------------------------------------------------
  238. // FW_CCommand::UndoIt
  239. //----------------------------------------------------------------------------------------
  240.  
  241. void FW_CCommand::UndoIt(Environment* ev)
  242. {
  243. FW_UNUSED(ev);
  244. }
  245.  
  246. //----------------------------------------------------------------------------------------
  247. // FW_CCommand::RedoIt
  248. //----------------------------------------------------------------------------------------
  249.  
  250. void FW_CCommand::RedoIt(Environment* ev)
  251. {
  252. FW_UNUSED(ev);
  253. }
  254.  
  255. //----------------------------------------------------------------------------------------
  256. // FW_CCommand::CommitDone
  257. //----------------------------------------------------------------------------------------
  258.  
  259. void FW_CCommand::CommitDone(Environment* ev)
  260. {
  261.     // Called by FW_CPart::DisposeActionState before deleting the command
  262.     // The command has been done, and possibly redone
  263.  
  264.     if (GetCanUndo(ev))
  265.         this->FreeUndoState(ev);
  266. }
  267.  
  268. //----------------------------------------------------------------------------------------
  269. // FW_CCommand::CommitUndone
  270. //----------------------------------------------------------------------------------------
  271.  
  272. void FW_CCommand::CommitUndone(Environment* ev)
  273. {
  274.     // Called by FW_CPart::DisposeActionState before deleting the command
  275.     // The last action for this command was an Undo
  276.  
  277.     if (GetCanUndo(ev))
  278.         this->FreeRedoState(ev);
  279. }
  280.  
  281. //----------------------------------------------------------------------------------------
  282. // FW_CCommand::SaveUndoState
  283. //----------------------------------------------------------------------------------------
  284. void FW_CCommand::SaveUndoState(Environment* ev)
  285. {
  286. FW_UNUSED(ev);
  287. }
  288.  
  289. //----------------------------------------------------------------------------------------
  290. // FW_CCommand::SaveRedoState
  291. //----------------------------------------------------------------------------------------
  292. void FW_CCommand::SaveRedoState(Environment* ev)
  293. {
  294. FW_UNUSED(ev);
  295. }
  296.  
  297. //----------------------------------------------------------------------------------------
  298. // FW_CCommand::FreeUndoState
  299. //----------------------------------------------------------------------------------------
  300. void FW_CCommand::FreeUndoState(Environment* ev)
  301. {
  302. FW_UNUSED(ev);
  303. }
  304.  
  305. //----------------------------------------------------------------------------------------
  306. // FW_CCommand::FreeRedoState
  307. //----------------------------------------------------------------------------------------
  308. void FW_CCommand::FreeRedoState(Environment* ev)
  309. {
  310. FW_UNUSED(ev);
  311. }
  312.  
  313. //----------------------------------------------------------------------------------------
  314. // FW_CCommand::SetMenuStrings
  315. //----------------------------------------------------------------------------------------
  316.  
  317. void FW_CCommand::SetMenuStrings(Environment* ev,
  318.                                  const FW_CString& undoString,
  319.                                  const FW_CString& redoString)
  320. {
  321. FW_UNUSED(ev);
  322.     PrivDisposeUndoStrings();
  323.     fUndoString = ::CopyIText(undoString.RevealODIText());
  324.     fRedoString = ::CopyIText(redoString.RevealODIText());
  325. }
  326.  
  327. //----------------------------------------------------------------------------------------
  328. // FW_CCommand::SetMenuStrings
  329. //----------------------------------------------------------------------------------------
  330.  
  331. void FW_CCommand::SetMenuStrings(Environment* ev,
  332.                                  char* undoChars,
  333.                                  char* redoChars)
  334. {
  335.     FW_CString255 undoString(undoChars);
  336.     FW_CString255 redoString(redoChars);
  337.     this->SetMenuStrings(ev, undoString, redoString);
  338. }
  339.  
  340. //----------------------------------------------------------------------------------------
  341. // FW_CCommand::SetMenuStringsFromResource
  342. //----------------------------------------------------------------------------------------
  343. void FW_CCommand::SetMenuStringsFromResource(Environment* ev, 
  344.                                              short stringResourceID, 
  345.                                              short undoStringID, 
  346.                                              short redoStringID)
  347. {
  348.     FW_PSharedLibraryResourceFile resFile(ev);
  349.     FW_CString undoString;
  350.     FW_CString redoString;
  351.     ::FW_LoadStringByID(ev, resFile, stringResourceID, FW_kMultiStringRes, undoStringID, undoString);
  352.     ::FW_LoadStringByID(ev, resFile, stringResourceID, FW_kMultiStringRes, redoStringID, redoString);
  353.     this->SetMenuStrings(ev, undoString, redoString);
  354. }
  355.  
  356. //----------------------------------------------------------------------------------------
  357. // FW_CCommand::AddAction
  358. //----------------------------------------------------------------------------------------
  359.  
  360. void FW_CCommand::AddAction(Environment* ev, 
  361.                             ODActionType actionType, 
  362.                             octet* dataPtr, 
  363.                             unsigned long dataSize,
  364.                             ODName* undoActionLabel, 
  365.                             ODName* redoActionLabel)
  366. {
  367.     // Set up the action data record
  368.     ODActionData actionState;
  369.     actionState._maximum = dataSize;
  370.     actionState._length = dataSize;
  371.     actionState._buffer = dataPtr;
  372.  
  373.     FW_CSession::GetUndo(ev)->AddActionToHistory(ev, fPart->GetODPart(ev),
  374.                                                           &actionState,
  375.                                                           actionType,
  376.                                                           undoActionLabel,
  377.                                                           redoActionLabel);
  378.     if (dataSize != 0)
  379.         fHasAddedAction = TRUE;    // OpenDoc has a ptr to this command object
  380. }
  381.  
  382. //----------------------------------------------------------------------------------------
  383. // FW_CCommand::IsOKtoEdit
  384. //----------------------------------------------------------------------------------------
  385.  
  386. FW_Boolean FW_CCommand::IsOKtoEdit(Environment* ev)
  387. {
  388.     FW_Boolean result = true;
  389.  
  390.     if (fCausesChange)
  391.     {
  392.         if (fPart->IsReadOnly(ev))
  393.             result = false;
  394.         else 
  395.             result = !fFrame->IsFrameInLinkDestination(ev);
  396.     }
  397.  
  398.     return result;
  399. }
  400.  
  401. //----------------------------------------------------------------------------------------
  402. // FW_CCommand::PrivLoadDefaultUndoStrings
  403. //----------------------------------------------------------------------------------------
  404.  
  405. void FW_CCommand::PrivLoadDefaultUndoStrings(Environment* ev)
  406. {
  407.     FW_CString undoString;
  408.     FW_CString redoString;
  409.     
  410.     ::FW_PrivLoadDefaultUndoStrings(ev, undoString, redoString);
  411.     SetMenuStrings(ev, undoString, redoString);
  412. }
  413.  
  414. //----------------------------------------------------------------------------------------
  415. // FW_CCommand::AddEndAction (static)
  416. //----------------------------------------------------------------------------------------
  417.  
  418. void FW_CCommand::AddEndAction(Environment* ev, short undoMsgID, FW_CPart* part)
  419. {
  420.     FW_CString undoString;
  421.     FW_CString redoString;
  422.     ::FW_PrivLoadUndoStrings(ev, undoMsgID, undoString, redoString);
  423.     ODName* undoActionLabel = ::CopyIText(undoString.RevealODIText());
  424.     ODName* redoActionLabel = ::CopyIText(redoString.RevealODIText());
  425.  
  426.     // Set up an empty action data record
  427.     ODActionData actionState;
  428.     actionState._maximum = 0;
  429.     actionState._length = 0;
  430.     actionState._buffer = NULL;
  431.  
  432.     FW_CSession::GetUndo(ev)->AddActionToHistory(ev, part->GetODPart(ev),
  433.                                                          &actionState,
  434.                                                          kODEndAction,
  435.                                                          undoActionLabel,
  436.                                                          redoActionLabel);
  437. }
  438.  
  439. //----------------------------------------------------------------------------------------
  440. // FW_CCommand::HandleUndo (static)
  441. //----------------------------------------------------------------------------------------
  442.  
  443. void FW_CCommand::HandleUndo(Environment* ev)
  444. {
  445.     UndoIt(ev);
  446.     
  447.     if (GetCausesChange(ev))
  448.         PropagateChanges(ev);
  449.         
  450. }
  451.  
  452. //----------------------------------------------------------------------------------------
  453. // FW_CCommand::HandleRedo (static)
  454. //----------------------------------------------------------------------------------------
  455.  
  456. void FW_CCommand::HandleRedo(Environment* ev)
  457. {
  458.     RedoIt(ev);
  459.     
  460.     if (GetCausesChange(ev))
  461.         PropagateChanges(ev);
  462.         
  463. }
  464.  
  465. //----------------------------------------------------------------------------------------
  466. // FW_CCommand::PropagateChanges (static)
  467. //----------------------------------------------------------------------------------------
  468.  
  469. void FW_CCommand::PropagateChanges(Environment* ev,  ODUpdateID id)
  470. {
  471.     GetPresentation(ev)->ContentUpdated(ev, id);
  472.     fPart->Changed(ev);
  473. }
  474.  
  475.