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 / FWDialog.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  11.5 KB  |  411 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Dialog.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 FWDIALOG_H
  13. #include "FWDialog.h"
  14. #endif
  15.  
  16. // ----- Framework Layer -----
  17.  
  18. #ifndef FWPART_H
  19. #include "FWPart.h"
  20. #endif
  21.  
  22. #ifndef FWUTIL_H
  23. #include "FWUtil.h"
  24. #endif
  25.  
  26. #ifndef FWFLOWIN_H
  27. #include "FWFloWin.h"
  28. #endif
  29.  
  30. #ifndef FWTABBER_H
  31. #include "FWTabber.h"
  32. #endif
  33.  
  34. #ifndef FWNOTDEF_H
  35. #include "FWNotDef.h"
  36. #endif
  37.  
  38. #ifndef FWIDLE_H
  39. #include "FWIdle.h"
  40. #endif
  41.  
  42. // ----- OS Layer -----
  43.  
  44. #ifndef FWMENU_H
  45. #include "FWMenu.h"
  46. #endif
  47.  
  48. #ifndef FWEVENT_H
  49. #include "FWEvent.h"
  50. #endif
  51.  
  52. #ifndef FWALERT_H
  53. #include "FWAlert.h"
  54. #endif
  55.  
  56. #ifndef SLMixOS_H
  57. #include "SLMixOS.h"
  58. #endif
  59.  
  60. #ifndef FWCFMRES_H
  61. #include "FWCFMRes.h"
  62. #endif
  63.  
  64. #ifndef FWSESION_H
  65. #include "FWSesion.h"
  66. #endif
  67.  
  68. // ----- Graphic Includes -----
  69.  
  70. #ifndef FWRECT_H
  71. #include "FWRect.h"
  72. #endif
  73.  
  74. #ifndef FWTXTBOX_H
  75. #include "FWTxtBox.h"
  76. #endif
  77.  
  78. #ifndef FWRECSHP_H
  79. #include "FWRecShp.h"
  80. #endif
  81.  
  82. #ifndef FWPICSHP_H
  83. #include "FWPicShp.h"        
  84. #endif
  85.  
  86. // ----- Foundation Layer -----
  87.  
  88. #ifndef FWEXCDEF_H
  89. #include "FWExcDef.h"
  90. #endif
  91.  
  92. #ifndef FWNOTIFN_H
  93. #include "FWNotifn.h"
  94. #endif
  95.  
  96. // ----- OpenDoc Includes -----
  97.  
  98. #ifndef SOM_ODArbitrator_xh
  99. #include <Arbitrat.xh>
  100. #endif
  101.  
  102. #ifndef SOM_ODFocusSet_xh
  103. #include <FocusSet.xh>
  104. #endif
  105.  
  106. //========================================================================================
  107. // Runtime Informations
  108. //========================================================================================
  109.  
  110. #ifdef FW_BUILD_MAC
  111. #pragma segment fwpart2
  112. #endif
  113.  
  114. FW_DEFINE_CLASS_M2(FW_CDialogFrame, FW_CFrame, FW_MReceiver)
  115. FW_DEFINE_AUTO(FW_CDialogFrame)
  116.  
  117. //========================================================================================
  118. //  class FW_CDialogFrame
  119. //========================================================================================
  120.  
  121. //----------------------------------------------------------------------------------------
  122. // FW_CDialogFrame::FW_CDialogFrame
  123. //----------------------------------------------------------------------------------------
  124. FW_CDialogFrame::FW_CDialogFrame(Environment* ev, 
  125.                                 ODFrame* odFrame, 
  126.                                 FW_CPresentation* presentation, 
  127.                                 FW_CPart* part)
  128.     : FW_CFrame(ev, odFrame, presentation, part),
  129.     FW_MReceiver(),
  130.     fDefaultButton(NULL),
  131.     fCancelButton(NULL)
  132. {
  133.     // Add a ViewTabber and an idler by default 
  134.     fViewTabber = new FW_CViewTabber(ev, this); 
  135.  
  136.     fIdler = FW_NEW(FW_CIdler, (this, 15));
  137.     fIdler->RegisterIdle(ev);            
  138.     
  139.     fIsModal = TRUE;        // [LSD] see non-modal dialogs later
  140.  
  141.     FW_END_CONSTRUCTOR
  142. }
  143.  
  144. //----------------------------------------------------------------------------------------
  145. // FW_CDialogFrame::~FW_CDialogFrame
  146. //----------------------------------------------------------------------------------------
  147.  
  148. FW_CDialogFrame::~FW_CDialogFrame()
  149. {
  150.     FW_START_DESTRUCTOR
  151.     
  152.     delete fIdler;
  153.     fIdler = NULL;
  154.  
  155.     // fViewTabber event handler is deleted automatically
  156. }
  157.  
  158. //----------------------------------------------------------------------------------------
  159. // FW_CDialogFrame::PrivButtonAttached
  160. //----------------------------------------------------------------------------------------
  161.  
  162. void FW_CDialogFrame::PrivButtonAttached(Environment* ev, FW_CButton* button)
  163. {
  164.     if (button->GetMessage(ev) == FW_kDefaultButtonMsg)
  165.     {
  166.         fDefaultButton = PrivSetDismissButton(ev, button, FW_kDefaultButtonMsg, fDefaultButton);
  167.     }
  168.     else if (button->GetMessage(ev) == FW_kCancelButtonMsg)
  169.     {
  170.         fCancelButton = PrivSetDismissButton(ev, button, FW_kCancelButtonMsg, fCancelButton);
  171.     }
  172. }
  173.  
  174. //----------------------------------------------------------------------------------------
  175. // FW_CDialogHandler::SetDefaultButton
  176. //----------------------------------------------------------------------------------------
  177.  
  178. void FW_CDialogFrame::SetDefaultButton(Environment* ev, ODID id)
  179. {
  180.     // Use this method only if you want to change or remove an existing default button.
  181.     // (Use id = 0 to remove an existing default button)
  182.     // The dialog's default button is automatically set when you use FW_kDefaultButtonMsg
  183.     // for the button's message value (either in code or resources)
  184.     
  185.     FW_CButton* button = NULL;
  186.     if (id != 0)
  187.     {
  188.         button = FW_DYNAMIC_CAST(FW_CButton, FindViewByID(ev, id));
  189.         FW_ASSERT(button);
  190.     }
  191.  
  192.     fDefaultButton = PrivSetDismissButton(ev, button, FW_kDefaultButtonMsg, fDefaultButton);
  193. }
  194.  
  195. //----------------------------------------------------------------------------------------
  196. // FW_CDialogFrame::SetCancelButton
  197. //----------------------------------------------------------------------------------------
  198.  
  199. void FW_CDialogFrame::SetCancelButton(Environment* ev, ODID id)
  200. {
  201.     // Use this method only if you want to change or remove an existing cancel button.
  202.     // (Use id = 0 to remove an existing cancel button)
  203.     // The dialog's cancel button is automatically set when you use FW_kCancelButtonMsg
  204.     // for the button's message value (either in code or resources)
  205.     
  206.     FW_CButton* button = NULL;
  207.     if (id != 0)
  208.     {
  209.         button = FW_DYNAMIC_CAST(FW_CButton, FindViewByID(ev, id));
  210.         FW_ASSERT(button);
  211.     }
  212.     
  213.     fCancelButton = PrivSetDismissButton(ev, button, FW_kCancelButtonMsg, fCancelButton);
  214. }
  215.  
  216. //----------------------------------------------------------------------------------------
  217. // FW_CDialogHandler::PrivSetDismissButton
  218. //----------------------------------------------------------------------------------------
  219.  
  220. FW_CButton* FW_CDialogFrame::PrivSetDismissButton(Environment* ev, FW_CButton* newButton, FW_Message message, FW_CButton* prevButton)
  221. {
  222.     if (prevButton) 
  223.     {
  224.         // Remove outline
  225.         if (message == FW_kDefaultButtonMsg)
  226.             prevButton->SetButtonKind(ev, FW_kPushButton);    
  227.         
  228.         // Remove connection
  229.         RemoveInterest(prevButton, message);
  230.  
  231.         // Reset button's message
  232.         prevButton->SetMessage(ev, FW_kNullMsg);
  233.         
  234.         prevButton = NULL;
  235.     }
  236.     
  237.     if (newButton) {
  238.         // Add outline
  239.         if (message == FW_kDefaultButtonMsg)
  240.             newButton->SetButtonKind(ev, FW_kDefaultPushButton);        
  241.         // Set the button's message & connect dialog
  242.         newButton->SetMessage(ev, message);
  243.         newButton->LinkControlTo(ev, this);
  244.     }
  245.     
  246.     return newButton;
  247. }
  248.  
  249. //----------------------------------------------------------------------------------------
  250. //    FW_CDialogFrame::HandleNotification
  251. //----------------------------------------------------------------------------------------
  252.  
  253. void FW_CDialogFrame::HandleNotification(Environment* ev, const FW_CNotification& notification)
  254. {
  255.     // ---- close the dialog on OK or Cancel ----
  256.     if (notification.GetMessage() == FW_kDefaultButtonMsg ||
  257.         notification.GetMessage() == FW_kCancelButtonMsg)
  258.     {
  259.         GetWindow(ev)->CloseAndRemove(ev);
  260.         //    ATTENTION: The whole window is gone at this point. So don't try to do
  261.         //    anything after this point
  262.     }
  263. }
  264.  
  265. //----------------------------------------------------------------------------------------
  266. // FW_CDialogFrame::NewModalDialog
  267. //----------------------------------------------------------------------------------------
  268.  
  269. FW_CDialogFrame* FW_CDialogFrame::NewModalDialog(Environment* ev, 
  270.                                             FW_CPart* part, 
  271.                                             FW_CPresentation* presentation,
  272.                                             const FW_CPoint& size, 
  273.                                             const FW_CPoint& position, 
  274.                                             FW_WindowStyle style, 
  275.                                             const FW_CString& windowTitle)
  276. {
  277.     // [LSD] todo: add checking on authorized window styles.  See FWWindow.k            
  278.     FW_WindowStyle    winStyle = FW_kModalDialog | style;
  279.  
  280.     // Create dialog window (which in turn will create a dialog frame through the
  281.     // part's NewFrame method, will create a facet and will create the subviews)
  282.     FW_CWindow* dialogWindow = new FW_CWindow(ev, part, 
  283.                                             NULL,         // no parent frame
  284.                                             FALSE,         // Dialogs are not persistent
  285.                                             FW_CPart::fgViewAsFrameToken,
  286.                                             presentation,
  287.                                             windowTitle,
  288.                                             size,
  289.                                             position,
  290.                                             winStyle);
  291.     
  292.     // Use standard position
  293.     if ((winStyle & FW_kStandardDialogPosition) != 0)
  294.     {
  295.         FW_PlatformError error;
  296.         ::FW_PositionModalDialog(dialogWindow->GetPlatformWindow(ev), &error);
  297.         FW_FailOnError(error);
  298.     }
  299.     
  300.     // Get the dialog frame from the window and try to open it
  301.     FW_CAcquiredODWindow aqODDialog = dialogWindow->AcquireODWindow(ev);
  302.     ODFrame* odFrame = aqODDialog->GetRootFrame(ev);
  303.     FW_CDialogFrame* dialogFrame = (FW_CDialogFrame *)FW_CFrame::ODtoFWFrame(ev, odFrame);
  304.     FW_Boolean isMoveable = winStyle & FW_kHasCaption ? true : false;
  305.     
  306.     if (dialogFrame->TryModalFocus(ev, odFrame, isMoveable) == FALSE) {        
  307.         // modal focus could not be granted    
  308.         delete dialogWindow;    
  309.         return NULL;    
  310.     }
  311.     return dialogFrame;
  312. }
  313.  
  314. //----------------------------------------------------------------------------------------
  315. // FW_CDialogFrame::NewAndShowModalDialog
  316. //----------------------------------------------------------------------------------------
  317. // Same as NewModalDialog but show the window too. Useful when no initialization is needed
  318.  
  319. FW_CDialogFrame* FW_CDialogFrame::NewAndShowModalDialog(Environment* ev,  
  320.                                     FW_CPart* part, FW_CPresentation* presentation,
  321.                                     const FW_CPoint& size, const FW_CPoint& position, 
  322.                                     FW_WindowStyle style, const FW_CString& windowTitle)
  323. {
  324.     FW_CDialogFrame* dialogFrame = NewModalDialog(ev, part, presentation, size, position,
  325.                                                         style, windowTitle);
  326.     
  327.     if (dialogFrame != NULL)
  328.     {
  329.         dialogFrame->GetWindow(ev)->Show(ev);
  330.     }
  331.     return dialogFrame;
  332. }
  333.  
  334. //----------------------------------------------------------------------------------------
  335. // FW_CDialogFrame::TryModalFocus
  336. //----------------------------------------------------------------------------------------
  337.  
  338. FW_Boolean FW_CDialogFrame::TryModalFocus(Environment* ev, ODFrame* odFrame, FW_Boolean isMoveable)
  339. {
  340.     if (FW_CSession::GetArbitrator(ev)->RequestFocus(ev, FW_CPart::fgModalFocusToken, odFrame))
  341.     {
  342.         // Add modal focus to the frame's focus set
  343.         GetFocusSet(ev)->Add(ev, FW_CPart::fgModalFocusToken);
  344.         
  345.         // Hide floating windows
  346.         FW_CFloatingWindow::HideShowFloatingWindows(ev, FALSE);
  347.         
  348.         // Disable the whole menubar
  349.         // (Edit menu will be enabled later if dialog contains an active text-edit) 
  350.         if (fIsModal)
  351.             GetPart(ev)->PrivEnableMenuBar(ev, FALSE, isMoveable);            
  352.     
  353.         // Select the first target
  354.         fViewTabber->Tab(ev, this);
  355.         
  356.         return TRUE;
  357.     }
  358.     return FALSE;
  359. }
  360.  
  361. //----------------------------------------------------------------------------------------
  362. //    FW_CDialogFrame::FrameRemoved
  363. //----------------------------------------------------------------------------------------
  364.  
  365. void FW_CDialogFrame::FrameRemoved(Environment* ev, FW_Boolean toStorage)
  366. {
  367.     // ----- re-enable the menubar after Modal dialog
  368.     if (fIsModal)
  369.         GetPart(ev)->PrivEnableMenuBar(ev, true, false);
  370.  
  371.     // ----- Call inherited -----
  372.     FW_CFrame::FrameRemoved(ev, toStorage);    
  373. }
  374.  
  375. //----------------------------------------------------------------------------------------
  376. // FW_CDialogFrame::DoVirtualKey
  377. //----------------------------------------------------------------------------------------
  378.  
  379. FW_Handled FW_CDialogFrame::DoVirtualKey(Environment* ev, const FW_CVirtualKeyEvent & event)
  380. {
  381.     FW_Handled handled = FW_kNotHandled;
  382.     FW_CButton* button = NULL;
  383.     
  384.     switch (event.GetKeyCode(ev)) {
  385.         case FW_kVKEnter:
  386.         case FW_kVKReturn:
  387.             button = GetDefaultButton(ev);
  388.             break;
  389.         
  390.         case FW_kVKEscape:    
  391.             button = GetCancelButton(ev);
  392.             break;
  393.         
  394.         default:
  395.             if (event.IsCommandPeriod(ev)) {
  396.                 button = GetCancelButton(ev);
  397.             }
  398.             break;
  399.     }
  400.     
  401.     if (button) {
  402.         button->SimulateButtonPressed(ev);
  403.         handled = FW_kHandled;
  404.     }
  405.     
  406.     // returning FW_kNotHandled will propagate the same key as a CharKeyEvent on the Mac
  407.     return handled;    
  408. }
  409.  
  410.  
  411.