Esempio n. 1
0
void wxDialog::DoShowModal()
{
    wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") );

    wxModalDialogs.Append(this);

    SetFocus() ;
    
#if TARGET_CARBON
    BeginAppModalStateForWindow(  (WindowRef) MacGetWindowRef()) ;
#else
    // TODO : test whether parent gets disabled
    bool formerModal = s_macIsInModalLoop ;
    s_macIsInModalLoop = true ;
#endif
    while ( IsModalShowing() )
    {
        wxTheApp->MacDoOneEvent() ;
        // calls process idle itself
    }

#if TARGET_CARBON
    EndAppModalStateForWindow( (WindowRef) MacGetWindowRef() ) ;
#else
    // TODO probably reenable the parent window if any
    s_macIsInModalLoop = formerModal ;
#endif
}
int FileDialog::ShowModal()
{
   OSErr err;
   NavDialogCreationOptions dialogCreateOptions;
   // set default options
   ::NavGetDefaultDialogCreationOptions(&dialogCreateOptions);
   
   // this was always unset in the old code
   dialogCreateOptions.optionFlags &= ~kNavSelectDefaultLocation;
   
   wxMacCFStringHolder message(m_message, GetFont().GetEncoding());
   dialogCreateOptions.windowTitle = message;
   
   wxMacCFStringHolder defaultFileName(m_fileName, GetFont().GetEncoding());
   dialogCreateOptions.saveFileName = defaultFileName;
   
   NavDialogRef dialog;
   NavObjectFilterUPP navFilterUPP = NULL;
   CustomData myData;
   
   SetRect(&myData.bounds, 0, 0, 0, 0);
   myData.me = this;
   myData.window = NULL;
   myData.defaultLocation = m_dir;
   myData.userpane = NULL;
   myData.choice = NULL;
   myData.button = NULL;
   myData.saveMode = false;
   myData.showing = true;
   
   Rect r;
   SInt16 base;
   SInt16 margin = 3;
   SInt16 gap = 0;
   
   MakeUserDataRec(&myData , m_wildCard);
   myData.currentfilter = m_filterIndex;
   size_t numFilters = myData.extensions.GetCount();
   if (numFilters)
   {
      CreateNewMenu(0, 0, &myData.menu);
      
      for ( size_t i = 0 ; i < numFilters ; ++i )
      {
         ::AppendMenuItemTextWithCFString(myData.menu,
                                          wxMacCFStringHolder(myData.name[i],
                                                              GetFont().GetEncoding()),
                                          4,
                                          i,
                                          NULL);
      }
      
      SetRect(&r, 0, margin, 0, 0);
      CreatePopupButtonControl(NULL, &r, CFSTR("Format:"), -12345, true, -1, teJustLeft, normal, &myData.choice);
      SetControlID(myData.choice, &kChoiceID);
      SetControlPopupMenuRef(myData.choice, myData.menu);
      SetControl32BitMinimum(myData.choice, 1);
      SetControl32BitMaximum(myData.choice, myData.name.GetCount());
      SetControl32BitValue(myData.choice, myData.currentfilter + 1);
      GetBestControlRect(myData.choice, &r, &base);
      SizeControl(myData.choice, r.right - r.left, r.bottom - r.top);
      UnionRect(&myData.bounds, &r, &myData.bounds);
      gap = 15;

      HIObjectSetAuxiliaryAccessibilityAttribute((HIObjectRef)myData.choice, 0, kAXDescriptionAttribute, CFSTR("Format"));
   }
   
   if (!m_buttonlabel.IsEmpty())
   {
      wxMacCFStringHolder cfString(wxStripMenuCodes(m_buttonlabel).c_str(), wxFONTENCODING_DEFAULT);
      SetRect(&r, myData.bounds.right + gap, margin, 0, 0);
      CreatePushButtonControl(NULL, &r, cfString, &myData.button);
      SetControlID(myData.button, &kButtonID);
      GetBestControlRect(myData.button, &r, &base);
      SizeControl(myData.button, r.right - r.left, r.bottom - r.top);
      UnionRect(&myData.bounds, &r, &myData.bounds);
   }
   
   // Expand bounding rectangle to include a top and bottom margin
   myData.bounds.top -= margin;
   myData.bounds.bottom += margin;
   
   dialogCreateOptions.optionFlags |= kNavNoTypePopup;
   
   if (m_dialogStyle & wxFD_SAVE)
   {
      dialogCreateOptions.modality = kWindowModalityWindowModal;
      dialogCreateOptions.parentWindow = (WindowRef) GetParent()->MacGetTopLevelWindowRef();
   
      myData.saveMode = true;
      
      if (!numFilters)
      {
         dialogCreateOptions.optionFlags |= kNavNoTypePopup;
      }
      dialogCreateOptions.optionFlags |= kNavDontAutoTranslate;
      dialogCreateOptions.optionFlags |= kNavDontAddTranslateItems;
      
      // The extension is important
      if (numFilters < 2)
         dialogCreateOptions.optionFlags |= kNavPreserveSaveFileExtension;
      
#if TARGET_API_MAC_OSX
      if (!(m_dialogStyle & wxFD_OVERWRITE_PROMPT))
      {
         dialogCreateOptions.optionFlags |= kNavDontConfirmReplacement;
      }
#endif
      
      err = ::NavCreatePutFileDialog(&dialogCreateOptions,
                                     // Suppresses the 'Default' (top) menu item
                                     kNavGenericSignature, kNavGenericSignature,
                                     sStandardNavEventFilter,
                                     &myData, // for defaultLocation
                                     &dialog);
   }
   else
   {
      
      //let people select bundles/programs in dialogs
      dialogCreateOptions.optionFlags |= kNavSupportPackages;
      
      navFilterUPP = NewNavObjectFilterUPP(CrossPlatformFilterCallback);
      err = ::NavCreateGetFileDialog(&dialogCreateOptions,
                                     NULL, // NavTypeListHandle
                                     sStandardNavEventFilter,
                                     NULL, // NavPreviewUPP
                                     navFilterUPP,
                                     (void *) &myData, // inClientData
                                     &dialog);
   }
   
   if (err == noErr)
      err = ::NavDialogRun(dialog);
   
   if (err == noErr)
   {
      myData.window = NavDialogGetWindow(dialog);
      Rect r;

      // This creates our "fake" dialog with the same dimensions as the sheet so
      // that Options dialogs will center properly on the sheet.  The "fake" dialog
      // is never actually seen.
      GetWindowBounds(myData.window, kWindowStructureRgn, &r);
      wxDialog::Create(NULL,  // no parent...otherwise strange things happen
                       wxID_ANY,
                       wxEmptyString,
                       wxPoint(r.left, r.top),
                       wxSize(r.right - r.left, r.bottom - r.top));
      
      BeginAppModalStateForWindow(myData.window);
      
      while (myData.showing)
      {
         wxTheApp->MacDoOneEvent();
      }
      
      EndAppModalStateForWindow(myData.window);
   }
   
   // clean up filter related data, etc.
   if (navFilterUPP)
      ::DisposeNavObjectFilterUPP(navFilterUPP);
   
   if (err != noErr)
      return wxID_CANCEL;
   
   NavReplyRecord navReply;
   err = ::NavDialogGetReply(dialog, &navReply);
   if (err == noErr && navReply.validRecord)
   {
      AEKeyword   theKeyword;
      DescType    actualType;
      Size        actualSize;
      FSRef       theFSRef;
      wxString thePath ;
      
      m_filterIndex = myData.currentfilter;
      
      long count;
      ::AECountItems(&navReply.selection , &count);
      for (long i = 1; i <= count; ++i)
      {
         err = ::AEGetNthPtr(&(navReply.selection), i, typeFSRef, &theKeyword, &actualType,
                             &theFSRef, sizeof(theFSRef), &actualSize);
         if (err != noErr)
            break;
         
         if (m_dialogStyle & wxFD_SAVE)
            thePath = wxMacFSRefToPath( &theFSRef , navReply.saveFileName ) ;
         else
            thePath = wxMacFSRefToPath( &theFSRef ) ;
         
         if (!thePath)
         {
            ::NavDisposeReply(&navReply);
            return wxID_CANCEL;
         }
         
         m_path = ConvertSlashInFileName(thePath);
         m_paths.Add(m_path);
         m_fileName = wxFileNameFromPath(m_path);
         m_fileNames.Add(m_fileName);
      }
      // set these to the first hit
      m_path = m_paths[0];
      m_fileName = wxFileNameFromPath(m_path);
      m_dir = wxPathOnly(m_path);
   }
   ::NavDisposeReply(&navReply);
   
   return (err == noErr) ? wxID_OK : wxID_CANCEL;
}