/*
* Copyright 2004 Perforce Software. All rights reserved.
*
* Developed by Data Shades Ltd.
*/
#define P43DS_MAIN
#include "P4GTMax.h"
#include "PerforceActionTable.h"
#include "P4GTUtils.h"
#include <iMenuMan.h>
#define PERFORCE_MENU_NAME _T("&Perforce")
/*
* Plugin initialisation
*/
DWORD P43ds::Start()
{
P4GT_Startup();
callbacks = new CallbackManager();
IMenuManager* manager = GetCOREInterface()->GetMenuManager();
IMenuBarContext* menuContext = ( IMenuBarContext* ) manager->GetContext( kMainMenuBar );
IMenu* mainMenu = menuContext->GetMenu();
// Get and activate action table
ActionTable *table = GetCOREInterface()->GetActionManager()->FindTable( PerforceActions );
GetCOREInterface()->GetActionManager()->ActivateActionTable( new PerforceActionCallBack(), PerforceActions );
// Make sure context is registered
manager->RegisterMenuBarContext( P43DS_MENU_CONTEXT_ID, PERFORCE_MENU_NAME );
// Check if menu is already installed
if ( manager->FindMenu( PERFORCE_MENU_NAME ) == NULL ) {
InstallPerforceMenu( manager, mainMenu, table );
}
// Return if you want remain loaded or not
return GUPRESULT_KEEP;
}
void P43ds::Stop( )
{
P4GT_Shutdown();
delete callbacks;
// Remove Perforce menu on shutdown so that the plugin
// can be uninstalled without the menu remaining behind
RemovePerforceMenu();
}
DWORD_PTR P43ds::Control( DWORD parameter ) {
return 0;
}
IOResult P43ds::Save( ISave *isave )
{
return IO_OK;
}
IOResult P43ds::Load( ILoad *iload )
{
return IO_OK;
}
void P43ds::AddMenuOption( IMenu *menu, ActionTable *table, int id )
{
IMenuItem* item = GetIMenuItem();
ActionItem *action = table->GetAction( id );
item->SetActionItem( action );
menu->AddItem( item );
}
void P43ds::AddMenuSep( IMenu *menu )
{
IMenuItem* sep = GetIMenuItem();
sep->ActAsSeparator();
menu->AddItem( sep );
}
void P43ds::InstallPerforceMenu( IMenuManager* manager, IMenu* mainMenu, ActionTable *table )
{
IMenu* perforceMenu = GetIMenu();
perforceMenu->SetTitle( PERFORCE_MENU_NAME );
// Register menu with manager
manager->RegisterMenu( perforceMenu, 0 );
// Associate menu with context
IMenuBarContext* context = (IMenuBarContext*) GetCOREInterface()->GetMenuManager()->GetContext( P43DS_MENU_CONTEXT_ID );
context->SetMenu( perforceMenu );
AddMenuOption( perforceMenu, table, ADD_TO_PERFORCE_ACTION );
AddMenuOption( perforceMenu, table, CHECK_OUT_PERFORCE_ACTION );
AddMenuOption( perforceMenu, table, CHECK_IN_PERFORCE_ACTION);
AddMenuOption( perforceMenu, table, LOCK_UNLOCK_PERFORCE_ACTION);
AddMenuOption( perforceMenu, table, UNDO_ADD_CHECK_OUT_PERFORCE_ACTION);
AddMenuSep( perforceMenu );
AddMenuOption( perforceMenu, table, LAST_RESULTS_PERFORCE_ACTION );
AddMenuOption( perforceMenu, table, DOCUMENT_STATUS_PERFORCE_ACTION );
AddMenuOption( perforceMenu, table, DOCUMENT_HISTORY_PERFORCE_ACTION );
AddMenuOption( perforceMenu, table, CHECKED_OUT_PERFORCE_ACTION );
AddMenuOption( perforceMenu, table, INFO_PERFORCE_ACTION );
AddMenuSep( perforceMenu );
AddMenuOption( perforceMenu, table, OPEN_DEPOT_PERFORCE_ACTION );
AddMenuSep( perforceMenu );
AddMenuOption( perforceMenu, table, OPTIONS_PERFORCE_ACTION );
AddMenuOption( perforceMenu, table, HELP_PERFORCE_ACTION );
AddMenuOption( perforceMenu, table, ABOUT_PERFORCE_ACTION );
AddMenuSep( perforceMenu );
AddMenuOption( perforceMenu, table, SERVER_ONLINE_ACTION );
#ifndef LANG_ja
const TCHAR* menuAnchor = _T( "&Help" );
#else
const TCHAR* menuAnchor = _T( "MAXScript(&M)" );
#endif
// Insert new menu
for ( int i=0; i<mainMenu->NumItems(); i++ ) {
IMenuItem* item = mainMenu->GetItem( i );
IMenu* subMenu = item->GetSubMenu();
//Insert before Help menu
if ( subMenu != NULL ) { //&& subMenu->GetTitle() == ( menuAnchor ) ) { // const wchar_t * title = subMenu->GetTitle().data();
if ( subMenu->GetTitle() == MSTR(menuAnchor) ) /// <<<=== problem lies here
{
IMenuItem* perforceItem = GetIMenuItem();
perforceItem->SetSubMenu( perforceMenu );
mainMenu->AddItem( perforceItem, i );
break;
}
}
}
manager->UpdateMenuBar();
// Save the file after installing the menu so that when we
// go to uninstall it, we don't have a race condition between
// the normal menu directory and the custom menu directory. This
// only happens if: we're not already using the custom directory
// (a clean install), we use the plugin once, delete it then restart
// Max. If you use Max twice with the plugin installed then remove it,
// there's no problem.
//
// Default menu file:
// c:\Program Files\Autodesk\3ds Max 2010\ui\MaxStartUI.mnu
// Custom menu location:
// c:\Users\username\AppData\local\Autodesk\3dsMax\2010 - 32bit\enu\UI\MaxStartUI.mnu
// The "[CustomMenus]" key of the ini file tells you which file it's using:
// c:\Users\username\AppData\local\Autodesk\3dsMax\2010 - 32bit\enu\3dsmax.ini
const TCHAR* menuFileName = manager->GetMenuFile();
manager->SaveMenuFile( menuFileName );
}
void P43ds::RemovePerforceMenu()
{
IMenuManager* manager = GetCOREInterface()->GetMenuManager();
IMenu* menu = manager->FindMenu( PERFORCE_MENU_NAME );
if ( menu ) {
while ( menu->NumItems() > 0) {
menu->RemoveItem( 0 );
}
// Remove menu from context
IMenuBarContext* context = (IMenuBarContext*)manager->GetContext( P43DS_MENU_CONTEXT_ID );
context->SetMenu( NULL );
manager->UnRegisterMenu( menu );
// Make sure the changes are saved to the menu file
const TCHAR* menuFileName = manager->GetMenuFile();
manager->SaveMenuFile( menuFileName );
}
}
ActionTable *P43ds::CreateActionTable()
{
PerforceActionTable *table = new PerforceActionTable( hInstance );
IActionManager* manager = GetCOREInterface()->GetActionManager();
manager->RegisterActionContext( PerforceContext, _T( "Perforce" ) );
manager->RegisterActionTable( table );
manager->ActivateActionTable( new PerforceActionCallBack(), PerforceActions );
return table;
}