FilterFamily Class Reference

Special version of an import filter. This filter is actually a subset of the installed filters, to allow the user to easily specify a broad category of file rather than the exact file format and application version that they want to import (because they might not actually know!). It understands all the files that all the family of filters understand, by the simple expedient of being a generic interface to all of them. i.e. Given any file, this filter asks all the others how compatible they are with the file. It then chooses the filter that has the highest compatibility rating, and gets it to import the file. More...

#include <filters.h>

Inheritance diagram for FilterFamily:

Filter ListItem CCObject SimpleCCObject BitmapFilterFamily GenericEPSFilter GenericFilter PaletteFilterFamily VectorFilterFamily List of all members.

Public Member Functions

 FilterFamily ()
 Initialise the FilterFamily object. This can import but not export.
 ~FilterFamily ()
 Destructor for FilterFamily object. Does nothing at present.
virtual BOOL IsDefaultDocRequired (const TCHAR *pcszPathName)
 Works out if opening a file of this type requires a default document to be loaded. If the file format supplies the document then return FALSE otherwise return TRUE. An example would be opening a bitmap file. This has no document defined in the file format and so we need to laod the default document before importing the bitmap into this file.
FilterGetBestFilter (CCLexFile *pFile, BOOL ShowWarnings=FALSE)
INT32 HowCompatible (PathName &Filename, ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize)
 Returns 0, to indicate that this filter does not recognise the file. This is because this is not a 'proper' import filter - it's just pretending to be a number of the other filters joined into one.
virtual BOOL DoImport (SelOperation *, CCLexFile *, Document *, BOOL Auto=FALSE, ImportPosition *Pos=NULL, KernelBitmap **ppImportedBitmap=NULL, DocCoord *pPosTranslate=NULL, String_256 *=NULL)
 Loads in the initial 1k of the file, and passes this around all the filters to see which ones understand it. It then chooses the filter that claims the highest 'compatibility', and calls its DoImport() function to load it.
virtual BOOL DoExport (Operation *, CCLexFile *, PathName *, Document *, BOOL)
 Dummy function - this filter does not allow export.
virtual BOOL ImportBitmap (CCLexFile *, KernelBitmap **)
 Loads in the initial 1k of the file, and passes this around all the filters to see which ones understand it. It then chooses the filter that claims the highest 'compatibility', and calls its ImportBitmap() function to load it.
virtual BOOL JoinFamily (CCRuntimeClass *)
 Over-rides this function, because we don't ever want a filter family to join another filter family, as this would be nonsensical.

Public Attributes

FilterpCachedBestFilter
CCRuntimeClasspFilterType

Detailed Description

Special version of an import filter. This filter is actually a subset of the installed filters, to allow the user to easily specify a broad category of file rather than the exact file format and application version that they want to import (because they might not actually know!). It understands all the files that all the family of filters understand, by the simple expedient of being a generic interface to all of them. i.e. Given any file, this filter asks all the others how compatible they are with the file. It then chooses the filter that has the highest compatibility rating, and gets it to import the file.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
It is also used to implement a 'generic' filter, which includes *all* filters, so that the user can just click on a file and not have to specify the actual filter to use unless they really want to. We will also use this generic filter to handle files that are dropped on Camelot's window.

See also:
Filter; Filter::HowCompatible

Definition at line 1010 of file filters.h.


Constructor & Destructor Documentation

FilterFamily::FilterFamily  ) 
 

Initialise the FilterFamily object. This can import but not export.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
See also:
FilterFamily; Filter

Definition at line 4629 of file filters.cpp.

04630 {
04631     // We can import, but not export.
04632     Flags.CanImport = TRUE;
04633     Flags.CanExport = FALSE;
04634     Flags.CanExportMultipleImages = FALSE;
04635     
04636     pCachedBestFilter = NULL;
04637 }

FilterFamily::~FilterFamily  ) 
 

Destructor for FilterFamily object. Does nothing at present.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
See also:
FilterFamily

