adding support for extraControl on osx_carbon

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63970 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor
2010-04-13 20:27:04 +00:00
parent 17e2694c59
commit 61ad44c7a9
3 changed files with 276 additions and 136 deletions

View File

@@ -44,6 +44,8 @@ public:
virtual void ModalFinishedCallback(void* panel, int resultCode); virtual void ModalFinishedCallback(void* panel, int resultCode);
#endif #endif
virtual bool SupportsExtraControl() const;
protected: protected:
// not supported for file dialog, RR // not supported for file dialog, RR
virtual void DoSetSize(int WXUNUSED(x), int WXUNUSED(y), virtual void DoSetSize(int WXUNUSED(x), int WXUNUSED(y),

View File

@@ -40,72 +40,167 @@ IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase)
// and a copy of the "previous" file spec of the reply record // and a copy of the "previous" file spec of the reply record
// so we can see if the selection has changed // so we can see if the selection has changed
struct OpenUserDataRec class OpenUserDataRec
{ {
public:
OpenUserDataRec( wxFileDialog* dialog );
bool FilterCallback( AEDesc *theItem, void *info, NavFilterModes filterMode );
void EventProc( NavEventCallbackMessage inSelector, NavCBRecPtr ioParams );
int GetCurrentFilter() const {return currentfilter;}
CFArrayRef GetMenuItems() const { return menuitems;}
private:
void EventProcCBEvent( NavCBRecPtr ioParams );
void EventProcCBEventMouseDown( NavCBRecPtr ioParams);
void EventProcCBStart( NavCBRecPtr ioParams );
void EventProcCBPopupMenuSelect( NavCBRecPtr ioParams );
void EventProcCBCustomize( NavCBRecPtr ioParams );
void EventProcCBAdjustRect( NavCBRecPtr ioParams );
bool CheckFile( const wxString &filename , OSType type);
void MakeUserDataRec( const wxString& filter);
wxFileDialog* dialog;
int currentfilter ; int currentfilter ;
bool saveMode ; wxString defaultLocation;
wxArrayString name ;
wxArrayString extensions ; wxArrayString extensions ;
wxArrayLong filtermactypes ; wxArrayLong filtermactypes ;
wxString defaultLocation; CFMutableArrayRef menuitems ;
CFArrayRef menuitems ; wxArrayString name ;
bool saveMode ;
}; };
typedef struct OpenUserDataRec OpenUserDataRec::OpenUserDataRec( wxFileDialog* d)
OpenUserDataRec, *OpenUserDataRecPtr;
static pascal void NavEventProc(
NavEventCallbackMessage inSelector,
NavCBRecPtr ioParams,
NavCallBackUserData ioUserData );
static NavEventUPP sStandardNavEventFilter = NewNavEventUPP(NavEventProc);
static pascal void NavEventProc(
NavEventCallbackMessage inSelector,
NavCBRecPtr ioParams,
NavCallBackUserData ioUserData )
{ {
OpenUserDataRec * data = ( OpenUserDataRec *) ioUserData ; dialog = d;
if (inSelector == kNavCBEvent) saveMode = dialog->HasFdFlag(wxFD_SAVE);
defaultLocation = dialog->GetDirectory();
MakeUserDataRec(dialog->GetWildcard());
currentfilter = dialog->GetFilterIndex();
menuitems = NULL;
size_t numFilters = extensions.GetCount();
if (numFilters)
{ {
menuitems = CFArrayCreateMutable( kCFAllocatorDefault ,
numFilters , &kCFTypeArrayCallBacks ) ;
for ( size_t i = 0 ; i < numFilters ; ++i )
{
CFArrayAppendValue( menuitems , (CFStringRef) wxCFStringRef( name[i] ) ) ;
} }
else if ( inSelector == kNavCBStart ) }
}
void OpenUserDataRec::EventProc(NavEventCallbackMessage inSelector,NavCBRecPtr ioParams)
{
switch (inSelector)
{ {
if (data && !(data->defaultLocation).empty()) case kNavCBEvent:
EventProcCBEvent(ioParams);
break;
case kNavCBStart:
EventProcCBStart(ioParams);
break;
case kNavCBPopupMenuSelect:
EventProcCBPopupMenuSelect(ioParams);
break;
case kNavCBCustomize:
EventProcCBCustomize(ioParams);
break;
case kNavCBAdjustRect:
EventProcCBAdjustRect(ioParams);
break;
default:
break;
}
}
void OpenUserDataRec::EventProcCBEvent(NavCBRecPtr callBackParms)
{
switch (callBackParms->eventData.eventDataParms.event->what)
{
case mouseDown:
{
EventProcCBEventMouseDown(callBackParms);
break;
}
}
}
void OpenUserDataRec::EventProcCBEventMouseDown(NavCBRecPtr callBackParms)
{
EventRecord *evt = callBackParms->eventData.eventDataParms.event;
Point where = evt->where;
GlobalToLocal(&where);
ControlRef whichControl = FindControlUnderMouse(where, callBackParms->window, NULL);
if (whichControl != NULL)
{
ControlKind theKind;
GetControlKind(whichControl, &theKind);
// Moving the focus if we clicked in an editable text control
// In this sample, we only have a Clock and an Unicode Edit controls
if ((theKind.kind == kControlKindEditUnicodeText) || (theKind.kind == kControlKindClock))
{
ControlRef currentlyFocusedControl;
GetKeyboardFocus(callBackParms->window, &currentlyFocusedControl);
if (currentlyFocusedControl != whichControl)
SetKeyboardFocus(callBackParms->window, whichControl, kControlFocusNextPart);
}
HandleControlClick(whichControl, where, evt->modifiers, NULL);
}
}
void OpenUserDataRec::EventProcCBStart(NavCBRecPtr ioParams)
{
if (!defaultLocation.empty())
{ {
// Set default location for the modern Navigation APIs // Set default location for the modern Navigation APIs
// Apple Technical Q&A 1151 // Apple Technical Q&A 1151
FSRef theFile; FSRef theFile;
wxMacPathToFSRef(data->defaultLocation, &theFile); wxMacPathToFSRef(defaultLocation, &theFile);
AEDesc theLocation = { typeNull, NULL }; AEDesc theLocation = { typeNull, NULL };
if (noErr == ::AECreateDesc(typeFSRef, &theFile, sizeof(FSRef), &theLocation)) if (noErr == ::AECreateDesc(typeFSRef, &theFile, sizeof(FSRef), &theLocation))
::NavCustomControl(ioParams->context, kNavCtlSetLocation, (void *) &theLocation); ::NavCustomControl(ioParams->context, kNavCtlSetLocation, (void *) &theLocation);
} }
if( data->extensions.GetCount() > 0 ) if( extensions.GetCount() > 0 )
{ {
NavMenuItemSpec menuItem; NavMenuItemSpec menuItem;
memset( &menuItem, 0, sizeof(menuItem) ); memset( &menuItem, 0, sizeof(menuItem) );
menuItem.version = kNavMenuItemSpecVersion; menuItem.version = kNavMenuItemSpecVersion;
menuItem.menuType = data->currentfilter; menuItem.menuType = currentfilter;
::NavCustomControl(ioParams->context, kNavCtlSelectCustomType, &menuItem); ::NavCustomControl(ioParams->context, kNavCtlSelectCustomType, &menuItem);
} }
}
else if ( inSelector == kNavCBPopupMenuSelect ) if (dialog->GetExtraControl())
{ {
ControlRef ref = dialog->GetExtraControl()->GetPeer()->GetControlRef();
NavCustomControl(ioParams->context, kNavCtlAddControl, ref);
}
}
void OpenUserDataRec::EventProcCBPopupMenuSelect(NavCBRecPtr ioParams)
{
NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ; NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ;
const size_t numFilters = data->extensions.GetCount(); const size_t numFilters = extensions.GetCount();
if ( menu->menuType < numFilters ) if ( menu->menuType < numFilters )
{ {
data->currentfilter = menu->menuType ; currentfilter = menu->menuType ;
if ( data->saveMode ) if ( saveMode )
{ {
int i = menu->menuType ; int i = menu->menuType ;
// isolate the first extension string // isolate the first extension string
wxString firstExtension = data->extensions[i].BeforeFirst('|').BeforeFirst(';'); wxString firstExtension = extensions[i].BeforeFirst('|').BeforeFirst(';');
wxString extension = firstExtension.AfterLast('.') ; wxString extension = firstExtension.AfterLast('.') ;
wxString sfilename ; wxString sfilename ;
@@ -122,14 +217,27 @@ static pascal void NavEventProc(
} }
} }
} }
}
void OpenUserDataRec::EventProcCBCustomize(NavCBRecPtr ioParams)
{
if (ioParams->customRect.right == 0 && ioParams->customRect.bottom == 0 && dialog->GetExtraControl())
{
wxSize size = dialog->GetExtraControl()->GetSize();
ioParams->customRect.right = size.x;
ioParams->customRect.bottom = size.y;
} }
} }
void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter ) void OpenUserDataRec::EventProcCBAdjustRect(NavCBRecPtr ioParams)
{ {
myData->menuitems = NULL ; }
myData->currentfilter = 0 ;
myData->saveMode = false ; void OpenUserDataRec::MakeUserDataRec( const wxString& filter )
{
menuitems = NULL ;
currentfilter = 0 ;
saveMode = false ;
if ( !filter.empty() ) if ( !filter.empty() )
{ {
@@ -144,11 +252,11 @@ void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter )
{ {
if ( isName ) if ( isName )
{ {
myData->name.Add( current ) ; name.Add( current ) ;
} }
else else
{ {
myData->extensions.Add( current ) ; extensions.Add( current ) ;
++filterIndex ; ++filterIndex ;
} }
@@ -165,19 +273,19 @@ void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter )
wxASSERT_MSG( filterIndex == 0 || !isName , wxT("incorrect format of format string") ) ; wxASSERT_MSG( filterIndex == 0 || !isName , wxT("incorrect format of format string") ) ;
if ( current.empty() ) if ( current.empty() )
myData->extensions.Add( myData->name[filterIndex] ) ; extensions.Add( name[filterIndex] ) ;
else else
myData->extensions.Add( current ) ; extensions.Add( current ) ;
if ( filterIndex == 0 || isName ) if ( filterIndex == 0 || isName )
myData->name.Add( current ) ; name.Add( current ) ;
++filterIndex ; ++filterIndex ;
const size_t extCount = myData->extensions.GetCount(); const size_t extCount = extensions.GetCount();
for ( size_t i = 0 ; i < extCount; i++ ) for ( size_t i = 0 ; i < extCount; i++ )
{ {
wxUint32 fileType, creator; wxUint32 fileType, creator;
wxString extension = myData->extensions[i]; wxString extension = extensions[i];
// Remove leading '*' // Remove leading '*'
if (extension.length() && (extension.GetChar(0) == '*')) if (extension.length() && (extension.GetChar(0) == '*'))
@@ -188,30 +296,30 @@ void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter )
extension = extension.Mid( 1 ); extension = extension.Mid( 1 );
if (wxFileName::MacFindDefaultTypeAndCreator( extension, &fileType, &creator )) if (wxFileName::MacFindDefaultTypeAndCreator( extension, &fileType, &creator ))
myData->filtermactypes.Add( (OSType)fileType ); filtermactypes.Add( (OSType)fileType );
else else
myData->filtermactypes.Add( '****' ); // We'll fail safe if it's not recognized filtermactypes.Add( '****' ); // We'll fail safe if it's not recognized
} }
} }
} }
static Boolean CheckFile( const wxString &filename , OSType type , OpenUserDataRecPtr data) bool OpenUserDataRec::CheckFile( const wxString &filename , OSType type)
{ {
wxString file(filename) ; wxString file(filename) ;
file.MakeUpper() ; file.MakeUpper() ;
if ( data->extensions.GetCount() > 0 ) if ( extensions.GetCount() > 0 )
{ {
//for ( int i = 0 ; i < data->numfilters ; ++i ) //for ( int i = 0 ; i < data->numfilters ; ++i )
int i = data->currentfilter ; int i = currentfilter ;
if ( data->extensions[i].Right(2) == wxT(".*") ) if ( extensions[i].Right(2) == wxT(".*") )
return true ; return true ;
{ {
if ( type == (OSType)data->filtermactypes[i] ) if ( type == (OSType)filtermactypes[i] )
return true ; return true ;
wxStringTokenizer tokenizer( data->extensions[i] , wxT(";") ) ; wxStringTokenizer tokenizer( extensions[i] , wxT(";") ) ;
while ( tokenizer.HasMoreTokens() ) while ( tokenizer.HasMoreTokens() )
{ {
wxString extension = tokenizer.GetNextToken() ; wxString extension = tokenizer.GetNextToken() ;
@@ -230,25 +338,11 @@ static Boolean CheckFile( const wxString &filename , OSType type , OpenUserDataR
return true ; return true ;
} }
// end wxmac bool OpenUserDataRec::FilterCallback(
wxFileDialog::wxFileDialog(
wxWindow *parent, const wxString& message,
const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
long style, const wxPoint& pos, const wxSize& sz, const wxString& name)
: wxFileDialogBase(parent, message, defaultDir, defaultFileName, wildCard, style, pos, sz, name)
{
wxASSERT_MSG( NavServicesAvailable() , wxT("Navigation Services are not running") ) ;
}
pascal Boolean CrossPlatformFilterCallback(
AEDesc *theItem, AEDesc *theItem,
void *info, void *info,
void *callBackUD,
NavFilterModes filterMode ) NavFilterModes filterMode )
{ {
OpenUserDataRecPtr data = (OpenUserDataRecPtr) callBackUD ;
if (filterMode == kNavFilteringBrowserList) if (filterMode == kNavFilteringBrowserList)
{ {
// We allow navigation to all folders. For files, we check against the current // We allow navigation to all folders. For files, we check against the current
@@ -282,7 +376,7 @@ pascal Boolean CrossPlatformFilterCallback(
if ( AEGetDescData (theItem, &fsref, sizeof (FSRef)) == noErr) if ( AEGetDescData (theItem, &fsref, sizeof (FSRef)) == noErr)
{ {
wxString file = wxMacFSRefToPath( &fsref ) ; wxString file = wxMacFSRefToPath( &fsref ) ;
return CheckFile( file , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ; return CheckFile( file , theInfo->fileAndFolder.fileInfo.finderInfo.fdType ) ;
} }
} }
} }
@@ -290,6 +384,50 @@ pascal Boolean CrossPlatformFilterCallback(
return true; return true;
} }
// end wxmac
pascal Boolean CrossPlatformFilterCallback(
AEDesc *theItem,
void *info,
void *callBackUD,
NavFilterModes filterMode );
pascal Boolean CrossPlatformFilterCallback(
AEDesc *theItem,
void *info,
void *callBackUD,
NavFilterModes filterMode )
{
OpenUserDataRec* data = (OpenUserDataRec*) callBackUD ;
return data->FilterCallback(theItem,info,filterMode);
}
static pascal void NavEventProc(
NavEventCallbackMessage inSelector,
NavCBRecPtr ioParams,
NavCallBackUserData ioUserData );
static NavEventUPP sStandardNavEventFilter = NewNavEventUPP(NavEventProc);
static pascal void NavEventProc(
NavEventCallbackMessage inSelector,
NavCBRecPtr ioParams,
NavCallBackUserData ioUserData )
{
OpenUserDataRec * data = ( OpenUserDataRec *) ioUserData ;
data->EventProc(inSelector, ioParams);
}
wxFileDialog::wxFileDialog(
wxWindow *parent, const wxString& message,
const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
long style, const wxPoint& pos, const wxSize& sz, const wxString& name)
: wxFileDialogBase(parent, message, defaultDir, defaultFileName, wildCard, style, pos, sz, name)
{
wxASSERT_MSG( NavServicesAvailable() , wxT("Navigation Services are not running") ) ;
}
int wxFileDialog::ShowModal() int wxFileDialog::ShowModal()
{ {
m_paths.Empty(); m_paths.Empty();
@@ -310,38 +448,21 @@ int wxFileDialog::ShowModal()
wxCFStringRef defaultFileName(m_fileName, GetFont().GetEncoding()); wxCFStringRef defaultFileName(m_fileName, GetFont().GetEncoding());
dialogCreateOptions.saveFileName = defaultFileName; dialogCreateOptions.saveFileName = defaultFileName;
NavDialogRef dialog; NavDialogRef dialog;
NavObjectFilterUPP navFilterUPP = NULL; NavObjectFilterUPP navFilterUPP = NULL;
OpenUserDataRec myData; OpenUserDataRec myData( this );
myData.defaultLocation = m_dir;
MakeUserDataRec(&myData , m_wildCard); dialogCreateOptions.popupExtension = myData.GetMenuItems();
myData.currentfilter = m_filterIndex;
size_t numFilters = myData.extensions.GetCount();
if (numFilters)
{
CFMutableArrayRef popup = CFArrayCreateMutable( kCFAllocatorDefault ,
numFilters , &kCFTypeArrayCallBacks ) ;
dialogCreateOptions.popupExtension = popup ;
myData.menuitems = dialogCreateOptions.popupExtension ;
for ( size_t i = 0 ; i < numFilters ; ++i )
{
CFArrayAppendValue( popup , (CFStringRef) wxCFStringRef( myData.name[i] , GetFont().GetEncoding() ) ) ;
}
}
if (HasFdFlag(wxFD_SAVE)) if (HasFdFlag(wxFD_SAVE))
{ {
myData.saveMode = true;
dialogCreateOptions.optionFlags |= kNavDontAutoTranslate; dialogCreateOptions.optionFlags |= kNavDontAutoTranslate;
dialogCreateOptions.optionFlags |= kNavDontAddTranslateItems; dialogCreateOptions.optionFlags |= kNavDontAddTranslateItems;
if (!numFilters) if (dialogCreateOptions.popupExtension == NULL)
dialogCreateOptions.optionFlags |= kNavNoTypePopup; dialogCreateOptions.optionFlags |= kNavNoTypePopup;
// The extension is important // The extension is important
if (numFilters < 2) if ( dialogCreateOptions.popupExtension == NULL || CFArrayGetCount(dialogCreateOptions.popupExtension)<2)
dialogCreateOptions.optionFlags |= kNavPreserveSaveFileExtension; dialogCreateOptions.optionFlags |= kNavPreserveSaveFileExtension;
if (!(m_windowStyle & wxFD_OVERWRITE_PROMPT)) if (!(m_windowStyle & wxFD_OVERWRITE_PROMPT))
@@ -371,6 +492,13 @@ int wxFileDialog::ShowModal()
&dialog ); &dialog );
} }
wxNonOwnedWindow::Create( GetParent(), NavDialogGetWindow(dialog) );
if (HasExtraControlCreator())
{
CreateExtraControl();
}
if (err == noErr) if (err == noErr)
err = ::NavDialogRun(dialog); err = ::NavDialogRun(dialog);
@@ -395,7 +523,7 @@ int wxFileDialog::ShowModal()
wxString thePath ; wxString thePath ;
long count; long count;
m_filterIndex = myData.currentfilter; m_filterIndex = myData.GetCurrentFilter();
::AECountItems( &navReply.selection, &count ); ::AECountItems( &navReply.selection, &count );
for (long i = 1; i <= count; ++i) for (long i = 1; i <= count; ++i)
{ {
@@ -435,5 +563,10 @@ int wxFileDialog::ShowModal()
return (err == noErr) ? wxID_OK : wxID_CANCEL; return (err == noErr) ? wxID_OK : wxID_CANCEL;
} }
bool wxFileDialog::SupportsExtraControl() const
{
return true;
}
#endif // wxUSE_FILEDLG #endif // wxUSE_FILEDLG

View File

@@ -52,6 +52,11 @@ wxFileDialog::wxFileDialog(
{ {
} }
bool wxFileDialog::SupportsExtraControl() const
{
return false;
}
NSArray* GetTypesFromFilter( const wxString filter ) NSArray* GetTypesFromFilter( const wxString filter )
{ {
NSMutableArray* types = nil; NSMutableArray* types = nil;