xpoilflt.cpp

Go to the documentation of this file.
00001 // $Id: xpoilflt.cpp 1708 2006-08-17 17:13:38Z gerry $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 // The module that controls the OIL side of import/export filters.
00100 
00101 
00102 #include "camtypes.h"
00103 
00104 #include "xpoilflt.h"
00105 
00106 #include "xpfilter.h"
00107 //#include "xpfres.h"
00108 //#include "mario.h"
00109 
00110 #include "strlist.h"
00111 #include "fileutil.h"
00112 #include "sgliboil.h"
00113 
00114 #include "ncntrcnt.h"
00115 //#include "nev.h"      // For _R(IDN_USER_CANCELLED)
00116 #include "xmlutils.h"
00117 #include "fillattr2.h"
00118 
00119 #include "camprocess.h"
00120 
00121 CC_IMPLEMENT_MEMDUMP(PluginOILFilter, OILFilter)
00122 CC_IMPLEMENT_DYNAMIC(PathNameListItem, ListItem)
00123 
00124 // This will get Camelot to display the filename and linenumber of any memory allocations
00125 // that are not released at program exit
00126 #define new CAM_DEBUG_NEW
00127 
00128 PropMapEntry aShadowTypes[] = { {_T("wall"), XPFP_SHADOWTYPE_WALL},
00129                                 {_T("floor"), XPFP_SHADOWTYPE_FLOOR},
00130                                 {_T("glow"), XPFP_SHADOWTYPE_GLOW},
00131                                 {_T("feather"), XPFP_SHADOWTYPE_FEATHER},
00132                                 {NULL, XPFP_UNKNOWN}};
00133 
00134 PropMapEntry aBevelTypes[] = { {_T("flat"), XPFP_BEVELTYPE_FLAT},
00135                                 {_T("round"), XPFP_BEVELTYPE_ROUND},
00136                                 {_T("halfround"), XPFP_BEVELTYPE_HALFROUND},
00137                                 {_T("frame"), XPFP_BEVELTYPE_FRAME},
00138                                 {_T("mesa1"), XPFP_BEVELTYPE_MESA_1},
00139                                 {_T("mesa2"), XPFP_BEVELTYPE_MESA_2},
00140                                 {_T("smooth1"), XPFP_BEVELTYPE_SMOOTH_1},
00141                                 {_T("smooth2"), XPFP_BEVELTYPE_SMOOTH_2},
00142                                 {_T("point1"), XPFP_BEVELTYPE_POINT_1},
00143                                 {_T("point2a"), XPFP_BEVELTYPE_POINT_2a},
00144                                 {_T("point2b"), XPFP_BEVELTYPE_POINT_2b},
00145                                 {_T("ruffle2a"), XPFP_BEVELTYPE_RUFFLE_2a},
00146                                 {_T("ruffle2b"), XPFP_BEVELTYPE_RUFFLE_2b},
00147                                 {_T("ruffle3a"), XPFP_BEVELTYPE_RUFFLE_3a},
00148                                 {_T("ruffle3b"), XPFP_BEVELTYPE_RUFFLE_3b},
00149                                 {NULL, XPFP_UNKNOWN}};
00150 
00151 PropMapEntry aBevelSides[] = { {_T("inner"), XPFP_BEVELSIDE_INNER},
00152                                 {_T("outer"), XPFP_BEVELSIDE_OUTER},
00153                                 {NULL, XPFP_UNKNOWN}};
00154 
00155 PropMapEntry aColourEffects[] = { {_T("fade"), XPFP_COLOUREFFECT_FADE},
00156                                 {_T("rainbow"), XPFP_COLOUREFFECT_RAINBOW},
00157                                 {_T("altrainbow"), XPFP_COLOUREFFECT_ALTRAINBOW},
00158                                 {NULL, XPFP_UNKNOWN}};
00159 
00160 PropMapEntry aMouldTypes[] = { {_T("envelope"), XPFP_MOULDTYPE_ENVELOPE},
00161                                 {_T("perspective"), XPFP_MOULDTYPE_PERSPECTIVE},
00162                                 {NULL, XPFP_UNKNOWN}};
00163 
00164 PropMapEntry aLineCaps[] = { {_T("butt"), XPFP_LINECAP_BUTT},
00165                                 {_T("round"), XPFP_LINECAP_ROUND},
00166                                 {_T("square"), XPFP_LINECAP_SQUARE},
00167                                 {NULL, XPFP_UNKNOWN}};
00168 
00169 PropMapEntry aLineJoins[] = { {_T("mitre"), XPFP_LINEJOIN_MITRE},
00170                                 {_T("round"), XPFP_LINEJOIN_ROUND},
00171                                 {_T("bevel"), XPFP_LINEJOIN_BEVEL},
00172                                 {NULL, XPFP_UNKNOWN}};
00173 
00174 PropMapEntry aFillShapes[] = { {_T("flat"), FILLSHAPE_FLAT},
00175                                 {_T("linear"), FILLSHAPE_LINEAR},
00176                                 {_T("circular"), FILLSHAPE_CIRCULAR},
00177                                 {_T("elliptical"), FILLSHAPE_ELLIPTICAL},
00178                                 {_T("conical"), FILLSHAPE_CONICAL},
00179                                 {_T("diamond"), FILLSHAPE_DIAMOND},
00180                                 {_T("3point"), FILLSHAPE_3POINT},
00181                                 {_T("4point"), FILLSHAPE_4POINT},
00182                                 {_T("bitmap"), FILLSHAPE_BITMAP},
00183                                 {_T("clouds"), FILLSHAPE_CLOUDS},
00184                                 {_T("plasma"), FILLSHAPE_PLASMA},
00185                                 {NULL, XPFP_UNKNOWN}};
00186 
00187 PropMapEntry aFillRepeats[] = { {_T("simple"), XPFP_FILLREPEAT_SIMPLE},
00188                                 {_T("repeat"), XPFP_FILLREPEAT_REPEAT},
00189                                 {_T("repeatinv"), XPFP_FILLREPEAT_REPEATINV},
00190                                 {_T("repeatex"), XPFP_FILLREPEAT_REPEATEXTRA},
00191                                 {NULL, XPFP_UNKNOWN}};
00192 
00193 PropMapEntry aTransTypes[] = { {_T("none"), TT_NoTranspType},
00194                                 {_T("mix"), TT_Mix},
00195                                 {_T("stained"), TT_StainGlass},
00196                                 {_T("bleach"), TT_Bleach},
00197                                 {_T("contrast"), TT_CONTRAST},
00198                                 {_T("saturation"), TT_SATURATION},
00199                                 {_T("darken"), TT_DARKEN},
00200                                 {_T("lighten"), TT_LIGHTEN},
00201                                 {_T("brightness"), TT_BRIGHTNESS},
00202                                 {_T("luminosity"), TT_LUMINOSITY},
00203                                 {_T("hue"), TT_HUE},
00204                                 {_T("bevel"), TT_BEVEL},
00205                                 {NULL, XPFP_UNKNOWN}};
00206 
00207 PropMapEntry aContentOnly[] = { {_T("text"), XPFP_CONTENTONLY_TEXT},
00208                                 {_T("plaintext"), XPFP_CONTENTONLY_PLAINTEXT},
00209                                 {NULL, XPFP_UNKNOWN}};
00210 
00211 
00212 /********************************************************************************************
00213 
00214 >   PluginOILFilter::PluginOILFilter()
00215 
00216     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
00217     Created:    26/01/05
00218     Purpose:    Sets up the list of filename extensions that this filter understands
00219                 and handles connection to external plugin object
00220 
00221 ********************************************************************************************/
00222 
00223 PluginOILFilter::PluginOILFilter(Filter *pFilter) : OILFilter(pFilter)
00224 {
00225     m_bImport = FALSE;
00226     m_bExport = FALSE;
00227 }
00228 
00229 
00230 
00231 
00232 /****************************************************************************
00233 
00234 >   BOOL PluginOILFilter::Init(const CLSID& rCLSID)
00235 
00236     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
00237     Created:    16/02/2005
00238 
00239     Inputs:     rCLSID      - 
00240     Returns:    TRUE if ok, FALSE if we find a problem and shouldn't use it
00241     Purpose:    Initialises the OIL specific parts of this filter (file 
00242                 extension, file type name, link to COM object etc).
00243 
00244 ****************************************************************************/
00245 
00246 BOOL PluginOILFilter::Init( xmlNode* pFilterNode )
00247 {
00248     // This would look a lot neater using functions from xmlutils.h
00249 
00250     m_InternalName = CXMLUtils::ConvertToWXString(xmlGetProp(pFilterNode, (xmlChar*)"name"));
00251 
00252     xmlNodePtr pChild = pFilterNode->children;
00253     // We will loop round until we run out of child elements
00254     // If an element has already been parsed then an error should be indicated
00255 
00256     while (pChild)
00257     {
00258         wxString strChildName = CXMLUtils::ConvertToWXString(pChild->name);
00259         
00260         if (strChildName == _T("#text") || xmlNodeIsText(pChild))
00261         {
00262             // ignore it
00263         }
00264         else if (strChildName == _T("DisplayName"))
00265         {
00266             xmlChar* pStr = xmlNodeListGetString(pChild->doc, pChild->xmlChildrenNode, 1);
00267             wxString sTemp = CXMLUtils::ConvertToWXString(pStr);
00268             FilterName = sTemp;
00269             xmlFree(pStr);
00270         }
00271         else if (strChildName == _T("Extensions"))
00272         {
00273             xmlChar* pStr = xmlNodeListGetString(pChild->doc, pChild->xmlChildrenNode, 1);
00274             wxString sTemp = CXMLUtils::ConvertToWXString(pStr);
00275             FilterExt = sTemp;
00276             xmlFree(pStr);
00277         }
00278         else if (strChildName == _T("CanImport"))
00279         {
00280             xmlChar* pStr = xmlNodeListGetString(pChild->doc, pChild->xmlChildrenNode, 1);
00281             m_CanImport = CXMLUtils::ConvertToWXString(pStr);
00282             xmlFree(pStr);
00283         }
00284         else if (strChildName == _T("DoImport"))
00285         {
00286             xmlChar* pStr = xmlNodeListGetString(pChild->doc, pChild->xmlChildrenNode, 1);
00287             m_DoImport = CXMLUtils::ConvertToWXString(pStr);
00288             xmlFree(pStr);
00289         }
00290         else if (strChildName == _T("PrepareExport"))
00291         {
00292             xmlChar* pStr = xmlNodeListGetString(pChild->doc, pChild->xmlChildrenNode, 1);
00293             m_PrepareExport = CXMLUtils::ConvertToWXString(pStr);
00294             xmlFree(pStr);
00295         }
00296         else if (strChildName == _T("DoExport"))
00297         {
00298             xmlChar* pStr = xmlNodeListGetString(pChild->doc, pChild->xmlChildrenNode, 1);
00299             m_DoExport = CXMLUtils::ConvertToWXString(pStr);
00300             xmlFree(pStr);
00301         }
00302         else
00303         {
00304             TRACEUSER("Gerry", _T("Ignoring '%s' element"), strChildName.c_str());
00305 //          ERROR1(FALSE, _R(IDE_XPF_BADXML));
00306         }
00307 
00308         pChild = pChild->next;
00309     }
00310 
00311     // This should be set to some sensible path but I've hardcoded it for now
00312     // We should change to making ~/.XaraLX into a directory and store the main config
00313     // file and these filter config files in there
00314     m_XMLFile.AssignHomeDir();
00315     m_XMLFile.AppendDir(_T(".XaraLXFilters"));
00316     m_XMLFile.Mkdir(0777, wxPATH_MKDIR_FULL);
00317 
00318     m_XMLFile.SetName(m_InternalName);
00319     m_XMLFile.SetExt(_T("xml"));
00320 
00321     m_bImport = !(m_DoImport.IsEmpty());
00322     m_bExport = !(m_DoExport.IsEmpty());
00323 
00324     return(m_bImport || m_bExport);     // If it doesn't do either then it isn't a filter
00325 }
00326 
00327 
00328 
00329 /****************************************************************************
00330 
00331 >   INT32 PluginOILFilter::HowCompatible(PathName& Filename)
00332 
00333     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
00334     Created:    16/02/2005
00335 
00336     Inputs:     Filename    - The file to test compatability of
00337     Returns:    An integer from 0 to 10, 0 meaning not interested and 10 
00338                 meaning it is definitely my format
00339     Purpose:    This function is called to determine if this plugin object 
00340                 can accept the specified file.
00341 
00342 ****************************************************************************/
00343 
00344 INT32 PluginOILFilter::HowCompatible(PathName& FileName)
00345 {
00346     INT32 HowCompatible = 0;
00347 
00348     // Here we need to run the plugin synchronously with the following options
00349     // -c -f <filename>
00350 
00351     // Check stderr for errors
00352     // Get HowCompatible from stdout
00353     if (!m_CanImport.IsEmpty())
00354     {
00355         wxString sCommand(m_CanImport);
00356         sCommand.Replace(_T("%IN%"), (LPCTSTR)FileName.GetPath());
00357 
00358         TRACEUSER("Gerry", _T("Running '%s'"), sCommand.c_str());
00359 
00360         wxArrayString saOutput;
00361         wxArrayString saErrors;
00362         INT32 code = wxExecute(sCommand, saOutput, saErrors, wxEXEC_NODISABLE);
00363         TRACEUSER("Gerry", _T("wxExecute returned %d"), code);
00364         if (code == 0)
00365         {
00366             // Extract the value from saOutput
00367             if (saOutput.Count() > 0)
00368             {
00369                 INT32 Val = wxAtoi(saOutput[0]);
00370                 TRACEUSER("Gerry", _T("Command '%s' returned string '%s'"), sCommand.c_str(), saOutput[0].c_str());
00371                 TRACEUSER("Gerry", _T("Value = %d"), Val);
00372                 if (Val >= 0 && Val <= 10)
00373                 {
00374                     HowCompatible = Val;
00375                 }
00376             }
00377             else
00378             {
00379                 TRACEUSER("Gerry", _T("Command '%s' returned no output value"), sCommand.c_str());
00380             }
00381         }
00382         else
00383         {
00384             TRACEUSER("Gerry", _T("Command '%s' exited with code %d"), sCommand.c_str(), code);
00385         }
00386     }
00387 
00388     return(HowCompatible);
00389 }
00390 
00391 
00392 
00393 
00394 /****************************************************************************
00395 
00396 >   BOOL PluginOILFilter::GetImportFile(CCLexFile* pFile, CCLexFile** ppNewFile)
00397 
00398     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
00399     Created:    16/02/2005
00400 
00401     Inputs:     pFile       - pointer to a CCLexFile
00402                 ppNewFile   - pointer to a pointer to a CCLexFile
00403     Returns:    TRUE if ok, FALSE if bother
00404     Purpose:    
00405 
00406 ****************************************************************************/
00407 
00408 BOOL PluginOILFilter::GetImportFile(CCLexFile* pFile, CCLexFile** ppNewFile)
00409 {
00410     ERROR2IF(pFile == NULL, FALSE,"PluginOILFilter::GetImportFile no file to import from");
00411     ERROR2IF(ppNewFile == NULL, FALSE,"PluginOILFilter::GetImportFile no newfile pointer");
00412 
00413     *ppNewFile = NULL;
00414 
00415     // Here we should really run the plugin asynchronously with the following options
00416     // -i -g -f <filename>
00417 
00418     // Redirect stdout to a CCLexFile
00419     // Check stderr during the Xar import and abort if an error is reported
00420 
00421     m_TempXarFile.SetPathName(_T("/tmp/xpftemp.xar"));
00422 
00423     CCDiskFile TempFile;
00424     if (!TempFile.open(m_TempXarFile, ios::out | ios::trunc | ios::binary))
00425     {
00426         // report an error here
00427         return FALSE;
00428     }
00429 
00430     PathName FileName = pFile->GetPathName();
00431 
00432     wxString sCommand(m_DoImport);
00433     sCommand.Replace(_T("%IN%"), (LPCTSTR)FileName.GetPath());
00434 
00435     TRACEUSER("Gerry", _T("Running '%s'"), sCommand.c_str());
00436 
00437     // Create a process with the TempFile as the stdout
00438     PluginFilterProcess* pTheProc = new PluginFilterProcess((PluginNativeFilter*)Parent, NULL, &TempFile);
00439 
00440     INT32 code = pTheProc->Execute(sCommand);
00441     TempFile.close();
00442     if (code != 0)
00443     {
00444         TRACEUSER("Gerry", _T("Execution of '%s' failed."), sCommand.c_str());
00445         // Extract error from a derived CamProcess class and report it
00446         pTheProc->ReportError();
00447         delete pTheProc;
00448         return(FALSE);
00449     }
00450 
00451     pTheProc->ReportWarning();
00452     delete pTheProc;
00453     pTheProc = NULL;
00454 
00455     CCDiskFile* pTempFile = new CCDiskFile();
00456     if (pTempFile)
00457     {
00458         if (pTempFile->open(m_TempXarFile, ios::in | ios::binary))
00459         {
00460             *ppNewFile = pTempFile;
00461             return(TRUE);
00462         }
00463 
00464         delete pTempFile;
00465     }
00466 
00467     return(FALSE);
00468 }
00469 
00470 
00471 
00472 /****************************************************************************
00473 
00474 >   BOOL PluginOILFilter::GetExportFile(CCLexFile** ppNewFile)
00475 
00476     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
00477     Created:    18/02/2005
00478 
00479     Inputs:     ppNewFile   - pointer to a pointer to a CCLexFile
00480     Returns:    TRUE if ok, FALSE if bother
00481     Purpose:    
00482 
00483 ****************************************************************************/
00484 
00485 BOOL PluginOILFilter::GetExportFile(PathName* pPath, CCLexFile** ppNewFile)
00486 {
00487     ERROR2IF(ppNewFile == NULL, FALSE,"PluginOILFilter::GetExportFile no newfile pointer");
00488 
00489     *ppNewFile = NULL;
00490 
00491     // Here we should run the plugin asynchronously with the following options
00492     // -e -g -f <filename> -x <xmlfilename>
00493 
00494     // The xmlfilename is a path to a user and filter specific file
00495     // e.g. ~/.XaraLX/filtername.xml
00496     // Create a CCLexFile derived object that sends its data to stdin
00497     // Check stderr during the Xar export and abort if an error is reported
00498 
00499     // However, this will not be trivial so intsead we will just create a 
00500     // CCDiskFile attached to a temporary filename and run the export process
00501     // in DoExport instead
00502 
00503     // Generate a temporary file name
00504     m_TempXarFile.SetPathName(_T("/tmp/xpftemp.xar"));
00505 
00506     CCDiskFile* pFile = new CCDiskFile();
00507     if (pFile)
00508     {
00509         if (pFile->open(m_TempXarFile, ios::out | ios::binary | ios::trunc))
00510         {
00511             *ppNewFile = pFile;
00512             return(TRUE);
00513         }
00514 
00515         delete pFile;
00516     }
00517 
00518     return(FALSE);
00519 }
00520 
00521 
00522 
00523 /****************************************************************************
00524 
00525 >   BOOL PluginOILFilter::GetCapabilities(CCLexFile* pFile, CapabilityTree* pCapTree)
00526 
00527     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
00528     Created:    18/02/2005
00529 
00530     Inputs:     pPlugCaps   - pointer to a PluginCapabilities
00531     Returns:    TRUE if ok, FALSE if bother
00532     Purpose:    
00533 
00534 ****************************************************************************/
00535 
00536 BOOL PluginOILFilter::GetCapabilities(CCLexFile* pFile, PathName* pPath, CapabilityTree* pCapTree)
00537 {
00538     // Here we need to run the plugin synchronously with the following options
00539     // -p -f <filename> -x <xmlfilename>
00540 
00541     // The xmlfilename is a path to a user and filter specific file
00542     // e.g. ~/.XaraLX/filtername.xml
00543 
00544     // The XML is returned via the file
00545 
00546     // Does this need double quotes to cope with spaces in filenames?
00547     wxString sCommand(m_PrepareExport);
00548     sCommand.Replace(_T("%OUT%"), (LPCTSTR)pPath->GetPath());
00549     sCommand.Replace(_T("%XML%"), m_XMLFile.GetFullPath());
00550 
00551     TRACEUSER("Gerry", _T("Running '%s'"), sCommand.c_str());
00552 
00553     wxArrayString saOutput;
00554     wxArrayString saErrors;
00555     INT32 code = wxExecute(sCommand, saOutput, saErrors, wxEXEC_NODISABLE);
00556 
00557 #ifdef _DEBUG
00558     for (UINT32 i = 0; i < saErrors.GetCount(); i++)
00559     {
00560         TRACEUSER("Gerry", _T("stderr: %s"), saErrors[i].c_str());
00561     }
00562 #endif
00563 
00564     if (code == 0)
00565     {
00566         BOOL bOK = BuildCapabilityTree(m_XMLFile.GetFullPath(), pCapTree);
00567         if (!bOK)
00568         {
00569             // Assume BuildCapabilityTree has already set an error
00570             return FALSE;
00571         }
00572     }
00573     else
00574     {
00575         TRACEUSER("Gerry", _T("Command '%s' exited with code %d"), sCommand.c_str(), code);
00576 
00577         // Get error message from saErrors
00578 
00579         // Look for the first entry that starts "ERROR:" and set the remainder of 
00580         // the line as the error message
00581         wxString line;
00582         size_t index = 0;
00583         while (index < saErrors.GetCount())
00584         {
00585             wxString rest;
00586             if (saErrors[index].StartsWith(_T("ERROR:"), &rest))
00587             {
00588                 Error::SetError(0, rest.c_str(), 0);
00589                 break;
00590             }
00591             index++;
00592         }
00593 
00594         if (index == saErrors.GetCount())
00595         {
00596             ERROR1(FALSE, _R(IDS_XPF_NO_ERROR_SET));
00597         }
00598 
00599         return(FALSE);
00600     }
00601 
00602     return(TRUE);
00603 }
00604 
00605 
00606 
00607 /****************************************************************************
00608 
00609 >   BOOL PluginOILFilter::DoExport(CCLexFile* pXarFile, PathName* pPath)
00610 
00611     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
00612     Created:    18/02/2005
00613 
00614     Inputs:     pXarFile    - pointer to a CCLexFile
00615                 pPath       - pointer to a PathName
00616     Returns:    TRUE if ok, FALSE if bother
00617     Purpose:    
00618 
00619 ****************************************************************************/
00620 
00621 BOOL PluginOILFilter::DoExport(CCLexFile* pXarFile, PathName* pPath)
00622 {
00623     // Here we should just need to wait for the process started in GetExportFile 
00624     // to finish
00625     // Check stderr for errors and progress
00626 
00627     // However for now we will instead
00628     // Run the plugin with the following options
00629     // -e -g -f <filename> -x <xmlfilename>
00630 
00631     // The xmlfilename is a path to a user and filter specific file
00632     // e.g. ~/.XaraLX/filtername.xml
00633 
00634     // Check stderr for errors
00635 
00636     wxString sCommand(m_DoExport);
00637     sCommand.Replace(_T("%OUT%"), (LPCTSTR)pPath->GetPath());
00638     sCommand.Replace(_T("%XML%"), m_XMLFile.GetFullPath());
00639 
00640     TRACEUSER("Gerry", _T("Running '%s'"), sCommand.c_str());
00641 
00642     CCDiskFile TempFile(CCFILE_DEFAULTSIZE, FALSE, FALSE);
00643     if (!TempFile.open(m_TempXarFile, ios::in | ios::binary))
00644     {
00645         // report an error here
00646         return FALSE;
00647     }
00648 
00649     // Create a process with the TempFile as the stdin
00650     PluginFilterProcess* pTheProc = new PluginFilterProcess((PluginNativeFilter*)Parent, &TempFile, NULL);
00651 
00652     INT32 code = pTheProc->Execute(sCommand);
00653     TRACEUSER("Gerry", _T("Execute returned %d"), code);
00654     TempFile.close();
00655     if (code != 0)
00656     {
00657         TRACEUSER("Gerry", _T("Execution of '%s' failed (%d)"), sCommand.c_str(), code);
00658         // Extract error and report it
00659         pTheProc->ReportError();
00660         delete pTheProc;
00661         return(FALSE);
00662     }
00663 
00664     pTheProc->ReportWarning();
00665     delete pTheProc;
00666 
00667     return(TRUE);
00668 }
00669 
00670 
00671 
00672 /****************************************************************************
00673 
00674 >   BOOL PluginOILFilter::BuildCapabilityTree(wxString strXmlFilename, CapabilityTree* pCapTree)
00675 
00676     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
00677     Created:    17/03/2005
00678 
00679     Inputs:     bsXML       - The XML to load
00680                 pCapTree    - pointer to a CapabilityTree to be filled in
00681     Returns:    Standard HRESULT
00682     Purpose:    Populates a CapabilityTree object with the XML
00683 
00684 ****************************************************************************/
00685 
00686 BOOL PluginOILFilter::BuildCapabilityTree(wxString strXmlFilename, CapabilityTree* pCapTree)
00687 {
00688     // First we need to load the XML into an XML DOM object
00689 
00690     // Set Parser flags here?
00691 //  hRes = pDoc->setProperty(CComBSTR(_T("SelectionLanguage")), CComVariant(_T("XPath")));
00692 //  hRes = pDoc->put_async(VARIANT_FALSE);
00693 //  hRes = pDoc->put_preserveWhiteSpace(VARIANT_TRUE);
00694 //  hRes = pDoc->put_validateOnParse(VARIANT_FALSE);
00695 //  hRes = pDoc->put_resolveExternals(VARIANT_FALSE);
00696 
00697     BOOL bOK = TRUE;
00698     xmlDocPtr doc;
00699 
00700     // If string param contains xml (like original Windows version)
00701 //  wxCharBuffer buf = strXML.mb_str(wxConvUTF8);
00702 //  doc = xmlParseDoc((const xmlChar*)buf.data());  // buf will be deallocated when it goes out of scope
00703 
00704     // If string param gives xml filename (like new LX version)
00705     wxCharBuffer buf = strXmlFilename.ToAscii();
00706     doc = xmlParseFile(buf.data());                 // buf will be deallocated when it goes out of scope
00707 #if _DEBUG
00708     if (doc==NULL)
00709         doc = xmlParseFile("/tmp/XaraLX/capstest.xml");
00710 #endif
00711     ERROR1IF(doc==NULL, FALSE, _R(IDE_XPF_BADXML));
00712 
00713     // The name of the root element should be XPFilterConfig
00714 
00715     xmlNodePtr node = xmlDocGetRootElement(doc);
00716     wxString strName = CXMLUtils::ConvertToWXString(node->name);
00717     if (strName!=_T("XPFilterConfig"))
00718         ERROR1(FALSE, _R(IDE_XPF_BADXML));
00719 
00720     xmlNodePtr pChild = node->children;
00721     INT32 Phase =0;
00722 
00723     // There are 7 phases to the parsing
00724     // We will loop round until we run out of child elements
00725     // After parsing a node the phase counter will be set to the phase just parsed
00726     // If an element should have already been parsed (using the phase counter)
00727     // then an error will be indicated
00728 
00729     while (pChild && bOK)
00730     {
00731         wxString strChildName = CXMLUtils::ConvertToWXString(pChild->name);
00732         
00733         if (strChildName == _T("#text") || xmlNodeIsText(pChild))
00734         {
00735             // ignore it
00736         }
00737         else if (strChildName == _T("Private"))
00738         {
00739             if (Phase > 0)
00740             {
00741                 ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE0));
00742             }
00743             // Ignore the entire element
00744             Phase = 1;
00745         }
00746         else if (strChildName == _T("Options"))
00747         {
00748             if (Phase > 1)
00749             {
00750                 ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE1));
00751             }
00752             bOK = ReadOptions(pChild, pCapTree);        // Read the options attributes
00753             Phase = 2;
00754         }
00755         else if (strChildName == _T("Rasterise"))
00756         {
00757             if (Phase > 2)
00758             {
00759                 ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE2));
00760             }
00761             bOK = ReadRasterise(pChild, pCapTree);      // Read the dpi and alpha attributes
00762             Phase = 3;
00763         }
00764         else if (strChildName == _T("Spread"))
00765         {
00766             if (Phase > 3)
00767             {
00768                 ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE3));
00769             }
00770             bOK = ReadSpread(pChild, pCapTree);     // Read the as attribute
00771             Phase = 4;
00772         }
00773         else if (strChildName == _T("Objects"))
00774         {
00775             if (Phase > 4)
00776             {
00777                 ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE4));
00778             }
00779             bOK = ReadObjects(pChild, pCapTree);        // Build the tree of XPFCapability derived objects
00780             Phase = 5;
00781         }
00782         else if (strChildName == _T("Attributes"))
00783         {
00784             if (Phase > 5)
00785             {
00786                 ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE5));
00787             }
00788             bOK = ReadAttributes(pChild, pCapTree); // Build the tree of XPFCapability derived objects
00789             Phase = 6;
00790         }
00791         else if (strChildName == _T("Colour"))
00792         {
00793             if (Phase > 6)
00794             {
00795                 ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE6));
00796             }
00797             bOK = ReadColour(pChild, pCapTree);     // Build the tree of XPFColour objects
00798             Phase = 7;
00799         }
00800         else
00801         {
00802             ERROR1(FALSE, _R(IDE_XPF_BADXML_UNEXPECTED_PHASE));
00803         }
00804 
00805         pChild = pChild->next;
00806     }
00807 
00808     xmlFreeDoc(doc);
00809 
00810     return bOK;
00811 }
00812 
00813 
00814 BOOL PluginOILFilter::ReadOptions(xmlNodePtr pNode, CapabilityTree* pCapTree)
00815 {
00816     BoundsWriteLevel Level = BWL_NONE;
00817 
00818     wxString strLevel = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"boundslevel"));
00819     if (strLevel == _T("none"))
00820     {
00821         Level = BWL_NONE;
00822     }
00823     else if (strLevel == _T("compound"))
00824     {
00825         Level = BWL_COMPOUND;
00826     }
00827     else if (strLevel == _T("all"))
00828     {
00829         Level = BWL_ALL;
00830     }
00831     else if (strLevel != _T(""))
00832     {
00833         ERROR1(FALSE, _R(IDE_XPF_BADXML_OPTIONS_BOUNDSLEVEL));
00834     }
00835 
00836     pCapTree->SetBoundsLevel(Level);
00837 
00838     BOOL bSelection = FALSE;
00839     wxString strSelection = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"selection"));
00840     bSelection = (strSelection == _T("true"));
00841 
00842     pCapTree->SetSelection(bSelection);
00843 
00844     BOOL bPreviewBitmap = FALSE;
00845     wxString strPreviewBitmap = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"thumbnail"));
00846     bPreviewBitmap = (strPreviewBitmap == _T("true"));
00847 
00848     pCapTree->SetPreviewBitmap(bPreviewBitmap);
00849 
00850     return TRUE;
00851 }
00852 
00853 
00854 BOOL PluginOILFilter::ReadRasterise(xmlNodePtr pNode, CapabilityTree* pCapTree)
00855 {
00856     double DPI = 96.0;
00857     BOOL bAlpha = TRUE;
00858     long Compression = 200;
00859     String_256 CommonTrans;
00860     BOOL bResample = FALSE;
00861     wxString str;
00862 
00863     str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"dpi"));
00864     if (!str.IsEmpty())
00865     {
00866         str.ToDouble(&DPI);
00867     }
00868 
00869     str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"alpha"));
00870     if (!str.IsEmpty())
00871     {
00872         bAlpha = (str == _T("true"));
00873     }
00874 
00875     str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"compression"));
00876     if (!str.IsEmpty())
00877     {
00878         str.ToLong(&Compression);
00879     }
00880 
00881     str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"commontrans"));
00882     if (!str.IsEmpty())
00883     {
00884         CommonTrans = str;
00885     }
00886 
00887     str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"resample"));
00888     if (!str.IsEmpty())
00889     {
00890         bResample = (str == _T("true"));
00891     }
00892 
00893     pCapTree->SetRasterise(DPI, bAlpha, (INT32)Compression, CommonTrans, bResample);
00894 
00895     return TRUE;
00896 }
00897 
00898 
00899 BOOL PluginOILFilter::ReadSpread(xmlNodePtr pNode, CapabilityTree* pCapTree)
00900 {
00901     XPFConvertType Type = XPFCONVTYPE_UNKNOWN;
00902     wxString str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"as"));
00903     if (str.IsEmpty())
00904     {
00905         Type = XPFCONVTYPE_NATIVE;
00906     }
00907     else if (str == _T("bitmap"))
00908     {
00909         Type = XPFCONVTYPE_BITMAP;
00910     }
00911     else
00912     {
00913         ERROR1(FALSE, _R(IDE_XPF_BADXML_SPREAD_CONVERTAS));
00914     }
00915 
00916     if (Type != XPFCONVTYPE_UNKNOWN)
00917         pCapTree->SetSpreadType(Type);
00918 
00919     return TRUE;
00920 }
00921 
00922 
00923 BOOL PluginOILFilter::ReadObjects(xmlNodePtr pNode, CapabilityTree* pCapTree)
00924 {
00925     // We must loop through the tree of elements
00926 
00927     // pNode is the Objects element so read the default as attribute
00928 
00929     XPFCapability* pObjects = NULL;
00930     XPFConvertType ObjectsType = XPFCONVTYPE_UNKNOWN;
00931 
00932     BOOL bOK = GetConvertAsType(pNode, &ObjectsType);
00933     if (!bOK)
00934     {
00935         TRACEUSER("Phil", _T("ReadObjects GetConvertAsType failed\n"));
00936         return FALSE;
00937     }
00938 
00939     // Loop through each child calling the CreateObjectNode recursive function
00940     // for each one
00941 
00942     xmlNodePtr pChild;
00943     pChild = pNode->children;
00944     XPFCapability* pLast = NULL;
00945 
00946     while (pChild)
00947     {
00948         XPFCapability* pCap = CreateObjectNode(pChild);
00949 
00950         if (pCap)
00951         {
00952             // If we have a capability node then add it to the list
00953             // If we do not have a node already then set pObjects
00954             if (pLast)
00955             {
00956                 pLast->SetNext(pCap);
00957             }
00958             else
00959             {
00960                 pObjects = pCap;
00961             }
00962             pLast = pCap;
00963         }
00964 
00965         pChild = pChild->next;
00966     }
00967 
00968     pCapTree->SetObjectsTree(pObjects, ObjectsType);
00969 
00970     return TRUE;
00971 }
00972 
00973 
00974 BOOL PluginOILFilter::ReadAttributes(xmlNodePtr pNode, CapabilityTree* pCapTree)
00975 {
00976     // We must loop through the tree of elements
00977 
00978     // pNode is the Attributes element so read the default as attribute
00979 
00980     XPFCapability* pAttrs = NULL;
00981     XPFConvertType AttrType = XPFCONVTYPE_UNKNOWN;
00982 
00983     BOOL bOK = GetConvertAsType(pNode, &AttrType);
00984     if (!bOK)
00985     {
00986         TRACEUSER("Phil", _T("ReadAttributes GetConvertAsType failed\n"));
00987         return FALSE;
00988     }
00989 
00990     // Loop through each child calling the CreateAttributeNode recursive function
00991     // for each one
00992 
00993     xmlNodePtr pChild;
00994     pChild = pNode->children;
00995     XPFCapability* pLast = NULL;
00996 
00997     while (pChild)
00998     {
00999         XPFCapability* pCap = CreateAttributeNode(pChild);
01000 
01001         if (pCap)
01002         {
01003             // If we have a node then add it to the list
01004             // If we do not have a node already then set m_pObjects
01005             if (pLast)
01006             {
01007                 pLast->SetNext(pCap);
01008             }
01009             else
01010             {
01011                 pAttrs = pCap;
01012             }
01013             pLast = pCap;
01014         }
01015 
01016         pChild = pChild->next;
01017     }
01018 
01019     pCapTree->SetAttributesTree(pAttrs, AttrType);
01020 
01021     return TRUE;
01022 }
01023 
01024 
01025 BOOL PluginOILFilter::ReadColour(xmlNodePtr pNode, CapabilityTree* pCapTree)
01026 {
01027     // We must loop through the tree of elements
01028 
01029     // pNode is the Attributes element so read the default as attribute
01030 
01031     XPFCapability* pCols = NULL;
01032     XPFConvertType ColType = XPFCONVTYPE_UNKNOWN;
01033 
01034     BOOL bOK = GetConvertAsType(pNode, &ColType);
01035     if (!bOK)
01036     {
01037         TRACEUSER("Phil", _T("ReadColour GetConvertAsType failed\n"));
01038         return FALSE;
01039     }
01040 
01041     // Loop through each child calling the CreateColourNode recursive function
01042     // for each one
01043 
01044     xmlNodePtr pChild;
01045     pChild = pNode->children;
01046     XPFCapability* pLast = NULL;
01047 
01048     while (pChild)
01049     {
01050         XPFCapability* pCap = CreateColourNode(pChild);
01051 
01052         if (pCap)
01053         {
01054             // If we have a node then add it to the list
01055             // If we do not have a node already then set m_pObjects
01056             if (pLast)
01057             {
01058                 pLast->SetNext(pCap);
01059             }
01060             else
01061             {
01062                 pCols = pCap;
01063             }
01064             pLast = pCap;
01065         }
01066 
01067         pChild = pChild->next;
01068     }
01069 
01070     pCapTree->SetColoursTree(pCols, ColType);
01071 
01072     return TRUE;
01073 }
01074 
01075 
01076 BOOL PluginOILFilter::GetConvertAsType(xmlNodePtr pNode, XPFConvertType* pValue)
01077 {
01078     XPFConvertType AsType = XPFCONVTYPE_UNKNOWN;
01079 
01080     if (pNode)
01081     {
01082         wxString str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"as"));
01083         if (!str.IsEmpty())
01084         {
01085             if (str == _T("native"))
01086             {
01087                 AsType = XPFCONVTYPE_NATIVE;
01088             }
01089             else if (str == _T("simple"))
01090             {
01091                 AsType = XPFCONVTYPE_SIMPLE;
01092             }
01093             else if (str == _T("stroked"))
01094             {
01095                 AsType = XPFCONVTYPE_STROKED;
01096             }
01097             else if (str == _T("bitmap"))
01098             {
01099                 AsType = XPFCONVTYPE_BITMAP;
01100             }
01101             else if (str == _T("bitmapfill"))
01102             {
01103                 AsType = XPFCONVTYPE_BITMAPFILL;
01104             }
01105             else if (str == _T("bitmaptrans"))
01106             {
01107                 AsType = XPFCONVTYPE_BITMAPTRANS;
01108             }
01109             else if (str == _T("bitmapfilltrans"))
01110             {
01111                 AsType = XPFCONVTYPE_BITMAPFILLTRANS;
01112             }
01113             else if (str == _T("bitmapspan"))
01114             {
01115                 AsType = XPFCONVTYPE_BITMAPSPAN;
01116             }
01117             else if (str == _T("reformat"))
01118             {
01119                 AsType = XPFCONVTYPE_REFORMAT;
01120             }
01121             else if (str == _T("remove"))
01122             {
01123                 AsType = XPFCONVTYPE_REMOVE;
01124             }
01125             else if (str == _T("simplergb"))
01126             {
01127                 AsType = XPFCONVTYPE_SIMPLERGB;
01128             }
01129             else if (str == _T("rgb"))
01130             {
01131                 AsType = XPFCONVTYPE_RGB;
01132             }
01133             else if (str == _T("cmyk"))
01134             {
01135                 AsType = XPFCONVTYPE_CMYK;
01136             }
01137             else
01138             {
01139                 ERROR1(FALSE, _R(IDE_XPF_BADXML_UNKNOWN_CONVTYPE));
01140             }
01141         }
01142     }
01143     else
01144     {
01145         ERROR1(FALSE, _R(IDE_XPF_BADXML_EXPECTED_CONVTYPE));
01146     }
01147 
01148     *pValue = AsType;
01149 
01150     return TRUE;
01151 }
01152 
01153 
01154 BOOL PluginOILFilter::GetXPFBOOL(xmlNodePtr pNode, LPTSTR pAttrName, XPFBOOL* pbValue)
01155 {
01156     XPFBOOL bValue = XPFB_UNKNOWN;
01157 
01158     if (pNode)
01159     {
01160         wxString strAttrName(pAttrName);
01161         wxCharBuffer buf = strAttrName.mb_str(wxConvUTF8);          // buf will remain allocated in this scope
01162         wxString str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)buf.data()));
01163         if (!str.IsEmpty())
01164         {
01165             if (str == _T("true"))
01166             {
01167                 bValue = XPFB_TRUE;
01168             }
01169             else if (str == _T("false"))
01170             {
01171                 bValue = XPFB_FALSE;
01172             }
01173             else
01174             {
01175                 ERROR1(FALSE, _R(IDE_XPF_BADXML_UNEXPECTED_BOOLVALUE));
01176             }
01177         }
01178     }
01179     else
01180     {
01181         ERROR1(FALSE, _R(IDE_XPF_BADXML_NULLNODE));
01182     }
01183 
01184     *pbValue = bValue;
01185 
01186     return TRUE;
01187 }
01188 
01189 
01190 BOOL PluginOILFilter::GetXPFProp(xmlNodePtr pNode, LPTSTR pAttrName, PropMapEntry aMap[], XPFProp* pValue)
01191 {
01192     XPFProp Value = XPFP_UNKNOWN;
01193 
01194     if (pNode)
01195     {
01196         wxString strAttrName(pAttrName);
01197         wxCharBuffer buf = strAttrName.mb_str(wxConvUTF8);          // buf will remain allocated in this scope
01198         wxString str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)buf.data()));
01199         if (!str.IsEmpty())
01200         {
01201             // Loop through the map until we find it or the NULL indicating the end
01202             INT32 Index = 0;
01203             while (aMap[Index].pName)
01204             {
01205                 if (str == aMap[Index].pName)
01206                 {
01207                     Value = aMap[Index].Value;
01208                     break;
01209                 }
01210                 Index++;
01211             }
01212 
01213             if (Value == XPFP_UNKNOWN)
01214             {
01215                 ERROR1(FALSE, _R(IDE_XPF_BADXML_UNEXPECTED_PROPVALUE));
01216             }
01217         }
01218     }
01219     else
01220     {
01221         ERROR1(FALSE, _R(IDE_XPF_BADXML_NULLNODE));
01222     }
01223 
01224     *pValue = Value;
01225 
01226     return TRUE;
01227 }
01228 
01229 
01230 XPFCapability* PluginOILFilter::CreateObjectNode(xmlNodePtr pNode)
01231 {
01232     XPFCapability* pCap = NULL;
01233 
01234     wxString strName = CXMLUtils::ConvertToWXString(pNode->name);
01235     
01236     if (strName == _T("#text") || xmlNodeIsText(pNode))
01237     {
01238         wxString str = CXMLUtils::ConvertToWXString(xmlNodeGetContent(pNode));
01239         TRACEUSER("Phil", _T("CreateObjectNode ignoring text %s\n"), (LPCTSTR)str);
01240         return(NULL);
01241     }
01242 
01243     XPFConvertType AsType = XPFCONVTYPE_UNKNOWN;
01244     BOOL bOK = GetConvertAsType(pNode, &AsType);
01245     if (!bOK)
01246     {
01247         TRACEUSER("Phil", _T("CreateObjectNode GetConvertAsType failed\n"));
01248         return NULL;
01249     }
01250 
01251     if (strName == _T("Layer"))
01252     {
01253         // Read the visible and locked attributes
01254         XPFBOOL bVisible = XPFB_UNKNOWN;
01255         bOK = GetXPFBOOL(pNode, _T("visible"), &bVisible);
01256         XPFBOOL bLocked = XPFB_UNKNOWN;
01257         bOK = GetXPFBOOL(pNode, _T("locked"), &bLocked);
01258         XPFBOOL bPrintable = XPFB_UNKNOWN;
01259         bOK = GetXPFBOOL(pNode, _T("printable"), &bPrintable);
01260         XPFBOOL bActive = XPFB_UNKNOWN;
01261         bOK = GetXPFBOOL(pNode, _T("active"), &bActive);
01262         XPFBOOL bBackground = XPFB_UNKNOWN;
01263         bOK = GetXPFBOOL(pNode, _T("background"), &bBackground);
01264         XPFBOOL bGuide = XPFB_UNKNOWN;
01265         bOK = GetXPFBOOL(pNode, _T("guide"), &bGuide);
01266         XPFProp ContentOnly = XPFP_UNKNOWN;
01267         bOK = GetXPFProp(pNode, _T("onlycontent"), aContentOnly, &ContentOnly);
01268         pCap = new XPFCLayer(AsType, bVisible, bLocked, bPrintable, bActive, bBackground, bGuide, ContentOnly);
01269     }
01270     else if (strName == _T("Contour"))
01271     {
01272         pCap = new XPFCContour(AsType);
01273     }
01274     else if (strName == _T("Shadow"))
01275     {
01276         // Read the type attribute
01277         XPFProp Type = XPFP_UNKNOWN;
01278         bOK = GetXPFProp(pNode, _T("type"), aShadowTypes, &Type);
01279         pCap = new XPFCShadow(AsType, Type);
01280     }
01281     else if (strName == _T("Bevel"))
01282     {
01283         // Read the type and side attributes
01284         XPFProp Type = XPFP_UNKNOWN;
01285         bOK = GetXPFProp(pNode, _T("type"), aBevelTypes, &Type);
01286         XPFProp Side = XPFP_UNKNOWN;
01287         bOK = GetXPFProp(pNode, _T("side"), aBevelSides, &Side);
01288         pCap = new XPFCBevel(AsType, Type, Side);
01289     }
01290     else if (strName == _T("Blend"))
01291     {
01292         // Read the effect, oncurve, posprofile and attrprofile attributes
01293         XPFProp Effect = XPFP_UNKNOWN;
01294         bOK = GetXPFProp(pNode, _T("effect"), aColourEffects, &Effect);
01295         XPFBOOL bOnCurve = XPFB_UNKNOWN;
01296         bOK = GetXPFBOOL(pNode, _T("oncurve"), &bOnCurve);
01297         XPFBOOL bObjProfile = XPFB_UNKNOWN;
01298         bOK = GetXPFBOOL(pNode, _T("posprofile"), &bObjProfile);
01299         XPFBOOL bAttrProfile = XPFB_UNKNOWN;
01300         bOK = GetXPFBOOL(pNode, _T("attrprofile"), &bAttrProfile);
01301         pCap = new XPFCBlend(AsType, Effect, bOnCurve, bObjProfile, bAttrProfile);
01302     }
01303     else if (strName == _T("Mould"))
01304     {
01305         // Read the as and type attributes
01306         XPFProp Type = XPFP_UNKNOWN;
01307         bOK = GetXPFProp(pNode, _T("type"), aMouldTypes, &Type);
01308         XPFBOOL bGradFill = XPFB_UNKNOWN;
01309         bOK = GetXPFBOOL(pNode, _T("gradfill"), &bGradFill);
01310         pCap = new XPFCMould(AsType, Type, bGradFill);
01311     }
01312     else if (strName == _T("Rectangle"))
01313     {
01314         // Read the as, rounded and complex attributes
01315         XPFBOOL bComplex = XPFB_UNKNOWN;
01316         bOK = GetXPFBOOL(pNode, _T("complex"), &bComplex);
01317         XPFBOOL bRounded = XPFB_UNKNOWN;
01318         bOK = GetXPFBOOL(pNode, _T("rounded"), &bRounded);
01319         XPFBOOL bStellated = XPFB_UNKNOWN;
01320         bOK = GetXPFBOOL(pNode, _T("stellated"), &bStellated);
01321         XPFBOOL bReformed = XPFB_UNKNOWN;
01322         bOK = GetXPFBOOL(pNode, _T("reformed"), &bReformed);
01323         pCap = new XPFCRectangle(AsType, bComplex, bRounded, bStellated, bReformed);
01324     }
01325     else if (strName == _T("Ellipse"))
01326     {
01327         // Read the as and complex attributes
01328         XPFBOOL bComplex = XPFB_UNKNOWN;
01329         bOK = GetXPFBOOL(pNode, _T("complex"), &bComplex);
01330         pCap = new XPFCEllipse(AsType, bComplex);
01331     }
01332     else if (strName == _T("Polygon"))
01333     {
01334         // Read the as, rounded, stellated and reformed attributes
01335         XPFBOOL bRounded = XPFB_UNKNOWN;
01336         bOK = GetXPFBOOL(pNode, _T("rounded"), &bRounded);
01337         XPFBOOL bStellated = XPFB_UNKNOWN;
01338         bOK = GetXPFBOOL(pNode, _T("stellated"), &bStellated);
01339         XPFBOOL bReformed = XPFB_UNKNOWN;
01340         bOK = GetXPFBOOL(pNode, _T("reformed"), &bReformed);
01341         pCap = new XPFCPolygon(AsType, bRounded, bStellated, bReformed);
01342     }
01343     else if (strName == _T("Bitmap"))
01344     {
01345         // Read the complex and contone attributes
01346         XPFBOOL bComplex = XPFB_UNKNOWN;
01347         bOK = GetXPFBOOL(pNode, _T("complex"), &bComplex);
01348         XPFBOOL bContone = XPFB_UNKNOWN;
01349         bOK = GetXPFBOOL(pNode, _T("contone"), &bContone);
01350         pCap = new XPFCBitmap(AsType, bComplex, bContone);
01351     }
01352     else if (strName == _T("Text"))
01353     {
01354         // Read the onpath, complex and plain attributes
01355         XPFBOOL bOnPath = XPFB_UNKNOWN;
01356         bOK = GetXPFBOOL(pNode, _T("onpath"), &bOnPath);
01357         XPFBOOL bComplex = XPFB_UNKNOWN;
01358         bOK = GetXPFBOOL(pNode, _T("complex"), &bComplex);
01359         XPFBOOL bPlain = XPFB_UNKNOWN;
01360         bOK = GetXPFBOOL(pNode, _T("plain"), &bPlain);
01361         XPFBOOL bAutoKern = XPFB_UNKNOWN;
01362         bOK = GetXPFBOOL(pNode, _T("autokern"), &bAutoKern);
01363         XPFBOOL bJustified = XPFB_UNKNOWN;
01364         bOK = GetXPFBOOL(pNode, _T("justified"), &bJustified);
01365         pCap = new XPFCText(AsType, bOnPath, bComplex, bPlain, bAutoKern, bJustified);
01366     }
01367     else if (strName == _T("ClipView"))
01368     {
01369         pCap = new XPFCClipView(AsType);
01370     }
01371     else if (strName == _T("BitmapEffect"))
01372     {
01373         pCap = new XPFCBitmapEffect(AsType);
01374     }
01375     else if (strName == _T("Feather"))
01376     {
01377         pCap = new XPFCFeather(AsType);
01378     }
01379     else
01380     {
01381         ERROR1(NULL, _R(IDE_XPF_BADXML_UNEXPECTED_OBJTYPE));
01382     }
01383 
01384     xmlNodePtr pChild;
01385     pChild = pNode->children;
01386     XPFCapability* pLast = NULL;
01387 
01388     while (pChild)
01389     {
01390         XPFCapability* pCapNode = CreateObjectNode(pChild);
01391 
01392         if (pCapNode)
01393         {
01394             // If we have a node then add it to the list
01395             // If we do not have a node already then set m_pObjects
01396             if (pLast)
01397             {
01398                 pLast->SetNext(pCapNode);
01399             }
01400             else
01401             {
01402                 pCap->SetChild(pCapNode);
01403             }
01404             pLast = pCapNode;
01405         }
01406 
01407         pChild = pChild->next;
01408     }
01409 
01410     return(pCap);
01411 }
01412 
01413 
01414 XPFCapability* PluginOILFilter::CreateAttributeNode(xmlNodePtr pNode)
01415 {
01416     XPFCapability* pCap = NULL;
01417 
01418     wxString strName = CXMLUtils::ConvertToWXString(pNode->name);
01419     
01420     if (strName == _T("#text") || xmlNodeIsText(pNode))
01421     {
01422         wxString str = CXMLUtils::ConvertToWXString(xmlNodeGetContent(pNode));
01423         TRACEUSER("Phil", _T("CreateAttributeNode ignoring text %s\n"), (LPCTSTR)str);
01424         return(NULL);
01425     }
01426 
01427     XPFConvertType AsType = XPFCONVTYPE_UNKNOWN;
01428     BOOL bOK = GetConvertAsType(pNode, &AsType);
01429     if (!bOK)
01430     {
01431         TRACEUSER("Phil", _T("CreateAttributeNode GetConvertAsType failed\n"));
01432         return NULL;
01433     }
01434 
01435     if (strName == _T("Fill"))
01436     {
01437         XPFProp Shape = XPFP_UNKNOWN;
01438         bOK = GetXPFProp(pNode, _T("shape"), aFillShapes, &Shape);
01439         XPFProp Repeat = XPFP_UNKNOWN;
01440         bOK = GetXPFProp(pNode, _T("repeat"), aFillRepeats, &Repeat);
01441         XPFBOOL bMultistage = XPFB_UNKNOWN;
01442         bOK = GetXPFBOOL(pNode, _T("multistage"), &bMultistage);
01443         XPFProp Effect = XPFP_UNKNOWN;
01444         bOK = GetXPFProp(pNode, _T("effect"), aColourEffects, &Effect);
01445         XPFBOOL bProfile = XPFB_UNKNOWN;
01446         bOK = GetXPFBOOL(pNode, _T("profile"), &bProfile);
01447         XPFBOOL bContone = XPFB_UNKNOWN;
01448         bOK = GetXPFBOOL(pNode, _T("contone"), &bContone);
01449         pCap = new XPFCFill(AsType, Shape, Repeat, bMultistage, Effect, bProfile, bContone);
01450     }
01451     else if (strName == _T("FillTrans"))
01452     {
01453         XPFProp Shape = XPFP_UNKNOWN;
01454         bOK = GetXPFProp(pNode, _T("shape"), aFillShapes, &Shape);
01455         XPFProp Type = XPFP_UNKNOWN;
01456         bOK = GetXPFProp(pNode, _T("type"), aTransTypes, &Type);
01457         XPFProp Repeat = XPFP_UNKNOWN;
01458         bOK = GetXPFProp(pNode, _T("repeat"), aFillRepeats, &Repeat);
01459         XPFBOOL bProfile = XPFB_UNKNOWN;
01460         bOK = GetXPFBOOL(pNode, _T("profile"), &bProfile);
01461         pCap = new XPFCFillTrans(AsType, Shape, Type, Repeat, bProfile);
01462     }
01463     else if (strName == _T("Line"))
01464     {
01465         XPFBOOL bDash = XPFB_UNKNOWN;
01466         bOK = GetXPFBOOL(pNode, _T("dash"), &bDash);
01467         XPFBOOL bArrowhead = XPFB_UNKNOWN;
01468         bOK = GetXPFBOOL(pNode, _T("arrowhead"), &bArrowhead);
01469         XPFProp Cap = XPFP_UNKNOWN;
01470         bOK = GetXPFProp(pNode, _T("cap"), aLineCaps, &Cap);
01471         XPFProp Join = XPFP_UNKNOWN;
01472         bOK = GetXPFProp(pNode, _T("join"), aLineJoins, &Join);
01473         XPFBOOL bStroke = XPFB_UNKNOWN;
01474         bOK = GetXPFBOOL(pNode, _T("stroke"), &bStroke);
01475         XPFBOOL bBrush = XPFB_UNKNOWN;
01476         bOK = GetXPFBOOL(pNode, _T("brush"), &bBrush);
01477         pCap = new XPFCLine(AsType, bDash, bArrowhead, Cap, Join, bStroke, bBrush);
01478     }
01479     else if (strName == _T("LineTrans"))
01480     {
01481         XPFProp Type = XPFP_UNKNOWN;
01482         bOK = GetXPFProp(pNode, _T("type"), aTransTypes, &Type);
01483         pCap = new XPFCLineTrans(AsType, Type);
01484     }
01485     else if (strName == _T("Feather"))
01486     {
01487         pCap = new XPFCFeather(AsType);
01488     }
01489     else
01490     {
01491         ERROR1(NULL, _R(IDE_XPF_BADXML_UNEXPECTED_ATTRTYPE));
01492     }
01493 
01494     xmlNodePtr pChild;
01495     pChild = pNode->children;
01496     XPFCapability* pLast = NULL;
01497 
01498     while (pChild)
01499     {
01500         XPFCapability* pCapNode = CreateAttributeNode(pChild);
01501 
01502         if (pCapNode)
01503         {
01504             // If we have a node then add it to the list
01505             // If we do not have a node already then set m_pObjects
01506             if (pLast)
01507             {
01508                 pLast->SetNext(pCapNode);
01509             }
01510             else
01511             {
01512                 pCap->SetChild(pCapNode);
01513             }
01514             pLast = pCapNode;
01515         }
01516 
01517         pChild = pChild->next;
01518     }
01519 
01520     return(pCap);
01521 }
01522 
01523 
01524 XPFCapability* PluginOILFilter::CreateColourNode(xmlNodePtr pNode)
01525 {
01526     XPFCapability* pCap = NULL;
01527 
01528     wxString strName = CXMLUtils::ConvertToWXString(pNode->name);
01529     
01530     if (strName == _T("#text") || xmlNodeIsText(pNode))
01531     {
01532         wxString str = CXMLUtils::ConvertToWXString(xmlNodeGetContent(pNode));
01533         TRACEUSER("Phil", _T("CreateColourNode ignoring text %s\n"), (LPCTSTR)str);
01534         return(NULL);
01535     }
01536 
01537     XPFConvertType AsType = XPFCONVTYPE_UNKNOWN;
01538     BOOL bOK = GetConvertAsType(pNode, &AsType);
01539     if (!bOK)
01540     {
01541         TRACEUSER("Phil", _T("CreateColourNode GetConvertAsType failed\n"));
01542         return NULL;
01543     }
01544 
01545     if (strName == _T("Colour"))
01546     {
01547         pCap = new XPFCColour(AsType);
01548     }
01549     else
01550     {
01551         ERROR1(NULL, _R(IDE_XPF_BADXML_UNEXPECTED_COLOURTYPE));
01552     }
01553 
01554     xmlNodePtr pChild;
01555     pChild = pNode->children;
01556     XPFCapability* pLast = NULL;
01557 
01558     while (pChild)
01559     {
01560         XPFCapability* pCapNode = CreateColourNode(pChild);
01561 
01562         if (pCapNode)
01563         {
01564             // If we have a node then add it to the list
01565             // If we do not have a node already then set m_pObjects
01566             if (pLast)
01567             {
01568                 pLast->SetNext(pCapNode);
01569             }
01570             else
01571             {
01572                 pCap->SetChild(pCapNode);
01573             }
01574             pLast = pCapNode;
01575         }
01576 
01577         pChild = pChild->next;
01578     }
01579 
01580     return(pCap);
01581 }
01582 
01583 /****************************************************************************
01584 
01585 >   void PluginOILFilter::Cleanup()
01586 
01587     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
01588     Created:    18/02/2005
01589 
01590     Purpose:    
01591 
01592 ****************************************************************************/
01593 
01594 void PluginOILFilter::Cleanup()
01595 {
01596 }
01597 
01598 
01599 
01600 PluginFilterProcess::PluginFilterProcess(PluginNativeFilter* pFilter, CCLexFile* pInFile, CCLexFile* pOutFile) :
01601     CamProcess(pInFile, pOutFile)
01602 {
01603     TRACEUSER("Gerry", _T("PluginFilterProcess::PluginFilterProcess"));
01604     m_pFilter = pFilter;
01605 }
01606 
01607 
01608 PluginFilterProcess::~PluginFilterProcess()
01609 {
01610     TRACEUSER("Gerry", _T("PluginFilterProcess::~PluginFilterProcess"));
01611 }
01612 
01613 
01614 void PluginFilterProcess::ProcessStdErr()
01615 {
01616 //  TRACEUSER("Gerry", _T("PluginFilterProcess::ProcessStdErr"));
01617 
01618     if (IsErrorAvailable())
01619     {
01620         wxTextInputStream tis(*GetErrorStream());
01621 
01622         // This assumes that the output is always line buffered
01623 //      while (!GetErrorStream()->Eof())
01624         while (IsErrorAvailable())
01625         {
01626             wxString line;
01627             line << tis.ReadLine();
01628 //          TRACEUSER("Gerry", _T("(stderr):%s"), line.c_str());
01629 
01630             if (!line.IsEmpty())
01631             {
01632                 // If line begins "MESSAGE:" then it is a debug message and can be discarded
01633                 wxString rest;
01634                 if (line.StartsWith(_T("MESSAGE:"), &rest))
01635                 {
01636 //                  TRACEUSER("Gerry", _T("XPFDebug:%s"), rest.c_str());
01637                 }
01638                 else if (line.StartsWith(_T("PROGRESS:"), &rest))
01639                 {
01640 //                  TRACEUSER("Gerry", _T("XPFProgress:%s"), rest.c_str());
01641                     if (m_pFilter)
01642                     {
01643                         unsigned long /*TYPENOTE: Correct*/ Val = wxStrtoul(rest.c_str(), NULL, 10);
01644                         if (Val > 0)
01645                         {
01646 //                          TRACEUSER("Gerry", _T("Setting progress to %d"), Val);
01647                             m_pFilter->SetProgressBarCount((UINT32)Val);
01648                         }
01649                     }
01650                 }
01651                 else if (line.StartsWith(_T("WARNING:"), &rest))
01652                 {
01653 //                  TRACEUSER("Gerry", _T("XPFWarning:%s"), rest.c_str());
01654                     m_Warnings.Add(rest);
01655                 }
01656                 else if (line.StartsWith(_T("ERROR:"), &rest))
01657                 {
01658 //                  TRACEUSER("Gerry", _T("XPFError:%s"), rest.c_str());
01659                     m_Errors.Add(rest);
01660                 }
01661                 else
01662                 {
01663 //                  TRACEUSER("Gerry", _T("Skipping stderr:%s"), line.c_str());
01664 //                  m_Errors.Add(line);
01665                 }
01666             }
01667         }
01668     }
01669 }
01670 
01671 
01672 BOOL PluginFilterProcess::ReportError()
01673 {
01674     TRACEUSER("Gerry", _T("PluginFilterProcess::ReportError"));
01675 
01676     // Get the first entry from m_ErrorList and pass it to Error::SetError
01677     if (m_Errors.GetCount() > 0)
01678     {
01679         Error::SetError(0, m_Errors[0].c_str(), 0);
01680     }
01681     else
01682     {
01683         ERROR1(FALSE, _R(IDS_XPF_NO_ERROR_SET));
01684     }
01685 
01686     return(FALSE);
01687 }
01688 
01689 
01690 void PluginFilterProcess::ReportWarning()
01691 {
01692     TRACEUSER("Gerry", _T("PluginFilterProcess::ReportWarning"));
01693 
01694     // Show the user the contents of m_WarningList
01695     for (size_t i = 0; i < m_Warnings.GetCount(); i++)
01696     {
01697         TRACEUSER("Gerry", _T("WARNING:%s"), m_Warnings[i].c_str());
01698     }
01699 }

Generated on Sat Nov 10 03:48:58 2007 for Camelot by  doxygen 1.4.4