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 }