Definition at line 4650 of file filters.cpp.

04651 {
04652 }


Member Function Documentation

BOOL FilterFamily::DoExport Operation ,
CCLexFile ,
PathName ,
Document ,
BOOL 
[virtual]
 

Dummy function - this filter does not allow export.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Parameters:
As base class version. [INPUTS]
Returns:
Always returns FALSE.

Errors: ENSURE failure when called.

Reimplemented from Filter.

Definition at line 5151 of file filters.cpp.

05152 {
05153     // This filter doesn't export.
05154     ENSURE(FALSE, "FilterFamily::DoExport() called - this should not happen!");
05155     return FALSE;
05156 }

BOOL FilterFamily::DoImport SelOperation pOp,
CCLexFile pFile,
Document pDestDoc,
BOOL  AutoChosen = FALSE,
ImportPosition Pos = NULL,
KernelBitmap **  ppImportedBitmap = NULL,
DocCoord pPosTranslate = NULL,
String_256 URL = NULL
[virtual]
 

Loads in the initial 1k of the file, and passes this around all the filters to see which ones understand it. It then chooses the filter that claims the highest 'compatibility', and calls its DoImport() function to load it.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/03/94
Parameters:
pOp - the live operation associated with this file import process. [INPUTS] pFile - The file to import from pDestDoc - the document to import the file into. Pos - ppImportedBitmap - this is used mainly in the bitfltr.cpp for the HTML import filter. HTMLFilter::DoImport() needs a pointer to a kernel bitmap to set the background bitmap up into Camelot. pPosTranslate - This is used too by the HTMLFilter in order to do a formatting. URL - the URL of the original imported file
Returns:
TRUE if the document was loaded ok, FALSE if not.

Errors: Out of memory, File not recognised.

See also:
Filter; Filter::DoImport; FilterFamily::GetBestFilter;

FilterFamily::IsDefaultDocRequired; Filter::IsDefaultDocRequired;

Reimplemented from Filter.

Definition at line 4991 of file filters.cpp.

04994 {
04995     // Work out the best filter to use on this file.
04996     // (ChrisG 1/2/01) We do want to be warned if this filter isn't perfect
04997     Filter *pBestFilter = GetBestFilter(pFile, TRUE);
04998 
04999     // If the filter is NULL then not found, must have set an error. 
05000     if (pBestFilter == NULL)
05001     {
05002         // Ensure the cached best filter is set to null
05003         pCachedBestFilter = NULL;
05004         return FALSE;
05005     }
05006     
05007     // Result: did we import the file ok?
05008     BOOL Result = FALSE;
05009 
05010     // Use this filter to import the file, and tell the filter that it was chosen
05011     // automatically.
05012     Result = pBestFilter->DoImport(pOp, pFile, pDestDoc, TRUE, Pos, NULL, NULL, URL);
05013 
05014     // Make sure the art file error is more specific
05015     if (!Result && pBestFilter->FilterID == FILTERID_NATIVE_EPS)
05016     {
05017         // Check that it is not our special do nothing message
05018         // or that the error has been reported before and cleared 
05019         if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED) &&
05020             Error::GetErrorNumber() != _R(IDT_IMPORT_USERABORT))
05021         {
05022             Error::ClearError();
05023             Error::SetError(_R(IDS_ERRORINARTFILE));
05024         }
05025     }
05026 
05027     // Ensure the cached best filter is set back to null again
05028     pCachedBestFilter = NULL;
05029 
05030     // Return the result of importing the file.
05031     return Result;
05032 }

Filter * FilterFamily::GetBestFilter CCLexFile pFile,
BOOL  ShowWarnings = FALSE
 

Definition at line 4703 of file filters.cpp.

