/**
/* Copyright (c) 2003by Marco Welti
/*
/* This document is bound by the QT Public License
/* (http://www.trolltech.com/licenses/qpl.html).
/* See License.txt for more information.
/*
/*
/*
/* ALL RIGHTS RESERVED.
/*
/* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
/* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
/* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
/* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
/* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
/* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
/* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
/***********************************************************************/
// ESBDSAddinImpl.cpp : Implementation of ESBDSAddinImpl
#include "stdafx.h"
#include "ESBDSAddin.h"
#include "DSAddin.h"
#include "CommandHandler.h"
#include "EventHandler.h"
#include "ComHelper.h"
#include <string>
using namespace std;
#include "ESBServer/src/ESBServer_i.c"
/////////////////////////////////////////////////////////////////////////////
// ESBDSAddinImpl
ESBDSAddinImpl::ESBDSAddinImpl()
: mApplication(NULL), mCommandHandler(NULL), mApplicationEventHandler(NULL),
mCookie(0), mClassRegistrationCookie(0)
{
DebugBox("ESBDSAddinImpl::ESBDSAddinImpl()");
}
HRESULT ESBDSAddinImpl::OnConnection(IApplication* application, VARIANT_BOOL isFirstTime, long dwCookie, VARIANT_BOOL* pbOnConnection)
{
SANDBOX_BEGIN("ESBDSAddinImpl", "OnConnection")
trace(sbox_class_name + "::" + sbox_method_name + "()");
*pbOnConnection = VARIANT_FALSE;
setupComStuff();
mApplication = application;
mCookie = dwCookie;
setupAddIn(isFirstTime == VARIANT_TRUE);
*pbOnConnection = VARIANT_TRUE;
return S_OK;
SANDBOX_END()
return E_FAIL;
}
HRESULT ESBDSAddinImpl::OnDisconnection(VARIANT_BOOL bLastTime)
{
trace("ESBDSAddinImpl::OnDisconnection()");
CoRevokeClassObject(mClassRegistrationCookie);
mApplication = NULL;
mCommandHandler = NULL;
mApplicationEventHandler = NULL;
return TRUE;
}
HRESULT ESBDSAddinImpl::gotoLine(BSTR filename, long line)
{
SANDBOX_BEGIN("ESBDSAddinImpl", "gotoLine()")
trace("ESBDSAddinImpl::gotoLine(): ");
CComPtr< IDispatch> tmp = 0;
cex_ = getApplication()->get_Documents(&tmp.p);
CComQIPtr< IDocuments> documents = tmp;
tmp = 0;
cex_ = documents->Open( filename, CComVariant(), CComVariant(), &tmp.p);
CComQIPtr< ITextDocument> document = tmp;
tmp = 0;
cex_ = document->get_Selection( &tmp.p);
CComQIPtr< ITextSelection> selection = tmp;
cex_ = selection->GoToLine(line, CComVariant(1));
SANDBOX_END()
return E_FAIL;
}
void ESBDSAddinImpl::setupComStuff()
{
CComPtr<IUnknown> pIUnk = 0;
cex_ = _Module.GetClassObject( GetObjectCLSID(), IID_IUnknown, reinterpret_cast<void**>(&pIUnk));
cex_ = CoRegisterClassObject(GetObjectCLSID(), pIUnk, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &mClassRegistrationCookie);
}
void ESBDSAddinImpl::setupAddIn(bool isFirstTime)
{
trace("ESBDSAddinImpl::setupAddIn()");
mCommandHandler = new_instance<CommandHandler>();
mCommandHandler->setAddIn(this);
mApplicationEventHandler = new_instance<ApplicationEventHandler>();
mApplicationEventHandler->setAddIn(this);
//tell vc about us....
cex_ = getApplication()->SetAddInInfo((long)_Module.GetModuleInstance(), mCommandHandler, IDR_TOOLBAR_MEDIUM, IDR_TOOLBAR_LARGE, mCookie);
//the event handler is already registered --> mApplicationEventHandler->setAddIn(this);
// register our commands with VC
VARIANT_BOOL bRet;
const size_t commandCnt = 6;
string commands[6][3] = {
{"ESBProperties", "\n\n\nEnable/Disable","setProperties"},
{"ESBShowOutlineBrowser", "\n\n\nShow Outline", "showOutlineBrowser"},
{"ESBShowHierarchyBrowser", "\n\n\nShow Hierarchy", "showHierarchyBrowser"},
{"ESBShowTypeBrowser", "\n\n\nShow Types", "showTypeBrowser"},
{"ESBShowMethodBrowser", "\n\n\nShow Methods", "showMethodBrowser"},
{"ESBShowWorkspaceBrowser", "\n\n\nShow Workspace", "showWorkspaceBrowser"},
};
for(int i = 0; i < commandCnt; i++) {
cex_ = getApplication()->AddCommand(CComBSTR((commands[i][0]+ commands[i][1]).c_str()), CComBSTR(commands[i][2].c_str()), i, mCookie, &bRet);
if(isFirstTime) {
cex_ = getApplication()->AddCommandBarButton(dsGlyph, CComBSTR(commands[i][0].c_str()), mCookie);
}
}
trace("... completed ESBDSAddinImpl::setupAddIn()");
}
CComPtr<IESBServerManager> ESBDSAddinImpl::getServerManager()
{
CComPtr<IESBServerManager> mgr;
try {
cex_ = mgr.CoCreateInstance(CLSID_ESBServerManagerCoClass);
} catch(...) {
if(getProperties().getMode() != 0 && MessageBox(NULL, "BeSweet server not running\nStart server Press Retry or Cancel to abort", "Be Sweet Addin", MB_RETRYCANCEL | MB_ICONERROR | MB_TOPMOST) == IDRETRY) {
return getServerManager();
} else {
throw;
}
}
return mgr;
}
CComPtr<IESBServer> ESBDSAddinImpl::getESBServer()
{
if(getProperties().getWorkspace().empty()) {
DebugBox("why is workspace-name empty ???");
return CComPtr<IESBServer>();
}
CComPtr<IESBServer> server;
string workspace= getProperties().getWorkspace();
cex_ = getServerManager()->getWorkspaceServer(CComBSTR(workspace.c_str()), &server);
return server;
};
void ESBDSAddinImpl::enable(bool enable)
{
getProperties().enabled(true);
}
void ESBDSAddinImpl::loadWorkspace(const std::string &workspace, const std::string &options)
{
trace("ESBDSAddinImpl::loadWorkspace(" + workspace + "," + options + ")");
string oldWorkspace = getProperties().getWorkspace();
string oldOptions = getProperties().getOptions();
getProperties().setWorkspace(workspace);
getProperties().setOptions(options);
if(getProperties().getOptions().empty()) {
::MessageBox(NULL, "No workspaces open !!", "Be Sweet Addin", MB_OK | MB_ICONEXCLAMATION | MB_TOPMOST);
throw runtime_error("No workspaces open !!");
}
if(handleDisabledState()) {
CComPtr<IESBServerManager> mgr = getServerManager();
if(!oldWorkspace.empty()) {
mgr->removeWorkspaceServer(CComBSTR(oldWorkspace.c_str()));
}
if(isWorkspaceValid()) {
CComPtr<IESBServer> server;
mgr->newWorkspaceServer(CComBSTR(getProperties().getWorkspace().c_str()), this, &server);
server->loadWorkspace(CComBSTR(getProperties().getOptions().c_str()));
} else {
MessageBox(0, ("workspace -" + getProperties().getWorkspace() + "- name empty...\nreopen Visual Studio workspace again!\n (File->Close Workspace, File->Recent Workspace)").c_str(), "Be Sweet Error", MB_OK | MB_ICONEXCLAMATION | MB_TOPMOST);
}
}
}
void ESBDSAddinImpl::closeWorkspace()
{
trace("ESBDSAddinImpl::closeWorkspace(" + getProperties().getWorkspace() + ")");
if(isWorkspaceValid()) {
getServerManager()->removeWorkspaceServer(CComBSTR(getProperties().getWorkspace().c_str()));
}
getProperties().setOptions("");
getProperties().setWorkspace("");
}
void ESBDSAddinImpl::reopenWorkspace()
{
trace("ESBDSAddinImpl::reopenWorkspace()");
if(handleDisabledState()) {
loadWorkspace(getProperties().getWorkspace(), getProperties().getOptions());
}
}
void ESBDSAddinImpl::documentChanged(const std::string &filename)
{
trace("ESBDSAddinImpl::documentChanged(" + filename + ")");
if(isEnabled()) {
getESBServer()->fileContentChanged(CComBSTR(filename.c_str()));
}
}
void ESBDSAddinImpl::documentActivated(const std::string &filename)
{
trace("ESBDSAddinImpl::documentActivated(" + filename + ")");
if(isEnabled()) {
getESBServer()->showFileOutline(CComBSTR(filename.c_str()));
}
}
void ESBDSAddinImpl::showBrowser(const std::string &browser, const std::string arg)
{
trace("ESBDSAddinImpl::showBrowser(" + browser + "," + arg + ")");
if(handleDisabledState()) {
getESBServer()->showBrowser(CComBSTR(browser.c_str()), CComBSTR(arg.c_str()));
}
}
bool ESBDSAddinImpl::handleDisabledState()
{
if(!isEnabled()) {
if(mProperties.getMode() == 0 /*silent*/) {
return false;
}
if(MessageBox(NULL, "Enable the BeSweet Addin", "BeSweet", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST) == IDNO) {
return false;
}
enable(true);
if(!isWorkspaceValid()) {
MessageBox(NULL, "Workspace empty\n Please reload Visual Studio workspace again!\n (File->Close Workspace, File->Recent Workspace)", "BeSweet", MB_OK | MB_ICONERROR);
return false;
}
reopenWorkspace();
}
return true;
}
void ESBDSAddinImpl::modifyProperties()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if(mProperties.DoModal() == IDOK && mProperties.needsReload()) {
reopenWorkspace();
}
}
void ESBDSAddinImpl::trace(const std::string &text)
{
if(getProperties().getMode() == 2) {
::MessageBox(NULL, text.c_str(), "BeSweet Trace", MB_OK | MB_ICONINFORMATION | MB_TOPMOST);
}
}