// $Id: debugdlg.cpp 1357 2006-06-25 11:31:45Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // debugdlg.cpp - The debug dialogue ////////////////////////////////////////////////////////////////////////////////////////////// // This dialogue appears on the debug menu in debug builds only // // It offers a dropdown list of 'command groups'. Selecting one of these then shows a list // // of available debugging commands which the user can invoke. Output from these commands // // will generally appear in the TRACE output. This offers a simple way of adding debug // // test code to the camelot menu tree so it can be easily triggered when you're ready for // // it. Add your code to the last 4 functions in this file // // SetGroupList - Sets the list of available groups // // SetCommandList - Sets the list of commands for the given group // // SetCommandValue - Sets the value field and help string for a given command // // InvokeCommand - Applies the given command from the given group, using whatever // // value the user typed into the 'value' field. // ////////////////////////////////////////////////////////////////////////////////////////////// #include "camtypes.h" #if _DEBUG // Includes for the dialogue itself #include "debugdlg.h" // kernel header //#include "dbgdlg.h" // winoil resource header //#include "jason.h" // For _R(IDS_DEBUGDLG) #include "progress.h" // For the progress hourglass //#include "resource.h" // For _R(IDS_CANCEL) // Includes for specific debug commands #include "colcontx.h" // Colour separation commands #include "colormgr.h" #include "colplate.h" //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "app.h" // Bitmap colour matching commands - in camtypes.h [AUTOMATICALLY REMOVED] //#include "bmplist.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "bitmap.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "bitmpinf.h" #include "prnmks.h" // Printer marks #include "princomp.h" // Print component (for always overprint black) #include "printctl.h" //#include "bmplist.h" // For bitmap list dumps - in camtypes.h [AUTOMATICALLY REMOVED] #include "nodecont.h" // ShadowType //#include "attrmgr.h" // For Stroke Provider commands - in camtypes.h [AUTOMATICALLY REMOVED] #include "groupops.h" #include "lineattr.h" #include "mkshapes.h" #include "pathstrk.h" #include "ppairbsh.h" #include "ppstroke.h" #include "ppvecstr.h" #include "strkattr.h" #include "valfunc.h" #include "objcache.h" // Object cache #include "cachrand.h" #include "cachweak.h" #include "cachfifo.h" //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "opimgset.h" #include "opliveeffects.h" //#include "xpehost.h" //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include #include #if FALSE #include #include "ccc.h" // <---- not here #endif //#include "mainfrm.h" CC_IMPLEMENT_DYNCREATE(DebugDlg, DialogOp) #define new CAM_DEBUG_NEW const INT32 DebugDlg::IDD = _R(IDD_DEBUGDLG); const CDlgMode DebugDlg::Mode = MODELESS; // Remember which command was selected last time we were open static INT32 LastSelectedIndex = 0; static INT32 LastSelectedGroup = 8; // StrokeProviders. Geez I'm lazy! static BOOL CloseAndExecute = FALSE; #if FALSE static TCHAR g_szScriptToExecute[] = TEXT("ScriptToExecute"); static String_256 g_ScriptToExecute; // Default to VBScript static TCHAR g_szScriptEngineCLSID[] = TEXT("B54F3741-5B07-11CF-A4B0-00AA004A55E8"); static String_256 g_ScriptEngineCLSID; static IActiveScript* m_pScriptEngine = NULL; static IActiveScriptParse* m_pScriptParser = NULL; // {BB1A2AE1-A4F9-11cf-8F20-00805F2CD064} static const IID IID_IActiveScript = { 0xbb1a2ae1, 0xa4f9, 0x11cf, {0x8f, 0x20, 0x0, 0x80, 0x5f, 0x2c, 0xd0, 0x64}}; // {BB1A2AE2-A4F9-11cf-8F20-00805F2CD064} static const IID IID_IActiveScriptParse = { 0xbb1a2ae2, 0xa4f9, 0x11cf, {0x8f, 0x20, 0x0, 0x80, 0x5f, 0x2c, 0xd0, 0x64}}; HRESULT InitializeScriptEngine(const GUID& ScriptCLSID) { HRESULT Result = S_OK; Result = CoCreateInstance(ScriptCLSID, NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void**)&m_pScriptEngine); if (SUCCEEDED(Result)) { Result = m_pScriptEngine->QueryInterface(IID_IActiveScriptParse, (void**)&m_pScriptParser); } if (SUCCEEDED(Result)) { Result = m_pScriptEngine->SetScriptState(SCRIPTSTATE_INITIALIZED); } if (SUCCEEDED(Result)) { Result = m_pScriptParser->InitNew(); } if (SUCCEEDED(Result)) { Result = m_pScriptEngine->AddNamedItem(OLESTR("Application"), SCRIPTITEM_ISVISIBLE); } return Result; } HRESULT ParseScript(const StringBase& ScriptName) { HRESULT Result = S_OK; ScriptName; // dosomething withthis BSTR bstrScript; EXCEPINFO ExceptionInfo; Result = m_pScriptParser->ParseScriptText(bstrScript, NULL,NULL,NULL,0,0,SCRIPTTEXT_ISVISIBLE,NULL,&ExceptionInfo); if (SUCCEEDED(Result)) { Result = m_pScriptEngine->SetScriptState(SCRIPTSTATE_STARTED); } return Result; } void ExecuteScript(const StringBase& ScriptName) { HRESULT Result = S_OK; CLSID ScriptCLSID; LPOLESTR OSScriptCLSID = (LPOLESTR)((LPTSTR)g_ScriptEngineCLSID); Result = ::CLSIDFromString(OSScriptCLSID, &ScriptCLSID); // LPOLESTR lpsz, //Pointer to the string representation of the CLSID if (SUCCEEDED(Result)) { Result = InitializeScriptEngine(ScriptCLSID); } if (SUCCEEDED(Result)) { Result = ParseScript(ScriptName); } } CC_IMPLEMENT_MEMDUMP(ConcurrencyController, CC_CLASS_MEMDUMP) ConcurrencyController::ConcurrencyController() { } ConcurrencyController::~ConcurrencyController() { } void ExecuteScript(const StringBase& ScriptName) { AfxMessageBox(TEXT("Not this week")); } #endif // Automation /******************************************************************************************** > DebugDlg::DebugDlg(): DialogOp(DebugDlg::IDD, DebugDlg::Mode) Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Purpose: DebugDlg constructor. ********************************************************************************************/ DebugDlg::DebugDlg() : DialogOp(DebugDlg::IDD, DebugDlg::Mode) { } /******************************************************************************************** > DebugDlg::~DebugDlg() Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Purpose: You'll never guess... ********************************************************************************************/ DebugDlg::~DebugDlg() { } /******************************************************************************************** > MsgResult DebugDlg::Message( CDlgMessage DlgMsg, CGadgetID Gadget) Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Inputs: Message - the message Outputs: - Returns: OK if it is happy Purpose: Handles all the debug dialog's messages Errors: - SeeAlso: - ********************************************************************************************/ MsgResult DebugDlg::Message(Msg* Message) { if (IS_OUR_DIALOG_MSG(Message)) { DialogMsg* Msg = (DialogMsg*)Message; BOOL EndDlg = FALSE; switch (Msg->DlgMsg) { case DIM_CREATE: { // Fill in the combobox of available command groups SetGroupList(); // Fill in the list of available commands SetCommandList(LastSelectedGroup); // And then fill in the value/description fields as appropriate to whatever // option is now selected in the list. INT32 Index = GetSelectedValueIndex(_R(IDC_DEBUGDLG_LIST)); SetCommandValue(LastSelectedGroup, Index); SetKeyboardFocus (_R(IDC_DEBUGDLG_VALUE1)) ; HighlightText (_R(IDC_DEBUGDLG_VALUE1)) ; CloseAndExecute = FALSE; } break; case DIM_COMMIT: case DIM_SOFT_COMMIT: { LastSelectedGroup = GetSelectedValueIndex(_R(IDC_DEBUGDLG_GROUP)); LastSelectedIndex = GetSelectedValueIndex(_R(IDC_DEBUGDLG_LIST)); String_256 Value = GetStringGadgetValue(_R(IDC_DEBUGDLG_VALUE1)); InvokeCommand(LastSelectedGroup, LastSelectedIndex, &Value); // And update the window state to reflect any change SetCommandValue(LastSelectedGroup, LastSelectedIndex); } break; case DIM_CANCEL: EndDlg = TRUE; break; case DIM_SELECTION_CHANGED: if (Msg->GadgetID == _R(IDC_DEBUGDLG_LIST)) { LastSelectedIndex = GetSelectedValueIndex(_R(IDC_DEBUGDLG_LIST)); SetCommandValue(LastSelectedGroup, LastSelectedIndex); } else if (Msg->GadgetID == _R(IDC_DEBUGDLG_GROUP)) { LastSelectedGroup = GetSelectedValueIndex(_R(IDC_DEBUGDLG_GROUP)); SetCommandList(LastSelectedGroup); LastSelectedIndex = 0; SetCommandValue(LastSelectedGroup, LastSelectedIndex); } break; case DIM_SELECTION_CHANGED_COMMIT: if (Msg->GadgetID == _R(IDC_DEBUGDLG_LIST)) { LastSelectedGroup = GetSelectedValueIndex(_R(IDC_DEBUGDLG_GROUP)); LastSelectedIndex = GetSelectedValueIndex(_R(IDC_DEBUGDLG_LIST)); SetCommandValue(LastSelectedGroup, LastSelectedIndex); String_256 Value = GetStringGadgetValue(_R(IDC_DEBUGDLG_VALUE1)); InvokeCommand(LastSelectedGroup, LastSelectedIndex, &Value); // And update the window state to reflect any change SetCommandValue(LastSelectedGroup, LastSelectedIndex); } break; default: // Do nothing break; } if (EndDlg) { Close(); End(); return(OK); } if (CloseAndExecute) { CloseAndExecute=FALSE; Close(); End(); InvokeLateCommand(LastSelectedGroup, LastSelectedIndex); return(OK); } return (DLG_EAT_IF_HUNGRY(Msg)); } return OK; } /******************************************************************************************** > OpState DebugDlg::GetState(String_256*, OpDescriptor*) Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Purpose: DebugDlg GetState method ********************************************************************************************/ OpState DebugDlg::GetState(String_256*, OpDescriptor*) { OpState OpSt; return(OpSt); } /******************************************************************************************** > BOOL DebugDlg::Init(void) Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Purpose: DebugDlg Init method. Called by sginit.cpp ********************************************************************************************/ BOOL DebugDlg::Init(void) { #if FALSE Camelot.DeclarePref( "DebugFlags", g_szScriptToExecute, &g_ScriptToExecute); Camelot.DeclarePref( "DebugFlags", g_szScriptEngineCLSID, &g_ScriptEngineCLSID); #endif return (RegisterOpDescriptor( 0, _R(IDS_DEBUGDLG), CC_RUNTIME_CLASS(DebugDlg), OPTOKEN_DEBUGDLG, DebugDlg::GetState, 0, // help ID 0 // bubble ID ) ); } /******************************************************************************************** > BOOL DebugDlg::Create() Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Returns: TRUE if successful, else FALSE Purpose: DebugDlg create method ********************************************************************************************/ BOOL DebugDlg::Create() { return(DialogOp::Create()); } /******************************************************************************************** > void DebugDlg::Do(OpDescriptor *Bob) Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Inputs: OpDescriptor of this op Purpose: Creates then opens the dialog ********************************************************************************************/ void DebugDlg::Do(OpDescriptor *Bob) { if (!Create()) { InformError(); End(); return; } Open(); } /******************************************************************************************** > void DebugDlg::SetGroupList(void) Author: Jason_Williams (Xara Group Ltd) Created: 20/5/96 Purpose: Sets the list of debug dialogue command groups ADD YOUR OWN GROUP NAMES TO THE END OF THE LIST Note the index of the group in the list - this is the GroupIndex used in the related functions (below). Notes: This only appears in DEBUG builds, so it's fine to inline strings ********************************************************************************************/ void DebugDlg::SetGroupList(void) { String_256 Temp; DeleteAllValues(_R(IDC_DEBUGDLG_GROUP)); #define ADDGROUP(name) { Temp = TEXT(name); SetStringGadgetValue(_R(IDC_DEBUGDLG_GROUP), Temp); } ADDGROUP("Imagesetting (Jason)"); // Group 0 ADDGROUP("Jason personal debug"); // Group 1 ADDGROUP("Mikes personal debug"); // Group 2 ADDGROUP("Wills bitmap debug"); // Group 3 ADDGROUP("Low memory debug"); // Group 4 ADDGROUP("Operation history dump"); // Group 5 // Neville 2/10/97 removal of vector stroking bits #ifdef VECTOR_STROKING ADDGROUP("Shadow rendering tests"); // Group 6 ADDGROUP("Stroke providers") // Group 7 ADDGROUP("Vector strokes") // Group 8 ADDGROUP("ObjectCache tests"); // Group 9 #endif // VECTOR_STROKING #if FALSE ADDGROUP("Script Execution"); // Group 10 #endif ADDGROUP("Phil Debug"); // Group 10 ADDGROUP("Gerry Debug"); // Group 11 // Add more groups here... #undef ADDGROUP // Select the last item the user selected, in the hope that this is useful SetSelectedValueIndex(_R(IDC_DEBUGDLG_GROUP), LastSelectedGroup); } /******************************************************************************************** > void DebugDlg::SetCommandList(INT32 GroupIndex) Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Inputs: GroupIndex - indicates which command group is to be used Purpose: Sets the list of debug dialogue commands ADD YOUR OWN COMMAND NAMES TO THE END OF THE LIST Note the index of the command in the list - this is the CommandIndex used in the related functions (below). Notes: This only appears in DEBUG builds, so it's fine to inline strings ********************************************************************************************/ void DebugDlg::SetCommandList(INT32 GroupIndex) { String_256 Temp; DeleteAllValues(_R(IDC_DEBUGDLG_LIST)); #define ADDCOMMAND(name) { Temp = TEXT(name); SetStringGadgetValue(_R(IDC_DEBUGDLG_LIST), Temp); } switch (GroupIndex) { case 0: // Jason's colour separation controls ------------------------------------ ADDCOMMAND("Normal document view"); // Command 0 ADDCOMMAND(" Composite preview"); // Command 1 ADDCOMMAND(" Cyan preview"); // Command 2 ADDCOMMAND(" Magenta preview"); // Command 3 ADDCOMMAND(" Yellow preview"); // Command 4 ADDCOMMAND(" Key preview"); // Command 5 ADDCOMMAND(" Spot plate"); // Command 6 ADDCOMMAND("Monochrome toggle"); // Command 7 ADDCOMMAND("Photographic negative toggle"); // Command 8 ADDCOMMAND("Overprint toggle"); // Command 9 ADDCOMMAND("Always overprint black"); // Command 10 break; case 1: // Jason's misc controls ------------------------------------------------- ADDCOMMAND("Write line to debug stream"); // Command 0 break; case 2: // Mike's misc controls -------------------------------------------------- ADDCOMMAND("Initialise print marks"); // Command 0 ADDCOMMAND("Add doc print mark"); // Command 1 ADDCOMMAND("Add a colour ramp entry"); // Command 2 ADDCOMMAND("Add a transparency ramp entry"); // Command 3 break; case 3: // Will's debug controls ------------------------------------------------- ADDCOMMAND("Dump global bitmap list"); // Command 0 ADDCOMMAND("Dump greyscale bitmap list"); // Command 1 break; case 4: // Low memory testing (by Peter) ----------------------------------------- ADDCOMMAND("Enable Low Memory Testing"); // Command 0 ADDCOMMAND(" Fail all claims"); // Command 1 ADDCOMMAND(" Fail all claims after n bytes"); // Command 2 ADDCOMMAND("Memory dump"); // Command 3 ADDCOMMAND("Camelot memory check"); // Command 4 ADDCOMMAND("MFC memory check (not for SmartHeap users)"); // Command 5 break; case 5: // Operation history dump (by Peter) ------------------------------------- ADDCOMMAND("Dump last operation"); // Command 0 ADDCOMMAND("Dump all operations"); // Command 1 break; // Neville 2/10/97 removal of vector stroking bits #ifdef VECTOR_STROKING case 6: ADDCOMMAND("Random positioning"); // Command 0 ADDCOMMAND("Linewidth"); // Command 1 ADDCOMMAND("StrokePathToPath"); // Command 2 ADDCOMMAND("FlattenExpand"); // Command 3 ADDCOMMAND("Bitmap Shadow"); // Command 4 break; case 7: // Stroke provider tests (Jason) ----------------------------------------- ADDCOMMAND("Old-style line"); // Command 0 ADDCOMMAND("Constant width stroke"); // Command 1 ADDCOMMAND("Linear Ramp"); // Command 2 ADDCOMMAND("S Ramp"); // Command 3 ADDCOMMAND("Blip"); // Command 4 ADDCOMMAND("Ellipse"); // Command 5 ADDCOMMAND("Teardrop"); // Command 6 ADDCOMMAND("Thumbtack"); // Command 7 ADDCOMMAND("Airbrush - S"); // Command 8 ADDCOMMAND("Airbrush - linear"); // Command 9 ADDCOMMAND("Airbrush - random"); // Command 10 ADDCOMMAND("Airbrush - L"); // Command 11 break; case 8: // Stroke provider tests (Jason) ----------------------------------------- ADDCOMMAND("Create new vector stroke"); // Command 0 ADDCOMMAND("Create new repeating vector stroke"); // Command 1 ADDCOMMAND("Apply last created vector stroke"); // Command 2 break; case 9: // Object cache tests (Olivier) ------------------------------------------ ADDCOMMAND("Fill up the cache"); // Command 1 ADDCOMMAND("Add fixed size objects"); // Command 2 ADDCOMMAND("Add randomed size objects") // Command 3 ADDCOMMAND("Add a big object"); // Command 4 break; #endif // VECTOR_STROKING #if FALSE case 10: // Script Execution (Colin) ------------------------------------------ ADDCOMMAND("Run the Script"); // Command 0 break; // Add further command groups here... #endif case 10: ADDCOMMAND("Apply default Live Effect (blur)"); // Command 0 ADDCOMMAND("Invoke IXaraPhotoEditor3"); // Command 1 ADDCOMMAND("End IXaraPhotoEditor3 Session"); // Command 2 ADDCOMMAND("Dump Bitmap Cache"); // Command 3 ADDCOMMAND("Create new spread"); // Command 4 break; case 11: // Gerry Debug ------------------------------------------ ADDCOMMAND("Command 0"); // Command 0 break; } #undef ADDCOMMMAND // Select the last item the user selected, in the hope that this is useful SetSelectedValueIndex(_R(IDC_DEBUGDLG_LIST), LastSelectedIndex); } /******************************************************************************************** > void DebugDlg::SetCommandValue(INT32 GroupIndex, INT32 CommandIndex) Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Inputs: GroupIndex - indicates which command group is to be used CommandIndex - the index of the command in the list - see DebugDlg::SetCommandList Purpose: Whenever a new command is chosen from the list, this function is called to fill in the "value" field with whatever number you like. ADD AN ENTRY TO THE SWITCH STATEMENT TO HANDLE YOUR COMMAND Set "Description" to a helpful description string Set "Value" to the current value (if any) associated with your command Set "IsEditable" if you want the value to be editable Notes: This only appears in DEBUG builds, so it's fine to inline strings ********************************************************************************************/ void DebugDlg::SetCommandValue(INT32 GroupIndex, INT32 CommandIndex) { String_256 Description(TEXT("Does an unknown debug option")); String_256 Value(TEXT("0")); BOOL IsEditable = FALSE; switch(GroupIndex) { case 0: // Jason's colour separation controls ------------------------------------ switch (CommandIndex) { case 0: Description = TEXT("Disables global colour separations"); break; case 1: Description = TEXT("Changes to a composite WYSIWYG print preview"); break; case 2: Description = TEXT("Changes to CYAN colour separation"); break; case 3: Description = TEXT("Changes to MAGENTA colour separation"); break; case 4: Description = TEXT("Changes to YELLOW colour separation"); break; case 5: Description = TEXT("Changes to KEY colour separation"); break; case 6: { Description = TEXT("Changes to specified SPOT separation"); Value = TEXT("1"); ColourContext *cc = ColourManager::GetColourContext(COLOURMODEL_RGBT, DocView::GetSelected()); ColourPlate *SepDescriptor = cc->GetColourPlate(); if (SepDescriptor && SepDescriptor->GetType() == COLOURPLATE_SPOT) { IndexedColour *pSpotCol = SepDescriptor->GetSpotColour(); if (pSpotCol) { // Count the spot colours until we find the required one ColourList* pColList = Document::GetSelected()->GetIndexedColours(); IndexedColour* pCol = (IndexedColour*) pColList->GetHead(); INT32 Count = 0; while (pCol != NULL) { if (pCol->GetType() == COLOURTYPE_SPOT && !pCol->IsDeleted()) { Count++; } if (pCol == pSpotCol) break; pCol = (IndexedColour*) pColList->GetNext(pCol); } if (pCol && Count > 0) Value._MakeMsg(_T("#1%d"), Count); } } // And allow the user to edit the string as they see fit IsEditable = TRUE; } break; case 7: { Description = TEXT("Toggles colour output to/from monochrome"); ColourContext *cc = ColourManager::GetColourContext(COLOURMODEL_RGBT, DocView::GetSelected()); ColourPlate *SepDescriptor = cc->GetColourPlate(); BOOL Mono = (SepDescriptor != NULL) ? SepDescriptor->IsMonochrome() : FALSE; Value = (Mono) ? TEXT("Enabled") : TEXT("Disabled"); } break; case 8: { Description = TEXT("Toggles colour output to/from photographic negative"); ColourContext *cc = ColourManager::GetColourContext(COLOURMODEL_RGBT, DocView::GetSelected()); ColourPlate *SepDescriptor = cc->GetColourPlate(); BOOL Negate = (SepDescriptor != NULL) ? SepDescriptor->IsNegative() : FALSE; Value = (Negate) ? TEXT("Enabled") : TEXT("Disabled"); } break; case 9: Description = TEXT("Toggles plate overprint for the current plate"); break; case 10: Description = TEXT("Toggles 'Always overprint black' state"); { Document *Bob = Document::GetSelected(); if (Bob != NULL) { PrintComponent *Sally = (PrintComponent *) Bob->GetDocComponent(CC_RUNTIME_CLASS(PrintComponent)); if (Sally != NULL) { PrintControl *Ernest = Sally->GetPrintControl(); if (Ernest != NULL) { TypesetInfo *Mavis = Ernest->GetTypesetInfo(); if (Mavis != NULL) { Value = (Mavis->AlwaysOverprintBlack()) ? TEXT("Enabled") : TEXT("Disabled"); } } } } } break; } break; case 1: // Jason's misc controls ------------------------------------------------- switch (CommandIndex) { case 0: Description = TEXT("Writes the 'value' string to the debug stream"); // Set up a default string in the value field Value = TEXT("--- trace marker inserted by user ---"); // And allow the user to edit the string as they see fit IsEditable = TRUE; break; } break; #ifndef WEBSTER // Neville 6/8/97 case 2: // Mikes's misc controls ------------------------------------------------- switch (CommandIndex) { case 0: Description = TEXT("Initialises the print mark managers cache"); break; case 1: Description = TEXT("Adds the first print mark to the selected doc"); break; case 2: Description = TEXT("Adds a new colour to a grad fills colour ramp"); // set up a default string in the value field Value = TEXT("128"); IsEditable = TRUE; break; case 3: Description = TEXT("Adds a new transp to a grad transp ramp"); // set up a default string in the value field Value = TEXT("128"); IsEditable = TRUE; break; } break; #endif // WEBSTER case 3: // Will's bitmap controls ------------------------------------------------- switch (CommandIndex) { case 0: Description = TEXT("Dumps the current global bitmap list"); break; case 1: Description = TEXT("Dumps the current greyscale bitmap list"); break; } break; case 4: // Low memory Testing (Peter) --------------------------------------------- switch (CommandIndex) { case 0: Description = TEXT("Enable or disbale low memory testing"); Value = (SimpleCCObject::GetLowMemoryState()) ? TEXT("Enabled") : TEXT("Disabled"); break; case 1: Description = TEXT("Fails all memory claims."); if (SimpleCCObject::GetLowMemoryState() && SimpleCCObject::GetLowMemoryLimit()==0) Value = TEXT("Enabled"); else Value = TEXT("Disabled"); break; case 2: Description = TEXT("Fails memory claims after the specified number of bytes have been claimed."); { String_32 Number; Number._MakeMsg(_T("#1%lu"), SimpleCCObject::GetLowMemoryLimit()); Value = Number; IsEditable = TRUE; break; } case 3: Description = TEXT("Lists all allocated objects to the TRACE display."); break; case 4: Description = TEXT("Checks guardwords on Camelot memory allocations."); break; case 5: Description = TEXT("MFC memory allocation check."); break; } break; case 5: // Operation history listing ------------------------------------------------- switch (CommandIndex) { case 0: Description = TEXT("Dump actions in the last operation (in the selected document) to TRACE display"); break; case 1: Description = TEXT("Dump actions in all operations (in the selected document) to TRACE display"); break; } break; #ifdef VECTOR_STROKING // Neville 6/8/97 case 6: switch (CommandIndex) { case 0: Description = TEXT("Render n copies around a centrepoint (Fails on large penumbras)"); break; case 1: Description = TEXT("Render decreasing linewidths with decreasing transparency (Fails on transparent shadows)"); break; case 2: Description = TEXT("Render StrokePathToPath linewidths (Far too slow (on complex shapes))"); break; case 3: Description = TEXT("Flatten and expand paths (Fails on inverted paths)"); break; case 4: Description = TEXT("Bitmap shadower Using new Shadower COM Object"); break; } break; case 7: // Stroke provider tests (Jason) ----------------------------------------- switch (CommandIndex) { case 0: Description = TEXT("Reset the stroke to 'old style line' (the default)"); break; case 1: Description = TEXT("Apply a constant width variable-width stroke attribute"); break; case 2: Description = TEXT("Apply a linear ramp variable-width stroke attribute"); break; case 3: Description = TEXT("Apply an 'S' ramp variable-width stroke attribute"); break; case 4: Description = TEXT("Apply a 'blip' variable-width stroke attribute"); break; case 5: Description = TEXT("Apply an 'ellipse' variable-width stroke attribute"); break; case 6: Description = TEXT("Apply a 'teardrop' variable-width stroke attribute"); break; case 7: Description = TEXT("Apply a 'thumbtack' variable-width stroke attribute"); break; case 8: Description = TEXT("Apply an airbrush stroke attribute"); break; case 9: Description = TEXT("Apply an airbrush stroke attribute"); break; case 10:Description = TEXT("Apply an airbrush stroke attribute"); break; case 11:Description = TEXT("Apply an airbrush stroke attribute"); break; } break; case 8: switch (CommandIndex) { case 0: Description = TEXT("Set the vector stroke brush from the selection"); break; case 1: Description = TEXT("Set the vector stroke brush, and make it repeating"); break; case 2: Description = TEXT("Apply the last vector stroke you created"); break; } break; case 9: switch (CommandIndex) { case 0: Description = TEXT("Add as many objects as needed to fill up the cache");break; case 1: Description = TEXT("Add several objects which size increase");break; case 2: Description = TEXT("Add several objects with a random size");break; case 3: Description = TEXT("Add an object bigger than the cachesize");break; } break; #endif // VECTOR_STROKING #if FALSE case 10: // Colin's script executioner ------------------------------------------------- switch (CommandIndex) { case 0: Description = TEXT("Run a Script"); break; } break; #endif case 10: // Phil's LiveEffects test ------------------------------------------------- switch (CommandIndex) { case 0: Description = TEXT("Apply the default debug effect to the selection"); break; case 1: Description = TEXT("Call the new XPE interface for modeless editing"); break; case 2: Description = TEXT("End the XPE editing session successfully"); break; case 3: Description = TEXT("Dump a description of the bitmap cache to the debug output"); break; case 4: Description = TEXT("Create a second spread! OOER!"); break; } break; case 11: // Gerry Debug------------------------------------------------- switch (CommandIndex) { case 0: Description = TEXT("Command 0"); break; } break; // case n: // Add your own command group(s) here } SetStringGadgetValue(_R(IDC_DEBUGDLG_COMMENT), Description); SetStringGadgetValue(_R(IDC_DEBUGDLG_VALUE1), Value); EnableGadget(_R(IDC_DEBUGDLG_VALUE1), IsEditable); } class NodeShadowController; /******************************************************************************************** > void DebugDlg::InvokeCommand(INT32 GroupIndex, INT32 CommandIndex, StringBase *NewValue) Author: Jason_Williams (Xara Group Ltd) Created: 8/5/96 Inputs: GroupIndex - indicates which command group is to be used CommandIndex - the index of the command in the list - see DebugDlg::SetCommandList NewValue - A string entered by the usert in the "Value" field of the dialogue. (e.g. this is used by Jason's CommandIndex 0 to output a string into the debug stream) Purpose: Invokes one of the debug commands. ADD AN ENTRY TO THE SWITCH STATEMENT TO HANDLE YOUR COMMAND Notes: This only appears in DEBUG builds ********************************************************************************************/ void DebugDlg::InvokeCommand(INT32 GroupIndex, INT32 CommandIndex, StringBase *NewValue) { String_256 Desc(TEXT("Doing debug command...")); Progress Hourglass((StringBase *) &Desc, -1, FALSE); // Hourglass while we're busy switch (GroupIndex) { case 0: // Jason's colour separation controls ------------------------------------ switch (CommandIndex) { case 0: // Normal document view if (DocView::GetSelected() != NULL) { // Remove any attached ColourPlate, and redraw all affected thingies DocView::GetSelected()->SetColourPlate(NULL); ColourManager::SelViewContextHasChanged(); } break; case 1: SetNewColourPlate(COLOURPLATE_COMPOSITE,0,0); break; case 2: SetNewColourPlate(COLOURPLATE_CYAN, 0,0); break; case 3: SetNewColourPlate(COLOURPLATE_MAGENTA, 0,0); break; case 4: SetNewColourPlate(COLOURPLATE_YELLOW, 0,0); break; case 5: SetNewColourPlate(COLOURPLATE_KEY, 0,0); break; case 6: { INT32 Pos = 0; INT32 SpotPlate = NewValue->ConvertToInteger(Pos); SetNewColourPlate(COLOURPLATE_SPOT, 0,SpotPlate); } break; case 7: SetNewColourPlate(COLOURPLATE_NONE, 1,0); break; case 8: SetNewColourPlate(COLOURPLATE_NONE, 2,0); break; case 9: SetNewColourPlate(COLOURPLATE_NONE, 3,0); break; case 10: { Document *Bob = Document::GetSelected(); if (Bob != NULL) { PrintComponent *Sally = (PrintComponent *) Bob->GetDocComponent(CC_RUNTIME_CLASS(PrintComponent)); if (Sally != NULL) { PrintControl *Ernest = Sally->GetPrintControl(); if (Ernest != NULL) { TypesetInfo *Mavis = Ernest->GetTypesetInfo(); if (Mavis != NULL) { Mavis->SetOverprintBlack(!Mavis->AlwaysOverprintBlack()); } } } } } break; default: ERROR3("Unknown debug command"); break; } break; case 1: // Jason's misc controls ------------------------------------------------- switch (CommandIndex) { case 0: // Output the "value" string (entered by the user) into the trace output. // I find this invaluable when dumping screeds of debug stuff, in order to // mark positions in the output so I can find the important info amongst // all the chaff. TRACE( _T("%s\n"), (TCHAR *) (*NewValue)); break; default: ERROR3("Unknown debug command"); break; } break; #ifndef WEBSTER // Neville 6/8/97 case 2: // Mike's misc controls ------------------------------------------------- switch (CommandIndex) { case 0: { // We need to execute this one after the dialogue has closed. // CloseAndExecute=TRUE; PrintMarksMan* pMarksMan = GetApplication()->GetMarksManager(); if (pMarksMan!=NULL) pMarksMan->ConstructCache(); } break; case 1: { PrintMarksMan* pMarksMan = GetApplication()->GetMarksManager(); if (pMarksMan!=NULL) { // get the first mark from the cache PrintMarkItem *pMarkItem = pMarksMan->PMMCache.GetFirstMark(); if (pMarkItem!=NULL) { UINT32 Handle=pMarkItem->GetHandle(); Document* pDoc = Document::GetSelected(); if (pDoc) pMarksMan->AddMarkToDoc(Handle,pDoc); } } } break; case 2: { // ok we need to find the selected object and alter its attribute to get a // colour fill applied. How do we do this? // hmm I'll work it out in a moment. // Well like this really... AttrColFillRampChange* pAttrib = new AttrColFillRampChange; if (pAttrib!=NULL) { INT32 Pos = 0; INT32 NewVal = NewValue->ConvertToInteger(Pos); float pos = ((float)NewVal) / 255.0f; if (pos<0.0f) pos=0.0f; if (pos>1.0f) pos=1.0f; // ok full yellow in the middle please srand((unsigned)time(NULL)); INT32 r,g,b; r = rand(); g = rand(); b = rand(); r &= 0xFF; g &= 0xFF; g &= 0xFF; DocColour TestColour(r,g,b); pAttrib->InitForColourAdd(&TestColour, pos); // AttributeSelected knows what to do with a selected attribute AttributeManager::AttributeSelected(NULL, pAttrib); } } break; case 3: { // Well like this really... AttrTranspFillRampChange* pAttrib = new AttrTranspFillRampChange; if (pAttrib!=NULL) { INT32 Pos = 0; INT32 NewVal = NewValue->ConvertToInteger(Pos); float pos = ((float)NewVal) / 255.0f; if (pos<0.0f) pos=0.0f; if (pos>1.0f) pos=1.0f; // ok full yellow in the middle please srand((unsigned)time(NULL)); UINT32 t = (UINT32)rand(); t = t & 0xFF; pAttrib->InitForTranspAdd(t, pos); // AttributeSelected knows what to do with a selected attribute AttributeManager::AttributeSelected(NULL, pAttrib); } } break; default: ERROR3("Unknown debug command"); break; } break; #endif // WEBSTER case 3: // Will's bitmap controls ------------------------------------------------- switch (CommandIndex) { case 0: { GlobalBitmapList* pBmpList = GetApplication()->GetGlobalBitmapList(); if (pBmpList) pBmpList->DumpGlobalBitmapListToTrace(); } break; // case 1: // { // GreyscaleBitmapList* pGreyList = // GetApplication()->GetGlobalBitmapList()->GetGreyscaleBitmapList(); // if (pGreyList) // pGreyList->DumpGreyscaleBitmapListToTrace(); // } // break; default: ERROR3("Unknown debug command"); break; } break; case 4 : switch (CommandIndex) { case 0: { SimpleCCObject::EnableLowMemoryTesting(); } break; case 1: { SimpleCCObject::EnableLowMemoryTesting(); SimpleCCObject::SetClaimLimit(0); } break; case 2: { INT32 Pos = 0; INT32 NewVal = NewValue->ConvertToInteger(Pos); SimpleCCObject::SetClaimLimit(NewVal); } break; case 3: { SimpleCCObject::MemoryDump(); } break; case 4: { SimpleCCObject::CheckMemory(TRUE); } break; case 5: { // BOOL MemOK = AfxCheckMemory(); // ERROR3IF(!MemOK, "MFC Memory check failure (look at TRACE output)"); } break; default: ERROR3("Unknown/Unimplemented debug command"); break; } break; case 5: switch (CommandIndex) { case 0: GetApplication()->DumpLastOp(); break; case 1: GetApplication()->DumpAllOps(); break; default: ERROR3("Unknown/Unimplemented debug command"); break; } break; #ifdef VECTOR_STROKING // Neville 6/8/97 case 6: // NodeShadowController::RenderMethod = (ShadowType)CommandIndex; break; case 7: // Stroke provider tests (Jason) ----------------------------------------- { AttrStrokeType *pStrokeAttr = new AttrStrokeType; PathProcessorStroke *pProcessor = NULL; AttrVariableWidth *pWidthAttr = new AttrVariableWidth; VariableWidthID Function = VarWidth_NotPredefined; ValueFunction *pFunction = NULL; // Check to see if there is a path processor already applied - if it is, the // options which only need to change the width function will not overwrite // the stroker (allowing you to change the shape on an Airbrushed stroke, etc) BOOL NeedToApplyType = FALSE; // BLOCK { SelRange *Selection = Camelot.FindSelection(); ERROR3IF(Selection == NULL, "No Selection SelRange!?!"); NodeAttribute *pNode = NULL; switch(Selection->FindCommonAttribute(CC_RUNTIME_CLASS(AttrStrokeType), &pNode)) { case SelRange::ATTR_COMMON: if (pNode != NULL) // Let's just be really safe { // There is a common attribute - but we must check if it supplies // a proper path processor (or if it is just an old-style line) StrokeTypeAttrValue *pSAV = (StrokeTypeAttrValue *) ((AttrStrokeType *)pNode)->GetAttributeValue(); if (pSAV == NULL || pSAV->GetPathProcessor() == NULL) NeedToApplyType = TRUE; } else NeedToApplyType = TRUE; break; default: NeedToApplyType = TRUE; break; } } switch (CommandIndex) { case 0: // leave processor and function undefined break; // Different width functions case 1: Function = VarWidth_Constant; break; case 2: Function = VarWidth_LinRamp; break; case 3: Function = VarWidth_SRamp; break; case 4: pFunction = new ValueFunctionBlip; break; case 5: pFunction = new ValueFunctionEllipse; break; case 6: pFunction = new ValueFunctionTeardrop; break; case 7: pFunction = new ValueFunctionThumbtack; break; case 8: // Airbrush stroke type case 9: case 10: case 11: pProcessor = new PathProcessorStrokeAirbrush; switch(CommandIndex) { case 8: // Airbrush stroke type break; case 9: { ValueFunction *pFunc = new ValueFunctionRampLinear(1.0, 0.0); ((PathProcessorStrokeAirbrush *)pProcessor)->SetIntensityFunction(pFunc); } break; case 10: { ValueFunction *pFunc = new ValueFunctionRandom(0, 0.0, 0.8); ((PathProcessorStrokeAirbrush *)pProcessor)->SetIntensityFunction(pFunc); } break; case 11: { ValueFunction *pFunc = new ValueFunctionRampL; ((PathProcessorStrokeAirbrush *)pProcessor)->SetIntensityFunction(pFunc); } break; } // BLOCK { // Airbrush defaults to using round caps & joins AttrJoinType *pJoinAttr = new AttrJoinType(); if (pJoinAttr != NULL) { pJoinAttr->Value.JoinType = RoundJoin; AttributeManager::AttributeSelected(pJoinAttr); } AttrStartCap *pCapAttr = new AttrStartCap; if (pCapAttr != NULL) { pCapAttr->Value.StartCap = LineCapRound; AttributeManager::AttributeSelected(pCapAttr); } } break; } if (CommandIndex != 0 && pProcessor == NULL) { // We only apply a variable-width PathProcessor if there was not already one // applied to to the selection. This allows us to change the width function // on airbrushed strokes, etc, without losing the stroke type if (NeedToApplyType) pProcessor = new PathProcessorStroke; else { delete pStrokeAttr; pStrokeAttr = NULL; } } if (pStrokeAttr != NULL && pProcessor != NULL) ((StrokeTypeAttrValue *)pStrokeAttr->GetAttributeValue())->SetPathProcessor(pProcessor); if (pWidthAttr != NULL) { if (Function != VarWidth_NotPredefined) ((VariableWidthAttrValue *)pWidthAttr->GetAttributeValue())->SetWidthFunction(Function); else if (pFunction != NULL) ((VariableWidthAttrValue *)pWidthAttr->GetAttributeValue())->SetWidthFunction(pFunction); else { // We're not trying to override the width, so vape our width attr delete pWidthAttr; pWidthAttr = NULL; } } // Now apply the attributes if (pStrokeAttr != NULL) AttributeManager::AttributeSelected(pStrokeAttr); if (pWidthAttr != NULL) AttributeManager::AttributeSelected(pWidthAttr); } break; case 8: { switch (CommandIndex) { case 0: case 1: // Rip up the selection and use that as the brush in future, please { // First, Make Shapes on everything so they're all simple paths String_256 Desc("Building new stroke brush..."); Progress::Start(FALSE, &Desc); OpDescriptor *pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_MAKE_SHAPES); if (pOp != NULL) pOp->Invoke(); // Second, Group everything pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_GROUP); if (pOp != NULL) pOp->Invoke(); // Finally, create a new brush PathStrokerVector::BodgeRipSelection((CommandIndex == 0) ? FALSE : TRUE); Progress::Stop(); } break; case 2: { AttrStrokeType *pStrokeAttr = new AttrStrokeType; PathProcessorStrokeVector *pProcessor = new PathProcessorStrokeVector; if (pStrokeAttr != NULL && pProcessor != NULL) { pProcessor->SetStrokeDefinition(PathStrokerVector::GetCurrentBrush()); ((StrokeTypeAttrValue *)pStrokeAttr->GetAttributeValue())->SetPathProcessor(pProcessor); AttributeManager::AttributeSelected(pStrokeAttr); } } break; } } break; case 9: { // Get the ObjectCache ObjectCache* pObjCache = GetApplication()->GetObjectCache(); if (pObjCache == NULL) return; WORD hObj = 0; switch(CommandIndex) { case 0: // Add 50 objects which size is sizeof(DummyCachedObject) { for (INT32 i=0;i<=50;i++) { DummyCachedObject* a = new DummyCachedObject; pObjCache->Add(a); } } break; case 1: // Add 50 objects which size is 'i' { for (INT32 i=0;i<=50;i++) { DummyCachedObject* b = new DummyCachedObject(i); pObjCache->Add(b); } } break; case 2: // Add 50 objects which size is rand()%50+1 { srand((unsigned)time(NULL)); for (INT32 i=1;i<=50;i++) { DummyCachedObject* c = new DummyCachedObject(rand()%50+1); pObjCache->Add(c); } } break; case 3: // Add an object which size is bigger than the cache size { DummyCachedObject* u = new DummyCachedObject(55); hObj = pObjCache->Add(u); } break; default: ERROR3("Unknown/Unimplemented debug command"); break; } } break; #endif // VECTOR_STROKING #if FALSE case 10: { ExecuteScript(g_ScriptToExecute); } break; #endif case 10: { switch(CommandIndex) { PORTNOTE("LiveEffects", "Removed use of LiveEffects") #ifndef EXCLUDE_FROM_XARALX case 0: { OpDescriptor* pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_APPLY_LIVEEFFECT); if (pOp != NULL) { OpLiveEffectParam Param; Param.bIsDestructive = FALSE; Param.strOpUnique = String(_T("Enhance")); pOp->Invoke(&Param); } } break; case 1: { OpDescriptor* pOp = OpDescriptor::FindOpDescriptor(OPTOKEN_EDIT_LIVEEFFECT); if (pOp != NULL) { OpLiveEffectParam Param; Param.bIsDestructive = FALSE; Param.strOpUnique = String(_T("Enhance")); pOp->Invoke(&Param); } } break; #endif case 2: { // XPEHost::EndEditSession(TRUE); } break; case 3: { CBitmapCache* pCache = GetApplication()->GetBitmapCache(); pCache->DebugDump(); } break; case 4: { //#if NEW_PASTEBOARD Spread* pSpread = Document::GetSelectedSpread(); Spread* pNewSpread = NULL; pSpread->NodeCopy((Node**)&pNewSpread); if (pNewSpread) { pNewSpread->AttachNode(pSpread, NEXT); pSpread->AdjustPasteboards(); } //#else // InformWarning(_R(IDS_SPREADTESTWARNING)); //#endif } break; } } break; case 11: // Gerry Debug { switch(CommandIndex) { case 0: { // Set the size of a slot to something weird // OILFixedDockingBar* pDockBar = (OILFixedDockingBar*)(GetMainFrame()->GetDockBar(DOCKBAR_RIGHT)); // pDockBar->SetSlotSize(0, 150); // GetMainFrame()->RecalcLayout(); } break; } } break; // case n: // Add other command group(s) here... } } /******************************************************************************************** > void DebugDlg::InvokeLateCommand(INT32 GroupIndex, INT32 CommandIndex) Author: Mike_Kenny (Xara Group Ltd) Created: 03/08/96 Inputs: GroupIndex - indicates which command group is to be used CommandIndex - the index of the command in the list - see DebugDlg::SetCommandList Purpose: Invokes one of the debug commands after the dialogue has been closed and the dialogue op has been ended. If you need to trigger an operation from this debug dialogue, just write your standard command handler to set the global CloseAndExecute variable, and add you command to this 'Late' command execution table. You will notice when you Apply/Execute your command the dialogue will disappear which is not that much of a disaster. Notes: This only appears in DEBUG builds ********************************************************************************************/ void DebugDlg::InvokeLateCommand(INT32 GroupIndex, INT32 CommandIndex) { String_256 Desc(TEXT("Doing debug command...")); Progress Hourglass((StringBase *) &Desc, -1, FALSE); // Hourglass while we're busy switch (GroupIndex) { case 0: // Jason's colour separation controls ------------------------------------ break; case 1: // Jason's misc controls ------------------------------------------------- break; case 2: // Mike's misc controls ------------------------------------------------- switch (CommandIndex) { case 0: { // PrintMarksMan* pMarksMan = GetApplication()->GetMarksManager(); // if (pMarksMan!=NULL) // pMarksMan->ConstructCache(); } break; } break; // case 3: // Add other late command group(s) here... } } #endif // if _DEBUG