04704 {
04705     ERROR2IF(pFile == NULL, NULL, "FilterFamily::GetBestFilter NULL CCFile* supplied");
04706     
04707     // Load the first 1k of the file.
04708     UINT32 SegmentSize = FILTER_HDRSIZE;
04709     size_t FileSize;
04710     ADDR FilterBuf = LoadInitialSegment(pFile, &SegmentSize, &FileSize);
04711 
04712     // Error occured when accessing file
04713     if (FilterBuf == NULL)
04714         return NULL;
04715 
04716 #if FALSE
04717     {
04718         DWORD* pDWord = (DWORD*) FilterBuf;
04719         BYTE* pByte = (BYTE*) FilterBuf;
04720 
04721         TRACE( _T("Initial segment\n"));
04722 
04723         for (UINT32 i = 0; i < 16; i++)
04724         {
04725             char c0 = isprint(pByte[0])?pByte[0]:'.';
04726             char c1 = isprint(pByte[1])?pByte[1]:'.';
04727             char c2 = isprint(pByte[2])?pByte[2]:'.';
04728             char c3 = isprint(pByte[3])?pByte[3]:'.';
04729             
04730             TRACE( _T("%04x : %08x  "), (i*4), pDWord[0]);
04731             TRACE( _T("%02x %02x %02x %02x  "), pByte[0], pByte[1], pByte[2], pByte[3]);
04732             TRACE( _T("%c%c%c%c\n"), c0, c1, c2, c3);
04733             pDWord += 1;
04734             pByte += 4;
04735         }
04736     }
04737 #endif
04738 
04739     // Try to create a file-path from the file.  Some files don't have a notion of a
04740     // path, for these ones we will use a blank string.
04741     PathName Path = pFile->GetPathName();
04742 
04743     // Create a list of all the filters that understand this file to one degree or
04744     // another, sorted on how much they like the file.
04745     CompatibleFilterList Filters;
04746 
04747     Filter* pFilter = Filter::GetFirst();
04748     while (pFilter != NULL)
04749     {
04750         // Inform any filters that we are about to do a HowCompatible call.
04751         // This would allow a set of filters which have common functionality hidden in a
04752         // filter that cannot import and cannot export handle this call and hence set
04753         // itself up. This would allow it to maybe cache a result which should only be
04754         // checked by the first filter in the group. 
04755         if (pFilter->JoinFamily(pFilterType) && (!pFilter->GetFlags().CanImport))
04756             /*BOOL ok =*/ pFilter->PreHowCompatible();
04757 
04758         if (pFilter->GetFlags().CanImport && pFilter->JoinFamily(pFilterType))
04759         {
04760             // This is an import filter which belongs to our family - ask it if it 
04761             // understands this file.
04762             INT32 Compatibility = pFilter->HowCompatible(Path, FilterBuf, SegmentSize, 
04763                                                        (UINT32) FileSize);
04764 
04765 //          RELTRACE( _T("Filter %s - Compatibility %d\n"), (LPCTSTR)pFilter->FilterName, (INT32)Compatibility);
04766             if (Compatibility > 0)
04767             {
04768                 // Add this filter to the list
04769                 if (Filters.AddFilter(pFilter, Compatibility) == FALSE)
04770                 {
04771                     // Error has occured - clean up our objects and return error
04772                     CCFree(FilterBuf);
04773                     Filters.DeleteAll();
04774                     return NULL;
04775                 }
04776             }
04777         }
04778 
04779         // Get the next filter.
04780         pFilter = Filter::GetNext(pFilter);
04781     }
04782 
04783     
04784     // added by Ben to avoid the MacPaint filter grabbing everything
04785     CompatibleFilter* pCFilter = (CompatibleFilter *)Filters.GetHead();
04786     
04787     // run through all the filters to see if their extensions match
04788     CompatibleFilter* pBestFilter = NULL;
04789     CompatibleFilter* pSecondBestFilter = NULL;
04790 
04791 /*  BOOL fPathValid = Path.IsValid();
04792     TRACEUSER( "JustinF", _T("File path is %s\n"),
04793         (LPCTSTR) (fPathValid ? Path.GetPath() : "INVALID"));
04794 */
04795 
04796     INT32 bestCompatibility = 0;
04797     while(pCFilter != NULL)
04798     {
04799 PORTNOTE("filter","Removed OILFilter usage")
04800 #ifndef EXCLUDE_FROM_XARALX
04801         // (ChrisG 22/01/01) File extension matching is now done for all of the filters,
04802         //  regardless of their current comaptibility score. If one is found that doesn't
04803         //  have the correct extension, then we subtract one from that filter's score.
04804         //
04805         // This allows dodgy EPS files to have a better chance of getting the right 
04806         //  filter without having to give any indication of what format they're in other than
04807         //  the file extension.
04808         //
04809         //  NOTE: This check is only done if the path is valid.
04810         if (fPathValid && !pCFilter->pFilter->pOILFilter->DoesExtensionOfFileMatch(pFile))
04811         {
04812             pCFilter->Compatibility --;
04813         }
04814 #endif
04815         // If this filter has a higher compatibility than the current best, make this the new
04816         // "best filter" and relegate the other to second best.
04817         if (pCFilter->Compatibility >= bestCompatibility)
04818         {
04819             pSecondBestFilter = pBestFilter;
04820             pBestFilter = pCFilter;
04821             bestCompatibility = pCFilter->Compatibility;
04822         }
04823         // if this isn't the best, but IS better than the previous best, then update SecondBest.
04824         else if (pSecondBestFilter != NULL)
04825         {
04826             if (pCFilter->Compatibility >= pSecondBestFilter->Compatibility)
04827             {
04828                 pSecondBestFilter = pCFilter;
04829             }
04830         }
04831 
04832         pCFilter = (CompatibleFilter*) Filters.GetNext(pCFilter);
04833     }
04834 
04835     // BODGE:
04836     // For now, just choose the filter at the head of the list.
04837     // We should check for the compatibility being less than 10 and provide a scrolly list 
04838     // for the user to choose from if more than one filter is interested.
04839     //
04840     // Improved 16/10/2000 by ChrisG - added a scan for the best possible compatibility, so 
04841     // that the filter's position in the list is not quite as important as it was. Although a 
04842     // dialog with a list box filled with the results and compatibilities would be better.
04843     //
04844     // Note: SecondBestFilter is a bit of an irrelevance now, but may be useful for debugging 
04845     // purposes
04846 
04847     if (pBestFilter == NULL)
04848     {
04849         // If we have a second best filter then choose it
04850         if (pSecondBestFilter != NULL)
04851             pBestFilter = pSecondBestFilter;
04852         else
04853         {
04854             pBestFilter = (CompatibleFilter*) Filters.GetHead();
04855             TRACE( _T("Couldn't find best filter in FilterFamily::GetBestFilter\n"));
04856         }
04857     }
04858 
04859     if (pBestFilter == NULL)
04860     {
04861 #ifdef STANDALONE
04862         // if this is the standalone version, see if it's an EPS file we just tried
04863         if(camStrncmp((char*) FilterBuf, "%!PS-Adobe", 10) == 0)
04864         {
04865             Error::SetError(_R(IDT_NOTTHISEPS));
04866             CCFree(FilterBuf);
04867             Filters.DeleteAll();
04868             return NULL;
04869         }
04870 #endif
04871         // None of the filters liked this file - tell the user
04872         CCFree(FilterBuf);
04873         Filters.DeleteAll();
04874         Error::SetError(_R(IDT_FILE_NOTRECOGNISED));
04875         return NULL;
04876     }
04877 
04878     // (ChrisG 1/2/01) if this filter is not perfectly compatible, tell the user, 
04879     //  if we're showing warnings
04880     if (pBestFilter->Compatibility < 9)
04881     {
04882         if (ShowWarnings)
04883             InformWarning (_R(IDT_IMPORTFILTER_NOTPERFECT));
04884     }
04885 
04886     // Free up the objects that we used
04887     Filter* pBest = pBestFilter->pFilter;
04888     CCFree(FilterBuf);
04889     Filters.DeleteAll();
04890     return pBest;   
04891 }   

