Use an additional layer of filtering based on file type if we fail on the IC check. This catches things that aren't mapped by IC but we still might want to open. Also fix up the event proc to process update events for windows in the bg. r=sfraser, bugs 50312, 51830

This commit is contained in:
pinkerton%netscape.com 2000-09-08 22:27:37 +00:00
parent 75c8ca9c3d
commit ea957680de
2 changed files with 59 additions and 15 deletions

View File

@ -37,6 +37,8 @@
#include "nsCarbonHelpers.h"
#include "nsFilePicker.h"
#include "nsMacWindow.h"
#include "nsMacMessageSink.h"
@ -160,25 +162,26 @@ NS_IMETHODIMP nsFilePicker::Show(PRInt16 *retval)
return NS_OK;
}
//-------------------------------------------------------------------------
//
// FileDialogEventHandlerProc
//
// An event filter proc for NavServices so the dialogs will be movable-modals. However,
// this doesn't seem to work as of yet...I'll play around with it some more.
// An event filter proc for NavServices so the dialogs will be movable-modals.
//
//-------------------------------------------------------------------------
static pascal void FileDialogEventHandlerProc( NavEventCallbackMessage msg, NavCBRecPtr cbRec, NavCallBackUserData data )
{
switch ( msg ) {
case kNavCBEvent:
switch ( cbRec->eventData.eventDataParms.event->what ) {
case updateEvt:
WindowPtr window = reinterpret_cast<WindowPtr>(cbRec->eventData.eventDataParms.event->message);
if (window) {
::BeginUpdate(window);
::EndUpdate(window);
}
WindowPtr window = reinterpret_cast<WindowPtr>(cbRec->eventData.eventDataParms.event->message);
nsMacWindow* macWindow = nsMacMessageSink::GetNSWindowFromMacWindow(window);
::BeginUpdate(window);
if (macWindow) {
EventRecord theEvent = *cbRec->eventData.eventDataParms.event;
macWindow->HandleOSEvent(theEvent);
}
::EndUpdate(window);
break;
}
break;
@ -192,8 +195,9 @@ static pascal void FileDialogEventHandlerProc( NavEventCallbackMessage msg, NavC
// Check our |mTypeLists| list to see if the given type is in there.
//
Boolean
nsFilePicker :: IsFileInFilterList ( ResType inType )
nsFilePicker :: IsTypeInFilterList ( ResType inType )
{
return false;
for ( int i = 0; i < mFilters.Count(); ++i ) {
for ( int j = 0; j < mTypeLists[i]->osTypeCount; ++j ) {
if ( mTypeLists[i]->osType[j] == inType )
@ -206,6 +210,30 @@ nsFilePicker :: IsFileInFilterList ( ResType inType )
} // IsFileInFilterList
Boolean
nsFilePicker :: IsExtensionInFilterList ( StrFileName & inFileName )
{
char extension[256];
// determine the extension from the file name
unsigned char* curr = &inFileName[inFileName[0]];
while ( curr != inFileName && *curr-- != '.' ) ;
if ( curr == inFileName ) // no '.' in string, fails this check
return false;
++curr; // we took one too many steps back
short extensionLen = (inFileName + inFileName[0]) - curr + 1;
strncpy ( extension, (char*)curr, extensionLen);
extension[extensionLen] = '\0';
// see if it is in our list
for ( int i = 0; i < mFlatFilters.Count(); ++i ) {
if ( *mFlatFilters[i] == extension )
return true;
}
return false;
}
//
// FileDialogFilterProc
//
@ -223,9 +251,13 @@ nsFilePicker :: FileDialogFilterProc ( AEDesc* theItem, void* theInfo,
if ( theItem->descriptorType == typeFSS ) {
NavFileOrFolderInfo* info = NS_REINTERPRET_CAST ( NavFileOrFolderInfo*, theInfo );
if ( !info->isFolder ) {
// check it against our list
if ( ! self->IsFileInFilterList(info->fileAndFolder.fileInfo.finderInfo.fdType) )
shouldDisplay = false;
// check it against our list. If that fails, check the extension directly
if ( ! self->IsTypeInFilterList(info->fileAndFolder.fileInfo.finderInfo.fdType) ) {
FSSpec fileSpec;
if ( ::AEGetDescData(theItem, &fileSpec, sizeof(FSSpec)) == noErr )
if ( ! self->IsExtensionInFilterList(fileSpec.name) )
shouldDisplay = false;
}
} // if file isn't a folder
} // if the item is an FSSpec
}
@ -235,6 +267,8 @@ nsFilePicker :: FileDialogFilterProc ( AEDesc* theItem, void* theInfo,
} // FileDialogFilterProc
//-------------------------------------------------------------------------
//
// GetFile
@ -512,6 +546,12 @@ nsFilePicker :: MapFilterToFileTypes ( )
typeTemp[typeTempIndex] = 0; // turn it into a pString
typeTemp[0] = typeTempIndex - 1;
// to make it easier to match file extensions while we're filtering, flatten
// out the list. Ignore filters that are just "*" and also remove the
// leading "*" from filters we do add.
if ( typeTemp[0] > 1 )
mFlatFilters.AppendCString ( nsCString((char*)&typeTemp[2]) ); // cut out the "*"
// ask IC if it's not "all files" (designated by "*")
if ( !(typeTemp[0] == 1 && typeTemp[1] == '*') ) {
mAllFilesDisplayed = PR_FALSE;
@ -541,7 +581,9 @@ nsFilePicker :: MapFilterToFileTypes ( )
}
else
{
typeTemp[typeTempIndex++] = tempChar;
// strip out whitespace as we goe
if ( tempChar != ' ' )
typeTemp[typeTempIndex++] = tempChar;
}
filterIndex++;

View File

@ -66,7 +66,8 @@ protected:
PRInt16 GetLocalFolder(Str255 & inTitle, FSSpec* outFileSpec);
void MapFilterToFileTypes ( ) ;
Boolean IsFileInFilterList ( ResType inType ) ;
Boolean IsTypeInFilterList ( ResType inType ) ;
Boolean IsExtensionInFilterList ( StrFileName & inFileName ) ;
// filter routine for file types
static pascal Boolean FileDialogFilterProc ( AEDesc* theItem, void* info,
@ -83,6 +84,7 @@ protected:
nsStringArray mFilters;
nsStringArray mTitles;
nsCStringArray mFlatFilters; // all the filters from mFilters, but one per string
NavTypeListPtr mTypeLists[kMaxTypeListCount];