plugmngr.cpp

Go to the documentation of this file.
00001 // $Id: plugmngr.cpp 1282 2006-06-09 09:46:49Z alex $
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 
00100 
00101 #include "camtypes.h"
00102 //#include "app.h"          // GetApplication() - in camtypes.h [AUTOMATICALLY REMOVED]
00103 
00104 #include "plugmngr.h"       // main header file
00105 #include "plugin.h"         // useful plug-in related items
00106 #include "fileutil.h"       // useful file utilities
00107 
00108 #include "pshpmngr.h"       // PhotoShopHandler
00109 #include "bfxmngr.h"        // Bfxhandler
00110 
00111 #include "plugbrws.h"
00112 #include "plugop.h"         // PlugInOp
00113 #include "plugopun.h"       // PlugInUndoOp
00114 
00115 //#include "plugres.h"      // _R(IDS_PLUGIN_ONE)
00116 #include "progress.h"       // Progress
00117 //#include "fixmem.h"           // CCMalloc CCFree - in camtypes.h [AUTOMATICALLY REMOVED]
00118 #include "sgliboil.h"       // SGLibOil::AppendSlashIfNotPresent
00119 #include "sgrmfile.h"       // LibSettings
00120 #include "product.h"        // PRODUCT_PLUGINS_INIFILE
00121 
00122 // Only include the freehand plug-ins if required
00123 #ifdef FREEHANDPLUGINS
00124 #include "xtrahand.h"       // Freehand Xtra Plugin Handler
00125 #endif // FREEHANDPLUGIN
00126 
00127 #include "menuitem.h"       // MenuItem
00128 #include "oilmenus.h"       // GetMainMDIMenu
00129 #include "menupref.h"       // CreateMenuItem
00130 #include "pshpop.h"         // OPTOKEN_PHOTOSHOP_APPLYLAST
00131 
00132 #include "registry.h"       // SaveRegistryEntries
00133 
00134 
00135 #include "appprefs.h"       // OPTOKEN_PLUGSDLG
00136 
00137 
00138 
00139 // Place any IMPLEMENT type statements here
00140 CC_IMPLEMENT_DYNAMIC(PlugInHandler, ListItem)
00141 CC_IMPLEMENT_DYNAMIC(PlugInManager, CCObject)
00142 
00143 // We want better memory tracking
00144 #define new CAM_DEBUG_NEW
00145 
00146 // declare any statics
00147 
00148 /********************************************************************************************
00149 
00150     Preference:     ParseAtStartUp
00151     Section:        Plug-ins
00152     Range:          TRUE or FALSE
00153     Purpose:        If TRUE, then the plug-in pathnames will be searched at start up for 
00154                     plug-ins. If FALSE, then the searching happens the first time any plug-in
00155                     UI is invoked.
00156     SeeAlso:        -
00157 
00158 ********************************************************************************************/
00159 
00160 BOOL PlugInManager::m_ParseAtStartUp    = TRUE;
00161 
00162 /**************************************************************************************
00163 
00164 >   PlugInHandler::PlugInHandler()
00165 
00166     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00167     Created:    10/12/96
00168     Purpose:    Main constructor for the plug-in handler in Camelot. 
00169 
00170 **************************************************************************************/
00171 
00172 PlugInHandler::PlugInHandler()
00173 {
00174 }
00175 
00176 /**************************************************************************************
00177 
00178 >   PlugInHandler::~PlugInHandler()
00179 
00180     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00181     Created:    10/12/96
00182     Purpose:    Main destructor for the plug-in handler in Camelot. 
00183 
00184 **************************************************************************************/
00185 
00186 PlugInHandler::~PlugInHandler()
00187 {
00188 }
00189 
00190 /**************************************************************************************
00191 
00192 >   virtual BOOL PlugInHandler::AddFixedPlugIns()
00193 
00194     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00195     Created:    4/3/97
00196     Inputs:     -
00197     Returns:    True if worked, False otherwise
00198     Purpose:    Add any fixed plug-ins to the list in the plug-in manager and register the op
00199                 descriptor to the system. By fixed, I mean those which are not file
00200                 related and hence will be loaded when the specified paths are parsed
00201                 for plug-ins.
00202                 This baseclass version does nothing.
00203 
00204 **************************************************************************************/
00205 
00206 BOOL PlugInHandler::AddFixedPlugIns()
00207 {
00208     return TRUE;
00209 }
00210 
00211 /**************************************************************************************
00212 
00213 >   virtual BOOL PlugInHandler::AddPlugIn(PlugInItem * pPlugIn, CCRuntimeClass* pClass = CC_RUNTIME_CLASS(PlugInOp),
00214                                           pfnGetState gs = PlugInOp::GetState)
00215 
00216     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00217     Created:    11/12/96
00218     Inputs:     pPlugIn     the new PlugInItem to add to the list
00219                 pClass      the operation handling class to use
00220                 gs          the GetState function to use
00221     Returns:    True if worked, False otherwise
00222     Purpose:    Add a plug-in to the list in the plug-in manager and register the op
00223                 descriptor to the system. 
00224 
00225 **************************************************************************************/
00226 
00227 BOOL PlugInHandler::AddPlugIn(PlugInItem * pPlugIn, CCRuntimeClass* pClass, pfnGetState gs)
00228 {
00229     PlugInManager* pManager = GetApplication()->GetPlugInManager();
00230     if (pManager == NULL)
00231         return FALSE;
00232     
00233     if (!pManager->AddPlugIn(pPlugIn))
00234         ERROR2(FALSE,"Failed to register a plug-in with plug-in manager");
00235 
00236     // Make up a unique name for the plug in
00237     String_32 OpToken = GetUniqueID();
00238     OpToken += pPlugIn->GetPlugInName();
00239     // Register this name as an OpDescriptor to the system so that we can use it
00240     // on menus etc.
00241     if (!PlugInOp::RegisterOpToken(OpToken, pPlugIn->GetPlugInName(), pClass, gs))
00242         ERROR2(FALSE,"Failed to register OpToken for a plug-in");
00243 
00244     // Now see if the family name is registered, if not then register it
00245     OpToken = GetUniqueID();
00246     OpToken += pPlugIn->GetFamilyName();
00247     OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OpToken);
00248     if (pOpDesc == NULL)
00249     {
00250         // Register this name as an OpDescriptor to the system so that we can use it
00251         // on menus etc.
00252         if (!PlugInOp::RegisterOpToken(OpToken, pPlugIn->GetFamilyName(), pClass, gs))
00253             ERROR2(FALSE,"Failed to register OpToken for a plug-in family name");
00254     }
00255 
00256     return TRUE;
00257 }
00258 
00259 /********************************************************************************************
00260 
00261 >   BOOL PhotoShopHandler::CreateMainMenuItems(PlugInManager * pManager, MenuItem * pRootMenu,
00262                                                BOOL AddSeparator = FALSE)
00263 
00264     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00265     Created:    12/1/97
00266     Inputs:     pManager    the plug-in manager to get at useful things like the plug-in list
00267                 pRootMenu   The root of the main menu to add the items to
00268                 AddSeparator    True if want a separator added to the last item on the menu
00269     Outputs:    -
00270     Returns:    True if the operation completed successfully
00271                 False if it failed in some way.
00272     Purpose:    After the plug in list has been sorted alphabetically we must add each item
00273                 in the list to the main plug-in menu. This is a handler's chance to insert
00274                 menu options into this menu.
00275                 This baseclass version does nothing and so needs to be overridden by a handler
00276                 to do something useful.
00277 
00278 ********************************************************************************************/
00279 
00280 BOOL PlugInHandler::CreateMainMenuItems(PlugInManager * pManager, MenuItem * pRootMenu,
00281                                         BOOL AddSeparator)
00282 {
00283     ERROR2IF(pManager == NULL || pRootMenu == NULL,FALSE,"CreateMainMenuItems bad parameters!");
00284 
00285     // This baseclass version does nothing
00286     return TRUE;
00287 }
00288 
00289 /**************************************************************************************
00290 **************************************************************************************/
00291 
00292 /**************************************************************************************
00293 
00294 >   PlugInManager::PlugInManager()
00295 
00296     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00297     Created:    9/12/96
00298     Purpose:    Main constructor for the plug-in manager in Camelot. 
00299 
00300 **************************************************************************************/
00301 
00302 PlugInManager::PlugInManager()
00303 {
00304     // Flag that we have not been initialised yet
00305     m_Initialised = FALSE;
00306     // Default to parsing paths at start up
00307     m_ParseAtStartUp = TRUE;
00308     // Flag that we have not searched the plug-ins path yet
00309     m_SearchedPaths = FALSE;
00310 }
00311 
00312 /**************************************************************************************
00313 
00314 >   PlugInManager::~PlugInManager()
00315 
00316     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00317     Created:    9/12/96
00318     Purpose:    Main destructor for the plug-in manager in Camelot. 
00319 
00320 **************************************************************************************/
00321 
00322 PlugInManager::~PlugInManager()
00323 {
00324     // Clean out our list of pathnames
00325     /* PlugInPath* pPath = (PlugInPath *)Paths.GetHead();
00326     while (pPath != NULL)
00327     {
00328         delete pBitmap->pBmp;
00329 
00330         // Try the next pathname in the list
00331         pPath = (PlugInPath *)Paths.GetNext(pPath);
00332     } */
00333 
00334     //Paths.DeleteAll();
00335 
00336     // Clean out the list of plug-in handlers that Camelot understands.
00337     m_HandlersList.DeleteAll();
00338 
00339     // Clean out the list of plug-in items
00340     DestroyPlugInsList();
00341 }
00342 
00343 /**************************************************************************************
00344 
00345 >   BOOL PlugInManager::DestroyPlugInsList()
00346 
00347     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00348     Created:    12/12/96
00349     Returns:    True if worked ok, False otherwise.
00350     Purpose:    Destroy the list of plugs that the plug-in manager in Camelot currently
00351                 has. 
00352 
00353 **************************************************************************************/
00354 
00355 BOOL PlugInManager::DestroyPlugInsList()
00356 {
00357     // We need to write the code to destruct an OpDescriptor and delink it from the
00358     // list before we can do this.
00359 
00360     // We must go through the list of plug-ins and deregister things like the
00361     // allocated op-descriptors that we allocated when the plug-in was created.
00362     PlugInItem* pPlugIn = (PlugInItem *)m_PlugInsList.GetHead();
00363     String_32 OpToken;
00364     String_32 FamilyOpToken;
00365     String_32 LastFamilyOpToken;
00366     while (pPlugIn != NULL)
00367     {
00368         OpToken = pPlugIn->GetUniqueID();
00369         FamilyOpToken = OpToken;
00370         OpToken += pPlugIn->GetPlugInName();
00371         FamilyOpToken += pPlugIn->GetFamilyName();
00372         // Search for the OpDescriptor
00373         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OpToken);
00374         if (pOpDesc != NULL)
00375         {
00376             OpDescriptor::DelinkDescriptor(pOpDesc);
00377             delete pOpDesc;
00378         }
00379         // If the family optoken changes then this is the time to delete it
00380         if (FamilyOpToken != LastFamilyOpToken)
00381         {
00382             // Search for the OpDescriptor
00383             pOpDesc = OpDescriptor::FindOpDescriptor(FamilyOpToken);
00384             if (pOpDesc != NULL)
00385             {
00386                 OpDescriptor::DelinkDescriptor(pOpDesc);
00387                 delete pOpDesc;
00388             }
00389         }
00390         
00391         LastFamilyOpToken = FamilyOpToken;
00392 
00393         // Try the next plug-in in the list
00394         pPlugIn = (PlugInItem *)m_PlugInsList.GetNext(pPlugIn);
00395     }
00396 
00397     // Clean out the list of plug-in items
00398     m_PlugInsList.DeleteAll();
00399 
00400     // Lastly, flag that we have now not parsed all the paths
00401     m_SearchedPaths = FALSE;
00402 
00403     return TRUE;
00404 }
00405 
00406 /**************************************************************************************
00407 **************************************************************************************/
00408 
00409 #define ADD_HANDLER(Classname) \
00410     {                                                                                   \
00411         /* Create, initialise and install a new plug-in handler */                      \
00412         Classname * pHandler = new Classname;                                           \
00413                                                                                         \
00414         if (pHandler == NULL) return FALSE;                                             \
00415                                                                                         \
00416         if (!pHandler->Init())                                                          \
00417         {                                                                               \
00418             /* Error occured - report it and stop trying to initialise filters. */      \
00419             InformError();                                                              \
00420             return TRUE;                                                                \
00421         }                                                                               \
00422                                                                                         \
00423         m_HandlersList.AddTail(pHandler);                                               \
00424     }
00425 
00426 /**************************************************************************************
00427 
00428 >   BOOL PlugInManager::Init()
00429 
00430     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00431     Created:    9/12/96
00432     Returns:    True if initialised ok, False otherwise.
00433     Purpose:    Main initialisation code for the plug-in manager in Camelot. 
00434 
00435 **************************************************************************************/
00436 
00437 BOOL PlugInManager::Init()
00438 {
00439 #ifndef WEBSTER
00440 #ifndef EXCLUDE_BFX
00441 //#ifdef NEW_NATIVE_FILTER
00442     ADD_HANDLER(BfxHandler);
00443 //#endif
00444 #endif
00445 #endif
00446     // Only include the freehand plug-ins if required
00447 #ifdef PHOTOSHOPPLUGINS 
00448     ADD_HANDLER(PhotoShopHandler);
00449 #endif
00450     // Only include the freehand plug-ins if required
00451 #ifdef FREEHANDPLUGINS
00452     ADD_HANDLER(XtraHandler);
00453 #endif
00454 
00455     if (!PlugInOp::Init())
00456         return FALSE;
00457 
00458     // Declare any preferences that we require.
00459     if ( Camelot.DeclareSection(TEXT("Plug-ins"), 3) )
00460     {
00461         // section declared ok so now define the preference option  
00462         Camelot.DeclarePref(TEXT("Plug-ins"), TEXT("ParseAtStartUp"), &m_ParseAtStartUp, 0, 1);
00463     }
00464 
00465     // load stored items from preference system
00466     BOOL ok = ReadPathNameList();
00467 
00468     ok = ok && PlugInOp::RegisterOpToken(OPTOKEN_PLUGINS_MENU, _R(IDS_PLUGINS));
00469     ok = ok && PlugInOp::RegisterOpToken(OPTOKEN_PLUGINS_MANAGER, _R(IDS_PLUGINS));
00470     ok = ok && PlugInOp::RegisterOpToken(OPTOKEN_PLUGINS_PARSING, _R(IDS_PLUGSIN_PARSING));
00471     ok = ok && PlugInOp::RegisterOpToken(OPTOKEN_PLUGINS_PLUGINSMNGR, _R(IDS_PLUGINS_PLUGINSMNGR));
00472 
00473     ok = ok && PlugInUndoOp::RegisterOpToken(OPTOKEN_PLUGINS_UNDO_MENU, _R(IDS_PLUGINS));
00474 
00475     // Lastly, note that initialised has been called
00476     m_Initialised = TRUE;
00477 
00478     return TRUE;
00479 }
00480 
00481 
00482 /********************************************************************************************
00483 
00484 >   static BOOL PlugInManager::WipePlugInsSettings()
00485 
00486     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00487     Created:    28/2/97
00488     Purpose:    Wipes the plug-in pathnames list from the ini file or from the registry.
00489     SeeAlso:    LibSettings::NukeSettings;
00490 
00491 
00492 ********************************************************************************************/
00493 
00494 BOOL PlugInManager::WipePlugInsSettings()
00495 {
00496 #ifdef SAVE_PREFS_TO_REGISTRY
00497     // Check if the registry entry is present or not. Look for the our special plugin related
00498     // items which should be stored in a 'PlugIns\\Plug-in Pathname List' key.
00499     // This is the section and sub-section name that we are going to use
00500     String_256 KeySectionName(PRODUCT_REGISTRYKEY_PLUGINS TEXT("\\Plug-in Pathname List"));
00501     DeleteRegKey(hAppStateRegKey, KeySectionName);
00502 
00503     // We must wipe the ini file as well as otherwise when the code checks to 
00504     // see if the registry settings and then falls back on the ini file if they
00505     // are not there, then we wont be using the default settings.
00506 #endif
00507 
00508     // Vape the plug-ins ini file
00509     String_256 PlugInsIni(PRODUCT_PLUGINS_INIFILE);
00510     LibSettings::NukeSettings(&PlugInsIni);
00511 
00512     return TRUE;
00513 }
00514 
00515 /********************************************************************************************
00516 
00517 >   BOOL PlugInManager::ReadPathNameList()
00518 
00519     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00520     Created:    17/12/96
00521     Purpose:    Reads the plug-in pathnames list in from the ini file.
00522                 This has to be a new ini file as the main ini file code cannot cope with
00523                 the concept of sections filled with an arbitrary number of items which need
00524                 cleaning out when resaving to remove old items no longer required.
00525                 The code is based on LibSettings::BuildList
00526     SeeAlso:    CFileList::ReadList(); LibSettings::BuildList;
00527 
00528 
00529 ********************************************************************************************/
00530 
00531 BOOL PlugInManager::ReadPathNameList()
00532 {
00533 #ifdef SAVE_PREFS_TO_REGISTRY
00534     // Check if the registry entry is present or not. Look for the our special plugin related
00535     // items which should be stored in a 'PlugIns\\Plug-in Pathname List' key.
00536     // This is the section and sub-section name that we are going to use
00537     String_256 KeySectionName(PRODUCT_REGISTRYKEY_PLUGINS TEXT("\\Plug-in Pathname List"));
00538     BOOL EntryPresent = CheckForRegistryEntry(KeySectionName);
00539 
00540     if (EntryPresent)
00541     {
00542         LoadRegistryEntries Loader;
00543         Loader.StartLoading(&KeySectionName);
00544 
00545         BOOL AddedItems = FALSE;
00546         String_256 FileName;
00547         while (Loader.LoadNextEntry(&FileName))
00548         {
00549             // only interested in items which contain some data!
00550             // If blank then we may parse the entire disc or currently selected directory!
00551             if (!FileName.IsEmpty())
00552             {
00553                 // Add a trailing slash if it hasn't got one
00554                 SGLibOil::AppendSlashIfNotPresent(&FileName);
00555                 PathName Path(FileName);
00556                 m_Paths.AddPathName(Path);
00557                 // Flag that we have added something
00558                 AddedItems = TRUE;
00559             }
00560         }
00561         Loader.StopLoading();
00562     }
00563     else
00564 #endif
00565     {
00566         // Read in the data from the older ini file that may be kicking around
00567         // This is the section name that we are going to use
00568         String_256 SectionName(TEXT("Plug-in Pathname List"));
00569         // This is the ini file that we are going to be using
00570         String_256 PlugInsIni(PRODUCT_PLUGINS_INIFILE);
00571 
00572         BOOL AddedItems = FALSE;
00573         String_256 FileName;
00574         CCDiskFile GetEntryFile(1024, FALSE, TRUE);
00575 
00576         if (LibSettings::GetEntryStart(&GetEntryFile, &PlugInsIni))
00577         {
00578             if (LibSettings::SeekToSection(&GetEntryFile, &SectionName))
00579             {
00580                 while (LibSettings::GetNextLine(&GetEntryFile, &FileName))
00581                 {
00582                     // Add a trailing slash if it hasn't got one
00583                     SGLibOil::AppendSlashIfNotPresent(&FileName);
00584                     PathName Path(FileName);
00585                     m_Paths.AddPathName(Path);
00586                     // Flag that we have added something
00587                     AddedItems = TRUE;
00588                 }
00589             }
00590 
00591             LibSettings::GetEntryFinish(&GetEntryFile);
00592         }
00593     }
00594 
00595     // Everything is ok
00596     return TRUE;
00597 }
00598 
00599 /********************************************************************************************
00600 
00601 >   BOOL PlugInManager::WritePathNameList()
00602 
00603     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00604     Created:    17/12/96
00605     Purpose:    Writes the list of plug-in pathnames to the ini file
00606                 This has to be a new ini file as the main ini file code cannot cope with
00607                 the concept of sections filled with an arbitrary number of items which need
00608                 cleaning out when resaving to remove old items no longer required.
00609     SeeAlso:    CFileList::WriteList()
00610 
00611 ********************************************************************************************/
00612 
00613 BOOL PlugInManager::WritePathNameList()
00614 {
00615 #ifdef SAVE_PREFS_TO_REGISTRY
00616     BOOL ok = TRUE;
00617 
00618     // This is the section and sub-section name that we are going to use
00619     String_256 SectionName(PRODUCT_REGISTRYKEY_PLUGINS TEXT("\\Plug-in Pathname List"));
00620     SaveRegistryEntries Saver;
00621     ok = Saver.StartSaving(&SectionName);
00622     ERROR3IF(!ok,"PlugInManager::WritePathNameList() couldn't start saving the settings");
00623     // Go through all our stored paths writing them out in the preferences.
00624     // DO NOT USE GetHead/GetNext as we would see all the paths, which is more than we should
00625     // be seeing. Use the offical GetFirstPath/GetNextPath routines which give us what we 
00626     // should be seeing, i.e. the user entered paths.
00627     PlugInPath* pPath = (PlugInPath *)m_Paths.GetFirstPath();
00628     PathName FileName;
00629     String_256 Line;
00630 
00631     while (pPath != NULL && ok)
00632     {
00633         // Get the pathname for this entry
00634         FileName = pPath->GetPathName();
00635         // Get the string that represents this
00636         Line = FileName.GetPath();
00637         // only write out the line if non-blank
00638         // If blank then we may parse the entire disc or currently selected directory!
00639         if (!Line.IsEmpty())
00640             ok = ok && Saver.SaveNextEntry(&Line);
00641         // if !ok then possibly write access denied on in file... or disk full...
00642         // So flag that we should stop outputting any more data
00643 
00644         // Try the next pathname in the list
00645         pPath = (PlugInPath *)m_Paths.GetNextPath(pPath);
00646     }
00647 
00648     Saver.StopSaving();
00649 #else
00650     // This is the section name that we are going to use
00651     String_256 SectionName(TEXT("Plug-in Pathname List"));
00652     // This is the ini file that we are going to be using
00653     String_256 PlugInsIni(PRODUCT_PLUGINS_INIFILE);
00654     
00655     LibSettings::StartOutput(&SectionName, &PlugInsIni);
00656     LibSettings::AddSection(&SectionName, &PlugInsIni);
00657 
00658     // Go through all our stored paths writing them out in the preferences.
00659     // DO NOT USE GetHead/GetNext as we would see all the paths, which is more than we should
00660     // be seeing. Use the offical GetFirstPath/GetNextPath routines which give us what we 
00661     // should be seeing, i.e. the user entered paths.
00662     PlugInPath* pPath = (PlugInPath *)m_Paths.GetFirstPath();
00663     PathName FileName;
00664     String_256 Line;
00665 
00666     BOOL ok = TRUE;
00667     while (pPath != NULL && ok)
00668     {
00669         // Get the pathname for this entry
00670         FileName = pPath->GetPathName();
00671         // Get the string that represents this
00672         Line = FileName.GetPath();
00673         if (!LibSettings::AddLine(&Line, &PlugInsIni))
00674         {
00675             // Possibly write access denied on in file... or disk full...
00676             // So flag that we should stop outputting any more data
00677             ok = FALSE;
00678         }
00679         // Try the next pathname in the list
00680         pPath = (PlugInPath *)m_Paths.GetNextPath(pPath);
00681     }
00682 #endif
00683     return TRUE;
00684 }
00685 
00686 /**************************************************************************************
00687 
00688 >   BOOL PlugInManager::SearchForPlugIns()
00689 
00690     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00691     Created:    17/12/96
00692     Returns:    True if parsed ok, False otherwise.
00693     Purpose:    Starts up the process of parsing all the paths specified to the plug-in
00694                 manager for plug-ins and stroing information on them in a list.
00695                 This is called during start up so needs to check the flag to see whether
00696                 the user has requested this to be done at the start, before actually
00697                 trying to parse.
00698 
00699 **************************************************************************************/
00700 
00701 BOOL PlugInManager::SearchForPlugIns()
00702 {
00703     // If the user has requested plug-in parsing at start up then now is the time to do it
00704     // Otherwise, delay until the first call
00705     if (m_ParseAtStartUp)
00706         return ParseAllPaths();
00707 
00708     // Otherwise we do the job later
00709     return TRUE;
00710 }
00711 
00712 /**************************************************************************************
00713 
00714 >   BOOL PlugInManager::CheckHaveDetailsOnPlugIns()
00715 
00716     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00717     Created:    17/12/96
00718     Returns:    True if parsed ok, False otherwise.
00719     Purpose:    Checks to see if the pathnames have been searched for plug-ins. If not
00720                 then do it now.
00721                 This should be called by any UI code before they try and put up any UI
00722                 of plug-ins, e.g. a menu of available plug-ins. If the user requested
00723                 not to parse pathnames at start up then this is where it happens.
00724 
00725 **************************************************************************************/
00726 
00727 BOOL PlugInManager::CheckHaveDetailsOnPlugIns()
00728 {
00729     // If we have not already parsed the paths then go and do it now as we need it.
00730     if (!m_SearchedPaths)
00731         return ParseAllPaths();
00732     
00733     // Otherwise we do the job later
00734     return TRUE;
00735 }
00736 
00737 /**************************************************************************************
00738 
00739 >   BOOL PlugInManager::ParseAllPaths()
00740 
00741     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00742     Created:    9/12/96
00743     Returns:    True if parsed ok, False otherwise.
00744     Purpose:    Starts up the process of parsing all the paths specified to the plug-in
00745                 manager for plug-ins and storing information on them in a list.
00746                 Assumes the list is either empty before we are called or the caller
00747                 has cleared it using 
00748 
00749 **************************************************************************************/
00750 
00751 BOOL PlugInManager::ParseAllPaths()
00752 {
00753     // First, flag that we have parsed all the paths
00754     m_SearchedPaths = TRUE;
00755 
00756     BOOL ParsedOk = TRUE;
00757 
00758 //#if NEW_NATIVE_FILTER
00759     // Now, go and make sure that we have no plug-ins main menu items
00760     DeleteMainMenuItems();
00761 //#endif
00762 
00763     // Start adding the plug-ins into the list
00764     // First any ones which are fixed or built in and not file related
00765     // Go through each of the handlers asking them to add fixed plug-ins.
00766     PlugInHandler* pHandler = (PlugInHandler *)m_HandlersList.GetHead();
00767     while (pHandler != NULL)
00768     {
00769         pHandler->AddFixedPlugIns();
00770 
00771         // Try the next handler in the list
00772         pHandler = (PlugInHandler *)m_HandlersList.GetNext(pHandler);
00773     }
00774 
00775     // Now look through all the directories that the user has specified
00776     
00777     // First remove all hidden items from the list
00778     // Put up an hourglass to show we are doing something
00779     Progress InitialPathsProgress(_R(IDS_PLUGSIN_PARSING));
00780     m_Paths.RemoveHiddenItems();
00781 
00782     // Now go through all the pathnames looking for sub-directories recursively
00783     // and add these to the list of items
00784     // The items we use MUST only ever see non-hidden paths, as otherwise
00785     // we will get very recursive!!!!!
00786     PlugInPath* pPath = (PlugInPath *)m_Paths.GetFirstPath();
00787     INT32 FilesCount = 0;
00788     while (pPath != NULL)
00789     {
00790         ParsedOk = ParsedOk && ParsePathNameForDirectories(pPath->GetPathName(), &FilesCount);
00791         pPath = (PlugInPath *)m_Paths.GetNextPath(pPath);
00792     }
00793 
00794     // Put up a progress bar to show we are doing something
00795     Progress PathsProgress(_R(IDS_PLUGSIN_PARSING), FilesCount);
00796 
00797     // Go through all our stored paths and check them for plug-ins stored in them.
00798     pPath = (PlugInPath *)m_Paths.GetHead();
00799     INT32 Count = 0;
00800     PathsProgress.Update(Count);
00801 
00802     while (pPath != NULL)
00803     {
00804         ParsedOk = ParsedOk && ParsePathName(pPath->GetPathName(), pPath->GetPathNameID(), &Count, PathsProgress);
00805 
00806         // Try the next pathname in the list
00807         pPath = (PlugInPath *)m_Paths.GetNext(pPath);
00808         PathsProgress.Update(Count);
00809     }
00810 
00811     // Sort those plug-ins that we have loaded
00812     SortPlugInsAlphabetically();
00813 
00814 //#if NEW_NATIVE_FILTER
00815     // Now, go and create the plug-ins main menu items required
00816     CreateMainMenuItems();
00817 //#endif
00818 
00819     return ParsedOk;
00820 }
00821 
00822 /**************************************************************************************
00823 
00824 >   BOOL PlugInManager::ParsePathNameForDirectories( const PathName& SearchPath, INT32 * pFilesCount)
00825 
00826     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00827     Created:    9/12/96
00828     Inputs:     ParsePath       the pathname to parse for new plug-ins
00829     Outputs:    pFilesCount     an updated count of the files discovered
00830     Returns:    True if parsed ok, False otherwise.
00831     Purpose:    Parse the given path for all directories. If found then add them as
00832                 hidden items to our list of paths so that the user cannot see them.
00833                 We do it this way so that we only ever store a PathID with a plug-in
00834                 record rather than having to store the pathname or sub-directories to
00835                 the pathname with the plug-in.
00836     Note:       Must be re-entrant!
00837     
00838 **************************************************************************************/
00839 
00840 BOOL PlugInManager::ParsePathNameForDirectories( const PathName& SearchPath, INT32 * pFilesCount)
00841 {
00842     PathName File = SearchPath;
00843     String_256 SearchDir = SearchPath.GetPath();
00844     // If the path is blank then ignore it otherwise we will search the entire hard drive
00845     // or currently selected directory!
00846     if (SearchDir.IsEmpty())
00847         return TRUE;
00848 
00849     SearchDir += "*.*";
00850     TRACEUSER( "Neville", _T("ParsePathNameForDirectories Search path is %s\n"), (TCHAR *)SearchDir);
00851     FindFiles Finder;
00852     BOOL IsDirectory = FALSE;
00853     if (Finder.StartFindingFiles(&SearchDir))
00854     {
00855         String_256 LeafName;
00856         while (TRUE)
00857         {
00858             if (!Finder.FindNextFile(&LeafName, &IsDirectory))
00859                 break;
00860 
00861             if (pFilesCount)
00862                 (*pFilesCount)++;
00863 
00864             // We have found a file or a directory.
00865             // In this case we only want to look for directories
00866             if (IsDirectory)
00867             {
00868                 // Do something with the directory "LeafName"
00869                 TRACEUSER( "Neville", _T("ParsePathNameForDirectories add directory %s\n"), (TCHAR *)LeafName);
00870                 String_256 NewSearchDir = SearchPath.GetPath();
00871                 NewSearchDir += LeafName;
00872                 // Add a trailing slash if it hasn't got one, which it shouldn't have
00873                 SGLibOil::AppendSlashIfNotPresent(&NewSearchDir);
00874                 PathName NewSearchPath(NewSearchDir);
00875                 // Add the new pathname to the list, but as a hidden one so that
00876                 // people not in the know do not see them.
00877                 PlugInPath * pPath = m_Paths.AddPathName(NewSearchPath, TRUE);
00878                 if (pPath)
00879                 {
00880                     // recover the id associated with the path
00881                     ParsePathNameForDirectories(NewSearchPath, pFilesCount);
00882                 }
00883             }
00884         }
00885 
00886         // Stop the process
00887         Finder.StopFindingFiles();
00888     }
00889 
00890     return TRUE;
00891 }
00892 
00893 /**************************************************************************************
00894 
00895 >   BOOL PlugInManager::ParsePathName( const PathName& SearchPath, const INT32 PathID, INT32 * pFilesCount,
00896                                        const Progress& PathsProgress )
00897 
00898     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00899     Created:    9/12/96
00900     Inputs:     ParsePath   the pathname to parse for new plug-ins
00901                 pathID      the ID assigned to this path
00902                 PathsProgress   the progress object to call for progress update
00903     Outputs:    pFilesCount an updated count of the files discovered
00904     Returns:    True if parsed ok, False otherwise.
00905     Purpose:    Parse the given path for all files and pass the files of the registered
00906                 types to the appropriate plug-in handler. The handler should then check
00907                 to see whether it likes this type of file and if so then create a new 
00908                 plug-in record of the correct type and then place useful details into
00909                 the record. Finally it should register the new plug-in record with the
00910                 plug-in manager i.e. this class.
00911                 The PathID should be stored in the plug-in record so that we do not
00912                 have to store the full path with all plug-in records.
00913     
00914 **************************************************************************************/
00915 
00916 BOOL PlugInManager::ParsePathName( const PathName& SearchPath, const INT32 PathID, INT32 * pFilesCount,
00917                                    const Progress& PathsProgress )
00918 {
00919     PathName File = SearchPath;
00920     String_256 SearchDir = SearchPath.GetPath();
00921     // If the path is blank then ignore it otherwise we will search the entire hard drive
00922     // or currently selected directory!
00923     if (SearchDir.IsEmpty())
00924         return TRUE;
00925 
00926     // We must set up the operating system current directory so that extra DLLs beside the
00927     // plug-ins can be picked up.
00928     BOOL ok = FileUtil::SetCurrentDirectory( SearchPath );
00929 
00930     SearchDir += "*.*";
00931     TRACEUSER( "Neville", _T("ParsePathName Search path is %s, found:-\n"), (TCHAR *)SearchDir);
00932     FindFiles Finder;
00933     BOOL IsDirectory = FALSE;
00934     if (Finder.StartFindingFiles(&SearchDir))
00935     {
00936         String_256 LeafName;
00937         while (TRUE)
00938         {
00939             if (!Finder.FindNextFile(&LeafName, &IsDirectory))
00940                 break;
00941 
00942             if (pFilesCount)
00943                 (*pFilesCount)++;
00944 
00945             // Do something with file "LeafName"
00946             TRACEUSER( "Neville", _T("ParsePathName parse plug-in file %s\n"), (TCHAR *)LeafName);
00947 
00948             // We have found a file or a directory.
00949             // In this case we only want to look for files
00950             if (!IsDirectory)
00951             {
00952                 File.SetFileNameAndType(LeafName);
00953                 String_32 FileType = File.GetType();
00954                 FileType.toLower();
00955                 PlugInHandler* pHandler = (PlugInHandler *)m_HandlersList.GetHead();
00956                 BOOL Found = FALSE;
00957                 while (pHandler != NULL && !Found)
00958                 {
00959                     String_32 HandlerFileType = pHandler->GetFileTypes();
00960                     // If the handler returns a filetype which is null then ignore it
00961                     // as this generally indicates that it will do its own thing.
00962                     // Handlers can specify a list of file types by splitting them with commas
00963                     if (!HandlerFileType.IsEmpty() && (HandlerFileType.Sub(FileType) != -1)) //FileType == HandlerFileType)
00964                         Found = TRUE;
00965                     else
00966                     {
00967                         // Try the next handler in the list
00968                         pHandler = (PlugInHandler *)m_HandlersList.GetNext(pHandler);
00969                     }
00970                 }
00971                 // If we have found this filetype in our list of handlers then
00972                 // ask that handler to parse the file.
00973                 if (Found && pHandler)
00974                 {
00975                     pHandler->ParsePlugIn(File, PathID);
00976                 }
00977 
00978                 // Update our progress bar for the file just parsed
00979                 if (pFilesCount)
00980                     PathsProgress.Update(*pFilesCount);
00981             }
00982         }
00983 
00984         // Stop the process
00985         Finder.StopFindingFiles();
00986     }
00987 
00988     return TRUE;
00989 }
00990 
00991 /**************************************************************************************
00992 
00993 >   BOOL PlugInManager::GetPlugInPath( PathName* NewSearchPath )
00994 
00995     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00996     Created:    11/12/96
00997     Inputs:     -
00998     Outputs:    NewSearchPath   the pathname to parse for new plug-ins
00999     Returns:    True if parsed ok, False otherwise.
01000     Purpose:    Allows the requesting of a pathname to parse plug-ins for from the user.
01001                 Its pops up a modified form of the stanadard file dialog box set up to
01002                 browse explicitly for paths rather than files.
01003                 Used by the plug-ins options tab.
01004 
01005 **************************************************************************************/
01006 
01007 BOOL PlugInManager::GetPlugInPath( PathName* NewSearchPath )
01008 {
01009     // Ask out special class to pop up a common file dialog box to the user and then
01010     // to return the path that the user has requested back to us.
01011     BOOL ok = PlugInsBrowser::GetLibPath(NewSearchPath);                            
01012     return ok;
01013 }
01014 
01015 /**************************************************************************************
01016 
01017 >   BOOL PlugInManager::AddPlugInPath( const PathName& NewSearchPath )
01018 
01019     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01020     Created:    12/12/96
01021     Inputs:     NewSearchPath   the pathname to add to the list
01022     Returns:    True if added ok, False otherwise.
01023     Purpose:    Adds a new pathname to the list of pathnames stored in the plug-in manager.
01024 
01025 **************************************************************************************/
01026 
01027 BOOL PlugInManager::AddPlugInPath( const PathName& NewSearchPath )
01028 {
01029     // First check to see if its blank or not. If so then ignore it
01030     String_256 SearchDir = NewSearchPath.GetPath();
01031     if (SearchDir.IsEmpty())
01032     {
01033         ERROR3("AddPlugInPath asked to add blank path!");
01034         return FALSE;
01035     }
01036 
01037     m_Paths.AddPathName(NewSearchPath);
01038     return TRUE;
01039 }
01040 
01041 /**************************************************************************************
01042 
01043 >   BOOL PlugInManager::DeletePlugInPath( const PathName& SearchPath )
01044 
01045     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01046     Created:    12/12/96
01047     Inputs:     SearchPath  the pathname to delete from the list
01048     Returns:    True if added ok, False otherwise.
01049     Purpose:    Deletes a pathname from the list of pathnames stored in the plug-in manager.
01050 
01051 **************************************************************************************/
01052 
01053 BOOL PlugInManager::DeletePlugInPath( const PathName& SearchPath )
01054 {
01055     return m_Paths.DeletePathName(SearchPath);
01056 }
01057 
01058 /**************************************************************************************
01059 
01060 >   PlugInPath * PlugInManager::GetFirstPathName()
01061 
01062     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01063     Created:    12/12/96
01064     Returns:    Pointer to a plug-in pathname in the list.
01065     Purpose:    Get the first plug-in pathname in the list stored in the plug-in manager.
01066                 This is just the list of user defined paths and does not include the
01067                 hidden paths that are stored in the list as well.
01068 
01069 **************************************************************************************/
01070 
01071 PlugInPath * PlugInManager::GetFirstPathName()
01072 {
01073     return (PlugInPath *)m_Paths.GetFirstPath();
01074 }
01075 
01076 /**************************************************************************************
01077 
01078 >   PlugInPath * PlugInManager::GetNextPathName(PlugInPath * pPath)
01079 
01080     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01081     Created:    12/12/96
01082     Inputs:     pPlugIn     pointer to the current plug-in in the list
01083     Returns:    Pointer to a plug-in pathname in the list.
01084     Purpose:    Get the next plug-in pathname in the list stored in the plug-in manager.
01085                 This is just the list of user defined paths and does not include the
01086                 hidden paths that are stored in the list as well.
01087 
01088 **************************************************************************************/
01089 
01090 PlugInPath * PlugInManager::GetNextPathName(PlugInPath * pPath)
01091 {
01092     return (PlugInPath *)m_Paths.GetNextPath(pPath);
01093 }
01094 
01095 /**************************************************************************************
01096 
01097 >   BOOL PlugInManager::AddPlugIn(PlugInItem * pPlugIn)
01098 
01099     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01100     Created:    11/12/96
01101     Returns:    True if worked, False otherwise
01102     Purpose:    Add a plug-in to the list in the plug-in manager and register the op
01103                 desciptor to the system. 
01104 
01105 **************************************************************************************/
01106 
01107 BOOL PlugInManager::AddPlugIn(PlugInItem * pPlugIn)
01108 {
01109     m_PlugInsList.AddTail(pPlugIn);
01110 
01111     return TRUE;
01112 }
01113 
01114 /**************************************************************************************
01115 
01116 >   BOOL PlugInManager::RemovePlugIn(PlugInItem * pPlugIn)
01117 
01118     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01119     Created:    15/1/97
01120     Inputs:     pPlugIn     - Pointer to plugin item
01121     Returns:    True if worked, False otherwise
01122     Purpose:    Removes a plug-in from the list in the plug-in manager (if it's there)
01123 
01124 **************************************************************************************/
01125 
01126 BOOL PlugInManager::RemovePlugIn(PlugInItem * pPlugIn)
01127 {
01128     if(m_PlugInsList.RemoveItem(pPlugIn) == NULL)
01129         return FALSE;
01130 
01131     return TRUE;
01132 }
01133 
01134 
01135 
01136 /**************************************************************************************
01137 
01138 >   PlugInItem * PlugInManager::GetFirstPlugIn()
01139 
01140     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01141     Created:    11/12/96
01142     Returns:    Pointer to a plug-in item in the list.
01143     Purpose:    Get the first plug-in item in the list stored in the plug-in manager.
01144 
01145 **************************************************************************************/
01146 
01147 PlugInItem * PlugInManager::GetFirstPlugIn()
01148 {
01149     return (PlugInItem *)m_PlugInsList.GetHead();
01150 }
01151 
01152 /**************************************************************************************
01153 
01154 >   PlugInItem * PlugInManager::GetNextPlugIn(PlugInItem * pPlugIn)
01155 
01156     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01157     Created:    11/12/96
01158     Inputs:     pPlugIn     pointer to the current plug-in in the list
01159     Returns:    Pointer to a plug-in item in the list.
01160     Purpose:    Get the next plug-in item in the list stored in the plug-in manager.
01161 
01162 **************************************************************************************/
01163 
01164 PlugInItem * PlugInManager::GetNextPlugIn(PlugInItem * pPlugIn)
01165 {
01166     return (PlugInItem *)m_PlugInsList.GetNext(pPlugIn);
01167 }
01168 
01169 /**************************************************************************************
01170 
01171 >   PlugInItem * PlugInManager::GetPreviousPlugIn(PlugInItem * pPlugIn)
01172 
01173     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01174     Created:    11/12/96
01175     Inputs:     pPlugIn     pointer to the current plug-in in the list
01176     Returns:    Pointer to a previous plug-in item in the list.
01177     Purpose:    Get the previous plug-in item in the list stored in the plug-in manager.
01178 
01179 **************************************************************************************/
01180 
01181 PlugInItem * PlugInManager::GetPreviousPlugIn(PlugInItem * pPlugIn)
01182 {
01183     return (PlugInItem *)m_PlugInsList.GetPrev(pPlugIn);
01184 }
01185 
01186 /**************************************************************************************
01187 
01188 >   BOOL PlugInManager::GetPlugInPathname(INT32 PathNameID, String_256 * pPathName)
01189 
01190     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01191     Created:    11/12/96
01192     Inputs:     PathNameID  id of the pathname to search for
01193                 pPathName   pointer to a string to fill in with the pathname
01194     pPlugIn     pointer to the current plug-in in the list
01195     Returns:    True if worked ok, False otherwise.
01196     Purpose:    Converts a pathanme id which is stored with each plug-in into the real
01197                 pathname that it corresponds to by searching the pathname list in the
01198                 plug-in manager.
01199 
01200 **************************************************************************************/
01201 
01202 BOOL PlugInManager::GetPlugInPathname(INT32 PathNameID, String_256 * pPathName)
01203 {
01204     ERROR2IF(pPathName == NULL,FALSE,"PlugInManager::GetPlugInPathname null pPath");
01205 
01206     // Make the string empty
01207     pPathName->Empty();
01208 
01209     // Go through all our stored paths and check them for plug-ins stored in them.
01210     PlugInPath* pPath = (PlugInPath *)m_Paths.GetHead();
01211     while (pPath != NULL)
01212     {
01213         if (pPath->GetPathNameID() == PathNameID)
01214         {
01215             *pPathName = pPath->GetPathNameAsString();
01216             return TRUE;
01217         }
01218 
01219         // Try the next pathname in the list
01220         pPath = (PlugInPath *)m_Paths.GetNext(pPath);
01221     }
01222 
01223     // Nothing found so  return this to the user
01224     return FALSE;
01225 }
01226 
01227 /********************************************************************************************
01228 
01229 >   BOOL PlugInManager::SortPlugInsAlphabetically()
01230 
01231     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01232     Created:    16/12/96
01233     Inputs:     -
01234     Outputs:    -
01235     Returns:    True if the operation completed successfully
01236                 False if it failed in some way.
01237     Purpose:    Sorts the list of plugs-in alphabetically
01238                 Borrowed code from SuperGallery::ApplySortNow as we need a much simpler version.
01239     Errors:     -
01240     SeeAlso:    ImportedColours::SortColoursByEntryNumber(); SuperGallery::ApplySortNow
01241 
01242 ********************************************************************************************/
01243 
01244 BOOL PlugInManager::SortPlugInsAlphabetically()
01245 {
01246     INT32 NumItems = 0;
01247 
01248     // Count the number of items we have to sort
01249     PlugInItem * pPlugIn = GetFirstPlugIn();
01250     while (pPlugIn != NULL)
01251     {
01252         NumItems ++;
01253         pPlugIn = GetNextPlugIn(pPlugIn);
01254     }
01255 
01256     // Start progress indicators, with a percentage based upon the number of items.
01257     // We will update twice for each group (after qsort and shuffle-items stages)
01258     Progress SortProgress(_R(IDS_PLUGSIN_SORTING), NumItems * 2, FALSE);
01259     INT32 NumItemsToSort = 0;
01260 
01261     if (NumItems > 1)
01262     {
01263         // Get memory for an array of pointers to these items
01264         PlugInItem **SortArray = (PlugInItem **)CCMalloc(NumItems * sizeof(PlugInItem *));
01265         if (SortArray == NULL)
01266             return FALSE;
01267 
01268         // Fill in the array with pointers to display items to sort
01269         INT32 i = 0;
01270         PlugInItem * pPlugIn = GetFirstPlugIn();
01271         while (pPlugIn != NULL)
01272         {
01273             SortArray[i++] = pPlugIn;
01274             pPlugIn = GetNextPlugIn(pPlugIn);
01275         }
01276 
01277         // Sort the array of pointers
01278         qsort(SortArray, NumItems, sizeof(PlugInItem *), PlugInManager::SortComparator);
01279 
01280         NumItemsToSort += NumItems;
01281         // Update percentage complete for the number of items processed
01282         SortProgress.Update(NumItemsToSort);
01283 
01284         // Now, take the sorted array, and rearrange the items to be in that order      
01285         // Special case the first item
01286         PlugInItem *pPrevPlugIn = GetPreviousPlugIn(SortArray[0]);
01287         if (pPrevPlugIn != NULL)
01288         {
01289             m_PlugInsList.RemoveItem(SortArray[0]);
01290             m_PlugInsList.InsertBefore(SortArray[1], SortArray[0]);
01291         }
01292 
01293         // Then whip through the rest of the items
01294         for (i = 1; i < NumItems; i++)
01295         {
01296             pPrevPlugIn = GetPreviousPlugIn(SortArray[i]);
01297             if (pPrevPlugIn != SortArray[i-1])
01298             {
01299                 m_PlugInsList.RemoveItem(SortArray[i]);
01300                 m_PlugInsList.InsertAfter(SortArray[i-1], SortArray[i]);
01301             }
01302         }
01303 
01304         // Free our temporary workspace
01305         CCFree(SortArray);
01306     }
01307     
01308     // End the progress bar that we started
01309     //EndSlowJob();
01310 
01311     // We seem to have sorted the items ok
01312     return TRUE;
01313 }
01314 
01315 /********************************************************************************************
01316 
01317 >   static INT32 __cdecl PlugInManager::SortComparator(const void *Item1, const void *Item2)
01318 
01319     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01320     Created:    31/5/96
01321     Inputs:     Item1, Item2 - the items to be compared
01322     Returns:    negative (I am lesser), 0 (we are equal), or positive (I am greater)
01323                 result of comparing the items with the EntryNumber stored in each item in
01324                 the loaded colour list.
01325     Purpose:    'qsort' comparator function, used when quicksorting the loaded colour list
01326     SeeAlso:    PlugInManager::SortPlugInsAlphabetically();
01327                 ImportedColours::SortColoursByEntryNumber();
01328                 SuperGallery::SortComparator; SuperGallery::ApplySortNow;
01329 
01330 ********************************************************************************************/
01331 
01332 INT32 __cdecl PlugInManager::SortComparator(const void *Item1, const void *Item2)
01333 {
01334 //  if (Item1 == NULL || Item2 == NULL)
01335 //      return 0;
01336 
01337     PlugInItem *pItem1 = *((PlugInItem **)Item1);
01338     PlugInItem *pItem2 = *((PlugInItem **)Item2);
01339 
01340     if (pItem1 == NULL || pItem2 == NULL)
01341     {
01342         ERROR3("PlugIn::SortComparator bad pointers!"); 
01343         return 0;
01344     }
01345 
01346     INT32 Result = 0;
01347 
01348     // Sort on family name as the highest priority
01349     if (pItem1->GetFamilyName() < pItem2->GetFamilyName())
01350         return(-1);
01351 
01352     if ((pItem1->GetFamilyName() == pItem2->GetFamilyName()) &&
01353         (pItem1->GetPlugInName() < pItem2->GetPlugInName())
01354         )
01355         return(-1);
01356 
01357     if ((pItem1->GetFamilyName() == pItem2->GetFamilyName()) &&
01358         (pItem1->GetPlugInName() == pItem2->GetPlugInName())
01359         )
01360         return 0;
01361     
01362     // Must be greater than
01363     return 1;
01364 }
01365 
01366 /********************************************************************************************
01367 
01368 >   MenuItem * PlugInManager::FindPlugInMainMenuItem()
01369 
01370     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> & Re-writen by sjk 2/8/00 so it doesn't have to be a top level menu!
01371     Created:    20/1/97
01372     Inputs:     -
01373     Outputs:    -
01374     Returns:    Pointer to the plug-in main menu item if the operation completed successfully
01375                 NULL if it failed in some way.
01376     Purpose:    Finds the main plug-in menu item and returns a pointer to it.
01377 
01378 ********************************************************************************************/
01379 MenuItem * PlugInManager::FindPlugInMainMenuItem(MenuItem * pMainMenu)
01380 {
01381     if (pMainMenu == NULL)
01382         pMainMenu = GetMainMDIMenu();
01383 
01384     MenuItem * pMenu = pMainMenu->GetFirstMenuItem();
01385 
01386     String_256 PlugInMenu(OPTOKEN_PLUGINS_UNDO_MENU);
01387     String_32 Desc;
01388     while (pMenu)
01389     {
01390         MenuItem * pSub = pMenu->GetFirstMenuItem();
01391 
01392         if (pSub)
01393         {
01394             // check sub menu
01395             pSub = FindPlugInMainMenuItem(pMenu);
01396         }
01397 
01398         // Get the OpToken for the current menu item or returned menu item
01399         String_32 * pDesc = pSub ? pSub->GetOpToken() : pMenu->GetOpToken();
01400         if (pDesc)
01401             Desc = *pDesc;
01402         else
01403             Desc.Empty();
01404 
01405         // If the OpTokens match then it is the one that we desire
01406         if (Desc == PlugInMenu)
01407             return pSub ? pSub : pMenu;
01408 
01409         // Go to the next main menu item in the list
01410         pMenu = pMainMenu->GetNextMenuItem(pMenu);
01411     }
01412 
01413     return NULL;
01414 }
01415 
01416 /********************************************************************************************
01417 
01418 >   BOOL PlugInManager::DeleteMainMenuItems()
01419 
01420     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01421     Created:    20/1/97
01422     Inputs:     -
01423     Outputs:    -
01424     Returns:    True if the operation completed successfully
01425                 False if it failed in some way.
01426     Purpose:    Before the pathnames are parsed, we must clear out the main menu items of
01427                 all the current plug-ins.
01428 
01429 ********************************************************************************************/
01430 
01431 BOOL PlugInManager::DeleteMainMenuItems()
01432 {
01433 //#if NEW_NATIVE_FILTER
01434     // Search the main menu items until we find the plug-ins one
01435     MenuItem * pRootMenu = FindPlugInMainMenuItem();
01436     if (pRootMenu == NULL)
01437         return FALSE;
01438 
01439     // Completely destroy this menu
01440     BOOL ok = DestroyCamMenu(pRootMenu);
01441     
01442     // We must add back an item so that the menu is not empty otherwise
01443     // all hell will break loose if its left in this state!!!!
01444     // Create a menu item for the apply last item
01445 //  MenuItem * pApplyLastItem = CreateMenuItem(OPTOKEN_PLUGINS_PARSING, pRootMenu->GetMenuId(), FALSE);
01446     // If created ok then add this to the main plug-in's menu
01447 //  if (pApplyLastItem)
01448 //      pRootMenu->AddMenuItem(pApplyLastItem);
01449 
01450     // Just in case anything goes wrong between here and adding the new plug-ins back in
01451     // we must make sure that the plug-ins win menu is updated to mirror the kernel
01452     // menu structure that we have just blatted
01453     BOOL update = UpdatePlugInsWinMenu(pRootMenu);
01454 
01455 //#endif
01456     return TRUE;
01457 }
01458 
01459 /********************************************************************************************
01460 
01461 >   BOOL PlugInManager::CreateMainMenuItems()
01462 
01463     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01464     Created:    17/1/97
01465     Inputs:     -
01466     Outputs:    -
01467     Returns:    True if the operation completed successfully
01468                 False if it failed in some way.
01469     Purpose:    After the plug in list has been sorted alphabetically we must add each item
01470                 in the list to the main plug-in menu.
01471 
01472 ********************************************************************************************/
01473 
01474 BOOL PlugInManager::CreateMainMenuItems()
01475 {
01476 /*
01477 //#if NEW_NATIVE_FILTER
01478     // Search the main menu items until we find the plug-ins one
01479     MenuItem * pRootMenu = FindPlugInMainMenuItem();
01480     if (pRootMenu == NULL)
01481         return FALSE;
01482 
01483 //  // Create the plug-ins manager menu item...
01484 //  MenuItem * pPlugDlgMngr = CreateMenuItem(OPTOKEN_PLUGSDLG, pRootMenu->GetMenuId(), TRUE);
01485 //  // If created ok then add this to the main plug-in's menu
01486 //  if (pPlugDlgMngr)
01487 //      pRootMenu->AddMenuItem(pPlugDlgMngr);
01488 
01489 
01490 //  // Create a menu item for the apply last item
01491     MenuItem * pApplyLastItem = CreateMenuItem(OPTOKEN_PHOTOSHOP_APPLYLAST, pRootMenu->GetMenuId(), FALSE);
01492     // If created ok then add this to the main plug-in's menu
01493     if (pApplyLastItem)
01494         pRootMenu->AddMenuItem(pApplyLastItem);
01495 //
01496 
01497 
01498     // Go through all the handlers asking them to add in sections to the main menu
01499     PlugInHandler* pHandler = (PlugInHandler *)m_HandlersList.GetHead();
01500     PlugInHandler* pNextHandler = NULL;
01501     BOOL AddedOk = TRUE;
01502     BOOL AddSeparator = TRUE;
01503     while (pHandler != NULL)
01504     {
01505         // Try the next handler in the list
01506         pNextHandler = (PlugInHandler *)m_HandlersList.GetNext(pHandler);
01507 
01508         // If there is a next handler then we must add a separator to the
01509         // end of the list.
01510         // This does assume that only one handler will not want to add items to the end.
01511         // but this is good enough for now
01512         if (pNextHandler && pNextHandler->GoingToAddMainMenuItems())
01513             AddSeparator = TRUE;
01514         else
01515             AddSeparator = FALSE;
01516 
01517         // Ask the handler to add its required section of the menu to the list
01518         AddedOk = pHandler->CreateMainMenuItems(this, pRootMenu, AddSeparator);
01519     
01520         // Try the next handler in the list
01521         pHandler = pNextHandler;
01522     }
01523     
01524 
01525     // Make sure that the plug-ins win menu is updated to mirror the kernel
01526     // menu structure that we have just created
01527     BOOL update = UpdatePlugInsWinMenu(pRootMenu);
01528 */
01529 
01530 //#endif
01531     return TRUE;
01532 }

Generated on Sat Nov 10 03:46:31 2007 for Camelot by  doxygen 1.4.4