INT32 FilterFamily::HowCompatible PathName Filename,
ADDR  HeaderStart,
UINT32  HeaderSize,
UINT32  FileSize
[virtual]
 

Returns 0, to indicate that this filter does not recognise the file. This is because this is not a 'proper' import filter - it's just pretending to be a number of the other filters joined into one.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Parameters:
As base class version. [INPUTS]
Returns:
Always returns 0 => don't understand file.
See also:
FilterFamily; Filter::HowCompatible

Reimplemented from Filter.

Definition at line 4672 of file filters.cpp.

04675 {
04676     return 0;
04677 }

BOOL FilterFamily::ImportBitmap CCLexFile pFile,
KernelBitmap **  ppBitmap
[virtual]
 

Loads in the initial 1k of the file, and passes this around all the filters to see which ones understand it. It then chooses the filter that claims the highest 'compatibility', and calls its ImportBitmap() function to load it.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
8/04/94
Parameters:
pFile - The file to import from [INPUTS]
*ppBitmap is updated to point at the imported bitmap. [OUTPUTS]
Returns:
TRUE if the bitmap was loaded ok, FALSE if not.

Errors: Out of memory, File not recognised.

See also:
Filter; Filter::ImportBitmap

Reimplemented from Filter.

Definition at line 5053 of file filters.cpp.

05054 {
05055     // If it is not a disk file, then bail right out now.
05056 //  if (!pFile->IS_KIND_OF(CCDiskFile)) return FALSE;
05057 
05058     // Find out the pathname of the file in question
05059     PathName Path = pFile->GetPathName();
05060 
05061     // Load the first 1k of the file.
05062     UINT32 SegmentSize = FILTER_HDRSIZE;
05063     size_t FileSize;
05064     ADDR FilterBuf = LoadInitialSegment(pFile, &SegmentSize, &FileSize);
05065     if (FilterBuf == NULL)
05066         // Error occured when accessing file
05067         return FALSE;
05068 
05069     // Create a list of all the filters that understand this file to one degree or
05070     // another, sorted on how much they like the file.
05071     CompatibleFilterList Filters;
05072 
05073     Filter* pFilter = Filter::GetFirst();
05074     while (pFilter != NULL)
05075     {
05076         // Inform any filters that we are about to do a HowCompatible call.
05077         // This would allow a set of filters which have common functionality hidden in a
05078         // filter that cannot import and cannot export handle this call and hence set
05079         // itself up. This would allow it to maybe cache a result which should only be
05080         // checked by the first filter in the group. 
05081         if (pFilter->JoinFamily(pFilterType) && (!pFilter->GetFlags().CanImport))
05082             /*BOOL ok =*/ pFilter->PreHowCompatible();
05083 
05084         if (pFilter->GetFlags().CanImport && pFilter->JoinFamily(pFilterType))
05085         {
05086             // This is an import filter which belongs to our family - ask it if it 
05087             // understands this file.
05088             INT32 Compatibility = pFilter->HowCompatible(Path, FilterBuf, SegmentSize, 
05089                                                        (UINT32) FileSize);
05090 
05091             if (Compatibility > 0)
05092             {
05093                 // Add this filter to the list
05094                 if (Filters.AddFilter(pFilter, Compatibility) == FALSE)
05095                 {
05096                     // Error has occured - clean up our objects and return error
05097                     CCFree(FilterBuf);
05098                     Filters.DeleteAll();
05099                     return FALSE;
05100                 }
05101             }
05102         }
05103 
05104         // Get the next filter.
05105         pFilter = Filter::GetNext(pFilter);
05106     }
05107 
05108     // BODGE:
05109     // For now, just choose the filter at the head of the list.
05110     // We should check for the compatibility being less than 10 and provide a scrolly list 
05111     // for the user to choose from if more than one filter is interested.
05112     CompatibleFilter* pBestFilter = (CompatibleFilter*) Filters.GetHead();
05113 
05114     // Result: did we import the file ok?
05115     BOOL Result;
05116 
05117     if (pBestFilter == NULL)
05118     {
05119         // None of the filters liked this file - tell the user
05120         Result = FALSE;
05121         Error::SetError(_R(IDT_FILE_NOTRECOGNISED));
05122     }
05123     else
05124     {
05125         // Use this filter to import the file, and tell the filter that it was chosen
05126         // automatically.
05127         Result = pBestFilter->pFilter->ImportBitmap(pFile, ppBitmap);
05128     }
05129 
05130     // Clean up
05131     CCFree(FilterBuf);
05132     Filters.DeleteAll();
05133 
05134     // Return the result of importing the file.
05135     return Result;
05136 }

BOOL FilterFamily::IsDefaultDocRequired const TCHAR pcszPathName  )  [virtual]
 

Works out if opening a file of this type requires a default document to be loaded. If the file format supplies the document then return FALSE otherwise return TRUE. An example would be opening a bitmap file. This has no document defined in the file format and so we need to laod the default document before importing the bitmap into this file.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/10/95
Parameters:
pcszPathName pointer to the pathname to check [INPUTS]
Returns:
TRUE if the filter requires a default document, FALSE if not.
See also:
Filter; Filter::IsDefaultDocRequired; CCamDoc::OnOpenDocument;

FilterFamily::DoImport; Filter::DoImport; FilterFamily::GetBestFilter

Reimplemented from Filter.

Definition at line 4913 of file filters.cpp.

04914 {
04915     // If the pathname passed in is NULL then there is nothing we can do so say no
04916     // default document is required.
04917     if (pcszPathName == NULL) return FALSE;
04918 
04919     // Ensure the cached best filter is set to null
04920     pCachedBestFilter = NULL;
04921 
04922     // Work out the best filter to use on this file.
04923     Filter* pBestFilter = NULL;
04924 
04925     // First off, we have to try and open the file
04926     CCDiskFile file(1024, FALSE, TRUE);
04927 
04928     // Build a string out of the path name
04929     String_256 FileName(pcszPathName);
04930 
04931     // get it into the proper PathName class
04932     PathName Path(FileName);
04933 
04934     // If we cannot open the file then return false
04935     if (!file.open(Path, ios::in | ios::binary)) return FALSE;      
04936 
04937     // Find the best file for this to use
04938     pBestFilter = GetBestFilter(&file);
04939     
04940     // On this pass, no errors are allowed, at present.
04941     Error::ClearError();
04942 
04943     // Close the file again
04944     if (file.isOpen()) file.close();
04945     
04946     // If the filter is NULL then not found, must have set an error. 
04947     if (pBestFilter == NULL) return FALSE;
04948 
04949     // Result: do we require the default document?
04950     BOOL Result;
04951 
04952     // Ask the best filter to see if we need to load a default document for it to use.
04953     // At this point the pathname is irrelevent.
04954     Result = pBestFilter->IsDefaultDocRequired(pcszPathName);
04955 
04956     // Make a note of the filter that we decided on as the best filter.
04957     pCachedBestFilter = pBestFilter;
04958 
04959     return Result;
04960 }   

BOOL FilterFamily::JoinFamily CCRuntimeClass  )  [virtual]
 

Over-rides this function, because we don't ever want a filter family to join another filter family, as this would be nonsensical.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/07/94
See also:
FilterFamily

Reimplemented from Filter.

Definition at line 5171 of file filters.cpp.

05172 {
05173     return FALSE;
05174 }


Member Data Documentation

Filter* FilterFamily::pCachedBestFilter
 

Definition at line 1034 of file filters.h.

CCRuntimeClass* FilterFamily::pFilterType
 

Definition at line 1035 of file filters.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:54:18 2007 for Camelot by  doxygen 1.4.4