/*------------ Model.idl ------------*/
// Model.idl : IDL source for Model.dll
//
// This file will be processed by the MIDL tool to
// produce the type library (Model.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
// ***********************************************************************
//
//
//
[
object,
uuid(7700BD00-1020-11D1-8304-0060979B3BF2),
pointer_default(unique)
]
interface IModelSecuritySink : IUnknown
{
[id(1)] HRESULT PasswordDialog(long pObject, BSTR* pPassword);
};
// ---------------------------------------------------------------------
// ModelLib
[
uuid(2E638520-61B4-11d2-B7DB-0060979B3BF2),
version(1.0),
]
library ModelLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
interface IModelSecuritySink;
};
/*------------ TBook.cpp ------------*/
#include "StdAfx.h"
// MAIN INCLUDE
#ifndef T_BOOK
#include "TBook.h"
#endif
// OTHER INCLUDES
#ifndef T_PAGE
#include "TPage.h"
#endif
#ifndef T_SUMMARY
#include "TSummary.h"
#endif
#ifndef T_INDEX
#include "TIndex.h"
#endif
#ifndef T_DB_PTR_ARRAY
#include "TDBPtrArray.h"
#endif
#ifndef T_PRIVATE_DB_ITERATOR
#include "TPrivateDBIterator.h"
#endif
#ifndef T_PSEPRO_DB
#include "TPseProDB.h"
#endif
#ifndef T_PTR_ARRAY
#include "TPtrArray.h"
#endif
#ifndef T_PROPERTY_OBJECT
#include "TPropertyObject.h"
#endif
#include "TPagePropertiesConstants.h"
#include "TBookPropertiesConstants.h"
#include "TPageIdentifiersConstants.h"
#include "TAppBrandingInfo.h"
#include "TUserInfo.h"
#include "TAppVersionInfo.h"
#include "TAnonymousGUID.h"
/***********************/
/***** class TBook *****/
/***********************/
_7X_DB_OBJECT_IMPLEMENT_ID(TBook, TMedium)
/****************************/
// SPECIFIC PSE PRO STUFF
boolean TBook::bStuff = TBook::init_relocation_hooks();
boolean TBook::init_relocation_hooks()
{
// Uncomment this if you want to debug 'fetch' ops
/*
os_ts::set_fetch_hook(
os_typespec::before_hook,
TBook::fetch_before,
(void*)NULL
);
os_ts::set_fetch_hook(
os_typespec::after_hook,
TBook::fetch_after,
(void*)NULL
);
*/
return true;
}
void TBook::fetch_before(void* object, os_int32, void* data, void*)
{
TBook* book = (TBook*)object;
TRACE1("TBook::fetch_before - [0x%x]\n",(void*)book);
}
void TBook::fetch_after(void* object, os_int32, void* data, void*)
{
TBook* book = (TBook*)object;
TRACE1("TBook::fetch_after - [0x%x]\n",(void*)book);
}
// CONSTRUCTORS
TBook::TBook()
: TMedium()
{
DB_ESTABLISH_FAULT_HANDLER
DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TDBPtrArray,fPageList,this);
DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TSummary,fSummary,this);
fSummary->setBook(this);
addPage(fSummary); // We want the root page to be in the flat list
DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TIndex,fIndex,this);
fIndex->setBook(this); // We need to do that because the Index is not under the Summary
fPagesBeforeSummaryList = null;
// We directly add the 'author' page to the pages before the summary
TPage* authorPage = null;
DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TPage,authorPage,this);
authorPage->setBook(this);
TPropertyObject* defaultProp = authorPage->getDefaultProperty();
defaultProp->putStringField(T_PAGE_PROPERTY_PAGELET_TYPE, TString("property"));
// Besides, the author page is considered SYTEM page
long systemFlag = F_PAGE_SYSTEM;
defaultProp->putLongField(T_PAGE_DEFAULT_PROPERTY_BEHAVIOUR, systemFlag);
// And the author page is attributed an identifier
TString authorIdentifier = T_AUTHOR_PAGE_IDENTIFIER;
defaultProp->putStringField(T_PAGE_DEFAULT_PROPERTY_IDENTIFIER, authorIdentifier);
addPageBeforeSummary(authorPage);
// Let's set the various properties default values
/******************/
/* Default Values */
/******************/
TPropertyObject* lBookDefaultProperty = null;
lBookDefaultProperty = getDefaultProperty();
ASSERT(lBookDefaultProperty);
USES_CONVERSION;
CLSID lBookID = CLSID_NULL;
TAnonymousGUID::CoCreateGuid(&lBookID);
CComBSTR lBookIDStr(lBookID);
lBookDefaultProperty->putStringField(T_BOOK_DEFAULT_PROPERTY_BOOK_ID, W2CT(lBookIDStr));
/*********************/
/* Author Properties */
/*********************/
TPropertyObject* lAuthorProperty = null;
DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TPropertyObject,lAuthorProperty,this);
TAppBrandingInfo lBrandingInfo;
TUserInfo lUserInfo;
TAppVersionInfo lAppInfo;
lAuthorProperty->putStringField(T_BOOK_AUTHOR_PROPERTY_AUTHOR_USER, lUserInfo.GetUserID());
lAuthorProperty->putStringField(T_BOOK_AUTHOR_PROPERTY_AUTHOR_SKU, lAppInfo.GetSKU());
lAuthorProperty->putStringField(T_BOOK_AUTHOR_PROPERTY_AUTHOR_PARTNER, lBrandingInfo.GetPartnerID());
setProperty(T_BOOK_AUTHOR_PROPERTY,lAuthorProperty);
DB_END_FAULT_HANDLER
}
// DESTRUCTORS
TBook::~TBook()
{
DB_ESTABLISH_FAULT_HANDLER
// Here I destroy my pointer fields not directly
// handled by a model
DB_DESTROY_OBJECT(fPageList);
DB_DESTROY_OBJECT(fPagesBeforeSummaryList);
DB_END_FAULT_HANDLER
}
// METHODS
TSummary* TBook::getSummary()
{
DB_ESTABLISH_FAULT_HANDLER
return fSummary;
DB_END_FAULT_HANDLER
// If fail
return null;
}
void TBook::setSummary(TSummary* pSummary)
{
DB_ESTABLISH_FAULT_HANDLER
fSummary = pSummary;
DB_END_FAULT_HANDLER
}
int TBook::getPageCount()
{
DB_ESTABLISH_FAULT_HANDLER
return fPageList->size();
//return fSummary->GetTotalPageCount();
DB_END_FAULT_HANDLER
// If fail
return 0;
}
void TBook::setBookStyle(int pBookStyle)
{
DB_ESTABLISH_FAULT_HANDLER
fBookStyle = pBookStyle;
DB_END_FAULT_HANDLER
}
int TBook::getBookStyle()
{
DB_ESTABLISH_FAULT_HANDLER
return fBookStyle;
DB_END_FAULT_HANDLER
// If fail
return 0;
}
TIndex* TBook::getIndex()
{
DB_ESTABLISH_FAULT_HANDLER
return fIndex;
DB_END_FAULT_HANDLER
// If fail
return null;
}
void TBook::setIndex(TIndex* pIndex)
{
DB_ESTABLISH_FAULT_HANDLER
fIndex = pIndex;
DB_END_FAULT_HANDLER
}
int TBook::getPagesBeforeSummaryCount()
{
DB_ESTABLISH_FAULT_HANDLER
if (fPagesBeforeSummaryList != null)
{
return fPagesBeforeSummaryList->size();
}
DB_END_FAULT_HANDLER
// If fail
return 0;
}
void TBook::addPageBeforeSummary(TPage* pPage)
{
DB_ESTABLISH_FAULT_HANDLER
if (pPage != null)
{
if (fPagesBeforeSummaryList == null)
{
DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TDBPtrArray,fPagesBeforeSummaryList,this);
}
fPagesBeforeSummaryList->addElement(pPage);
}
DB_END_FAULT_HANDLER
}
void TBook::removePageBeforeSummary(TPage* pPage)
{
DB_ESTABLISH_FAULT_HANDLER
if (pPage != null)
{
if (fPagesBeforeSummaryList != null)
{
fPagesBeforeSummaryList->removeElement(pPage);
}
}
DB_END_FAULT_HANDLER
}
TPage* TBook::getPageBeforeSummary(int pIndex)
{
DB_ESTABLISH_FAULT_HANDLER
if ((pIndex > 0) && (pIndex <= fPagesBeforeSummaryList->size()))
{
return (TPage *)fPagesBeforeSummaryList->elementAt(pIndex - 1);
}
DB_END_FAULT_HANDLER
// If fail
return null;
}
boolean TBook::isPageBeforeSummary(TPage* pPage)
{
DB_ESTABLISH_FAULT_HANDLER
if (pPage != null)
{
return fPagesBeforeSummaryList->contains(pPage);
}
DB_END_FAULT_HANDLER
// If fail
return false;
}
TPage* TBook::getPrimaryPage()
{
DB_ESTABLISH_FAULT_HANDLER
return m_pPrimaryPage;
DB_END_FAULT_HANDLER
// If fail
return null;
}
void TBook::setPrimaryPage(TPage* pPage)
{
DB_ESTABLISH_FAULT_HANDLER
m_pPrimaryPage = pPage;
DB_END_FAULT_HANDLER
}
TPage* TBook::getSecondaryPage()
{
DB_ESTABLISH_FAULT_HANDLER
return m_pSecondaryPage;
DB_END_FAULT_HANDLER
// If fail
return null;
}
void TBook::setSecondaryPage(TPage* pPage)
{
DB_ESTABLISH_FAULT_HANDLER
m_pSecondaryPage = pPage;
DB_END_FAULT_HANDLER
}
TPage* TBook::getSelectedPage()
{
DB_ESTABLISH_FAULT_HANDLER
return m_pSelectedPage;
DB_END_FAULT_HANDLER
// If fail
return null;
}
void TBook::setSelectedPage(TPage* pPage)
{
DB_ESTABLISH_FAULT_HANDLER
m_pSelectedPage = pPage;
DB_END_FAULT_HANDLER
}
//////////
// Methods dealing with the fPageList
//////////
void TBook::addPage(TPage* pPage)
{
DB_ESTABLISH_FAULT_HANDLER
if (pPage != null)
{
if (fPageList != null)
{
// We must handle here the fact that the pPage
// may be a chapter and have sub-pages and no forget
//to actually add ALL the pages
fPageList->addElement(pPage);
TPtrIterator* pageIter = pPage->getPages();
if (pageIter != null)
{
while (pageIter->hasMoreElements())
{
TPage* curPage = (TPage *)pageIter->nextElement();
this->addPage(curPage);
}
delete pageIter;
}
}
}
DB_END_FAULT_HANDLER
}
void TBook::insertPage(TPage* pPage, int pPos)
{
DB_ESTABLISH_FAULT_HANDLER
if (pPage != null)
{
if (fPageList != null)
{
// We must handle here the fact that the pPage
// may be a chapter and have sub-pages and no forget
//to actually insert ALL the pages
TPtrIterator* pageIter = pPage->getPages();
if ((pageIter != null) && (pageIter->hasMoreElements()))
{
delete pageIter; // it was just to see if subPages or not
TPtrArray tmpArray;
insertPageHelper((TPtrArray *)&tmpArray,pPage);
// Here I have a filled tmpArray
int insertPos = pPos;
TPtrIterator* tmpArrayIter = tmpArray.elements();
while (tmpArrayIter->hasMoreElements())
{
TPage* curPage = (TPage *)tmpArrayIter->nextElement();
fPageList->insertElementAt(curPage,insertPos-1);
insertPos++;
}
delete tmpArrayIter;
}
else
{
fPageList->insertElementAt(pPage,pPos-1);
}
}
}
DB_END_FAULT_HANDLER
}
void TBook::insertPageHelper(TPtrArray* pArray, TPage* pPage)
{
DB_ESTABLISH_FAULT_HANDLER
pArray->addElement(pPage);
TPtrIterator* pageIter = pPage->getPages();
if (pageIter != null)
{
while (pageIter->hasMoreElements())
{
TPage* curPage = (TPage *)pageIter->nextElement();
insertPageHelper(pArray,curPage);
}
delete pageIter;
}
DB_END_FAULT_HANDLER
}
boolean TBook::removePage(TPage* pPage)
{
boolean lRemoved = false;
DB_ESTABLISH_FAULT_HANDLER
if ((pPage != null) && (fPageList != null))
{
// We must handle here the fact that the pPage
// may be a chapter and have sub-pages and no forget
//to actually remove ALL the pages
lRemoved = fPageList->removeElement(pPage);
/*
TPtrIterator* pageIter = pPage->getPages();
if (pageIter != null)
{
while (pageIter->hasMoreElements())
{
TPage* curPage = (TPage *)pageIter->nextElement();
this->removePage(curPage);
}
delete pageIter;
}
*/
}
DB_END_FAULT_HANDLER
return lRemoved;
}
TPage* TBook::getPage(int pIndex)
{
DB_ESTABLISH_FAULT_HANDLER
if ((pIndex > 0) && (pIndex <= fPageList->size()))
{
TPage* thePage;
thePage = (TPage *)fPageList->elementAt(pIndex - 1);
ATLASSERT(thePage);
if (thePage == NULL)
{
fPageList->removeElementAt(pIndex - 1);
}
return thePage;
}
DB_END_FAULT_HANDLER
return null;
}
int TBook::getPageIndex(TPage* pPage)
{
DB_ESTABLISH_FAULT_HANDLER
if ((pPage != null) && (fPageList != null))
{
return fPageList->indexOf(pPage) + 1;
}
DB_END_FAULT_HANDLER
return 0;
}/*------------ TBook.h ------------*/
#ifndef T_BOOK
#define T_BOOK
#ifndef T_MEDIUM
#include "TMedium.h"
#endif
// INCLUDES
#ifndef T_STRING
#include "TString.h"
#endif
#include
// CLASS IMPORTS
class TString;
class TDBString;
class TMedium;
class TPage;
class TSummary;
class TIndex;
class TDBPtrArray;
class TPtrArray;
//#include "TPtrArray.h"
/***********************/
/***** class TBook *****/
/***********************/
class TBook : public TMedium
{
// SPECIFIC PSE PRO STUFF
public:
static void fetch_before(void*, os_int32, void*, void*);
static void fetch_after(void*, os_int32, void*, void*);
static boolean init_relocation_hooks();
static boolean bStuff;
// CONSTRUCTORS
public:
TBook(); //default
protected:
private:
// DESTRUCTORS
public:
~TBook();
protected:
private:
// FIELDS
public:
protected:
private:
int fLastPrimaryPage; //the last opened page, in order to open the book at this page the next time
TDBPtrArray* fPagesBeforeSummaryList; //list of the special pages located before the summary
TSummary* fSummary; //the summary is the tree-root of the chapter/page hierarchy
TIndex* fIndex; //the index is the last page of the book (the last item in the fPageList in fact)
int fBookStyle; // Index of book style for interface
TDBPtrArray* fPageList; //useful to speed-up page number display on the bookbinding
TPage* m_pPrimaryPage;
TPage* m_pSecondaryPage;
TPage* m_pSelectedPage;
// METHODS
public:
TSummary* getSummary();
void setSummary(TSummary* pSummary);
int getPageCount(); //total nb. of pages in the book
TIndex* getIndex();
void setIndex(TIndex* pIndex);
int getBookStyle();
void setBookStyle(int pBookStyle);
TPage* getPrimaryPage();
void setPrimaryPage(TPage* pPage);
TPage* getSecondaryPage();
void setSecondaryPage(TPage* pPage);
TPage* getSelectedPage();
void setSelectedPage(TPage* pPage);
int getPagesBeforeSummaryCount();
void addPageBeforeSummary(TPage* pPage);
void removePageBeforeSummary(TPage* pPage);
TPage* getPageBeforeSummary(int pIndex); // 1-based
boolean isPageBeforeSummary(TPage* pPage);
// Methods dealing with the fPageList
void addPage(TPage* pPage);
void insertPage(TPage* pPage, int pPos); // 1-based
boolean removePage(TPage* pPage);
TPage* getPage(int pIndex); // 1-based
int getPageIndex(TPage* pPage); // 1-based
public:
_7X_DB_OBJECT_DECLARE_ID()
protected:
private:
void insertPageHelper(TPtrArray* pArray, TPage* pPage);
}; // class TBook
#endif // T_BOOK
/*------------ THighlighter.cpp ------------*/
#include "StdAfx.h"
// MAIN INCLUDE
#ifndef T_HIGHLIGHTER
#include "THighlighter.h"
#endif
// OTHER INCLUDES
#ifndef T_PSEPRO_DB
#include "TPseProDB.h"
#endif
/**************************/
/***** class THighlighter *****/
/**************************/
_7X_DB_OBJECT_IMPLEMENT_ID(THighlighter, TAnnotation)
/****************************/
// CONSTRUCTORS
THighlighter::THighlighter()
: TAnnotation()
{
DB_ESTABLISH_FAULT_HANDLER
DB_END_FAULT_HANDLER
}
// DESTRUCTORS
THighlighter::~THighlighter()
{
DB_ESTABLISH_FAULT_HANDLER
// Here I destroy my pointer fields not directly
// handled by a model
DB_END_FAULT_HANDLER
}
// METHODS
void THighlighter::setIndexBegin(long pIndexBegin)
{
DB_ESTABLISH_FAULT_HANDLER
fIndexBegin = pIndexBegin;
DB_END_FAULT_HANDLER
}
long THighlighter::getIndexBegin()
{
DB_ESTABLISH_FAULT_HANDLER
return fIndexBegin;
DB_END_FAULT_HANDLER
}
void THighlighter::setIndexEnd(long pIndexEnd)
{
DB_ESTABLISH_FAULT_HANDLER
fIndexEnd = pIndexEnd;
DB_END_FAULT_HANDLER
}
long THighlighter::getIndexEnd()
{
DB_ESTABLISH_FAULT_HANDLER
return fIndexEnd;
DB_END_FAULT_HANDLER
}
/*------------ THighlighter.h ------------*/
#ifndef T_HIGHLIGHTER
#define T_HIGHLIGHTER
// INCLUDES
#ifndef T_ANNOTATION
#include "TAnnotation.h"
#endif
// CLASS IMPORTS
/**************************/
/***** class THighlighter *****/
/**************************/
class THighlighter : public TAnnotation
{
// CONSTRUCTORS
public:
THighlighter(); //default
protected:
private:
// DESTRUCTORS
public:
~THighlighter();
protected:
private:
// FIELDS
public:
protected:
private:
long fIndexBegin;
long fIndexEnd;
// METHODS
public:
void setIndexBegin(long pIndexBegin);
long getIndexBegin();
void setIndexEnd(long pIndexEnd);
long getIndexEnd();
public:
_7X_DB_OBJECT_DECLARE_ID()
protected:
private:
}; // class THighlighter
#endif // T_HIGHLIGHTER
/*------------ TMetaManager.cpp ------------*/
#include "StdAfx.h"
// MAIN INCLUDE
#ifndef T_META_MANAGER
#include "TMetaManager.h"
#endif
// OTHER INCLUDES
#ifndef T_STRING_TO_PTR_HASHTABLE
#include "TStringToPtrHashTable.h"
#endif
#ifndef T_PTR_TO_PTR_HASHTABLE
#include "TPtrToPtrHashTable.h"
#endif
#ifndef T_GLOBALS_DB
#include "TGlobalsDB.h"
#endif
#ifndef T_DB_NAME_TRANSLATOR
#include "TDbNameTranslator.h"
#endif
#ifndef T_PTR_ITERATOR
#include "TPtrIterator.h"
#endif
#ifndef T_STRING_ITERATOR
#include "TStringIterator.h"
#endif
#include "TAllModel.h"
#include "TAllDBObject.h"
#include "TManager.h"
#include "TManagerTemplate.h"
#include "TModelNames.h"
#include "TLocker.h"
// Root Managers
#ifndef T_MEDIA_LIBRARY_MANAGER
#include "TMediaLibraryManager.h"
#endif
#ifndef T_CONTENTS_BAG_MANAGER
#include "TContentsBagManager.h"
#endif
#ifndef T_CONTEXT_OBJECT_MANAGER
#include "TContextObjectManager.h"
#endif
#ifndef T_ANNOTATIONS_BAG_MANAGER
#include "TAnnotationsBagManager.h"
#endif
#ifndef T_MEDIUM_SHELL_LINKS_STORE_MANAGER
#include "TMediumShellLinksStoreManager.h"
#endif
/******************************/
/***** class TMetaManager *****/
/******************************/
//#define USE_GUID_HASHTABLE
//#define USE_GUID_MAP
template<> UINT AFXAPI HashKey (GUID& key) {
UINT lHash = key.Data1 + key.Data2 + key.Data3;
// lHash += (DWORD)key.Data4 + (DWORD)&key.Data4[4];
return lHash;
}
#ifndef USE_GUID_MODEL_IDS
CMap gTable;
#else // USE_GUID_MODEL_IDS
#ifdef USE_GUID_HASHTABLE
#include "TGenericHashTable.h"
#include "TPtrIterator.h"
class TGUIDIterator : public TIterator {};
TGenericHashTable gTable;
#else // USE_GUID_HASHTABLE
#ifdef USE_GUID_MAP
CMap gTable;
#else // USE_GUID_MAP
CMap gTable;
#endif // USE_GUID_MAP
#endif // USE_GUID_HASHTABLE
#endif // USE_GUID_MODEL_IDS
TLocker gManagerLock;
// METHODS
TManager* TMetaManager::getMgrFromDbName(TString pDbName)
{
// for thread safeness
TLockPtr lLock(&gManagerLock);
TModelID modelName = TDbNameTranslator::getModelNameFromDbName(pDbName);
TManager* lManager = null;
#if defined(USE_GUID_MODEL_IDS) && !defined(USE_GUID_HASHTABLE)
#ifdef USE_GUID_MAP
gTable.Lookup(modelName, lManager);
#else // USE_GUID_MAP
gTable.Lookup(&modelName, lManager);
#endif // USE_GUID_MAP
#else
gTable.Lookup(modelName, lManager);
#endif
if (lManager == null)
{
lManager = initTableEntry(modelName);
}
return lManager;
}
TManager* TMetaManager::getMgrFromModelName(TModelID pModelName)
{
// for thread safeness
TLockPtr lLock(&gManagerLock);
TManager* lManager = null;
#if defined(USE_GUID_MODEL_IDS) && !defined(USE_GUID_HASHTABLE)
#ifdef USE_GUID_MAP
gTable.Lookup(pModelName, lManager);
#else // USE_GUID_MAP
gTable.Lookup(&pModelName, lManager);
#endif // USE_GUID_MAP
#else
gTable.Lookup(pModelName, lManager);
#endif
if (lManager == null)
{
lManager = initTableEntry(pModelName);
}
return lManager;
}
TObjectModel* TMetaManager::createModelInstance(TModelID pModelName, boolean pForceNotRoot)
{
// for thread safeness
TLockPtr lLock(&gManagerLock);
TManager* lManager = getMgrFromModelName(pModelName);
if (lManager != null)
return lManager->createInstance(pForceNotRoot);
return null;
}
boolean TMetaManager::createModelInstance(TModelID pModelName, void** pObject, boolean pForceNotRoot)
{
// for thread safeness
TLockPtr lLock(&gManagerLock);
*pObject = createModelInstance(pModelName, pForceNotRoot);
return *pObject ? true : false;
}
void TMetaManager::cleanAll()
{
// for thread safeness
TLockPtr lLock(&gManagerLock);
// We need to maintain a list of the removed managers
// because removing (mgr2) may cause the re-creation of an already
// removed one (mgr1)...
// I know this isn't very clean, but as we have already handled the
// models managed by mgr1, we'll let it die alone in memory after
// mgr2 has re-created it...
#ifndef USE_GUID_MODEL_IDS
CArray lAlreadyProcessedMgrsArray;
#else // USE_GUID_MODEL_IDS
CArray lAlreadyProcessedMgrsArray;
#endif // USE_GUID_MODEL_IDS
POSITION lPos = gTable.GetStartPosition();
while (lPos != NULL)
{
TManager* curMgr;
#ifdef USE_GUID_MODEL_IDS
#if defined(USE_GUID_MAP)
TModelID curKey;
gTable.GetNextAssoc(lPos, curKey, curMgr);
#else // USE_GUID_MAP
void* curKey;
gTable.GetNextAssoc(lPos, curKey, curMgr);
#endif // USE_GUID_MAP
#else // USE_GUID_MODEL_IDS
CString curKey;
gTable.GetNextAssoc(lPos, curKey, curMgr);
#endif // USE_GUID_MODEL_IDS
boolean bContains = false;
for (int ii = 0; ii < lAlreadyProcessedMgrsArray.GetSize(); ii++)
{
if ( lAlreadyProcessedMgrsArray[ii] == curKey)
{
bContains = true;
break;
}
}
if (!bContains)
{
lAlreadyProcessedMgrsArray.Add(curKey);
gTable.RemoveKey(curKey);
delete curMgr;
lPos = gTable.GetStartPosition();
}
}
lAlreadyProcessedMgrsArray.RemoveAll();
gTable.RemoveAll();
}
TManager* TMetaManager::initTableEntry(TModelID pModelName)
{
TManager* lManager = null;
if (pModelName == T_MEDIA_CASE_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_MEDIA_LIBRARY_MODEL_NAME)
{
lManager = new TMediaLibraryManager();
}
else if (pModelName == T_MEDIA_SHELF_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_BOOK_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_BOOK_ALIAS_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_CHAPTER_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_DIVIDER_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_INDEX_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_PAGE_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
// else if (pModelName == T_SUBSCRIPTION_MODEL_NAME)
// lManager = new TManagerTemplate();
else if (pModelName == T_SUMMARY_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
// else if (pModelName == T_BOOKMARK_MODEL_NAME)
// lManager = new TManagerTemplate();
// else if (pModelName == T_KEYWORD_MODEL_NAME)
// lManager = new TManagerTemplate();
// else if (pModelName == T_KEYWORDS_STICKER_MODEL_NAME)
// lManager = new TManagerTemplate();
else if (pModelName == T_HIGHLIGHTER_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_STICKER_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_ANNOTATIONS_BAG_MODEL_NAME)
{
lManager = new TAnnotationsBagManager();
}
else if (pModelName == T_CONTENT_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_CONTENTS_BAG_MODEL_NAME)
{
lManager = new TContentsBagManager();
}
else if (pModelName == T_PROPERTY_OBJECT_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
else if (pModelName == T_CONTEXT_MODEL_NAME)
{
lManager = new TContextObjectManager();
}
else if (pModelName == T_MEDIUM_SHELL_LINKS_STORE_MODEL_NAME)
{
lManager = new TMediumShellLinksStoreManager();
}
else if (pModelName == T_MEDIUM_SHELL_LINK_MODEL_NAME)
{
lManager = new TManagerTemplate();
}
if (lManager != null)
#if defined(USE_GUID_MODEL_IDS) && !defined(USE_GUID_HASHTABLE)
#ifdef USE_GUID_MAP
gTable.SetAt(pModelName, lManager);
#else // USE_GUID_MAP
gTable.SetAt(&pModelName, lManager);
#endif // USE_GUID_MAP
#else
gTable.SetAt(pModelName, lManager);
#endif
return lManager;
}
boolean TMetaManager::checkModelPointerValidity(void* pPtr)
{
// for thread safeness
TLockPtr lLock(&gManagerLock);
boolean res = FALSE;
POSITION lPos = gTable.GetStartPosition();
while (lPos != NULL)
{
TManager* curManager;
#ifdef USE_GUID_MODEL_IDS
#if defined(USE_GUID_MAP)
TModelID curKey;
gTable.GetNextAssoc(lPos, curKey, curManager);
#else // USE_GUID_MAP
void* curKey;
gTable.GetNextAssoc(lPos, curKey, curManager);
#endif // USE_GUID_MAP
#else // USE_GUID_MODEL_IDS
CString curKey;
gTable.GetNextAssoc(lPos, curKey, curManager);
#endif // USE_GUID_MODEL_IDS
res = curManager->checkModelPointerValidity(pPtr);
if (res == TRUE)
break;
}
return res;
}
HRESULT TMetaManager::setModelCachedDataModified(TObjectModel* pObjectModel)
{
// for thread safeness
TLockPtr lLock(&gManagerLock);
TManager* lManager = getMgrFromModelName(pObjectModel->getID());
if (lManager != null)
{
return lManager->setModelCachedDataModified(pObjectModel);
}
return S_FALSE;
}
HRESULT TMetaManager::flushCachedData()
{
HRESULT hRes = S_OK;
// for thread safeness
TLockPtr lLock(&gManagerLock);
POSITION lPos = gTable.GetStartPosition();
while (lPos != NULL)
{
TManager* curManager;
#ifdef USE_GUID_MODEL_IDS
#if defined(USE_GUID_MAP)
TModelID curKey;
gTable.GetNextAssoc(lPos, curKey, curManager);
#else // USE_GUID_MAP
void* curKey;
gTable.GetNextAssoc(lPos, curKey, curManager);
#endif // USE_GUID_MAP
#else // USE_GUID_MODEL_IDS
CString curKey;
gTable.GetNextAssoc(lPos, curKey, curManager);
#endif // USE_GUID_MODEL_IDS
HRESULT res = curManager->flushCachedData();
if (res != S_OK)
hRes = res;
}
return hRes;
}
HRESULT TMetaManager::flushCachedData(TObjectModel* pObjectModel)
{
// for thread safeness
TLockPtr lLock(&gManagerLock);
TManager* lManager = getMgrFromModelName(pObjectModel->getID());
if (lManager != null)
{
return lManager->flushCachedData(pObjectModel);
}
return S_FALSE;
}/*------------ TModelHelpers.h ------------*/
#ifndef T_MODEL_HELPERS
#define T_MODEL_HELPERS
#include "TMetaManager.h"
#include "TPropertyObjectModel.h"
#include "TMediaLibraryModel.h"
#include "TBookModel.h"
#include "TPageModel.h"
#include "TIndexModel.h"
#include "TSummaryModel.h"
#include "TMediumPropertiesConstants.h"
#include "TBookPropertiesConstants.h"
#include "TPagePropertiesConstants.h"
#include "TModelNames.h"
template
HRESULT GetModelProperty(model* pModel, LPCTSTR pName, TPropertyObjectModel** pProp)
{
HRESULT lResult;
lResult = pModel->getProperty(pName, pProp);
ATLASSERT(FAILED(lResult) || (*pProp != NULL));
return lResult;
}
template
HRESULT GetModelProperty(model* pModel, LPCTSTR pName, TPropertyObjectModel** pProp, BOOL pCreate)
{
HRESULT lResult;
lResult = pModel->getProperty(pName, pProp);
ATLASSERT(FAILED(lResult) || (*pProp != NULL));
if (FAILED(lResult))
{
if ( (!pCreate) || (*pProp != NULL) )
return lResult;
lResult = TMetaManager::createModelInstance(T_PROPERTY_OBJECT_MODEL_NAME, (void**)pProp) ? S_OK : E_FAIL;
ATLASSERT(SUCCEEDED(lResult));
if (SUCCEEDED(lResult) && (*pProp != NULL))
{
pModel->setProperty(pName, *pProp);
}
}
return lResult;
}
template
HRESULT GetSecurityProperty(model* pMedium, TPropertyObjectModel** pSecurity)
{
ATLASSERT(pMedium);
return GetModelProperty(pMedium, T_MEDIUM_SECURITY_PROPERTY, pSecurity);
}
template
HRESULT GetAuthorProperty(model* pBook, TPropertyObjectModel** pAuthor)
{
ATLASSERT(pBook);
return GetModelProperty(pBook, T_BOOK_AUTHOR_PROPERTY, pAuthor);
}
template
BOOL IsReadProtected(model* pMedium)
{
ATLASSERT(pMedium);
TModelPtr lProp;
if (GetSecurityProperty(pMedium, &lProp) == S_OK)
{
boolean lBool;
if (lProp->getBooleanField(T_MEDIUM_SECURITY_PROPERTY_READ_PROTECTED, &lBool) && lBool)
return TRUE;
}
return FALSE;
}
template
BOOL IsModifyProtected(model* pMedium)
{
ATLASSERT(pMedium);
TModelPtr lProp;
if (GetSecurityProperty(pMedium, &lProp) == S_OK)
{
boolean lBool;
if (lProp->getBooleanField(T_MEDIUM_SECURITY_PROPERTY_MODIFY_PROTECTED, &lBool) && lBool)
return TRUE;
}
return FALSE;
}
template
BOOL IsTrashable(model* pBook)
{
ATLASSERT(pBook);
if (IsSystem(pBook)
|| IsModifyProtected(pBook))
return FALSE;
return TRUE;
}
template
long GetBehaviour(model* pPage)
{
TModelPtr lPageProperty;
pPage->getDefaultProperty(&lPageProperty);
ATLASSERT(lPageProperty);
if (lPageProperty == NULL)
return F_PAGE_DEFAULT_BEHAVIOUR;
long lPageBehaviour = F_PAGE_DEFAULT_BEHAVIOUR;
lPageProperty->getLongField(T_PAGE_DEFAULT_PROPERTY_BEHAVIOUR, &lPageBehaviour);
return lPageBehaviour;
}
template
HRESULT AddBehaviour(model* pPage, long pNewBehavior)
{
TModelPtr lPageProperty;
pPage->getDefaultProperty(&lPageProperty);
ATLASSERT(lPageProperty);
if (lPageProperty == NULL)
return E_FAIL;
long lPageBehaviour = F_PAGE_DEFAULT_BEHAVIOUR;
lPageProperty->getLongField(T_PAGE_DEFAULT_PROPERTY_BEHAVIOUR, &lPageBehaviour);
lPageProperty->putLongField(T_PAGE_DEFAULT_PROPERTY_BEHAVIOUR, lPageBehaviour | pNewBehavior);
return S_OK;
}
template
BOOL IsRemovable(model* pPage)
{
ATLASSERT(pPage);
TModelPtr lBook;
pPage->getBook(&lBook);
ATLASSERT(lBook);
if (IsModifyProtected(lBook.p))
return FALSE;
if (GetBehaviour(pPage) & F_PAGE_NOT_REMOVABLE)
return FALSE;
return TRUE;
}
template
BOOL IsCopiable(model* pPage)
{
ATLASSERT(pPage);
if (GetBehaviour(pPage) & F_PAGE_NOT_COPIABLE)
return FALSE;
return TRUE;
}
template
BOOL IsMovable(model* pPage)
{
ATLASSERT(pPage);
if (GetBehaviour(pPage) & F_PAGE_NOT_MOVABLE)
return FALSE;
return TRUE;
}
template
BOOL IsStretchable(model* pPage)
{
ATLASSERT(pPage);
if (GetBehaviour(pPage) & F_PAGE_NOT_STRETCHABLE)
return FALSE;
return TRUE;
}
template
BOOL HaveUserDefinedTitle(model* pPage)
{
ATLASSERT(pPage);
if (GetBehaviour(pPage) & F_PAGE_DEFINED_TITLE)
return TRUE;
return FALSE;
}
template
BOOL IsSystem(model* );
inline BOOL IsSystem(TBookModel* pBook)
{
TModelPtr lProp;
if (pBook && pBook->getDefaultProperty(&lProp) == S_OK)
{
boolean lBool;
if (lProp->getBooleanField(T_BOOK_DEFAULT_PROPERTY_SYSTEM_BOOK, &lBool) && lBool)
return TRUE;
}
return FALSE;
}
inline BOOL IsSystem(TPageModel* pPage)
{
ATLASSERT(pPage);
if ((GetBehaviour(pPage) & F_PAGE_SYSTEM) == F_PAGE_SYSTEM)
return TRUE;
return FALSE;
}
inline BOOL IsChapter(TPageModel* pPage)
{
ATLASSERT(pPage);
return pPage->isInstanceOf(T_CHAPTER_MODEL_NAME);
}
template
void GetAnnotationsPossibilities(model*,bool* pIsHighlightable,bool* pIsNotable );
inline void GetAnnotationsPossibilities( TPageModel *pPage,bool* pIsHighlightable,bool* pIsNotable )
{
if( pPage )
{
ATLASSERT( pPage );
CString lPageType = pPage->getID();
// We can put post-it only on web page
*pIsNotable = IsSystem( pPage ) ? false : lPageType == T_PAGE_MODEL_NAME;
// We can put highlight only on non system web page
*pIsHighlightable = *pIsNotable;
// To do : manage the readonly state of the book
}
else
{
*pIsHighlightable = *pIsNotable = false;
}
}
inline HRESULT GetNextPage(TPageModel* pPage, TPageModel** pNext)
{
ATLASSERT(pNext);
if (pNext == NULL)
return E_INVALIDARG;
ATLASSERT(pPage);
TModelPtr lBook;
pPage->getBook(&lBook);
ATLASSERT(lBook);
if (lBook == NULL)
return E_FAIL;
int lIndex;
lBook->getPageIndex(pPage, &lIndex);
if (lIndex)
{
if (lBook->getPage(lIndex + 1, pNext) == S_OK)
return S_OK;
return lBook->getIndex((TIndexModel**)pNext);
}
TModelPtr lIndexPage;
lBook->getIndex(&lIndexPage);
if (lIndexPage == pPage)
return S_FALSE;
int lCount = lBook->getPagesBeforeSummaryCount();
// If more then 1 page, change this !!!!
ATLASSERT(lCount == 1);
TModelPtr lAuthorPage;
lBook->getPageBeforeSummary(1, &lAuthorPage);
// this was first page
if (lAuthorPage == pPage)
return lBook->getSummary((TSummaryModel**)pNext);
*pNext = NULL;
return E_FAIL;
}
inline HRESULT GetPrevPage(TPageModel* pPage, TPageModel** pPrev)
{
ATLASSERT(pPage);
TModelPtr lBook;
pPage->getBook(&lBook);
ATLASSERT(lBook);
if (lBook == NULL)
return E_FAIL;
int lIndex;
lBook->getPageIndex(pPage, &lIndex);
if (lIndex > 1)
return lBook->getPage(lIndex - 1, pPrev);
TModelPtr lIndexPage;
int lCount = 0;
lBook->getIndex(&lIndexPage);
if (lIndexPage == pPage)
{
lBook->getPageCount(&lCount);
return lBook->getPage(lCount, pPrev);
}
lCount = lBook->getPagesBeforeSummaryCount();
// If more then 1 page, change this !!!!
ATLASSERT(lCount == 1);
if (!lIndex)
// this was already the first page of the book
return S_FALSE;
return lBook->getPageBeforeSummary(1, pPrev);
}
inline HRESULT GetSystemBook(long pId, TBookModel** pBook)
{
ATLASSERT(pBook);
if (pBook == NULL)
return E_INVALIDARG;
*pBook = NULL;
TModelPtr lLib;
TModelPtr lBook;
TMetaManager::createModelInstance(T_MEDIA_LIBRARY_MODEL_NAME, (void**)&lLib);
ATLASSERT(lLib);
if (lLib == NULL)
return E_FAIL;
lLib->getSpecialMediumInLibrary((TMediaLibraryModel::ESpecialMediumId)pId, (TMediumModel**)&lBook);
ATLASSERT(lBook);
if (lBook == NULL)
return E_FAIL;
*pBook = lBook;
(*pBook)->AddRef();
return S_OK;
}
inline HRESULT GetLastPageBeforeIndex(TBookModel* pBook, TPageModel** pPage)
{
ATLASSERT(pBook);
return pBook->getPage(pBook->getPageCount(), pPage);
}
template
BOOL GetStringDefaultProperty(model* pModel, LPCTSTR pField, CString& pValue)
{
TModelPtr lModelProperty;
pModel->getDefaultProperty(&lModelProperty);
ATLASSERT(lModelProperty);
if (lModelProperty == NULL)
return FALSE;
return lModelProperty->getStringField(pField, &pValue);
}
template
BOOL SetStringDefaultProperty(model* pModel, LPCTSTR pField, LPCTSTR pValue)
{
TModelPtr lModelProperty;
pModel->getDefaultProperty(&lModelProperty);
ATLASSERT(lModelProperty);
if (lModelProperty == NULL)
return FALSE;
lModelProperty->putStringField(pField, pValue);
return TRUE;
}
template
BOOL GetBooleanDefaultProperty(model* pModel, LPCTSTR pField, VARIANT_BOOL* pValue)
{
TModelPtr lModelProperty;
pModel->getDefaultProperty(&lModelProperty);
ATLASSERT(lModelProperty);
if (lModelProperty == NULL)
return FALSE;
boolean lBool;
if (lModelProperty->getBooleanField(pField, &lBool))
{
*pValue = ( lBool ? VARIANT_TRUE : VARIANT_FALSE );
return TRUE;
}
else
return FALSE;
}
template
BOOL SetBooleanDefaultProperty(model* pModel, LPCTSTR pField, VARIANT_BOOL pValue)
{
TModelPtr lModelProperty;
pModel->getDefaultProperty(&lModelProperty);
ATLASSERT(lModelProperty);
if (lModelProperty == NULL)
return FALSE;
lModelProperty->putBooleanField(pField, ( (pValue == VARIANT_TRUE) ? true : false ));
return TRUE;
}
#endif // T_MODEL_HELPERS
/*------------ TPage.cpp ------------*/
#include "StdAfx.h"
// MAIN INCLUDE
#ifndef T_PAGE
#include "TPage.h"
#endif
// OTHER INCLUDES
#ifndef T_CHAPTER
#include "TChapter.h"
#endif
#ifndef T_ANNOTATION
#include "TAnnotation.h"
#endif
#ifndef T_CONTENT
#include "TContent.h"
#endif
#ifndef T_DB_PTR_ARRAY
#include "TDBPtrArray.h"
#endif
#ifndef T_PRIVATE_DB_ITERATOR
#include "TPrivateDBIterator.h"
#endif
#ifndef T_PSEPRO_DB
#include "TPseProDB.h"
#endif
#ifndef T_EXCEPTION
#include "TException.h"
#endif
#ifndef T_PROPERTY_OBJECT
#include "TPropertyObject.h"
#endif
#ifndef T_PAGE_PROPERTIES_CONSTANTS
#include "TPagePropertiesConstants.h"
#endif
/********************************/
/***** abstract class TPage *****/
/********************************/
_7X_DB_OBJECT_IMPLEMENT_ID(TPage, TDBObject)
/****************************/
// SPECIFIC PSE PRO STUFF
boolean TPage::bStuff = TPage::init_relocation_hooks();
boolean TPage::init_relocation_hooks()
{
// Uncomment this if you want to debug 'fetch' ops
/*
os_ts::set_fetch_hook(
os_typespec::before_hook,
TPage::fetch_before,
(void*)NULL
);
os_ts::set_fetch_hook(
os_typespec::after_hook,
TPage::fetch_after,
(void*)NULL
);
*/
return true;
}
void TPage::fetch_before(void* object, os_int32, void* data, void*)
{
TPage* page = (TPage*)object;
TRACE1("TPage::fetch_before - [0x%x]\n",(void*)page);
}
void TPage::fetch_after(void* object, os_int32, void* data, void*)
{
TPage* page = (TPage*)object;
TRACE1("TPage::fetch_after - [0x%x]\n",(void*)page);
}
// CONSTRUCTORS
TPage::TPage()
: TDBObject()
{
DB_ESTABLISH_FAULT_HANDLER
fChapter = null;
fAnnotationVector = null;
fContent = null;
fSubscription = null;
// Let's set the various properties default values
TPropertyObject* defaultProp = this->getDefaultProperty();
defaultProp->putBooleanField(T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY, true);
defaultProp->putLongField(T_PAGE_DEFAULT_PROPERTY_SUB_ANNOTATIONS_COUNT, 0);
DB_END_FAULT_HANDLER
}
// DESTRUCTORS
TPage::~TPage()
{
DB_ESTABLISH_FAULT_HANDLER
// Here I destroy my pointer fields not directly
// handled by a model
DB_DESTROY_OBJECT(fAnnotationVector);
fTitle.Empty();
DB_END_FAULT_HANDLER
}
// METHODS
int TPage::searchWordFrom(TString pWord, int pFrom)
{
//DB_ESTABLISH_FAULT_HANDLER
return 0;
//DB_END_FAULT_HANDLER
}
TBook* TPage::getBook()
{
TBook* lResBook = NULL;
DB_ESTABLISH_FAULT_HANDLER
lResBook = fBook;
DB_END_FAULT_HANDLER
return lResBook;
}
void TPage::setBook(TBook* pBook)
{
DB_ESTABLISH_FAULT_HANDLER
fBook = pBook;
DB_END_FAULT_HANDLER
}
TPtrIterator* TPage::getPages()
{
//DB_ESTABLISH_FAULT_HANDLER
return NULL;
//DB_END_FAULT_HANDLER
}
TChapter* TPage::getChapter()
{
TChapter* lResChapter = NULL;
DB_ESTABLISH_FAULT_HANDLER
lResChapter = fChapter;
DB_END_FAULT_HANDLER
return lResChapter;
}
void TPage::setChapter(TChapter* pParent)
{
DB_ESTABLISH_FAULT_HANDLER
fChapter = pParent;
DB_END_FAULT_HANDLER
}
TPageNumbering TPage::getPageNumber()
{
LONG lPageNumber = -1;
DB_ESTABLISH_FAULT_HANDLER
lPageNumber = fPageNumber;
DB_END_FAULT_HANDLER
return TPageNumbering(lPageNumber, T_PAGE_NUMBERING_TYPE_PAGE);
}
void TPage::setPageNumber(int pPageNumber)
{
DB_ESTABLISH_FAULT_HANDLER
fPageNumber = pPageNumber;
DB_END_FAULT_HANDLER
}
int TPage::getPagePosition()
{
DB_ESTABLISH_FAULT_HANDLER
TChapter* parentChapter;
parentChapter = getChapter();
if (parentChapter == null)
return 0;
int pos = 1;
TPtrIterator* iter;
iter = parentChapter->getPages();
while (iter->hasMoreElements())
{
TPage* curPage;
curPage = (TPage *)iter->nextElement();
if (curPage == this)
{
delete iter;
return pos;
}
pos++;
}
delete iter;
DB_END_FAULT_HANDLER
return 0;
}
TString TPage::getTitle()
{
DB_ESTABLISH_FAULT_HANDLER
return LPCTSTR(fTitle);
DB_END_FAULT_HANDLER
}
void TPage::setTitle(TString pTitle)
{
DB_ESTABLISH_FAULT_HANDLER
fTitle = pTitle;
DB_END_FAULT_HANDLER
}
boolean TPage::containsAnnotation(TAnnotation* pAnnotation)
{
DB_ESTABLISH_FAULT_HANDLER
if (fAnnotationVector && pAnnotation)
{
TPtrIterator *iter = fAnnotationVector->elements();
while (iter->hasMoreElements())
{
TAnnotation* curAnnotation = (TAnnotation *)iter->nextElement();
if (curAnnotation == pAnnotation)
{
delete iter;
return true;
}
}
delete iter;
}
DB_END_FAULT_HANDLER
return false;
}
void TPage::addAnnotation(TAnnotation* pAnnotation)
{
if (pAnnotation == null)
return ;
DB_ESTABLISH_FAULT_HANDLER
if (!fAnnotationVector)
{
DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TDBPtrArray,fAnnotationVector,this);
//fAnnotationVector = TPseProObjectCreator::createPtrArray(this);
fAnnotationVector->addElement(pAnnotation);
}
else if (!containsAnnotation(pAnnotation))
{
fAnnotationVector->addElement(pAnnotation);
}
DB_END_FAULT_HANDLER
}
void TPage::removeAnnotation(TAnnotation* pAnnotation)
{
DB_ESTABLISH_FAULT_HANDLER
if (fAnnotationVector && pAnnotation)
{
for (int ii = 0; ii < fAnnotationVector->size(); ii++)
{
if (fAnnotationVector->elementAt(ii) == pAnnotation)
{
fAnnotationVector->removeElementAt(ii);
return;
}
}
}
DB_END_FAULT_HANDLER
}
TPtrIterator* TPage::getAnnotations()
{
TPtrIterator* lResult = null;
DB_ESTABLISH_FAULT_HANDLER
if (fAnnotationVector)
lResult = new TDBPtrArrayIterator(fAnnotationVector);
DB_END_FAULT_HANDLER
return lResult;
}
long TPage::getAnnotationsCount()
{
long lResult = 0;
DB_ESTABLISH_FAULT_HANDLER
if (fAnnotationVector)
lResult = fAnnotationVector->size();
DB_END_FAULT_HANDLER
return lResult;
}
TContent* TPage::getContent()
{
TContent* lResContent = NULL;
DB_ESTABLISH_FAULT_HANDLER
lResContent = fContent;
DB_END_FAULT_HANDLER
return lResContent;
}
void TPage::setContent(TContent* pContent)
{
DB_ESTABLISH_FAULT_HANDLER
if (fContent == pContent)
return ;
if (fContent != null)
fContent->removePage(this);
fContent = pContent;
if (fContent != null)
fContent->addPage(this);
DB_END_FAULT_HANDLER
}/*------------ TPage.h ------------*/
#ifndef T_PAGE
#define T_PAGE
// INCLUDES
#ifndef T_DB_OBJECT
#include "TDBObject.h"
#endif
#ifndef T_DB_STRING
#include "TDBString.h"
#endif
#ifndef T_PAGE_NUMBERING
#include "TPageNumbering.h"
#endif
// CLASS IMPORTS
class TChapter;
class TAnnotation;
class TBook;
class TDBObject;
class TString;
class TDBString;
class TDBPtrArray;
class TSubscription;
class TContent;
class TPtrIterator;
/***********************/
/***** class TPage *****/
/***********************/
class TPage : public TDBObject
{
// SPECIFIC PSE PRO STUFF
public:
static void fetch_before(void*, os_int32, void*, void*);
static void fetch_after(void*, os_int32, void*, void*);
static boolean init_relocation_hooks();
static boolean bStuff;
// CONSTRUCTORS
public:
TPage(); //default
protected:
private:
// DESTRUCTORS
public:
~TPage();
protected:
private:
// FIELDS
public:
protected:
int fPageNumber;
//fPageNumber : page's position in its parent chapter :
//Example : parentChapter --- page 1 (=> (1,typePage) == "1")
// |
// |- subChapter 1 (=> (1,typeChapter) == "I")
// |
// |- page 2 (=> (2,typePage) == "2")
private:
TBook* fBook;
TDBString fTitle;
TChapter* fChapter; //the chapter this page is in
TDBPtrArray* fAnnotationVector;
TContent* fContent;
TSubscription* fSubscription;
// METHODS
public:
virtual int searchWordFrom(TString pWord, int pFrom); //text search in page
virtual TBook* getBook();
virtual void setBook(TBook* pBook);
virtual TPtrIterator* getPages(); // return the sub-pages of this page (actually used by TChapter....)
TChapter* getChapter();
void setChapter(TChapter* pParent);
virtual TPageNumbering getPageNumber();
void setPageNumber(int pPageNumber);
int getPagePosition(); // 1-based
// sequential pos in parent, not taking into
// account any kind of page's type
TString getTitle();
void setTitle(TString pTitle);
void addAnnotation(TAnnotation* pAnnotation);
void removeAnnotation(TAnnotation* pAnnotation);
boolean containsAnnotation(TAnnotation* pAnnotation);
TPtrIterator* getAnnotations();
long getAnnotationsCount();
TContent* getContent();
void setContent(TContent* pContent);
public:
_7X_DB_OBJECT_DECLARE_ID()
protected:
private:
}; // class TPage
#endif // T_PAGE
/*------------ TSticker.cpp ------------*/
#include "StdAfx.h"
// MAIN INCLUDE
#ifndef T_STICKER
#include "TSticker.h"
#endif
// OTHER INCLUDES
#ifndef T_PSEPRO_DB
#include "TPseProDB.h"
#endif
/**************************/
/***** class TSticker *****/
/**************************/
_7X_DB_OBJECT_IMPLEMENT_ID(TSticker, TAnnotation)
/****************************/
// CONSTRUCTORS
TSticker::TSticker()
: TAnnotation()
{
DB_ESTABLISH_FAULT_HANDLER
DB_END_FAULT_HANDLER
}
// DESTRUCTORS
TSticker::~TSticker()
{
DB_ESTABLISH_FAULT_HANDLER
// Here I destroy my pointer fields not directly
// handled by a model
DB_END_FAULT_HANDLER
}
// METHODS
void TSticker::setPosition(int pX, int pY)
{
DB_ESTABLISH_FAULT_HANDLER
fPosX = pX;
fPosY = pY;
DB_END_FAULT_HANDLER
}
void TSticker::setSize(int pWidth, int pHeight)
{
DB_ESTABLISH_FAULT_HANDLER
fWidth = pWidth;
fHeight = pHeight;
DB_END_FAULT_HANDLER
}
TPoint TSticker::getPosition()
{
DB_ESTABLISH_FAULT_HANDLER
return TPoint(fPosX,fPosY);
DB_END_FAULT_HANDLER
}
TPoint TSticker::getSize()
{
DB_ESTABLISH_FAULT_HANDLER
return TPoint(fWidth,fHeight);
DB_END_FAULT_HANDLER
}
/*------------ TSticker.h ------------*/
#ifndef T_STICKER
#define T_STICKER
// INCLUDES
#ifndef T_ANNOTATION
#include "TAnnotation.h"
#endif
#ifndef T_POINT
#include "TPoint.h"
#endif
// CLASS IMPORTS
/**************************/
/***** class TSticker *****/
/**************************/
class TSticker : public TAnnotation
{
// CONSTRUCTORS
public:
TSticker(); //default
protected:
private:
// DESTRUCTORS
public:
~TSticker();
protected:
private:
// FIELDS
public:
protected:
private:
int fPosX;
int fPosY;
int fWidth;
int fHeight;
// METHODS
public:
void setPosition(int pX = 0, int pY = 0);
TPoint getPosition();
void setSize(int pWidth = 100, int pHeight = 100);
TPoint getSize();
public:
_7X_DB_OBJECT_DECLARE_ID()
protected:
private:
}; // class TSticker
#endif // T_STICKER
/*------------ TOfficeConverter.cpp ------------*/
// MAIN INCLUDE
#include "stdafx.h"
#include "TOfficeConverter.h"
// OTHER INCLUDES
#include
#include "TErr.h"
#include "TSystemMimeHelper.h"
#include "TInternetExplorerMimeHelper.h"
#include "TPtrArray.h"
#include "TGlobalResource.h"
// DEFINES
const GUID IID_IWorksheet = { 0x000208D8, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } };
const GUID IID_IChart = { 0x000208D6, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } };
// Microsoft Word Error Codes
#define E_MICROSOFT_WORD_WRONG_PASSWORD 0x800a1520
// Microsoft Excel Error Codes
#define E_MICROSOFT_EXCEL_WRONG_PASSWORD 0x03ec
/********************************/
/***** class TWordConverter *****/
/********************************/
TWordConverter::TWordConverter()
: TOfficeConverter()
{
}
TWordConverter::~TWordConverter()
{
}
HRESULT TWordConverter::Convert()
{
HRESULT lResult;
CComBSTR lProgID;
lResult = GetApplicationProgID(&lProgID);
if (SUCCEEDED(lResult))
lResult = ConvertDocument(lProgID, L"Documents");
return lResult;
}
HRESULT TWordConverter::GetSaveAsConvertFormat(DWORD* pFormatResult)
{
if (!pFormatResult)
return E_INVALIDARG;
if ( m_lSaveAsConvertFormat.vt == VT_I4 )
{
// already computed
*pFormatResult = m_lSaveAsConvertFormat.iVal;
return S_OK;
}
if (GetCurrentVersion() > 8)
{
// We must get the HTML Format Number from Word TypeLib
HRESULT lResult;
long lHTMLFileFormat;
lResult = GetEnumConstantFromTypeLib(L"WdSaveFormat",L"wdFormatHTML",&lHTMLFileFormat);
if (SUCCEEDED(lResult))
{
m_lSaveAsConvertFormat = CComVariant(lHTMLFileFormat,VT_I4);
*pFormatResult = lHTMLFileFormat;
return S_OK;
}
}
else
{
// We must get the HTML Format Number from Word
// (generic method found at http://msdn.microsoft.com/library/techart/w2h.htm)
HRESULT lResult;
if (!m_OfficeAppDriver)
{
// Create Office App Object
lResult = InitializeOfficeAppDriver();
ATLASSERT(SUCCEEDED(lResult) && m_OfficeAppDriver);
if (!(SUCCEEDED(lResult) && m_OfficeAppDriver))
return E_FAIL;
}
// Do not show window
CComVariant lVisible(false);
lResult = m_OfficeAppDriver.PutPropertyByName(L"Visible", &lVisible);
CComVariant lFileConvertersResult;
lResult = m_OfficeAppDriver.GetPropertyByName(L"FileConverters", &lFileConvertersResult);
if (SUCCEEDED(lResult) && lFileConvertersResult.vt == VT_DISPATCH)
{
CComDispatchDriver lFileConvertersDriver(lFileConvertersResult.pdispVal);
CComVariant lFileConvertersCountResult;
lResult = lFileConvertersDriver.GetPropertyByName(L"Count", &lFileConvertersCountResult);
ATLASSERT(SUCCEEDED(lResult) && lFileConvertersCountResult.vt == VT_I4);
if (SUCCEEDED(lResult) && lFileConvertersCountResult.vt == VT_I4)
{
for (int ii = 1; ii <= lFileConvertersCountResult.iVal; ii++)
{
CComVariant lCurFileConverterIdx(ii);
CComVariant lCurFileConverterResult;
lResult = lFileConvertersDriver.Invoke1(L"Item", &lCurFileConverterIdx, &lCurFileConverterResult);
if (SUCCEEDED(lResult) && lCurFileConverterResult.vt == VT_DISPATCH)
{
// Here we have an IFileConverter dispatch
CComDispatchDriver lCurFileConverterDriver(lCurFileConverterResult.pdispVal);
CComVariant lCurFileConverterClassNameResult;
lResult = lCurFileConverterDriver.GetPropertyByName(L"ClassName", &lCurFileConverterClassNameResult);
ATLASSERT(SUCCEEDED(lResult) && lCurFileConverterClassNameResult.vt == VT_BSTR);
if (SUCCEEDED(lResult) && lCurFileConverterClassNameResult.vt == VT_BSTR)
{
if (lCurFileConverterClassNameResult.bstrVal && (!wcsicmp(L"HTML", lCurFileConverterClassNameResult.bstrVal)))
{
CComVariant lCurFileConverterSaveFormatResult;
lResult = lCurFileConverterDriver.GetPropertyByName(L"SaveFormat", &lCurFileConverterSaveFormatResult);
ATLASSERT(SUCCEEDED(lResult) && lCurFileConverterSaveFormatResult.vt == VT_I4);
if (SUCCEEDED(lResult) && lCurFileConverterSaveFormatResult.vt == VT_I4)
{
m_lSaveAsConvertFormat = lCurFileConverterSaveFormatResult;
*pFormatResult = lCurFileConverterSaveFormatResult.iVal;
// Release Office App Object
// -> NO - It will be done when the converter is destroyed
return S_OK;
}
}
}
}
}
}
}
// Release Office App Object
// -> NO - It will be done when the converter is destroyed
}
return E_FAIL;
}
HRESULT TWordConverter::GetConvertedDocumentMime(BSTR* pResMime)
{
*pResMime = CComBSTR(L"text/html").Copy();
return S_OK;
}
HRESULT TWordConverter::OnOpen(LPDISPATCH pDisp, VARIANT* pResult)
{
CComDispatchDriver lDocumentsDriver(pDisp);
CComVariant lOpenResult;
HRESULT lResult;
// The following call is supported by Word 97, 2000 and plus...
{
CComVariant varArgs[9];
varArgs[8] = m_From; // FileName
varArgs[7] = false; // ConfirmConversions
varArgs[6] = true; // ReadOnly
varArgs[5] = false; // AddToRecentFiles
varArgs[4] = L""; // PasswordDocument
varArgs[3] = L""; // PasswordTemplate
varArgs[2] = false; // Revert
varArgs[1] = L""; // WritePasswordDocument
varArgs[0] = L""; // WritePasswordTemplate
long lDispId_Documents_Open;
lResult = lDocumentsDriver.GetIDOfName(L"Open", &lDispId_Documents_Open);
if (SUCCEEDED(lResult))
{
EXCEPINFO pExcepInfo;
unsigned int puArgErr = 0;
DISPPARAMS dispparams = { &varArgs[0], NULL, 9, 0 };
lResult = ((IDispatch *)lDocumentsDriver)->Invoke(
lDispId_Documents_Open,
IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&lOpenResult,
&pExcepInfo,
&puArgErr);
if (SUCCEEDED(lResult) && (lOpenResult.vt == VT_DISPATCH))
{
lOpenResult.Detach(pResult);
}
else
{
if (pExcepInfo.scode == E_MICROSOFT_WORD_WRONG_PASSWORD)
{
lResult = OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED;
}
}
}
}
return lResult;
}
HRESULT TWordConverter::OnSave(LPDISPATCH pDisp)
{
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lResult;
// Before doing any publication to HTML, let's set the HTML format
// options for the current document
CComVariant lWebOptionsResult;
// DISPID lWebOptionsID;
// lResult = GetPropertyIDFromTypeLib(L"Document", L"WebOptions", &lWebOptionsID);
lResult = lDocumentDriver.GetPropertyByName(L"WebOptions", &lWebOptionsResult);
if (FAILED(lResult) || lWebOptionsResult.vt != VT_DISPATCH)
lResult = lDocumentDriver.GetProperty(0x14a, &lWebOptionsResult);
if (SUCCEEDED(lResult) && lWebOptionsResult.vt == VT_DISPATCH)
{
CComDispatchDriver lWebOptionsDriver(lWebOptionsResult.pdispVal);
long lWdBrowserLevel_wdBrowserLevelV4;
lResult = GetEnumConstantFromTypeLib(L"WdBrowserLevel",L"wdBrowserLevelV4",&lWdBrowserLevel_wdBrowserLevelV4);
if (SUCCEEDED(lResult))
{
CComVariant lWebOptions_BrowserLevel(lWdBrowserLevel_wdBrowserLevelV4);
lResult = lWebOptionsDriver.PutPropertyByName(L"BrowserLevel", &lWebOptions_BrowserLevel);
}
CComVariant lWebOptions_OptimizeForBrowser(true);
lResult = lWebOptionsDriver.PutPropertyByName(L"OptimizeForBrowser", &lWebOptions_OptimizeForBrowser);
CComVariant lWebOptions_AllowPNG(false);
lResult = lWebOptionsDriver.PutPropertyByName(L"AllowPNG", &lWebOptions_AllowPNG);
CComVariant lWebOptions_RelyOnVML(false);
lResult = lWebOptionsDriver.PutPropertyByName(L"RelyOnVML", &lWebOptions_RelyOnVML);
}
DWORD lConvertFormat = 0;
lResult = GetSaveAsConvertFormat(&lConvertFormat);
if (SUCCEEDED(lResult))
{
CComVariant lTo(m_To);
CComVariant lFormat(lConvertFormat, VT_I4);
lResult = lDocumentDriver.Invoke2(L"SaveAs", &lTo, &lFormat);
if (FAILED(lResult))
lResult = lDocumentDriver.Invoke2(0x178, &lTo, &lFormat);
ATLASSERT(SUCCEEDED(lResult));
}
return lResult;
}
HRESULT TWordConverter::OnClose(LPDISPATCH pDisp)
{
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lCloseResult;
long lWdSaveOptions_wdDoNotSaveChanges = 0;
lCloseResult = GetEnumConstantFromTypeLib(L"WdSaveOptions", L"wdDoNotSaveChanges", &lWdSaveOptions_wdDoNotSaveChanges);
ATLASSERT(SUCCEEDED(lCloseResult));
long lWdOriginalFormat_wdOriginalDocumentFormat = 0;
lCloseResult = GetEnumConstantFromTypeLib(L"WdOriginalFormat", L"wdOriginalDocumentFormat", &lWdOriginalFormat_wdOriginalDocumentFormat);
ATLASSERT(SUCCEEDED(lCloseResult));
CComVariant lSaveChanges(lWdSaveOptions_wdDoNotSaveChanges);
CComVariant lOriginalFormat(lWdOriginalFormat_wdOriginalDocumentFormat);
lCloseResult = lDocumentDriver.Invoke2(L"Close", &lSaveChanges, &lOriginalFormat);
if (FAILED(lCloseResult))
lCloseResult = lDocumentDriver.Invoke2(0x451, &lSaveChanges, &lOriginalFormat);
ATLASSERT(SUCCEEDED(lCloseResult) && "Close fail: trying to Quit app");
if (FAILED(lCloseResult))
{
lCloseResult = UninitializeOfficeAppDriver();
ATLASSERT(SUCCEEDED(lCloseResult) && "Uninitialize fail: Doc not closed => convertion will fail");
}
return lCloseResult;
}
HRESULT TWordConverter::OnPostProcessDocument(LPDISPATCH pDisp)
{
if (GetCurrentVersion() <= 8)
return E_NOTIMPL;
// On some IE 5.0 versions, the HTML source generated by Word 2000 contains some
// attributes that make images not to display properly.
// Therefore, we will rewrite those HTML source parts
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lResult;
CString lFromFileContent;
CStdioFile lFromFile;
if (lFromFile.Open(CString(m_To), CFile::modeRead))
{
{
const int bufferSize = 4096;
BYTE buffer[bufferSize];
memset(&buffer,0,bufferSize);
for (;;)
{
int bytesRead = lFromFile.Read(buffer,bufferSize);
if (bytesRead <= 0)
{
break;
}
buffer[bytesRead] = 0;
lFromFileContent += buffer;
}
}
lFromFile.Close();
}
if (!lFromFileContent.IsEmpty())
{
// Let's do our post-processing here
{
// On some IE 5.0 versions, we have issues with images not displaying correctly.
// It seems that it is due to the 'class=shape' attribute that Word put on IMG tags...
// Therefore, let's rename the '.shape' style
lFromFileContent.Replace( _T(".shape"), _T(".shap0") );
lFromFileContent.Replace( _T(".SHAPE"), _T(".SHAP0") );
CString lResultBuffer;
lResult = OnPostProcessDocument_RemoveConditionalComments(pDisp, lFromFileContent, lResultBuffer);
if (SUCCEEDED(lResult))
{
lFromFileContent = lResultBuffer;
}
lResultBuffer.Empty();
lResult = OnPostProcessDocument_RemoveXmlNamespaces(pDisp, lFromFileContent, lResultBuffer);
if (SUCCEEDED(lResult))
{
lFromFileContent = lResultBuffer;
}
}
// And then, let's save our post-processed document back
CStdioFile lToFile;
if (lToFile.Open(CString(m_To), CFile::modeWrite | CFile::modeCreate))
{
lToFile.Write(
lFromFileContent.GetBuffer(1),
lFromFileContent.GetLength());
lToFile.Flush();
lToFile.Close();
}
}
return S_OK;
}
HRESULT TWordConverter::DisableAlerts()
{
HRESULT lResult;
LONG lDisableAlertValue;
lResult = GetEnumConstantFromTypeLib(L"WdAlertLevel", L"wdAlertsNone", &lDisableAlertValue);
ATLASSERT(SUCCEEDED(lResult));
if (SUCCEEDED(lResult))
{
CComVariant lDisplayAlerts(lDisableAlertValue);
lResult = m_OfficeAppDriver.PutPropertyByName(L"DisplayAlerts", &lDisplayAlerts);
ATLASSERT(SUCCEEDED(lResult));
}
return lResult;
}
/*************************************/
/***** class TWordImageConverter *****/
/*************************************/
TWordImageConverter::TWordImageConverter()
: TWordConverter()
{
}
HRESULT TWordImageConverter::OnOpen(LPDISPATCH pDisp, VARIANT* pResult)
{
CComDispatchDriver lDocumentsDriver(pDisp);
CComVariant lAddResult;
HRESULT lResult;
lResult = lDocumentsDriver.Invoke0(L"Add", pResult);
ATLASSERT(SUCCEEDED(lResult) && pResult->vt == VT_DISPATCH);
if (SUCCEEDED(lResult) && pResult->vt == VT_DISPATCH)
{
CComDispatchDriver lDocumentDriver(pResult->pdispVal);
CComVariant lShapes;
lResult = lDocumentDriver.GetPropertyByName(L"Shapes", &lShapes);
ATLASSERT(SUCCEEDED(lResult) && lShapes.vt == VT_DISPATCH);
if (SUCCEEDED(lResult) && lShapes.vt == VT_DISPATCH)
{
CComVariant lFrom(m_From);
CComDispatchDriver lShapesDriver(lShapes.pdispVal);
lResult = lShapesDriver.Invoke1(L"AddPicture", &lFrom);
ATLASSERT(SUCCEEDED(lResult));
return lResult;
}
}
return E_FAIL;
}
HRESULT TWordImageConverter::OnEnumerateGeneratedFiles(LPDISPATCH pDisp)
{
// This is the place to do everything you want with generated files since everything
// is closed by now, and we have to fill our m_ExportedFilesList array in...
CComDispatchDriver lDocumentDriver(pDisp);
// HRESULT lResult;
CString lFolderTo(m_To);
TPath lPath(lFolderTo);
lPath.RemoveFileSpec();
TStringArray lExportedFilesList;
/* BOOL bResFileList = */ TPath::GetFileListInDirectory(lFolderTo,TRUE,FALSE,lExportedFilesList);
TSystemMimeHelper* lSystemMimeHelper = new TSystemMimeHelper();
TInternetExplorerMimeHelper* lIEMimeHelper = new TInternetExplorerMimeHelper();
TString lFirstImageFoundPath;
TString lFirstImageFoundMimeType;
for (int ii = 0; ii < lExportedFilesList.size(); ii++)
{
TString curFilePath = lExportedFilesList.elementAt(ii);
if (curFilePath)
{
TString curFileExt;
TString curFileMime;
TPath::FindExtension(curFilePath,curFileExt);
lSystemMimeHelper->getFirstMimeTypeFromFileExtension(curFileExt,curFileMime);
curFileMime.MakeLower();
if ((curFileMime.Find(_T("image/")) != -1) && lIEMimeHelper->isMimeTypeSupported(curFileMime))
{
/* Test Aborted Defect 544
CFileStatus status;
CFile cfile;
// Test the picture size if it is valid
// Case Filter Error No544
if( CFile::GetStatus( curFilePath, status ) ) // static function
{
if ((status.m_size == 0) || ((curFileMime.Find(_T("gif")) != -1) && (status.m_size <= 73)))
{
break;
}
}
else break;
*/
lFirstImageFoundPath = curFilePath;
lFirstImageFoundMimeType = curFileMime;
// Since we have issues with IE which says that it supports PNG whereas it does not completely,
// (actually, PNG is supported if embedded in an HTML page, but not when navigating directly on it)
// we prefer not to output PNG files...
// This test should be temporary since we may not be always sure that Office Converters generate
// other image formats (GIF,JPG...) than PNG!!!
if (curFileMime.Find(_T("png")) == -1)
break;
}
}
}
delete lIEMimeHelper;
delete lSystemMimeHelper;
if (!lFirstImageFoundPath.IsEmpty())
{
BOOL lFileOp;
CString lTarget(m_To);
lFileOp = ::DeleteFile(lTarget);
if (!lFileOp)
{
// On Office 97 it something need times to close the file !!!!
::Sleep(300);
lFileOp = ::DeleteFile(lTarget);
}
ATLASSERT(lFileOp);
if (lFileOp)
{
lFileOp = ::MoveFile(lFirstImageFoundPath, lTarget);
ATLASSERT(lFileOp);
if (lFileOp)
m_ExportedFilesList.addElement(lTarget);
}
m_ConvertedImageMime = lFirstImageFoundMimeType;
return S_OK;
}
else
{
return E_FAIL;
}
}
HRESULT TWordImageConverter::GetConvertedDocumentMime(BSTR* pResMime)
{
if (m_ConvertedImageMime.Length() > 0)
{
*pResMime = CComBSTR(m_ConvertedImageMime).Copy();
return S_OK;
}
else
{
if (!m_ExportedFilesList.isEmpty())
{
TSystemMimeHelper* lSystemMimeHelper = new TSystemMimeHelper();
TInternetExplorerMimeHelper* lIEMimeHelper = new TInternetExplorerMimeHelper();
BOOL bMimeFound = FALSE;
for (int ii = 0; ii < m_ExportedFilesList.size(); ii++)
{
TString curFilePath = m_ExportedFilesList.elementAt(ii);
if (curFilePath)
{
TString curFileExt;
TString curFileMime;
TPath::FindExtension(curFilePath,curFileExt);
lSystemMimeHelper->getFirstMimeTypeFromFileExtension(curFileExt,curFileMime);
curFileMime.MakeLower();
if ((curFileMime.Find(_T("image/")) != -1) && lIEMimeHelper->isMimeTypeSupported(curFileMime))
{
*pResMime = CComBSTR(curFileMime).Copy();
bMimeFound = TRUE;
break;
}
}
}
delete lIEMimeHelper;
delete lSystemMimeHelper;
if (bMimeFound)
return S_OK;
}
// Either we do not have converted anything
// or we do not have filled the m_ExportedFilesList list up...
*pResMime = NULL;
return E_FAIL;
}
}
/*********************************/
/***** class TExcelConverter *****/
/*********************************/
TExcelConverter::TExcelConverter()
: TOfficeConverter()
{
}
HRESULT TExcelConverter::Convert()
{
HRESULT lResult;
CComBSTR lProgID;
lResult = GetApplicationProgID(&lProgID);
if (SUCCEEDED(lResult))
lResult = ConvertDocument(lProgID, L"WorkBooks");
return lResult;
}
HRESULT TExcelConverter::GetConvertedDocumentMime(BSTR* pResMime)
{
*pResMime = CComBSTR(L"text/html").Copy();
return S_OK;
}
HRESULT TExcelConverter::GetSaveAsConvertFormat(DWORD* pFormatResult)
{
if (!pFormatResult)
return E_INVALIDARG;
if (GetCurrentVersion() > 8)
{
if ( m_lSaveAsConvertFormat.vt == VT_I4 )
{
// already computed
*pFormatResult = m_lSaveAsConvertFormat.iVal;
return S_OK;
}
// We must get the HTML Format Number from Excel TypeLib
HRESULT lResult;
long lHTMLFileFormat;
lResult = GetEnumConstantFromTypeLib(L"XlFileFormat",L"xlHtml",&lHTMLFileFormat);
if (SUCCEEDED(lResult))
{
m_lSaveAsConvertFormat = CComVariant(lHTMLFileFormat,VT_I4);
*pFormatResult = lHTMLFileFormat;
return S_OK;
}
else
{
return E_FAIL;
}
}
else
{
// Previous version of Excel did not support 'Save As... HTML'
return E_NOTIMPL;
}
}
HRESULT TExcelConverter::OnOpen(LPDISPATCH pDisp, VARIANT* pResult)
{
CComDispatchDriver lDocumentsDriver(pDisp);
HRESULT lResult;
if (GetCurrentVersion() <= 8)
{
// Excel 97
CComVariant lApplicationResult;
lResult = lDocumentsDriver.GetPropertyByName(L"Application", &lApplicationResult);
ATLASSERT(SUCCEEDED(lResult) && lApplicationResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lApplicationResult.vt == VT_DISPATCH))
return E_FAIL;
CComDispatchDriver lApplicationDriver(lApplicationResult.pdispVal);
CComVariant lAppAddInsResult;
lResult = lApplicationDriver.GetPropertyByName(L"AddIns", &lAppAddInsResult);
ATLASSERT(SUCCEEDED(lResult) && lAppAddInsResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lAppAddInsResult.vt == VT_DISPATCH))
return E_FAIL;
CComDispatchDriver lAppAddInsDriver(lAppAddInsResult.pdispVal);
long lDispId_AddIns_Item;
lResult = lAppAddInsDriver.GetIDOfName(L"Item", &lDispId_AddIns_Item);
if (!SUCCEEDED(lResult))
return E_FAIL;
CComVariant lInternetAssistantWizardAddInFullName;
BOOL bInternetAssistantWizardAddInInstalled = FALSE;
CComVariant lAddInsCountResult;
lResult = lAppAddInsDriver.GetPropertyByName(L"Count", &lAddInsCountResult);
ATLASSERT(SUCCEEDED(lResult) && lAddInsCountResult.vt == VT_I4);
if (SUCCEEDED(lResult) && lAddInsCountResult.vt == VT_I4)
{
for (int ii = 1; ii <= lAddInsCountResult.iVal; ii++)
{
CComVariant lCurAddInResult;
{
CComVariant varArgs_param1(ii);
CComVariant varArgs[1] = { varArgs_param1 };
DISPPARAMS dispparams = { &varArgs[0], NULL, 1, 0};
lResult = ((IDispatch *)lAppAddInsDriver)->Invoke(
lDispId_AddIns_Item,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET,
&dispparams,
&lCurAddInResult,
NULL,
NULL);
}
ATLASSERT(SUCCEEDED(lResult) && lCurAddInResult.vt == VT_DISPATCH);
if (SUCCEEDED(lResult) && lCurAddInResult.vt == VT_DISPATCH)
{
// Here we have an IAddIn dispatch
CComDispatchDriver lAppAddInDriver(lCurAddInResult.pdispVal);
CComVariant lAddInFileNameResult;
lResult = lAppAddInDriver.GetPropertyByName(L"Name", &lAddInFileNameResult);
ATLASSERT(SUCCEEDED(lResult) && lAddInFileNameResult.vt == VT_BSTR);
if (SUCCEEDED(lResult) && lAddInFileNameResult.vt == VT_BSTR)
{
if (lAddInFileNameResult.bstrVal && (!wcsicmp(L"HTML.XLA", lAddInFileNameResult.bstrVal)))
{
CComVariant lAddInInstalled(true);
lResult = lAppAddInDriver.PutPropertyByName(L"Installed",&lAddInInstalled);
if (SUCCEEDED(lResult))
{
lResult = lAppAddInDriver.GetPropertyByName(L"FullName", &lInternetAssistantWizardAddInFullName);
if (SUCCEEDED(lResult))
{
bInternetAssistantWizardAddInInstalled = TRUE;
}
break;
}
}
}
}
}
}
if (!bInternetAssistantWizardAddInInstalled)
return E_FAIL;
// At least, now we know the HTML.XLA library is installed, let's load it in
// our document's context so that its macros get accessible
CComVariant lHtmlLibraryOpenResult;
lResult = lDocumentsDriver.Invoke1(L"Open", &lInternetAssistantWizardAddInFullName, &lHtmlLibraryOpenResult);
ATLASSERT(SUCCEEDED(lResult) && lHtmlLibraryOpenResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lHtmlLibraryOpenResult.vt == VT_DISPATCH))
return E_FAIL;
// Now, the 'htmlconvert' macro is loaded
// (see http://www.microsoft.com/ExcelDev/Articles/ConvHTML.htm for API details)
}
CComVariant lOpenResult;
// The following call is supported by Excel 97, 2000 and plus...
{
CComVariant varArgs[11];
varArgs[10] = m_From; // FileName
varArgs[9] = 0; // UpdateLinks
varArgs[8] = true; // ReadOnly
varArgs[7].vt = VT_ERROR;
varArgs[7].scode = DISP_E_PARAMNOTFOUND;
varArgs[6] = L""; // Password
varArgs[5] = L""; // WriteResPassword
varArgs[4] = true; // IgnoreReadOnlyRecommended
varArgs[3].vt = VT_ERROR;
varArgs[3].scode = DISP_E_PARAMNOTFOUND;
varArgs[2].vt = VT_ERROR;
varArgs[2].scode = DISP_E_PARAMNOTFOUND;
varArgs[1].vt = VT_ERROR;
varArgs[1].scode = DISP_E_PARAMNOTFOUND;
varArgs[0] = false; // Notify
long lDispId_Documents_Open;
lResult = lDocumentsDriver.GetIDOfName(L"Open", &lDispId_Documents_Open);
if (SUCCEEDED(lResult))
{
EXCEPINFO pExcepInfo;
unsigned int puArgErr = 0;
DISPPARAMS dispparams = { &varArgs[0], NULL, 11, 0 };
lResult = ((IDispatch *)lDocumentsDriver)->Invoke(
lDispId_Documents_Open,
IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&lOpenResult,
&pExcepInfo,
&puArgErr);
if (SUCCEEDED(lResult) && (lOpenResult.vt == VT_DISPATCH))
{
lOpenResult.Detach(pResult);
}
else
{
if (pExcepInfo.wCode == E_MICROSOFT_EXCEL_WRONG_PASSWORD)
{
lResult = OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED;
}
}
}
}
return lResult;
}
HRESULT TExcelConverter::OnSave_Excel2000(LPDISPATCH pDisp)
{
if (GetCurrentVersion() <= 8)
return E_NOTIMPL;
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lResult;
CString lFolderTo(m_To);
TPath lPath(lFolderTo);
lPath.RemoveFileSpec();
// Before doing any publication to HTML, let's set the HTML format
// options for the current document
CComVariant lWebOptionsResult;
lResult = lDocumentDriver.GetPropertyByName(L"WebOptions", &lWebOptionsResult);
if (SUCCEEDED(lResult) && lWebOptionsResult.vt == VT_DISPATCH)
{
CComDispatchDriver lWebOptionsDriver(lWebOptionsResult.pdispVal);
CComVariant lWebOptions_AllowPNG(false);
lResult = lWebOptionsDriver.PutPropertyByName(L"AllowPNG", &lWebOptions_AllowPNG);
CComVariant lWebOptions_DownloadComponents(false);
lResult = lWebOptionsDriver.PutPropertyByName(L"DownloadComponents", &lWebOptions_DownloadComponents);
CComVariant lWebOptions_RelyOnVML(false);
lResult = lWebOptionsDriver.PutPropertyByName(L"RelyOnVML", &lWebOptions_RelyOnVML);
}
// Then, let's iterate on each workbook's sheet and publish it to HTML
CComVariant lSheetsResult;
lResult = lDocumentDriver.GetPropertyByName(L"Sheets", &lSheetsResult);
ATLASSERT(SUCCEEDED(lResult) && lSheetsResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lSheetsResult.vt == VT_DISPATCH))
return E_FAIL;
CComDispatchDriver lSheetsDriver(lSheetsResult.pdispVal);
// We will store here the file path of each published workbook's sheet,
// as well as its sheet name,
// so that we will reassemble them into one big file when the work is done...
struct TPublishedSheetData
{
TString m_stgMainHTMLFilePath;
TString m_stgSheetName;
};
TPtrArray lPublishedSheetsDataArray;
CComVariant lSheetsCountResult;
lResult = lSheetsDriver.GetPropertyByName(L"Count", &lSheetsCountResult);
ATLASSERT(SUCCEEDED(lResult) && lSheetsCountResult.vt == VT_I4);
if (SUCCEEDED(lResult) && lSheetsCountResult.vt == VT_I4 && lSheetsCountResult.iVal > 0)
{
// Let's get the constant values needed when invoking the IPublishObjects methods
long lXlSourceType_xlSourceSheet;
lResult = GetEnumConstantFromTypeLib(L"XlSourceType",L"xlSourceSheet",&lXlSourceType_xlSourceSheet);
long lXlSourceType_xlSourceChart;
lResult = GetEnumConstantFromTypeLib(L"XlSourceType",L"xlSourceChart",&lXlSourceType_xlSourceChart);
long lXlHtmlType_xlHtmlStatic;
lResult = GetEnumConstantFromTypeLib(L"XlHtmlType",L"xlHtmlStatic",&lXlHtmlType_xlHtmlStatic);
CComVariant lPublishObjectsResult;
lResult = lDocumentDriver.GetPropertyByName(L"PublishObjects", &lPublishObjectsResult);
ATLASSERT(SUCCEEDED(lResult) && lPublishObjectsResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lPublishObjectsResult.vt == VT_DISPATCH))
return E_FAIL;
CComDispatchDriver lPublishObjectsDriver(lPublishObjectsResult.pdispVal);
long lDispId_Sheets_Item;
lResult = lSheetsDriver.GetIDOfName(L"Item", &lDispId_Sheets_Item);
if (!SUCCEEDED(lResult))
return E_FAIL;
long lDispId_PublishObjects_Item;
lResult = lPublishObjectsDriver.GetIDOfName(L"Item", &lDispId_PublishObjects_Item);
if (!SUCCEEDED(lResult))
return E_FAIL;
for (int iSheetIdx = 1; iSheetIdx <= lSheetsCountResult.iVal; iSheetIdx++)
{
CComVariant lCurSheetIdx(iSheetIdx);
CComVariant lCurSheetResult;
{
CComVariant varArgs_param1(lCurSheetIdx);
CComVariant varArgs[1] = { varArgs_param1 };
DISPPARAMS dispparams = { &varArgs[0], NULL, 1, 0};
lResult = ((IDispatch *)lSheetsDriver)->Invoke(
lDispId_Sheets_Item,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET,
&dispparams,
&lCurSheetResult,
NULL,
NULL);
}
ATLASSERT(SUCCEEDED(lResult) && lCurSheetResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lCurSheetResult.vt == VT_DISPATCH))
continue;
// Here we have an IWorksheet or an IChart dispatch
CComDispatchDriver lCurSheetDriver(lCurSheetResult.pdispVal);
CComVariant lPublishObjectResult;
// Let's generate a temporary file name for the published file
CString lTemporaryPublishedFilePath;
TPath::CreateRandomFilePath(lFolderTo,_T(".htm"),lTemporaryPublishedFilePath);
CString lCurSheetName(_T(""));
CComPtr lCheckIWorksheetInterface;
lResult = lCurSheetDriver.p->QueryInterface(IID_IWorksheet,(void**)&lCheckIWorksheetInterface);
if (lCheckIWorksheetInterface)
{
// We know that we have an IWorksheet dispatch
CComDispatchDriver lCurWorksheetDriver(lCurSheetDriver.p);
CComVariant lCurWorksheetNameResult;
lResult = lCurWorksheetDriver.GetPropertyByName(L"Name", &lCurWorksheetNameResult);
lCurSheetName = CString(lCurWorksheetNameResult.bstrVal);
{
CComVariant varArgs_param1(lXlSourceType_xlSourceSheet); // SourceType
CComVariant varArgs_param2(lTemporaryPublishedFilePath); // FileName
CComVariant varArgs_param3(lCurWorksheetNameResult); // Sheet
CComVariant varArgs_param4(L""); // Source
CComVariant varArgs_param5(lXlHtmlType_xlHtmlStatic); // HtmlType
CComVariant varArgs[5] = {
varArgs_param5,
varArgs_param4,
varArgs_param3,
varArgs_param2,
varArgs_param1
};
long lDispId_PublishObjects_Add;
lResult = lPublishObjectsDriver.GetIDOfName(L"Add", &lDispId_PublishObjects_Add);
if (SUCCEEDED(lResult))
{
EXCEPINFO pExcepInfo;
unsigned int puArgErr = 0;
DISPPARAMS dispparams = { &varArgs[0], NULL, 5, 0 };
lResult = ((IDispatch *)lPublishObjectsDriver)->Invoke(
lDispId_PublishObjects_Add,
IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&lPublishObjectResult,
&pExcepInfo,
&puArgErr);
}
}
}
else
{
CComPtr lCheckIChartInterface;
lResult = lCurSheetDriver.p->QueryInterface(IID_IChart,(void**)&lCheckIChartInterface);
if (lCheckIChartInterface)
{
// We know that we have an IChart dispatch
CComDispatchDriver lCurChartDriver(lCurSheetDriver.p);
CComVariant lCurChartNameResult;
lResult = lCurChartDriver.GetPropertyByName(L"Name", &lCurChartNameResult);
lCurSheetName = CString(lCurChartNameResult.bstrVal);
{
CComVariant varArgs_param1(lXlSourceType_xlSourceChart); // SourceType
CComVariant varArgs_param2(lTemporaryPublishedFilePath); // FileName
CComVariant varArgs_param3(lCurChartNameResult); // Sheet
CComVariant varArgs_param4(L""); // Source
CComVariant varArgs_param5(lXlHtmlType_xlHtmlStatic); // HtmlType
CComVariant varArgs[5] = {
varArgs_param5,
varArgs_param4,
varArgs_param3,
varArgs_param2,
varArgs_param1
};
long lDispId_PublishObjects_Add;
lResult = lPublishObjectsDriver.GetIDOfName(L"Add", &lDispId_PublishObjects_Add);
if (SUCCEEDED(lResult))
{
EXCEPINFO pExcepInfo;
unsigned int puArgErr = 0;
DISPPARAMS dispparams = { &varArgs[0], NULL, 5, 0 };
lResult = ((IDispatch *)lPublishObjectsDriver)->Invoke(
lDispId_PublishObjects_Add,
IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&lPublishObjectResult,
&pExcepInfo,
&puArgErr);
}
}
}
}
ATLASSERT(SUCCEEDED(lResult) && lPublishObjectResult.vt == VT_DISPATCH);
if (SUCCEEDED(lResult) && lPublishObjectResult.vt == VT_DISPATCH)
{
// Here we have an PublishObject dispatch
CComDispatchDriver lPublishObjectDriver(lPublishObjectResult.pdispVal);
CComVariant lCreate(true);
lResult = lPublishObjectDriver.Invoke1(L"Publish", &lCreate);
ATLASSERT(SUCCEEDED(lResult));
if (SUCCEEDED(lResult))
{
TPublishedSheetData* lNewData = new TPublishedSheetData();
lNewData->m_stgMainHTMLFilePath = lTemporaryPublishedFilePath;
lNewData->m_stgSheetName = lCurSheetName;
lPublishedSheetsDataArray.addElement(lNewData);
}
}
}
// Let's now reassemble every generated file into one big HTML file
if (lPublishedSheetsDataArray.size() > 0)
{
CStdioFile lToFile;
if (lToFile.Open(CString(m_To), CFile::modeWrite | CFile::modeCreate))
{
for (int ii = 0; ii < lPublishedSheetsDataArray.size(); ii++)
{
TPublishedSheetData* curSheetData = (TPublishedSheetData*)lPublishedSheetsDataArray.elementAt(ii);
CString curGeneratedFilePath = curSheetData->m_stgMainHTMLFilePath;
CString curSheetName = curSheetData->m_stgSheetName;
CStdioFile lFromFile;
if (lFromFile.Open(curGeneratedFilePath, CFile::modeRead))
{
CString lFromFileContent;
{
const int bufferSize = 4096;
BYTE buffer[bufferSize];
memset(&buffer,0,bufferSize);
for (;;)
{
int bytesRead = lFromFile.Read(buffer,bufferSize);
if (bytesRead <= 0)
{
break;
}
buffer[bytesRead] = 0;
lFromFileContent += buffer;
}
}
lFromFile.Close();
// Here we can write some extra HTML
CString lSheetHeaderHtmlTemplate;
KBLoadString(IDS_MIMEFILTER_OFFICE_EXCEL2000_SHEET_HEADER_TEMPLATE,lSheetHeaderHtmlTemplate);
if (!lSheetHeaderHtmlTemplate.IsEmpty())
{
CString lSheetNameTemplate;
KBLoadString(IDS_MIMEFILTER_OFFICE_EXCEL2000_SHEET_NAME_TEMPLATE,lSheetNameTemplate);
CString lSheetNameCompleted;
lSheetNameCompleted.FormatMessage(
lSheetNameTemplate,
curSheetName
);
CString lSheetNumberCompleted;
if (lPublishedSheetsDataArray.size() > 1)
{
CString lSheetNumberTemplate;
KBLoadString(IDS_MIMEFILTER_OFFICE_EXCEL2000_SHEET_NUMBER_TEMPLATE,lSheetNumberTemplate);
lSheetNumberCompleted.FormatMessage(
lSheetNumberTemplate,
ii+1,
lPublishedSheetsDataArray.size()
);
}
CString lSheetHeaderHtmlCompleted;
lSheetHeaderHtmlCompleted.FormatMessage(
lSheetHeaderHtmlTemplate,
lSheetNameCompleted,
lSheetNumberCompleted
);
lToFile.WriteString(lSheetHeaderHtmlCompleted);
}
lToFile.Write(
lFromFileContent.GetBuffer(1),
lFromFileContent.GetLength());
TRY
{
CFile::Remove(curGeneratedFilePath);
}
CATCH(CFileException, e)
{
}
END_CATCH
// Here we can write some extra HTML
if (ii < lPublishedSheetsDataArray.size() - 1)
{
lToFile.WriteString("\r\n");
lToFile.WriteString("
\r\n");
}
}
}
lToFile.Flush();
lToFile.Close();
lResult = S_OK;
}
else
{
lResult = E_FAIL;
}
}
else
{
lResult = E_FAIL;
}
}
// Clean-up
for (int ii = 0; ii < lPublishedSheetsDataArray.size(); ii++)
{
TPublishedSheetData* curSheetData = (TPublishedSheetData*)lPublishedSheetsDataArray.elementAt(ii);
delete curSheetData;
}
lPublishedSheetsDataArray.removeAllElements();
return lResult;
}
HRESULT TExcelConverter::OnSave_Excel97(LPDISPATCH pDisp)
{
if (GetCurrentVersion() > 8)
return E_NOTIMPL;
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lResult;
CComVariant lApplicationResult;
lResult = lDocumentDriver.GetPropertyByName(L"Application", &lApplicationResult);
ATLASSERT(SUCCEEDED(lResult) && lApplicationResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lApplicationResult.vt == VT_DISPATCH))
return E_FAIL;
CComDispatchDriver lApplicationDriver(lApplicationResult.pdispVal);
// The 'htmlconvert' macro has been loaded in the 'OnOpen' method
// (see http://www.microsoft.com/ExcelDev/Articles/ConvHTML.htm for API details)
// Let's now pick up everything we want to export in our excel workspace...
CComVariant lSheetsResult;
lResult = lDocumentDriver.GetPropertyByName(L"Sheets", &lSheetsResult);
ATLASSERT(SUCCEEDED(lResult) && lSheetsResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lSheetsResult.vt == VT_DISPATCH))
return E_FAIL;
CComDispatchDriver lSheetsDriver(lSheetsResult.pdispVal);
// I guess we should try and do something very clever like iterating on all the
// sheets, exporting all of them one by one, and then generating a root HTML
// document from scratch that would reference all of them in a very nice looking
// way... (TO DO)
// Anyway, for now, let's just iterate on all the sheets on save them foot-to-head
// in one single file...
CComVariant lSheetsCountResult;
lResult = lSheetsDriver.GetPropertyByName(L"Count", &lSheetsCountResult);
ATLASSERT(SUCCEEDED(lResult) && lSheetsCountResult.vt == VT_I4);
if (SUCCEEDED(lResult) && lSheetsCountResult.vt == VT_I4 && lSheetsCountResult.iVal > 0)
{
// Let's create the "array of variants" variant which will hold all
// the objects we want to be exported by the 'HTMLConvert' macro
// As we do not know yet the number of items we will export, we create at first an empty array
CComVariant lRangeAndChartToConvertSafeArray;
lResult = CreateRedimOneDimArray(lRangeAndChartToConvertSafeArray,0);
if (!(SUCCEEDED(lResult)))
return E_FAIL;
long lDispId_Sheets_Item;
lResult = lSheetsDriver.GetIDOfName(L"Item", &lDispId_Sheets_Item);
if (!SUCCEEDED(lResult))
return E_FAIL;
for (int iSheetIdx = 1; iSheetIdx <= lSheetsCountResult.iVal; iSheetIdx++)
{
CComVariant lCurSheetIdx(iSheetIdx);
CComVariant lCurSheetResult;
{
CComVariant varArgs_param1(lCurSheetIdx);
CComVariant varArgs[1] = { varArgs_param1 };
DISPPARAMS dispparams = { &varArgs[0], NULL, 1, 0};
lResult = ((IDispatch *)lSheetsDriver)->Invoke(
lDispId_Sheets_Item,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET,
&dispparams,
&lCurSheetResult,
NULL,
NULL);
}
ATLASSERT(SUCCEEDED(lResult) && lCurSheetResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lCurSheetResult.vt == VT_DISPATCH))
return E_FAIL;
// Here we have an IWorksheet or an IChart dispatch
CComDispatchDriver lCurSheetDriver(lCurSheetResult.pdispVal);
CComPtr lCheckIWorksheetInterface;
lResult = lCurSheetDriver.p->QueryInterface(IID_IWorksheet,(void**)&lCheckIWorksheetInterface);
if (lCheckIWorksheetInterface)
{
// We know that we have an IWorksheet dispatch
CComDispatchDriver lCurWorksheetDriver(lCurSheetDriver.p);
//******
//*** Here we get the RANGE we want to export
//******
CComVariant lCurWorksheetRangeResult;
lResult = lCurWorksheetDriver.GetPropertyByName(L"UsedRange", &lCurWorksheetRangeResult);
if (!(SUCCEEDED(lResult) && lCurWorksheetRangeResult.vt == VT_DISPATCH))
{
ATLASSERT(FALSE);
TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__,
_T("Error (0x%1!x!) - Worksheet.UsedRange FAILED"), lResult);
}
else
{
// Let's add our RANGE object to the objects to export
CComVariant lCurVariantToInsert(lCurWorksheetRangeResult.pdispVal);
long lNewSize;
GetOneDimArrayElemCount(lRangeAndChartToConvertSafeArray,&lNewSize);
lNewSize++;
long idx[1];
idx[0] = lNewSize - 1;
lResult = CreateRedimOneDimArray(lRangeAndChartToConvertSafeArray,lNewSize);
if (SUCCEEDED(lResult))
{
SafeArrayPutElement(lRangeAndChartToConvertSafeArray.parray, idx, &lCurVariantToInsert);
}
}
//******
//*** Here we get the CHART OBJECTS we want to export
//******
CComVariant lCurWorksheetChartObjectsResult;
lResult = lCurWorksheetDriver.Invoke0(L"ChartObjects", &lCurWorksheetChartObjectsResult);
if (SUCCEEDED(lResult) && lCurWorksheetChartObjectsResult.vt == VT_DISPATCH)
{
CComDispatchDriver lChartObjectsDriver(lCurWorksheetChartObjectsResult.pdispVal);
CComVariant lChartObjectsCountResult;
lResult = lChartObjectsDriver.GetPropertyByName(L"Count", &lChartObjectsCountResult);
ATLASSERT(SUCCEEDED(lResult) && lChartObjectsCountResult.vt == VT_I4);
if (SUCCEEDED(lResult) && lChartObjectsCountResult.vt == VT_I4)
{
for (int ii = 1; ii <= lChartObjectsCountResult.iVal; ii++)
{
CComVariant lCurChartObjectIdx(ii);
CComVariant lCurChartObjectResult;
lResult = lChartObjectsDriver.Invoke1(L"Item", &lCurChartObjectIdx, &lCurChartObjectResult);
if (SUCCEEDED(lResult) && lCurChartObjectResult.vt == VT_DISPATCH)
{
// Here we have an IChartObject dispatch
CComDispatchDriver lCurChartObjectDriver(lCurChartObjectResult.pdispVal);
CComVariant lCurChartResult;
lResult = lCurChartObjectDriver.GetPropertyByName(L"Chart", &lCurChartResult);
ATLASSERT(SUCCEEDED(lResult) && lCurChartResult.vt == VT_DISPATCH);
if (SUCCEEDED(lResult) && lCurChartResult.vt == VT_DISPATCH)
{
// Here we have an IChart dispatch
CComDispatchDriver lCurChartDriver(lCurChartResult.pdispVal);
// Let's add our CHART object to the objects to export
CComVariant lCurVariantToInsert(lCurChartResult.pdispVal);
long lNewSize;
GetOneDimArrayElemCount(lRangeAndChartToConvertSafeArray,&lNewSize);
lNewSize++;
long idx[1];
idx[0] = lNewSize - 1;
lResult = CreateRedimOneDimArray(lRangeAndChartToConvertSafeArray,lNewSize);
if (SUCCEEDED(lResult))
{
SafeArrayPutElement(lRangeAndChartToConvertSafeArray.parray, idx, &lCurVariantToInsert);
}
}
}
}
}
}
}
else
{
CComPtr lCheckIChartInterface;
lResult = lCurSheetDriver.p->QueryInterface(IID_IChart,(void**)&lCheckIChartInterface);
if (lCheckIChartInterface)
{
// We know that we have an IChart dispatch
CComDispatchDriver lCurChartDriver(lCurSheetDriver.p);
// Let's add our CHART object to the objects to export
CComVariant lCurVariantToInsert(lCurSheetResult.pdispVal);
long lNewSize;
GetOneDimArrayElemCount(lRangeAndChartToConvertSafeArray,&lNewSize);
lNewSize++;
long idx[1];
idx[0] = lNewSize - 1;
lResult = CreateRedimOneDimArray(lRangeAndChartToConvertSafeArray,lNewSize);
if (SUCCEEDED(lResult))
{
SafeArrayPutElement(lRangeAndChartToConvertSafeArray.parray, idx, &lCurVariantToInsert);
}
}
}
}
//******
//*** Here we get the worksheet's name we will display as HTML header
//******
CComVariant lDocumentTitleResult;
{
lResult = lDocumentDriver.GetPropertyByName(L"Title", &lDocumentTitleResult);
ATLASSERT(SUCCEEDED(lResult) && lDocumentTitleResult.vt == VT_BSTR);
if (!(SUCCEEDED(lResult) && lDocumentTitleResult.vt == VT_BSTR))
{
lDocumentTitleResult = L"";
}
}
CComVariant lDocumentDescription(L"");
CComVariant lLineBeforeTable(false);
if ( (CComBSTR(lDocumentTitleResult.bstrVal).Length() != 0) || (CComBSTR(lDocumentDescription.bstrVal).Length() != 0) )
{
lLineBeforeTable = VARIANT_TRUE;
}
{
// Macro Name
CComVariant varArgs_param1(L"HTMLConvert");
// Macro Param 1: RangeAndChartToConvert
CComVariant varArgs_param2(lRangeAndChartToConvertSafeArray);
// Macro Param 2: UseExistingFile
CComVariant varArgs_param3(false);
// Macro Param 3: UseFrontPageForExistingFile
CComVariant varArgs_param4(false);
// Macro Param 4: AddToFrontPageWeb
CComVariant varArgs_param5(false);
// Macro Param 5: CodePage
CComVariant varArgs_param6((long)1252);
// Macro Param 6: HTMLFilePath
CComVariant varArgs_param7(m_To);
// Macro Param 7: ExistingFilePath
CComVariant varArgs_param8(L"");
// Macro Param 8: TitleFullPage
CComVariant varArgs_param9(lDocumentTitleResult);
// Macro Param 9: HeaderFullPage
CComVariant varArgs_param10(lDocumentTitleResult);
// Macro Param 10: DescriptionFullPage
CComVariant varArgs_param11(lDocumentDescription);
// Macro Param 11: LineBeforeTableFullPage
CComVariant varArgs_param12(lLineBeforeTable);
// Macro Param 12: LineAfterTableFullPage
CComVariant varArgs_param13(false);
// Macro Param 13: LastUpdate
CComVariant varArgs_param14;
// Macro Param 14: NameFullPage
CComVariant varArgs_param15;
// Macro Param 15: EmailFullPage
CComVariant varArgs_param16;
CComVariant varArgs[16] = {
varArgs_param16,
varArgs_param15,
varArgs_param14,
varArgs_param13,
varArgs_param12,
varArgs_param11,
varArgs_param10,
varArgs_param9,
varArgs_param8,
varArgs_param7,
varArgs_param6,
varArgs_param5,
varArgs_param4,
varArgs_param3,
varArgs_param2,
varArgs_param1
};
CComVariant lRunHtmlConvertResult;
{
// We'd rather use the fastidious 'Invoke' code instead of the shorter 'InvokeN' call
// because it allows us to catch exceptions and if the MACRO is not found, we do not
// get an error code but rather an exception...
//lResult = lApplicationDriver.InvokeN( L"Run", &varArgs[0], 7, &lRunHtmlConvertResult );
long lDispId_Application_Run;
lResult = lApplicationDriver.GetIDOfName(L"Run", &lDispId_Application_Run);
if (SUCCEEDED(lResult))
{
EXCEPINFO pExcepInfo;
unsigned int puArgErr = 0;
DISPPARAMS dispparams = { &varArgs[0], NULL, 16, 0 };
lResult = ((IDispatch *)lApplicationDriver)->Invoke(
lDispId_Application_Run,
IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&lRunHtmlConvertResult,
&pExcepInfo,
&puArgErr);
if (lResult == DISP_E_EXCEPTION)
{
ATLTRACE("EXCEPTION - Source: %s - Description: %s\n",CString(pExcepInfo.bstrSource),CString(pExcepInfo.bstrDescription));
}
else if ( (lResult == DISP_E_TYPEMISMATCH) || (lResult == DISP_E_PARAMNOTFOUND) )
{
ATLTRACE("PARAMETER ERROR - ArgPos: %d\n",puArgErr);
}
}
}
if (SUCCEEDED(lResult))
ATLTRACE("htmlconvert SUCCESS\n");
else
ATLTRACE("htmlconvert FAILURE\n");
}
DestroyOneDimArray(lRangeAndChartToConvertSafeArray);
}
return lResult;
}
HRESULT TExcelConverter::OnSave(LPDISPATCH pDisp)
{
if (GetCurrentVersion() > 8)
return OnSave_Excel2000(pDisp);
return OnSave_Excel97(pDisp);
}
HRESULT TExcelConverter::OnClose(LPDISPATCH pDisp)
{
// For now, let's just have the default behavior, that is close the xls doxument
// To make things cleaner, we might want to close the html.xla library as well, but
// as it is closed anyway when Excel is closed, let's get rid of this...
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lCloseResult;
CComVariant lSaveChanges(false);
lCloseResult = lDocumentDriver.Invoke1(L"Close", &lSaveChanges);
return lCloseResult;
}
HRESULT TExcelConverter::OnPostProcessDocument(LPDISPATCH pDisp)
{
if (GetCurrentVersion() <= 8)
return E_NOTIMPL;
// On some IE 5.0 versions, the HTML source generated by Word 2000 contains some
// attributes that make images not to display properly.
// Therefore, we will rewrite those HTML source parts
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lResult;
CString lFromFileContent;
CStdioFile lFromFile;
if (lFromFile.Open(CString(m_To), CFile::modeRead))
{
{
const int bufferSize = 4096;
BYTE buffer[bufferSize];
memset(&buffer,0,bufferSize);
for (;;)
{
int bytesRead = lFromFile.Read(buffer,bufferSize);
if (bytesRead <= 0)
{
break;
}
buffer[bytesRead] = 0;
lFromFileContent += buffer;
}
}
lFromFile.Close();
}
if (!lFromFileContent.IsEmpty())
{
// Let's do our post-processing here
{
// On some IE 5.0 versions, we have issues with images not displaying correctly.
// It seems that it is due to the 'class=shape' attribute that Word put on IMG tags...
// Therefore, let's rename the '.shape' style
lFromFileContent.Replace( _T(".shape"), _T(".shap0") );
lFromFileContent.Replace( _T(".SHAPE"), _T(".SHAP0") );
CString lResultBuffer;
lResult = OnPostProcessDocument_RemoveConditionalComments(pDisp, lFromFileContent, lResultBuffer);
if (SUCCEEDED(lResult))
{
lFromFileContent = lResultBuffer;
}
lResultBuffer.Empty();
lResult = OnPostProcessDocument_RemoveXmlNamespaces(pDisp, lFromFileContent, lResultBuffer);
if (SUCCEEDED(lResult))
{
lFromFileContent = lResultBuffer;
}
}
// And then, let's save our post-processed document back
CStdioFile lToFile;
if (lToFile.Open(CString(m_To), CFile::modeWrite | CFile::modeCreate))
{
lToFile.Write(
lFromFileContent.GetBuffer(1),
lFromFileContent.GetLength());
lToFile.Flush();
lToFile.Close();
}
}
return S_OK;
}
HRESULT TExcelConverter::DisableAlerts()
{
HRESULT lResult;
CComVariant lDisplayAlertsValue(false);
lResult = m_OfficeAppDriver.PutPropertyByName(L"DisplayAlerts", &lDisplayAlertsValue);
ATLASSERT(SUCCEEDED(lResult));
return lResult;
}
HRESULT TExcelConverter::CreateRedimOneDimArray(VARIANT& varSrc, DWORD dwSize)
{
HRESULT lResult;
UINT nDim;
// Clear VARIANT and re-create SafeArray if necessary
if ( (varSrc.vt != (VT_VARIANT | VT_ARRAY)) || ((nDim = ::SafeArrayGetDim(varSrc.parray)) != 1) )
{
lResult = ::VariantClear(&varSrc);
ASSERT( SUCCEEDED(lResult) );
varSrc.vt = VT_VARIANT | VT_ARRAY;
SAFEARRAYBOUND bound;
bound.cElements = dwSize;
bound.lLbound = 0;
varSrc.parray = ::SafeArrayCreate(VT_VARIANT, 1, &bound);
if (varSrc.parray == NULL)
return E_FAIL;
}
else
{
// Must redimension array if necessary
long lLower, lUpper;
lResult = ::SafeArrayGetLBound(varSrc.parray, 1, &lLower);
ASSERT( SUCCEEDED(lResult) );
lResult = ::SafeArrayGetUBound(varSrc.parray, 1, &lUpper);
ASSERT( SUCCEEDED(lResult) );
// Upper bound should always be greater than lower bound
long lSize = lUpper - lLower;
if (lSize < 0)
{
lSize = 0;
}
if ((DWORD)lSize != dwSize)
{
SAFEARRAYBOUND bound;
bound.cElements = dwSize;
bound.lLbound = lLower;
lResult = ::SafeArrayRedim(varSrc.parray, &bound);
ASSERT( SUCCEEDED(lResult) );
}
}
return S_OK;
}
HRESULT TExcelConverter::GetOneDimArrayElemCount(VARIANT& varSrc, long* dwSize)
{
if (!dwSize)
return S_FALSE;
HRESULT lResult;
UINT nDim;
if ( (varSrc.vt != (VT_VARIANT | VT_ARRAY)) || ((nDim = ::SafeArrayGetDim(varSrc.parray)) != 1) )
{
return E_FAIL;
}
else
{
long lLower, lUpper;
lResult = ::SafeArrayGetLBound(varSrc.parray, 1, &lLower);
ASSERT( SUCCEEDED(lResult) );
lResult = ::SafeArrayGetUBound(varSrc.parray, 1, &lUpper);
ASSERT( SUCCEEDED(lResult) );
long lElemCount = lUpper - lLower;
if (lElemCount < 0)
lElemCount = 0;
else
lElemCount++;
*dwSize = lElemCount;
}
return S_OK;
}
HRESULT TExcelConverter::DestroyOneDimArray(VARIANT& varSrc)
{
HRESULT lResult;
if ( (varSrc.vt != (VT_VARIANT | VT_ARRAY)) )
{
return E_FAIL;
}
else
{
lResult = ::SafeArrayDestroy(varSrc.parray);
ASSERT( SUCCEEDED(lResult) );
}
return S_OK;
}
/**************************************/
/***** class TPowerPointConverter *****/
/**************************************/
TPowerPointConverter::TPowerPointConverter()
: TOfficeConverter()
{
}
HRESULT TPowerPointConverter::Convert()
{
HRESULT lResult;
CComBSTR lProgID;
lResult = GetApplicationProgID(&lProgID);
if (SUCCEEDED(lResult))
lResult = ConvertDocument(lProgID, L"Presentations");
return lResult;
}
HRESULT TPowerPointConverter::GetSaveAsConvertFormat(DWORD* pFormatResult)
{
if (!pFormatResult)
return E_INVALIDARG;
if (GetCurrentVersion() > 8)
{
if ( m_lSaveAsConvertFormat.vt == VT_I4 )
{
// already computed
*pFormatResult = m_lSaveAsConvertFormat.iVal;
return S_OK;
}
// We must get the HTML Format Number from PowerPoint TypeLib
HRESULT lResult;
long lGIFFileFormat;
lResult = GetEnumConstantFromTypeLib(L"PpSaveAsFileType",L"ppSaveAsGIF",&lGIFFileFormat);
if (SUCCEEDED(lResult))
{
m_lSaveAsConvertFormat = CComVariant(lGIFFileFormat,VT_I4);
*pFormatResult = lGIFFileFormat;
return S_OK;
}
else
{
return E_FAIL;
}
}
else
{
// Previous version of PowerPoint did not support 'Save As... HTML'
return E_NOTIMPL;
}
}
HRESULT TPowerPointConverter::GetConvertedDocumentMime(BSTR* pResMime)
{
*pResMime = CComBSTR(L"text/html").Copy();
return S_OK;
}
HRESULT TPowerPointConverter::OnOpen(LPDISPATCH pDisp, VARIANT* pResult)
{
CComDispatchDriver lDocumentsDriver(pDisp);
CComVariant lOpenResult;
HRESULT lResult;
// The following call is supported by PowerPoint 97, 2000 and plus...
{
CComVariant varArgs_param1(m_From); // FileName
CComVariant varArgs_param2(true); // ReadOnly
CComVariant varArgs_param3(false); // Untitled
CComVariant varArgs_param4(false); // WithWindow
CComVariant varArgs[4] = {
varArgs_param4,
varArgs_param3,
varArgs_param2,
varArgs_param1
};
long lDispId_Documents_Open;
lResult = lDocumentsDriver.GetIDOfName(L"Open", &lDispId_Documents_Open);
if (SUCCEEDED(lResult))
{
EXCEPINFO pExcepInfo;
unsigned int puArgErr = 0;
DISPPARAMS dispparams = { &varArgs[0], NULL, 4, 0 };
lResult = ((IDispatch *)lDocumentsDriver)->Invoke(
lDispId_Documents_Open,
IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&lOpenResult,
&pExcepInfo,
&puArgErr);
if (SUCCEEDED(lResult) && (lOpenResult.vt == VT_DISPATCH))
{
lOpenResult.Detach(pResult);
}
}
}
return lResult;
}
HRESULT TPowerPointConverter::OnSave(LPDISPATCH pDisp)
{
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lResult;
CComVariant lTo(m_To);
CComVariant lFilterName;
if (this->IsExportGraphicFilterInstalled(_T("image/gif")))
{
lFilterName = CComVariant(L"gif");
}
else if (this->IsExportGraphicFilterInstalled(_T("image/jpeg")))
{
lFilterName = CComVariant(L"jpg");
}
if (lFilterName.vt != VT_EMPTY)
{
lResult = lDocumentDriver.Invoke2(L"Export", &lTo, &lFilterName);
ATLASSERT(SUCCEEDED(lResult));
}
else
{
if (GetCurrentVersion() > 8)
{
// In the PowerPoint 2000 & + case, we still have the possibility to
// use the 'Save As... HTML' feature
DWORD lConvertFormat = 0;
lResult = GetSaveAsConvertFormat(&lConvertFormat);
if (SUCCEEDED(lResult))
{
CComVariant lFormat(lConvertFormat, VT_I4);
lResult = lDocumentDriver.Invoke2(L"SaveAs", &lTo, &lFormat);
ATLASSERT(SUCCEEDED(lResult));
}
}
else
{
// Else, we cannot export therefore we fail
return E_FAIL;
}
}
if (!SUCCEEDED(lResult))
return lResult;
// At last, now that we have generated the 'graphic' files, let's generate the
// HTML file putting together all of them
TStringArray lGeneratedFilesArray;
CString lToDirectory(m_To);
TPath lPath(lToDirectory);
lPath.RemoveFileSpec();
/* BOOL bResFileList = */ TPath::GetFileListInDirectory(lToDirectory,TRUE,FALSE,lGeneratedFilesArray);
if (!lGeneratedFilesArray.isEmpty())
{
// First, let's sort the array by creation date
TStringArray lDuplicateGeneratedFilesArray;
TStringIterator* lIter = lGeneratedFilesArray.elements();
while (lIter && lIter->hasMoreElements())
{
lDuplicateGeneratedFilesArray.addElement(lIter->nextElement());
}
delete lIter;
TStringArray lSortedGeneratedFilesArray;
int lDuplicateGeneratedFilesArraySize = lDuplicateGeneratedFilesArray.size();
for (int ii = 0; ii < lDuplicateGeneratedFilesArraySize; ii++)
{
int lFoundIndex = 0;
CTime lFoundCreationTime;
for (int jj = 0; jj < lDuplicateGeneratedFilesArray.size(); jj++)
{
TString lCurFile = lDuplicateGeneratedFilesArray.elementAt(jj);
CFileStatus lFileStatus;
CFile::GetStatus(lCurFile,lFileStatus);
CTime lCurFileCreationTime = lFileStatus.m_ctime;
if ( (jj == 0) || (lCurFileCreationTime < lFoundCreationTime) )
{
lFoundCreationTime = lCurFileCreationTime;
lFoundIndex = jj;
}
}
lSortedGeneratedFilesArray.addElement(lDuplicateGeneratedFilesArray.elementAt(lFoundIndex));
lDuplicateGeneratedFilesArray.removeElementAt(lFoundIndex);
}
// Generate HTML file beside the graphic files
CString lToFileName;
CString lToPath(m_To);
TPath::FindFileName(lToPath, lToFileName);
CString lToGraphicFilesDirectory(lSortedGeneratedFilesArray.elementAt(0));
TPath::RemoveFileSpec(lToGraphicFilesDirectory);
CString lHtmlFilePath(lToGraphicFilesDirectory);
TPath lPath(lHtmlFilePath);
lPath.AddPath(lToFileName);
CStdioFile lFile;
if (lFile.Open(lHtmlFilePath, CFile::modeWrite | CFile::modeCreate))
{
lFile.WriteString("");
for (int ii = 0; ii < lSortedGeneratedFilesArray.size(); ii++)
{
CString lCurImageSrc = lSortedGeneratedFilesArray.elementAt(ii);
CString lCurImageSrcFileName;
TPath::FindFileName(lCurImageSrc,lCurImageSrcFileName);
lFile.WriteString("
");
if (ii != lSortedGeneratedFilesArray.size() - 1)
{
lFile.WriteString("\r\n");
lFile.WriteString("
\r\n");
}
}
lFile.WriteString("");
lFile.Close();
}
}
return lResult;
}
HRESULT TPowerPointConverter::OnClose(LPDISPATCH)
{
return E_NOTIMPL;
}
HRESULT TPowerPointConverter::OnPostProcessDocument(LPDISPATCH pDisp)
{
if (GetCurrentVersion() <= 8)
return E_NOTIMPL;
// On some IE 5.0 versions, the HTML source generated by Word 2000 contains some
// attributes that make images not to display properly.
// Therefore, we will rewrite those HTML source parts
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lResult;
CString lFromFileContent;
CStdioFile lFromFile;
if (lFromFile.Open(CString(m_To), CFile::modeRead))
{
{
const int bufferSize = 4096;
BYTE buffer[bufferSize];
memset(&buffer,0,bufferSize);
for (;;)
{
int bytesRead = lFromFile.Read(buffer,bufferSize);
if (bytesRead <= 0)
{
break;
}
buffer[bytesRead] = 0;
lFromFileContent += buffer;
}
}
lFromFile.Close();
}
if (!lFromFileContent.IsEmpty())
{
// Let's do our post-processing here
{
// On some IE 5.0 versions, we have issues with images not displaying correctly.
// It seems that it is due to the 'class=shape' attribute that Word put on IMG tags...
// Therefore, let's rename the '.shape' style
lFromFileContent.Replace( _T(".shape"), _T(".shap0") );
lFromFileContent.Replace( _T(".SHAPE"), _T(".SHAP0") );
CString lResultBuffer;
lResult = OnPostProcessDocument_RemoveConditionalComments(pDisp, lFromFileContent, lResultBuffer);
if (SUCCEEDED(lResult))
{
lFromFileContent = lResultBuffer;
}
lResultBuffer.Empty();
lResult = OnPostProcessDocument_RemoveXmlNamespaces(pDisp, lFromFileContent, lResultBuffer);
if (SUCCEEDED(lResult))
{
lFromFileContent = lResultBuffer;
}
}
// And then, let's save our post-processed document back
CStdioFile lToFile;
if (lToFile.Open(CString(m_To), CFile::modeWrite | CFile::modeCreate))
{
lToFile.Write(
lFromFileContent.GetBuffer(1),
lFromFileContent.GetLength());
lToFile.Flush();
lToFile.Close();
}
}
return S_OK;
}/*------------ TOfficeConverter.h ------------*/
#ifndef _T_Office_Converter_h_
#define _T_Office_Converter_h_
// MAIN INCLUDE
#include "TOfficeHelper.h"
// OTHER INCLUDES
#include
#include "TStringArray.h"
#include "TPath.h"
#include "TErr.h"
#include "TIEConditionalCommentsParser.h"
// DEFINES
#ifdef _DEBUG
#define _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib 0
#endif // _DEBUG
/****************************************/
/***** TOfficeConverter Error Codes *****/
/****************************************/
#define OFFICECONVERTER_E_APPLICATION_CREATION_FAILED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 200)
#define OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 201)
#define OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 202)
#define OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 203)
#define OFFICECONVERTER_E_APPLICATION_ENUMERATE_GENERATED_FILES_FAILED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 204)
/*******************************************/
/***** template class TOfficeConverter *****/
/*******************************************/
template
class TOfficeConverter : public theOfficeHelper
{
public:
TOfficeConverter()
: theOfficeHelper()
{
m_lSaveAsConvertFormat.Clear();
}
virtual ~TOfficeConverter()
{
// Release Office App Object
HRESULT lResult;
lResult = UninitializeOfficeAppDriver();
ATLASSERT(SUCCEEDED(lResult));
}
virtual HRESULT Convert() = 0;
virtual HRESULT GetSaveAsConvertFormat(DWORD* pFormatResult) = 0;
virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime) = 0;
void SetSource(LPCTSTR pFrom) { m_From = pFrom; }
void SetTarget(LPCTSTR pTo) { m_To = pTo; }
void GetExportedFilesList(TStringArray& pResultArray)
{
if (!pResultArray.isEmpty())
pResultArray.removeAllElements();
for (int ii = 0; ii < m_ExportedFilesList.size(); ii++)
{
pResultArray.addElement(m_ExportedFilesList.elementAt(ii));
}
}
protected:
virtual HRESULT OnVersion(BSTR) { return E_NOTIMPL; }
virtual HRESULT OnOpen(LPDISPATCH, VARIANT*) { return E_NOTIMPL; }
virtual HRESULT OnSave(LPDISPATCH) { return E_NOTIMPL; }
virtual HRESULT OnClose(LPDISPATCH) { return E_NOTIMPL; }
virtual HRESULT OnPostProcessDocument(LPDISPATCH) { return E_NOTIMPL; }
virtual HRESULT OnEnumerateGeneratedFiles(LPDISPATCH) { return E_NOTIMPL; }
virtual HRESULT DisableAlerts() { return E_NOTIMPL; }
virtual bool GetVisible() { return false; }
HRESULT GetInitialVisibleStateForQuitHandling(VARIANT* pInitialVisibleStateResult)
{
// This method should be virtual but it is called from the TOfficeConverter destructor and we
// do not have the virtual table of our specialized object anymore!!!
// Therfore, let's be really dirty...
if (m_AppName.CompareNoCase(CString("powerpoint")) == 0)
{
*pInitialVisibleStateResult = m_InitialVisibleState;
return S_OK;
}
return E_NOTIMPL;
}
HRESULT ConvertDocument(LPCWSTR pAppProgID, LPCWSTR pDocumentsName)
{
HRESULT lResult;
// Initialize generated files list
m_ExportedFilesList.removeAllElements();
// Make sure the Office App Object is created
if (!m_OfficeAppDriver)
{
lResult = InitializeOfficeAppDriver();
ATLASSERT(SUCCEEDED(lResult) && m_OfficeAppDriver);
if (!(SUCCEEDED(lResult) && m_OfficeAppDriver))
{
return lResult;
}
}
DisableAlerts();
CComVariant lValue;
lResult = m_OfficeAppDriver.GetPropertyByName(L"Version", &lValue);
ATLASSERT(SUCCEEDED(lResult));
// Do some special processing on version
if (SUCCEEDED(lResult) && lValue.vt == VT_BSTR)
{
lResult = OnVersion(lValue.bstrVal);
if (FAILED(lResult) && lResult != E_NOTIMPL)
{
// Release Office App Object
// -> NO - It will be done when the converter is destroyed
return lResult;
}
}
// Open source document
CComVariant lDocumentsValue;
CComPtr lDocument;
lResult = m_OfficeAppDriver.GetPropertyByName(pDocumentsName, &lDocumentsValue);
ATLASSERT(SUCCEEDED(lResult) && lDocumentsValue.vt == VT_DISPATCH);
if (SUCCEEDED(lResult) && lDocumentsValue.vt == VT_DISPATCH)
{
CComVariant lOpenResult;
lResult = OnOpen(lDocumentsValue.pdispVal, &lOpenResult);
if (lResult == E_NOTIMPL)
{
CComDispatchDriver lDocumentsDriver(lDocumentsValue.pdispVal);
CComVariant lFrom(m_From);
lResult = lDocumentsDriver.Invoke1(L"Open", &lFrom, &lOpenResult);
}
ATLASSERT(SUCCEEDED(lResult) && lOpenResult.vt == VT_DISPATCH);
if (SUCCEEDED(lResult) && lOpenResult.vt == VT_DISPATCH)
{
lDocument = lOpenResult.pdispVal;
CComDispatchDriver lDocumentDriver(lDocument);
lResult = OnSave(lDocument);
if (lResult == E_NOTIMPL)
{
DWORD lConvertFormat = 0;
lResult = GetSaveAsConvertFormat(&lConvertFormat);
if (SUCCEEDED(lResult))
{
CComVariant lTo(m_To);
CComVariant lFormat(lConvertFormat, VT_I4);
lResult = lDocumentDriver.Invoke2(L"SaveAs", &lTo, &lFormat);
ATLASSERT(SUCCEEDED(lResult));
}
}
if (!SUCCEEDED(lResult))
{
lResult = OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED;
}
HRESULT lCloseResult;
lCloseResult = OnClose(lDocument);
if (lCloseResult == E_NOTIMPL)
{
lCloseResult = lDocumentDriver.Invoke0(L"Close");
}
ATLASSERT(SUCCEEDED(lCloseResult));
if (!SUCCEEDED(lCloseResult))
{
CComBSTR lAppName;
GetCurrentVersionFullAppName(&lAppName);
TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__,
_T("Error (0x%1!x!) when closing the [%2] document"), lCloseResult, (CString(lAppName).IsEmpty()?_T("??"):CString(lAppName)));
}
HRESULT lPostProcessDocumentResult;
lPostProcessDocumentResult = OnPostProcessDocument(lDocument);
if ( (lPostProcessDocumentResult != E_NOTIMPL) && (!SUCCEEDED(lPostProcessDocumentResult)) )
{
CComBSTR lAppName;
GetCurrentVersionFullAppName(&lAppName);
TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__,
_T("Error (0x%1!x!) when post-processing the [%2] document"), lPostProcessDocumentResult, (CString(lAppName).IsEmpty()?_T("??"):CString(lAppName)));
}
HRESULT lEnumerateGeneratedFilesResult;
lEnumerateGeneratedFilesResult = OnEnumerateGeneratedFiles(lDocument);
if (lEnumerateGeneratedFilesResult == E_NOTIMPL)
{
CString lTo(m_To);
TPath lPath(lTo);
lPath.RemoveFileSpec();
BOOL bResFileList = TPath::GetFileListInDirectory(lTo,TRUE,FALSE,m_ExportedFilesList);
lEnumerateGeneratedFilesResult = (bResFileList?S_OK:E_FAIL);
}
ATLASSERT(SUCCEEDED(lEnumerateGeneratedFilesResult));
if (!SUCCEEDED(lEnumerateGeneratedFilesResult))
{
lResult = OFFICECONVERTER_E_APPLICATION_ENUMERATE_GENERATED_FILES_FAILED;
}
}
else
{
if (lResult != OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED)
{
lResult = OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED;
}
}
}
// Release Office App Object
// -> NO - It will be done when the converter is destroyed
return lResult;
}
HRESULT GetEnumNameFromTypeLib(BSTR pEnumName, ITypeInfo** pTypeInfo)
{
HRESULT lResult;
if ((!pEnumName) || (!pTypeInfo))
return E_INVALIDARG;
if (!m_OfficeAppDriver)
{
// Create Office App Object
lResult = InitializeOfficeAppDriver();
ATLASSERT(SUCCEEDED(lResult) && m_OfficeAppDriver);
if (!(SUCCEEDED(lResult) && m_OfficeAppDriver))
return E_FAIL;
}
CComPtr lOfficeAppTypeLib;
CComPtr lTypeInfo_OfficeApp;
lResult = ((IDispatch*)m_OfficeAppDriver)->GetTypeInfo(0, LOCALE_USER_DEFAULT, &lTypeInfo_OfficeApp);
if (!(SUCCEEDED(lResult) && lTypeInfo_OfficeApp))
return E_FAIL;
unsigned int lNotUsed = 0;
lResult = lTypeInfo_OfficeApp->GetContainingTypeLib(&lOfficeAppTypeLib,&lNotUsed);
if (!SUCCEEDED(lResult))
return E_FAIL;
CComPtr lOfficeAppTypeLib_Comp;
lResult = lOfficeAppTypeLib->GetTypeComp(&lOfficeAppTypeLib_Comp);
HRESULT lHashVal_EnumName;
lHashVal_EnumName = LHashValOfNameSys(SYS_WIN32,LOCALE_USER_DEFAULT,pEnumName);
CComPtr lTypeComp_EnumName;
return lOfficeAppTypeLib_Comp->BindType(pEnumName, lHashVal_EnumName, pTypeInfo, &lTypeComp_EnumName);
}
HRESULT GetEnumConstantFromTypeLib(BSTR pEnumName, BSTR pConstantInEnumName, long* pConstantValue)
{
if ((!pEnumName) || (!pConstantInEnumName) || (!pConstantValue))
return E_INVALIDARG;
HRESULT lResult;
CComPtr lTypeInfo_EnumName;
lResult = GetEnumNameFromTypeLib(pEnumName, &lTypeInfo_EnumName);
if (FAILED(lResult) || (lTypeInfo_EnumName == NULL))
return E_FAIL;
TYPEATTR* lTypeAttr_EnumName = NULL;
lResult = lTypeInfo_EnumName->GetTypeAttr(&lTypeAttr_EnumName);
if (FAILED(lResult) || (lTypeAttr_EnumName == NULL))
return E_FAIL;
if (lTypeAttr_EnumName->typekind == TKIND_ENUM)
{
for (int ii = 0; ii < lTypeAttr_EnumName->cVars; ii++)
{
VARDESC* lCurVarDesc = NULL;
lResult = lTypeInfo_EnumName->GetVarDesc(ii,&lCurVarDesc);
if (FAILED(lResult) || (lCurVarDesc == NULL))
continue;
long idMember = lCurVarDesc->memid;
CComBSTR lCurVar_Name;
lResult = lTypeInfo_EnumName->GetDocumentation(idMember, &lCurVar_Name, NULL, NULL, NULL);
if (SUCCEEDED(lResult) && lCurVar_Name)
{
if (!wcsicmp(pConstantInEnumName, lCurVar_Name))
{
if (lCurVarDesc->varkind == VAR_CONST)
{
ASSERT(lCurVarDesc->lpvarValue->vt == VT_I4);
long lCurVarDesc_Value = lCurVarDesc->lpvarValue->iVal;
ATLTRACE("Name: %s - Value: %d\n",CString(lCurVar_Name),lCurVarDesc_Value);
#if _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib
CString lTmp;
lTmp.Format(
"Name: %s - Value: %d",
CString(lCurVar_Name),
lCurVarDesc_Value);
::MessageBox(NULL,lTmp,CString("GetEnumConstantFromTypeLib"),MB_OK);
#endif // _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib
// Yeepee!! We have our result!
// 1- Let's release everything we got
lTypeInfo_EnumName->ReleaseVarDesc(lCurVarDesc);
lTypeInfo_EnumName->ReleaseTypeAttr(lTypeAttr_EnumName);
// 2- Let's return our result
*pConstantValue = lCurVarDesc_Value;
return S_OK;
}
}
}
lTypeInfo_EnumName->ReleaseVarDesc(lCurVarDesc);
}
}
lTypeInfo_EnumName->ReleaseTypeAttr(lTypeAttr_EnumName);
// Release Office App Object
// -> NO - It will be done when the converter is destroyed
return E_FAIL;
}
HRESULT GetPropertyIDFromTypeLib(BSTR pObjectName, BSTR pPropertyName, DISPID* pId)
{
if ((!pObjectName) || (!pPropertyName) || (!pId))
return E_INVALIDARG;
HRESULT lResult;
CComPtr lTypeInfo_ObjectName;
lResult = GetEnumNameFromTypeLib(pObjectName, &lTypeInfo_ObjectName);
if (FAILED(lResult) || (lTypeInfo_ObjectName == NULL))
return E_FAIL;
TYPEATTR* lTypeAttr_ObjectName = NULL;
lResult = lTypeInfo_ObjectName->GetTypeAttr(&lTypeAttr_ObjectName);
if (FAILED(lResult) || (lTypeAttr_ObjectName == NULL))
return E_FAIL;
if (lTypeAttr_ObjectName->typekind == TKIND_DISPATCH)
{
for (int ii = 0; ii < lTypeAttr_ObjectName->cFuncs; ii++)
{
VARDESC* lCurVarDesc = NULL;
lResult = lTypeInfo_ObjectName->GetVarDesc(ii,&lCurVarDesc);
if (FAILED(lResult) || (lCurVarDesc == NULL))
continue;
long idMember = lCurVarDesc->memid;
CComBSTR lCurVar_Name;
lResult = lTypeInfo_ObjectName->GetDocumentation(idMember, &lCurVar_Name, NULL, NULL, NULL);
if (SUCCEEDED(lResult) && lCurVar_Name)
{
if (!wcsicmp(pPropertyName, lCurVar_Name))
{
if (lCurVarDesc->varkind == VAR_DISPATCH)
{
ATLTRACE("Name: %s - Value: %d\n",CString(lCurVar_Name), idMember);
#if _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib
CString lTmp;
lTmp.Format("Name: %s - Value: %d", CString(lCurVar_Name), idMember);
::MessageBox(NULL,lTmp,CString("GetPropertyIDFromTypeLib"),MB_OK);
#endif // _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib
// Yeepee!! We have our result!
// 1- Let's release everything we got
lTypeInfo_ObjectName->ReleaseVarDesc(lCurVarDesc);
lTypeInfo_ObjectName->ReleaseTypeAttr(lTypeAttr_ObjectName);
// 2- Let's return our result
*pId = idMember;
return S_OK;
}
}
}
lTypeInfo_ObjectName->ReleaseVarDesc(lCurVarDesc);
}
}
lTypeInfo_ObjectName->ReleaseTypeAttr(lTypeAttr_ObjectName);
// Release Office App Object
// -> NO - It will be done when the converter is destroyed
return E_FAIL;
}
HRESULT InitializeOfficeAppDriver()
{
HRESULT lResult;
CComPtr lOfficeAppResult;
// Create Office App Object
CComBSTR lProgID;
lResult = GetApplicationProgID(&lProgID);
if (FAILED(lResult))
return E_FAIL;
lResult = CreateApplication(lProgID, &lOfficeAppResult);
ATLASSERT(SUCCEEDED(lResult) && lOfficeAppResult);
if (FAILED(lResult) || (lOfficeAppResult == NULL))
return OFFICECONVERTER_E_APPLICATION_CREATION_FAILED;
m_OfficeAppDriver = lOfficeAppResult;
CComVariant lInitialVisibleState;
lResult = m_OfficeAppDriver.GetPropertyByName(L"Visible", &lInitialVisibleState);
ATLASSERT(SUCCEEDED(lResult));
if (SUCCEEDED(lResult))
{
m_InitialVisibleState = lInitialVisibleState;
}
// Set the show State
CComVariant lVisible(GetVisible());
lResult = m_OfficeAppDriver.PutPropertyByName(L"Visible", &lVisible);
ATLASSERT(SUCCEEDED(lResult));
return S_OK;
}
HRESULT UninitializeOfficeAppDriver()
{
// Let's be sure we quit properly the office app
if (m_OfficeAppDriver == NULL)
return S_OK;
HRESULT lResult = S_OK;
CComVariant lInitialVisibleState;
if ( (GetInitialVisibleStateForQuitHandling(&lInitialVisibleState) == E_NOTIMPL) || (lInitialVisibleState.bVal == CComVariant(VARIANT_FALSE).bVal) )
{
lResult = m_OfficeAppDriver.Invoke0(L"Quit");
ATLASSERT(SUCCEEDED(lResult));
if (!SUCCEEDED(lResult))
{
CComBSTR lAppName;
GetCurrentVersionFullAppName(&lAppName);
TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__,
_T("Error (0x%1!x!) when quitting the [%2] application"), lResult, (CString(lAppName).IsEmpty()?_T("??"):CString(lAppName)));
}
}
m_OfficeAppDriver.Release();
return lResult;
}
HRESULT OnPostProcessDocument_RemoveConditionalComments(LPDISPATCH pDisp, CString pBufferIn, CString& pBufferOut)
{
if (GetCurrentVersion() <= 8)
return E_NOTIMPL;
CComDispatchDriver lDocumentDriver(pDisp);
HRESULT lResult;
CString lBufferIn = pBufferIn;
CString lBufferOut;
int lBufferInCopyFromPos = 0;
TIEConditionalCommentsCollection* lCollection = NULL;
TIEConditionalCommentsParser lParser;
lResult = lParser.setStringToParse(lBufferIn);
if ( lResult == S_OK )
{
lResult = lParser.getConditionalComments(&lCollection);
if ( (lResult == S_OK) && (lCollection != NULL) )
{
TIEConditionalCommentsCollectionIterator* lIterator = lCollection->elements();
while (lIterator && lIterator->hasMoreElements())
{
TIEConditionalCommentInfo* lCurCCInfo = (TIEConditionalCommentInfo *)lIterator->nextElement();
if ( lCurCCInfo->fBeginningPattern_stgFeature.CompareNoCase(_T("vml")) == 0 )
{
if ( lCurCCInfo->fBeginningPattern_bFeatureVersionComparisonCase )
{
// Let's remove the whole Conditional Comment block
int lCCBlock_BeginPos = lCurCCInfo->fHeader_nBeginPos;
int lCCBlock_EndPos = lCurCCInfo->fEndingPattern_nEndPos;
lBufferOut += lBufferIn.Mid(lBufferInCopyFromPos,lCCBlock_BeginPos-lBufferInCopyFromPos);
lBufferInCopyFromPos = lCCBlock_EndPos;
}
else if ( lCurCCInfo->fBeginningPattern_bFeaturePresenceCase && lCurCCInfo->fBeginningPattern_bFeaturePresenceCase_Negation )
{
// Let's just remove the Conditional Comment tags
int lCCBeginTag_BeginPos = lCurCCInfo->fHeader_nBeginPos;
int lCCBeginTag_EndPos = lCurCCInfo->fBeginningPattern_nEndPos;
int lCCEndTag_BeginPos = lCurCCInfo->fEndingPattern_nBeginPos;
int lCCEndTag_EndPos = lCurCCInfo->fEndingPattern_nEndPos;
lBufferOut += lBufferIn.Mid(lBufferInCopyFromPos,lCCBeginTag_BeginPos-lBufferInCopyFromPos);
lBufferOut += lBufferIn.Mid(lCCBeginTag_EndPos,lCCEndTag_BeginPos-lCCBeginTag_EndPos);
lBufferInCopyFromPos = lCCEndTag_EndPos;
}
}
}
delete lIterator;
}
}
delete lCollection;
lBufferOut += lBufferIn.Mid(lBufferInCopyFromPos);
pBufferOut = lBufferOut;
return S_OK;
}
HRESULT OnPostProcessDocument_RemoveXmlNamespaces(LPDISPATCH pDisp, CString pBufferIn, CString& pBufferOut)
{
if (GetCurrentVersion() <= 8)
return E_NOTIMPL;
CComDispatchDriver lDocumentDriver(pDisp);
CString lBufferIn = pBufferIn;
// We do not want any XML namespace specification global to the document to be kept
// because it causes problems when displayed on Netscape...
// For instance, we want to remove the string below:
// xmlns:v="urn:schemas-microsoft-com:vml"
CString lBufferIn_lowerCase = lBufferIn;
lBufferIn_lowerCase.MakeLower();
CString lPattern_FirstMatchingPattern( _T("xmlns:") );
// *** Detection of the Global XML Namespace Definition beginning pattern ***
// State Diagram: s=="xmlns:" --> E1
// E1 --> E2 (s=="[A-Za-z0-9]")
// E2 --> E2 (s=="[A-Za-z0-9]*")
// E2 --> E3 (s==" ")
// E2 --> E4 (s=="=")
// E3 --> E3 (s==" ")
// E3 --> E4 (s=="=")
// E4 --> E4 (s==" ")
// E4 --> E_OK (s=="\"")
// Error State: E_FAIL
enum eStatesDiagram
{
E_STATE_E1,
E_STATE_E2,
E_STATE_E3,
E_STATE_E4,
E_STATE_E_OK,
E_STATE_E_FAIL,
};
int lSearchPos = 0;
BOOL bSearchOver = FALSE;
while (!bSearchOver)
{
int lPattern_BeginPos = -1;
int lPattern_EndPos = -1;
int lFoundPos = lBufferIn_lowerCase.Find( lPattern_FirstMatchingPattern , lSearchPos );
if (lFoundPos != -1)
{
lPattern_BeginPos = lFoundPos;
int lCurPos = lFoundPos;
lCurPos += lPattern_FirstMatchingPattern.GetLength();
eStatesDiagram lCurrentEngineState = E_STATE_E1;
while ( (lCurrentEngineState != E_STATE_E_OK) && (lCurrentEngineState != E_STATE_E_FAIL) )
{
TCHAR lCurChar = lBufferIn_lowerCase.GetAt(lCurPos);
switch (lCurrentEngineState)
{
case E_STATE_E1:
{
if ( _istalnum( lCurChar ) != 0 )
{
lCurrentEngineState = E_STATE_E2;
lCurPos++;
}
else
lCurrentEngineState = E_STATE_E_FAIL; // Error
break;
}
case E_STATE_E2:
{
if ( _istalnum( lCurChar ) != 0 )
{
lCurrentEngineState = E_STATE_E2;
lCurPos++;
}
else if ( lCurChar == _T(' ') )
{
lCurrentEngineState = E_STATE_E3;
lCurPos++;
}
else if ( lCurChar == _T('=') )
{
lCurrentEngineState = E_STATE_E4;
lCurPos++;
}
else
lCurrentEngineState = E_STATE_E_FAIL; // Error
break;
}
case E_STATE_E3:
{
if ( lCurChar == _T(' ') )
{
lCurrentEngineState = E_STATE_E3;
lCurPos++;
}
else if ( lCurChar == _T('=') )
{
lCurrentEngineState = E_STATE_E4;
lCurPos++;
}
else
lCurrentEngineState = E_STATE_E_FAIL; // Error
break;
}
case E_STATE_E4:
{
if ( lCurChar == _T(' ') )
{
lCurrentEngineState = E_STATE_E4;
lCurPos++;
}
else if ( lCurChar == _T('\"') )
{
lCurrentEngineState = E_STATE_E_OK;
lCurPos++;
lPattern_EndPos = lCurPos;
}
else
lCurrentEngineState = E_STATE_E_FAIL; // Error
break;
}
default:
{
// Error
lCurrentEngineState = E_STATE_E_FAIL;
}
}
}
if (lCurrentEngineState == E_STATE_E_OK)
{
// Success
// Here I've got something like xmlns:v="
// Therefore I must find the ending double-quote and do deletions
int lEndDoubleQuotePos = lBufferIn_lowerCase.Find( _T("\"") , lPattern_EndPos );
if ( lEndDoubleQuotePos != -1 )
{
lBufferIn_lowerCase.Delete( lPattern_BeginPos , (lEndDoubleQuotePos + 1) - lPattern_BeginPos );
lBufferIn.Delete( lPattern_BeginPos , (lEndDoubleQuotePos + 1) - lPattern_BeginPos );
}
lSearchPos = 0;
}
else
{
lSearchPos += lPattern_FirstMatchingPattern.GetLength();
}
}
else
{
bSearchOver = TRUE;
}
}
pBufferOut = lBufferIn;
return S_OK;
}
protected:
CComBSTR m_From;
CComBSTR m_To;
TStringArray m_ExportedFilesList;
CComVariant m_lSaveAsConvertFormat;
CComVariant m_InitialVisibleState;
// m_OfficeAppDriver is initialized by calling InitializeOfficeAppDriver()
// You should always check m_OfficeAppDriver (in fact m_OfficeAppDriver.p) to see if it has been initialized
// before using it
CComDispatchDriver m_OfficeAppDriver;
};
/********************************/
/***** class TWordConverter *****/
/********************************/
class TWordConverter : public TOfficeConverter
{
public:
TWordConverter();
~TWordConverter();
virtual HRESULT Convert();
virtual HRESULT GetSaveAsConvertFormat(DWORD* pFormatResult);
virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime);
virtual HRESULT OnOpen(LPDISPATCH pDisp, VARIANT* pResult);
virtual HRESULT OnSave(LPDISPATCH pDisp);
virtual HRESULT OnClose(LPDISPATCH pDisp);
virtual HRESULT OnPostProcessDocument(LPDISPATCH pDisp);
virtual HRESULT DisableAlerts();
};
/*************************************/
/***** class TWordImageConverter *****/
/*************************************/
class TWordImageConverter : public TWordConverter
{
public:
TWordImageConverter();
virtual HRESULT OnOpen(LPDISPATCH pDisp, VARIANT* pResult);
virtual HRESULT OnEnumerateGeneratedFiles(LPDISPATCH pDisp);
virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime);
protected:
CComBSTR m_ConvertedImageMime;
};
/*********************************/
/***** class TExcelConverter *****/
/*********************************/
class TExcelConverter : public TOfficeConverter
{
public:
TExcelConverter();
virtual HRESULT Convert();
virtual HRESULT GetSaveAsConvertFormat(DWORD* pFormatResult);
virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime);
virtual HRESULT OnOpen(LPDISPATCH pDisp, VARIANT* pResult);
virtual HRESULT OnSave(LPDISPATCH pDisp);
virtual HRESULT OnClose(LPDISPATCH pDisp);
virtual HRESULT OnPostProcessDocument(LPDISPATCH pDisp);
virtual HRESULT DisableAlerts();
protected:
HRESULT CreateRedimOneDimArray(VARIANT& varSrc, DWORD dwSize);
HRESULT GetOneDimArrayElemCount(VARIANT& varSrc, long* dwSize);
HRESULT DestroyOneDimArray(VARIANT& varSrc);
HRESULT OnSave_Excel2000(LPDISPATCH pDisp);
HRESULT OnSave_Excel97(LPDISPATCH pDisp);
};
/**************************************/
/***** class TPowerPointConverter *****/
/**************************************/
class TPowerPointConverter : public TOfficeConverter
{
public:
TPowerPointConverter();
virtual HRESULT Convert();
virtual HRESULT GetSaveAsConvertFormat(DWORD* pFormatResult);
virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime);
virtual HRESULT OnOpen(LPDISPATCH pDisp, VARIANT* pResult);
virtual HRESULT OnSave(LPDISPATCH pDisp);
virtual HRESULT OnClose(LPDISPATCH);
virtual HRESULT OnPostProcessDocument(LPDISPATCH pDisp);
virtual bool GetVisible()
{
if (GetCurrentVersion() < 10)
return true;
return false;
}
};
#endif // _T_Office_Converter_h_
/*------------ TOfficeHelper.cpp ------------*/
#include "stdafx.h"
// MAIN INCLUDE
#include "TOfficeHelper.h"
// OTHER INCLUDES
#include "TPath.h"
#include "TStringArray.h"
#include "TRegKey.h"
#include "TSystemMimeHelper.h"
#include "TOfficeImportMimeHelper.h"
#include "TErr.h"
/*******************************/
/***** class TOfficeHelper *****/
/*******************************/
TOfficeHelper::TOfficeHelper(LPCTSTR pAppName)
: m_AppName(pAppName), m_dwVersion(0)
{
// Init
IsInstalled();
}
BOOL TOfficeHelper::IsInstalled(BSTR* pVersion)
{
return GetCurrentVersion(m_AppName + _T(".Application"), pVersion);
}
HRESULT TOfficeHelper::CanExportToHTML(BSTR pMime)
{
// Use specialized office helpers instead
ASSERT(FALSE);
return E_FAIL;
}
HRESULT TOfficeHelper::GetApplicationProgID(BSTR* pProgIDResult)
{
// Use specialized office helpers instead
ASSERT(FALSE);
return E_NOTIMPL;
}
BOOL TOfficeHelper::GetInstallPath(BSTR* pPath)
{
if (m_InstallPath.IsEmpty())
{
HRESULT lResult;
HKEY lAppKey;
CRegKey lKey;
CString lKeyName;
lAppKey = GetAppKey();
if (lAppKey == NULL)
return FALSE;
lResult = lKey.Open(lAppKey, _T("InstallRoot"), KEY_READ);
::RegCloseKey(lAppKey);
if (lResult != ERROR_SUCCESS)
return FALSE;
DWORD lSize = MAX_PATH;
lResult = lKey.QueryValue(m_InstallPath.GetBufferSetLength(lSize), _T("Path"), &lSize);
m_InstallPath.ReleaseBuffer();
if (lResult != ERROR_SUCCESS)
return FALSE;
}
if (pPath)
*pPath = CComBSTR(m_InstallPath).Detach();
return TRUE;
}
BOOL TOfficeHelper::MinimumVersion(DWORD pVersion)
{
return GetCurrentVersion() >= pVersion;
}
DWORD TOfficeHelper::GetCurrentVersion()
{
if (m_dwVersion == 0 && m_AppName.GetLength())
GetCurrentVersion(m_AppName + _T(".Application"), NULL);
return m_dwVersion;
}
BOOL TOfficeHelper::GetCurrentVersion(LPCTSTR pApp, BSTR* pVersion)
{
if (m_dwVersion == 0)
{
CRegKey lKey;
if (lKey.Open(HKEY_CLASSES_ROOT, pApp, KEY_READ) != ERROR_SUCCESS)
return FALSE;
if (lKey.Open(lKey.m_hKey, _T("CurVer"), KEY_READ) != ERROR_SUCCESS)
return FALSE;
DWORD lSize = 128;
if (lKey.QueryValue(m_AppFullName.GetBufferSetLength(lSize), NULL, &lSize) != ERROR_SUCCESS)
return FALSE;
m_AppFullName.ReleaseBuffer();
m_AppVersion = m_AppFullName.Mid(_tcslen(pApp) + 1);
m_dwVersion = atoi(m_AppVersion);
}
else
{
if (m_AppVersion.IsEmpty())
{
m_AppVersion.Format(_T("%d"), m_dwVersion);
}
}
if (pVersion)
*pVersion = CComBSTR(m_AppVersion).Detach();
return TRUE;
}
BOOL TOfficeHelper::GetCurrentVersionFullAppName(BSTR* pFullAppName)
{
if (m_AppFullName.IsEmpty())
{
if (!GetCurrentVersion(m_AppName + _T(".Application"), NULL))
return FALSE;
ASSERT(!m_AppVersion.IsEmpty());
}
if (pFullAppName)
*pFullAppName = CComBSTR(m_AppFullName).Detach();
return TRUE;
}
BOOL TOfficeHelper::IsExportGraphicFilterInstalled(LPCTSTR pMime)
{
BOOL bResult = FALSE;
if (CString(pMime).IsEmpty())
return FALSE;
CString lKeyPath;
lKeyPath = "Software\\Microsoft\\Shared Tools";
CRegKey lKey;
HRESULT lResult;
lResult = lKey.Open(HKEY_LOCAL_MACHINE, lKeyPath, KEY_READ);
if (lResult == ERROR_SUCCESS)
{
CRegKey lGraphicKey;
lResult = lGraphicKey.Open(lKey.m_hKey, _T("Graphics Filters\\Export"), KEY_READ);
if (lResult == ERROR_SUCCESS)
{
TStringArray lResArray;
GetExportMimes(lGraphicKey.m_hKey, &lResArray);
CString lMime(pMime);
lMime.MakeLower();
if ( lResArray.contains(lMime) )
{
return TRUE;
}
}
}
return bResult;
}
BOOL TOfficeHelper::IsExportTextConverterInstalled(LPCTSTR pMime)
{
BOOL bResult = FALSE;
if (CString(pMime).IsEmpty())
return FALSE;
CString lKeyPath;
lKeyPath = "Software\\Microsoft\\Shared Tools";
CRegKey lKey;
HRESULT lResult;
lResult = lKey.Open(HKEY_LOCAL_MACHINE, lKeyPath, KEY_READ);
if (lResult == ERROR_SUCCESS)
{
CRegKey lTextKey;
lResult = lTextKey.Open(lKey.m_hKey, _T("Text Converters\\Export"), KEY_READ);
if (lResult == ERROR_SUCCESS)
{
TStringArray lResArray;
GetExportMimes(lTextKey.m_hKey, &lResArray);
CString lMime(pMime);
lMime.MakeLower();
if ( lResArray.contains(lMime) )
{
return TRUE;
}
}
}
return bResult;
}
HKEY TOfficeHelper::GetAppKey()
{
CRegKey lKey;
CString lKeyName;
if (m_AppVersion.IsEmpty())
{
if (!GetCurrentVersion(m_AppName + _T(".Application"), NULL))
return NULL;
ASSERT(!m_AppVersion.IsEmpty());
}
lKeyName = _T("Software\\Microsoft\\Office\\") + m_AppVersion + _T(".0\\") + m_AppName;
lKey.Open(HKEY_LOCAL_MACHINE, lKeyName, KEY_READ);
return lKey.Detach();
}
void TOfficeHelper::GetExportMimes(HKEY hKey, TStringArray* pInResArray)
{
HRESULT lResult = ERROR_SUCCESS;
CRegKey lSubKey;
DWORD lIndex;
CString lKeyName;
CString lDefaultValue;
TSystemMimeHelper lHelper;
for (lIndex = 0; lResult != ERROR_NO_MORE_ITEMS; lIndex++)
{
DWORD lSize = 128;
lResult = ::RegEnumKey(hKey, lIndex, lKeyName.GetBufferSetLength(lSize), lSize);
if (lResult == ERROR_SUCCESS)
{
lResult = lSubKey.Open(hKey, lKeyName, KEY_READ);
if (lResult == ERROR_SUCCESS)
{
CString lExtensions;
lResult = lSubKey.QueryValue(lExtensions.GetBufferSetLength(lSize), _T("Extensions"), &lSize);
if (lResult == ERROR_SUCCESS)
{
DWORD lNextExtPos;
CString lExt;
BOOL lEnd = FALSE;
while (!lEnd)
{
lNextExtPos = lExtensions.Find(' ');
if (lNextExtPos != -1)
{
lExt = lExtensions.Mid(0, lNextExtPos);
lExtensions = lExtensions.Mid(lNextExtPos + 1);
}
else
{
lExt = lExtensions;
lEnd = TRUE;
}
lHelper.getMimeTypesFromFileExtension(lExt, &pInResArray);
}
}
}
}
}
}
TOfficeHelper::E_OFFICE_HELPER TOfficeHelper::GetPreferredExportToHTMLHelper(BSTR pMime)
{
HRESULT lResult_PowerPoint;
HRESULT lResult_Excel;
HRESULT lResult_Word;
if (!pMime)
return E_HELPER_UNKNOWN;
TPowerPointHelper lPowerpointHelper;
lResult_PowerPoint = lPowerpointHelper.CanExportToHTML(pMime);
if (lResult_PowerPoint == S_OK)
{
return E_HELPER_POWERPOINT;
}
TExcelHelper lExcelHelper;
lResult_Excel = lExcelHelper.CanExportToHTML(pMime);
if (lResult_Excel == S_OK)
{
return E_HELPER_EXCEL;
}
TWordHelper lWordHelper;
lResult_Word = lWordHelper.CanExportToHTML(pMime);
if (lResult_Word == S_OK)
{
return E_HELPER_WORD;
}
// Error case
if (lResult_Excel == OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED)
{
return E_HELPER_UNKNOWN_EXCEL97_HTMLCONVERTER_MISSING_CASE;
}
else
{
return E_HELPER_UNKNOWN;
}
}
HRESULT TOfficeHelper::CreateApplication(LPCWSTR pName, LPDISPATCH* pDisp)
{
HRESULT lResult;
CLSID clsid;
lResult = CLSIDFromProgID(pName, &clsid);
// Very important: let's other threads and processes do stuffs before we go on
// (it allows for instance a closing PowerPoint instance to shutdown properly...)
::Sleep(100);
// First method to do it
lResult = ::CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)pDisp);
if (SUCCEEDED(lResult))
return lResult;
// Second method to do it !!!
BIND_OPTS bo = { sizeof(BIND_OPTS) };
lResult = ::CoGetObject(pName, &bo, IID_IDispatch, (void**)pDisp);
if (SUCCEEDED(lResult))
return lResult;
// Third method to do it !!!
CComPtr lMoniker;
CComPtr lApp;
lResult = ::CreateClassMoniker(clsid, &lMoniker);
if (SUCCEEDED(lResult))
{
CComPtr lBindCtx;
lResult = ::CreateBindCtx(0, &lBindCtx);
if (SUCCEEDED(lResult) && lBindCtx)
{
// Let's set a deadline for binding operations
// *** The code below crashes on SetBindOptions !!! ***
/*
BIND_OPTS lBindOptions;
lBindOptions.cbStruct = sizeof(BIND_OPTS);
lResult = lBindCtx->GetBindOptions(&lBindOptions);
if ( SUCCEEDED(lResult) )
{
lBindOptions.dwTickCountDeadline = 100;
lResult = lBindCtx->SetBindOptions(&lBindOptions);
}
*/
// Now, let's try some times to create our application instance
for (int ii = 0; ii <= 5; ii++)
{
lResult = lMoniker->BindToObject(lBindCtx, NULL, IID_IUnknown, (void**)&lApp);
if ( SUCCEEDED(lResult) )
{
CComQIPtr lFactory(lApp);
if (lFactory)
{
lResult = lFactory->CreateInstance(NULL, IID_IDispatch, (void**)pDisp);
if ( SUCCEEDED(lResult) )
{
break;
}
}
else
{
lResult = E_FAIL;
}
lApp.Release();
}
::Sleep(1000);
}
}
}
return lResult;
}
/*****************************/
/***** class TWordHelper *****/
/*****************************/
CComVariant TWordHelper::m_bWord97HTMLConverterInstalled;
TWordHelper::TWordHelper()
: TOfficeHelper(_T("Word"))
{
}
HRESULT TWordHelper::CanExportToHTML(BSTR pMime)
{
//////////
// First, let's see if OFFICE can import such MIME
//////////
if (pMime)
{
TOfficeImportMimeHelper* lMimeHelper = new TOfficeImportMimeHelper();
BOOL bResult = lMimeHelper->isMimeTypeSupported(CString(pMime));
delete lMimeHelper;
if (!bResult)
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_SUPPORTED;
}
//////////
// Then, let's define here which MIMEs we want our WORD app to export to HTML
//////////
// In order to simplify things up, let's say that WORD app will be used to export
// every MIME that won't get exported by other office apps, namely EXCEL and POWERPOINT
if (pMime)
{
TExcelHelper lExcelHelper;
if (lExcelHelper.CanExportToHTML(pMime) == S_OK)
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_HANDLED;
TPowerPointHelper lPowerpointHelper;
if (lExcelHelper.CanExportToHTML(pMime) == S_OK)
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_HANDLED;
}
//////////
// Then, let's see if our WORD app is able to export to HTML
//////////
// Word 2000 or +
if (MinimumVersion(9))
{
return S_OK;
}
// Word 97
if (GetCurrentVersion() == 8)
{
// Need to check if the HTML File Converter is installed
BOOL bHTMLConverterInstalled = FALSE;
if ( (m_bWord97HTMLConverterInstalled.vt != VT_EMPTY) )
{
bHTMLConverterInstalled = ((m_bWord97HTMLConverterInstalled.boolVal == VARIANT_TRUE)?TRUE:FALSE);
}
else
{
HRESULT lResult;
CComPtr lWordAppResult;
// Create WORD App Object
CComBSTR lProgID;
lResult = GetApplicationProgID(&lProgID);
if (FAILED(lResult))
{
m_bWord97HTMLConverterInstalled = VARIANT_FALSE;
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED;
}
lResult = CreateApplication(lProgID, &lWordAppResult);
ATLASSERT(SUCCEEDED(lResult) && lWordAppResult);
if (FAILED(lResult) || (lWordAppResult == NULL))
{
m_bWord97HTMLConverterInstalled = VARIANT_FALSE;
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED;
}
CComDispatchDriver lWordAppDriver(lWordAppResult);
// Do not show window
CComVariant lVisible(VARIANT_FALSE);
lResult = lWordAppDriver.PutPropertyByName(L"Visible", &lVisible);
CComVariant lFileConvertersResult;
lResult = lWordAppDriver.GetPropertyByName(L"FileConverters", &lFileConvertersResult);
if (SUCCEEDED(lResult) && lFileConvertersResult.vt == VT_DISPATCH)
{
CComDispatchDriver lFileConvertersDriver(lFileConvertersResult.pdispVal);
CComVariant lFileConvertersCountResult;
lResult = lFileConvertersDriver.GetPropertyByName(L"Count", &lFileConvertersCountResult);
ATLASSERT(SUCCEEDED(lResult) && lFileConvertersCountResult.vt == VT_I4);
if (SUCCEEDED(lResult) && lFileConvertersCountResult.vt == VT_I4)
{
for (int ii = 1; ii <= lFileConvertersCountResult.iVal; ii++)
{
CComVariant lCurFileConverterIdx(ii);
CComVariant lCurFileConverterResult;
lResult = lFileConvertersDriver.Invoke1(L"Item", &lCurFileConverterIdx, &lCurFileConverterResult);
if (SUCCEEDED(lResult) && lCurFileConverterResult.vt == VT_DISPATCH)
{
// Here we have an IFileConverter dispatch
CComDispatchDriver lCurFileConverterDriver(lCurFileConverterResult.pdispVal);
CComVariant lCurFileConverterClassNameResult;
lResult = lCurFileConverterDriver.GetPropertyByName(L"ClassName", &lCurFileConverterClassNameResult);
ATLASSERT(SUCCEEDED(lResult) && lCurFileConverterClassNameResult.vt == VT_BSTR);
if (SUCCEEDED(lResult) && lCurFileConverterClassNameResult.vt == VT_BSTR)
{
if (lCurFileConverterClassNameResult.bstrVal && (!wcsicmp(L"HTML", lCurFileConverterClassNameResult.bstrVal)))
{
bHTMLConverterInstalled = TRUE;
break;
}
}
}
}
}
}
// Release WORD App Object
lResult = lWordAppDriver.Invoke0(L"Quit");
ATLASSERT(SUCCEEDED(lResult));
m_bWord97HTMLConverterInstalled = (bHTMLConverterInstalled?VARIANT_TRUE:VARIANT_FALSE);
}
if (bHTMLConverterInstalled)
return S_OK;
else
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED;
}
// Before Word 97
if (GetCurrentVersion() < 8)
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_APPVERSION_LT_8;
return E_FAIL;
}
HRESULT TWordHelper::GetApplicationProgID(BSTR* pProgIDResult)
{
if (!pProgIDResult)
return E_INVALIDARG;
*pProgIDResult = CComBSTR(L"Word.Application").Copy();
return S_OK;
}
/******************************/
/***** class TExcelHelper *****/
/******************************/
CComVariant TExcelHelper::m_bExcel97HTMLConverterInstalled;
TExcelHelper::TExcelHelper()
: TOfficeHelper(_T("Excel"))
{
}
HRESULT TExcelHelper::CanExportToHTML(BSTR pMime)
{
//////////
// First, let's see if OFFICE can import such MIME
//////////
if (pMime)
{
TOfficeImportMimeHelper* lMimeHelper = new TOfficeImportMimeHelper();
BOOL bResult = lMimeHelper->isMimeTypeSupported(CString(pMime));
delete lMimeHelper;
if (!bResult)
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_SUPPORTED;
}
//////////
// Then, let's define here which MIMEs we want our EXCEL app to export to HTML
//////////
// Let's only export EXCEL documents through EXCEL
if (pMime)
{
if ( (wcsstr(pMime, L"excel") == NULL) && (wcsstr(pMime, L"xls") == NULL) )
{
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_HANDLED;
}
}
//////////
// Then, let's see if our EXCEL app is able to export to HTML
//////////
// Excel 2000 or +
if (MinimumVersion(9))
{
return S_OK;
}
// Excel 97
if (GetCurrentVersion() == 8)
{
// Need to check if the HTML File Converter is installed
BOOL bHTMLConverterInstalled = FALSE;
if ( (m_bExcel97HTMLConverterInstalled.vt != VT_EMPTY) )
{
bHTMLConverterInstalled = ((m_bExcel97HTMLConverterInstalled.boolVal == VARIANT_TRUE)?TRUE:FALSE);
}
else
{
BOOL bHeavyCheck = TRUE; // a light check might be enough???
if (bHeavyCheck)
{
//////////
// HEAVY CHECK: We will create an EXCEL app and ask it if the "html.xla" addin is installed
//////////
HRESULT lResult;
CComPtr lExcelAppResult;
// Create EXCEL App Object
CComBSTR lProgID;
lResult = GetApplicationProgID(&lProgID);
if (FAILED(lResult))
{
m_bExcel97HTMLConverterInstalled = VARIANT_FALSE;
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED;
}
lResult = CreateApplication(lProgID, &lExcelAppResult);
ATLASSERT(SUCCEEDED(lResult) && lExcelAppResult);
if (FAILED(lResult) || (lExcelAppResult == NULL))
{
m_bExcel97HTMLConverterInstalled = VARIANT_FALSE;
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED;
}
CComDispatchDriver lExcelAppDriver(lExcelAppResult);
// Do not show window
CComVariant lVisible(VARIANT_FALSE);
lResult = lExcelAppDriver.PutPropertyByName(L"Visible", &lVisible);
CComVariant lAppAddInsResult;
lResult = lExcelAppDriver.GetPropertyByName(L"AddIns", &lAppAddInsResult);
ATLASSERT(SUCCEEDED(lResult) && lAppAddInsResult.vt == VT_DISPATCH);
if (!(SUCCEEDED(lResult) && lAppAddInsResult.vt == VT_DISPATCH))
{
// Release EXCEL App Object
lResult = lExcelAppDriver.Invoke0(L"Quit");
ATLASSERT(SUCCEEDED(lResult));
m_bExcel97HTMLConverterInstalled = VARIANT_FALSE;
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED;
}
CComDispatchDriver lAppAddInsDriver(lAppAddInsResult.pdispVal);
long lDispId_AddIns_Item;
lResult = lAppAddInsDriver.GetIDOfName(L"Item", &lDispId_AddIns_Item);
if (!SUCCEEDED(lResult))
{
// Release EXCEL App Object
lResult = lExcelAppDriver.Invoke0(L"Quit");
ATLASSERT(SUCCEEDED(lResult));
m_bExcel97HTMLConverterInstalled = VARIANT_FALSE;
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED;
}
CComVariant lAddInsCountResult;
lResult = lAppAddInsDriver.GetPropertyByName(L"Count", &lAddInsCountResult);
ATLASSERT(SUCCEEDED(lResult) && lAddInsCountResult.vt == VT_I4);
if (SUCCEEDED(lResult) && lAddInsCountResult.vt == VT_I4)
{
for (int ii = 1; ii <= lAddInsCountResult.iVal; ii++)
{
CComVariant lCurAddInResult;
{
CComVariant varArgs_param1(ii);
CComVariant varArgs[1] = { varArgs_param1 };
DISPPARAMS dispparams = { &varArgs[0], NULL, 1, 0};
lResult = ((IDispatch *)lAppAddInsDriver)->Invoke(
lDispId_AddIns_Item,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET,
&dispparams,
&lCurAddInResult,
NULL,
NULL);
}
ATLASSERT(SUCCEEDED(lResult) && lCurAddInResult.vt == VT_DISPATCH);
if (SUCCEEDED(lResult) && lCurAddInResult.vt == VT_DISPATCH)
{
// Here we have an IAddIn dispatch
CComDispatchDriver lAppAddInDriver(lCurAddInResult.pdispVal);
CComVariant lAddInFileNameResult;
lResult = lAppAddInDriver.GetPropertyByName(L"Name", &lAddInFileNameResult);
ATLASSERT(SUCCEEDED(lResult) && lAddInFileNameResult.vt == VT_BSTR);
if (SUCCEEDED(lResult) && lAddInFileNameResult.vt == VT_BSTR)
{
if (lAddInFileNameResult.bstrVal && (!wcsicmp(L"HTML.XLA", lAddInFileNameResult.bstrVal)))
{
bHTMLConverterInstalled = TRUE;
break;
}
}
}
}
}
// Release EXCEL App Object
lResult = lExcelAppDriver.Invoke0(L"Quit");
ATLASSERT(SUCCEEDED(lResult));
}
else // !bHeavyCheck
{
//////////
// LIGHT CHECK: We will simply search on our hard-drive if the "html.xla" file is present
//////////
if ( GetInstallPath() )
{
// This way, we do not rely upon some folder name not even published in the registry...
CString lHtmlXlaFilePath;
BOOL bFound = TPath::SearchFilePath(m_InstallPath,_T("html.xla"),lHtmlXlaFilePath);
if (bFound)
{
bHTMLConverterInstalled = TRUE;
}
}
}
m_bExcel97HTMLConverterInstalled = (bHTMLConverterInstalled?VARIANT_TRUE:VARIANT_FALSE);
}
if (bHTMLConverterInstalled)
return S_OK;
else
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED;
}
// Before Excel 97
if (GetCurrentVersion() < 8)
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_APPVERSION_LT_8;
return E_FAIL;
}
HRESULT TExcelHelper::GetApplicationProgID(BSTR* pProgIDResult)
{
if (!pProgIDResult)
return E_INVALIDARG;
*pProgIDResult = CComBSTR(L"Excel.Application").Copy();
return S_OK;
}
/***********************************/
/***** class TPowerPointHelper *****/
/***********************************/
CComVariant TPowerPointHelper::m_bPowerpoint97WebGraphicConverterInstalled;
TPowerPointHelper::TPowerPointHelper()
: TOfficeHelper(_T("PowerPoint"))
{
}
HRESULT TPowerPointHelper::GetApplicationProgID(BSTR* pProgIDResult)
{
if (!pProgIDResult)
return E_INVALIDARG;
*pProgIDResult = CComBSTR(L"PowerPoint.Application").Copy();
return S_OK;
}
HRESULT TPowerPointHelper::CanExportToHTML(BSTR pMime)
{
//////////
// First, let's see if OFFICE can import such MIME
//////////
if (pMime)
{
TOfficeImportMimeHelper* lMimeHelper = new TOfficeImportMimeHelper();
BOOL bResult = lMimeHelper->isMimeTypeSupported(CString(pMime));
delete lMimeHelper;
if (!bResult)
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_SUPPORTED;
}
//////////
// Then, let's define here which MIMEs we want our POWERPOINT app to export to HTML
//////////
// Let's only export POWERPOINT documents through POWERPOINT
if (pMime)
{
if ( wcsstr(pMime, L"powerpoint") == NULL )
{
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_HANDLED;
}
}
//////////
// Then, let's see if our POWERPOINT app is able to export to HTML
//////////
// Powerpoint 2000 or +
if (MinimumVersion(9))
{
return S_OK;
}
// Powerpoint 97
if (GetCurrentVersion() == 8)
{
// Need to check if a web graphic format converter is installed
BOOL bWebGraphicConverterInstalled = FALSE;
if ( (m_bPowerpoint97WebGraphicConverterInstalled.vt != VT_EMPTY) )
{
bWebGraphicConverterInstalled = ((m_bPowerpoint97WebGraphicConverterInstalled.boolVal == VARIANT_TRUE)?TRUE:FALSE);
}
else
{
bWebGraphicConverterInstalled = IsExportGraphicFilterInstalled(_T("image/gif"));
if (!bWebGraphicConverterInstalled)
bWebGraphicConverterInstalled = IsExportGraphicFilterInstalled(_T("image/jpeg"));
m_bPowerpoint97WebGraphicConverterInstalled = (bWebGraphicConverterInstalled?VARIANT_TRUE:VARIANT_FALSE);
}
if (bWebGraphicConverterInstalled)
return S_OK;
else
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED;
}
// Before Powerpoint 97
if (GetCurrentVersion() < 8)
return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_APPVERSION_LT_8;
return E_FAIL;
}
/*------------ TOfficeToHTMLExportEngine.cpp ------------*/
#include "StdAfx.h"
#include "Cache.h"
#include "TNetHelpers.h"
#include "TUrl.h"
#include "TOfficeToHTMLExportEngine.h"
#include "TOfficeConverter.h"
#include "TOfficeHelper.h"
#include "TPath.h"
#include "TSystemInfo.h"
#include "TOfficeImportMimeHelper.h"
TOfficeToHTMLExportEngine::TOfficeToHTMLExportEngine(LPCWSTR pMime)
{
m_InMime = pMime;
}
TOfficeToHTMLExportEngine::~TOfficeToHTMLExportEngine()
{
}
HRESULT TOfficeToHTMLExportEngine::Initialize()
{
return E_NOTIMPL;
}
HRESULT TOfficeToHTMLExportEngine::Uninitialize()
{
return E_NOTIMPL;
}
HRESULT TOfficeToHTMLExportEngine::export(LPCTSTR inFileName, LPCTSTR outFileName, LPCTSTR inFileURL)
{
HRESULT lResult = E_FAIL;
TOfficeHelper::E_OFFICE_HELPER lPreferredOfficeApp = TOfficeHelper::GetPreferredExportToHTMLHelper(m_InMime);
if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_UNKNOWN_EXCEL97_HTMLCONVERTER_MISSING_CASE)
{
return EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME_EXCEL97_HTMLCONVERTER_MISSING_CASE;
}
else if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_UNKNOWN)
{
return EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME;
}
TOfficeImportMimeHelper* lHelper;
LPCTSTR lExtension;
lExtension = ::PathFindExtension(outFileName);
if (*lExtension == 0)
lExtension = ::PathFindExtension(inFileName);
if (*lExtension == 0)
lExtension = ::PathFindExtension(inFileURL);
lHelper = new TOfficeImportMimeHelper();
if (!lHelper->isExtensionSupported(lExtension))
{
delete lHelper;
return EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_EXTENSION;
}
delete lHelper;
// We will generate our converted files to a temporary folder at first
// Therefore, let's create a temporary folder...
CString lTmpOutFilePath;
{
CString lTempPath;
TPath::CreateNewDirectoryPath(TSystemInfo::GetTempPath(),lTempPath);
TPath::CreateDirectory(lTempPath);
CString lTmpOutFileName;
lTmpOutFileName = ::PathFindFileName(outFileName);
lTmpOutFilePath = lTempPath;
TPath lPath(lTmpOutFilePath);
lPath.AddPath(lTmpOutFileName);
}
// Then, let's instantiate the right converter and do conversion
TStringArray lGeneratedFilesList;
CComBSTR bstrOfficeConverterFullName;
BOOL lIsImage = FALSE;
if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_WORD)
{
lIsImage = !wcsnicmp(m_InMime, L"image/", 6);
// Special case for encapsuleted postscript
if (!wcsicmp(m_InMime, L"application/postscript"))
{
if (!_tcscmp(lExtension, ".eps"))
lIsImage = TRUE;
}
if (lIsImage)
{
TWordImageConverter lConverter;
lConverter.GetCurrentVersionFullAppName(&bstrOfficeConverterFullName);
lConverter.SetSource(inFileName);
lConverter.SetTarget(lTmpOutFilePath);
lResult = lConverter.Convert();
if (SUCCEEDED(lResult))
{
lConverter.GetExportedFilesList(lGeneratedFilesList);
lConverter.GetConvertedDocumentMime(&m_OutMime);
}
}
else
{
TWordConverter lConverter;
lConverter.GetCurrentVersionFullAppName(&bstrOfficeConverterFullName);
lConverter.SetSource(inFileName);
lConverter.SetTarget(lTmpOutFilePath);
lResult = lConverter.Convert();
if (SUCCEEDED(lResult))
{
lConverter.GetExportedFilesList(lGeneratedFilesList);
lConverter.GetConvertedDocumentMime(&m_OutMime);
}
}
}
else if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_EXCEL)
{
TExcelConverter lConverter;
lConverter.GetCurrentVersionFullAppName(&bstrOfficeConverterFullName);
lConverter.SetSource(inFileName);
lConverter.SetTarget(lTmpOutFilePath);
lResult = lConverter.Convert();
if (SUCCEEDED(lResult))
{
lConverter.GetExportedFilesList(lGeneratedFilesList);
lConverter.GetConvertedDocumentMime(&m_OutMime);
}
}
else if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_POWERPOINT)
{
TPowerPointConverter lConverter;
lConverter.GetCurrentVersionFullAppName(&bstrOfficeConverterFullName);
lConverter.SetSource(inFileName);
lConverter.SetTarget(lTmpOutFilePath);
lResult = lConverter.Convert();
if (SUCCEEDED(lResult))
{
lConverter.GetExportedFilesList(lGeneratedFilesList);
ATLASSERT(lGeneratedFilesList.size() > 0);
lConverter.GetConvertedDocumentMime(&m_OutMime);
}
}
else
{
return EXPORTENGINE_E_MICROSOFT_OFFICE_CONVERTER_NOT_IMPLEMENTED;
}
m_OfficeConverterFullName = CString(bstrOfficeConverterFullName);
if (SUCCEEDED(lResult) && lGeneratedFilesList.size() == 0)
{
lResult = EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME;
}
if (SUCCEEDED(lResult))
{
// I'm gonna move every file to its final destination
// and I'll add every sub-file of the main outfile to our cache
CString lOutFileFolderPath(outFileName);
TPath::RemoveFileSpec(lOutFileFolderPath);
CString lTmpOutFileName;
TPath::FindFileName(lTmpOutFilePath,lTmpOutFileName);
CString lTmpOutFileFolderPath; // The folder where the lTmpOutFilePath has actually been generated
{
for (int ii = 0; ii < lGeneratedFilesList.size(); ii++)
{
CString lCurGeneratedFile = lGeneratedFilesList.elementAt(ii);
CString lCurFileName;
TPath::FindFileName(lCurGeneratedFile,lCurFileName);
if (lTmpOutFileName.CompareNoCase(lCurFileName) == 0)
{
lTmpOutFileFolderPath = lCurGeneratedFile;
TPath::RemoveFileSpec(lTmpOutFileFolderPath);
break;
}
}
}
ASSERT(!lTmpOutFileFolderPath.IsEmpty());
for (int ii = 0; ii < lGeneratedFilesList.size(); ii++)
{
CString lCurGeneratedFile = lGeneratedFilesList.elementAt(ii);
CString lCurFileName;
TPath::FindFileName(lCurGeneratedFile,lCurFileName);
CString lCurRelativeFilePath;
BOOL bResRelative = TPath::GetRelativeFilePath(lTmpOutFileFolderPath, lCurGeneratedFile, lCurRelativeFilePath);
if (bResRelative)
{
if (lTmpOutFileName.CompareNoCase(lCurFileName) == 0)
{
CString lCurNewFilePath(lOutFileFolderPath);
TPath lPath(lCurNewFilePath);
lPath.AddPath(lCurFileName);
// Just to be sure the folder exists
CString lDestFolder(lCurNewFilePath);
TPath::RemoveFileSpec(lDestFolder);
TPath::CreateDirectory(lDestFolder);
TRY
{
CFile::Rename(lCurGeneratedFile,lCurNewFilePath);
}
CATCH (CFileException, cfe)
{
}
END_CATCH
}
else
{
CComPtr lFilterCache;
// Try to create the filter cache
if (lFilterCache == NULL && FAILED(GetCache(T_FILTER_CACHE_NAME, &lFilterCache)))
continue;
CComPtr lCacheEntry;
// Create new URL
TUrl lUrl(inFileURL);
lUrl.CombineUrl(lCurRelativeFilePath);
// Create Cache entry
CComBSTR bstr_nonExportedFileURL = lUrl.extendedUrlString();
lResult = lFilterCache->createEntry(bstr_nonExportedFileURL, &lCacheEntry);
// Get Cache file name
CComBSTR bstr_lFileName;
lCacheEntry->getFileName(&bstr_lFileName);
// Move file to cache file
// and add to list
TRY
{
CFile::Rename(lCurGeneratedFile,CString(bstr_lFileName));
}
CATCH (CFileException, cfe)
{
}
END_CATCH
// validate cache entry, so that it can be saved and used
lCacheEntry->commit();
}
}
}
}
else
{
switch (lResult)
{
case OFFICECONVERTER_E_APPLICATION_CREATION_FAILED:
{
lResult = EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_CREATION_FAILED;
break;
}
case OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED:
{
lResult = EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED;
break;
}
case OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED:
{
lResult = EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED;
break;
}
case OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED:
{
lResult = EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED;
break;
}
case OFFICECONVERTER_E_APPLICATION_ENUMERATE_GENERATED_FILES_FAILED:
{
lResult = EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME;
break;
}
default:
{
lResult = EXPORTENGINE_E_OFFICECONVERTER_GENERIC_ERROR;
}
}
}
if (!lTmpOutFilePath.IsEmpty())
{
CString lTmpOutDirPath(lTmpOutFilePath);
TPath::RemoveFileSpec(lTmpOutDirPath);
TPath::RemoveDirectory(lTmpOutDirPath);
}
if ( SUCCEEDED(lResult) && lIsImage )
{
// We return a special success value to avoid caller to check mime type
// (and maybe in case lIsImage is not equivalent to 'image/...' mime type???)
return EXPORTENGINE_S_PICTURE_RESULT;
}
return lResult;
}
TString TOfficeToHTMLExportEngine::getExportedMime()
{
if (m_OutMime.Length() > 0)
{
return CString(m_OutMime);
}
else
{
// default return value
return _T("text/html");
}
}
TString TOfficeToHTMLExportEngine::getOfficeConverterFullName()
{
return CString(m_OfficeConverterFullName);
}
/*------------ TOfficeToHTMLExportEngine.h ------------*/
#ifndef T_OFFICE_TO_HTML_EXPORT_ENGINE
#define T_OFFICE_TO_HTML_EXPORT_ENGINE
// INCLUDES
#include "TExportEngine.h"
#include "TString.h"
#include "TLocker.h"
#include "TPtrArray.h"
// CLASS IMPORTS
/*************************************/
/** class TOfficeToHTMLExportEngine **/
/*************************************/
class TOfficeToHTMLExportEngine : public TExportEngine
{
// CONSTRUCTORS
public:
TOfficeToHTMLExportEngine(LPCWSTR pMime = NULL); //default
virtual ~TOfficeToHTMLExportEngine();
// METHODS
public:
virtual HRESULT Initialize();
virtual HRESULT Uninitialize();
virtual HRESULT export(LPCTSTR inFileName, LPCTSTR outFileName, LPCTSTR inFileURL);
virtual TString getExportedMime();
TString getOfficeConverterFullName();
protected:
CComBSTR m_InMime;
CComBSTR m_OutMime;
CComBSTR m_OfficeConverterFullName;
}; // class TOfficeToHTMLExportEngine
#endif // T_HTML_EXPORT_ENGINE
/*------------ TSOfficeMimeFilter.cpp ------------*/
// MAIN INCLUDE
#include "stdafx.h"
#include "TSOfficeMimeFilter.h"
// OTHER INCLUDES
#include "TFilterGlobals.h"
#include "TOfficeToHTMLExportEngine.h"
// Cache Stuff
#include "TNetHelpers.h"
#include "TUrl.h"
#include "atlconv.h"
#include "FilterResource.h"
#include "SharedResource.h"
#include "TLanguage.h"
#include "TSystemMimeHelper.h"
#include "THtmlString.h"
#include "TSystemInfo.h"
#include "TPath.h"
#include "TSevenixUrlInfo.h"
#include "Shlwapi.h"
// DEBUG DEFINES
//#define DEBUG_MIME_FILTER
#ifndef RT_HTML
#define RT_HTML MAKEINTRESOURCE(23)
#endif
/////////////////////
extern HINSTANCE g_hDllMain;
/////////////////////////////////////////////////////////////////////////////
// TSevenixOfficeMimeFilter
HRESULT TSevenixOfficeMimeFilter::FinalConstruct()
{
TRACE(_T("TSevenixOfficeMimeFilter::FinalConstruct\n"));
// Initialize personnal data
fReportDataSFalseOccurred = false;
fExporterActive = true;
fExportedFile = null;
fNonExportedFile = null;
fNonExportedFileCached = false;
fExportSucceeded = false;
fReadSFalseOccurred = false;
m_ReportDataReadState = 0;
m_ReadState = 0;
m_DocSize = 0;
m_CurrentRead = 0;
m_IsLocked = FALSE;
m_IsTerminate = FALSE;
m_HandleError = FALSE;
m_Redirecting = FALSE;
m_HaveAbort = FALSE;
m_RootDocument = FALSE;
m_CanReload = TRUE;
m_IsSearch = FALSE;
return S_OK;
}
void TSevenixOfficeMimeFilter::FinalRelease()
{
TRACE(_T("TSevenixOfficeMimeFilter::FinalRelease\n"));
if (m_SupBindInfo)
m_SupBindInfo.Release();
if (m_SupSink)
m_SupSink.Release();
if (fProtocolProxy)
fProtocolProxy.Release();
fCacheEntry = NULL;
}
// ********************************************************************************
// IInternetProtocolRoot
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Start(
/* [in] */ LPCWSTR szMime,
/* [in] */ IInternetProtocolSink __RPC_FAR *pOIProtSink,
/* [in] */ IInternetBindInfo __RPC_FAR *pOIBindInfo,
/* [in] */ DWORD grfPI,
/* [in] */ DWORD dwReserved)
{
TRACE(_T("TSevenixOfficeMimeFilter::Start\n"));
USES_CONVERSION;
HRESULT lResult = S_OK;
// Initialization
PROTOCOLFILTERDATA* pfd = (PROTOCOLFILTERDATA *)dwReserved;
BINDINFO lBi;
lBi.cbSize = sizeof(BINDINFO);
DWORD pBindf;
HRESULT bindRes = pOIBindInfo->GetBindInfo(&pBindf,&lBi);
ATLASSERT(SUCCEEDED(bindRes));
fProtocolProxy = pfd->pProtocol;
m_SupSink = pOIProtSink;
m_SupBindInfo = pOIBindInfo;
ASSERT(fProtocolProxy);
ASSERT(m_SupSink);
ASSERT(m_SupBindInfo);
fExportedFile = null;
fNonExportedFile = null;
fNonExportedFileCached = false;
fExportSucceeded = false;
fReadSFalseOccurred = false;
fExporterActive = true;
m_SourceMime = szMime;
return lResult;
}
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Continue(
/* [in] */ PROTOCOLDATA __RPC_FAR *pMimeFilterData)
{
TRACE(_T("TSevenixOfficeMimeFilter::Continue\n"));
HRESULT lResult = S_OK;
if (fProtocolProxy != NULL)
lResult = fProtocolProxy->Continue(pMimeFilterData);
return lResult;
}
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Abort(
/* [in] */ HRESULT hrReason,
/* [in] */ DWORD dwOptions)
{
TRACE(_T("TSevenixOfficeMimeFilter::Abort\n"));
HRESULT lResult = S_OK;
// Proxy the call
if (fProtocolProxy != NULL)
{
lResult = fProtocolProxy->Abort(hrReason, dwOptions);
}
m_HaveAbort = TRUE;
return lResult;
}
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Terminate(
/* [in] */ DWORD dwOptions)
{
TRACE(_T("TSevenixOfficeMimeFilter::Terminate\n"));
HRESULT lResult = S_OK;
// proxy call
if (fProtocolProxy != NULL)
{
lResult = fProtocolProxy->Terminate(dwOptions);
}
if (!m_IsLocked)
{
CloseAll();
ReleaseAll();
}
m_IsTerminate = TRUE;
return lResult;
}
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Suspend( void)
{
TRACE(_T("TSevenixOfficeMimeFilter::Suspend\n"));
HRESULT lResult = S_OK;
if (fProtocolProxy != NULL)
lResult = fProtocolProxy->Suspend();
return lResult;
}
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Resume( void)
{
TRACE(_T("TSevenixOfficeMimeFilter::Resume\n"));
HRESULT lResult = S_OK;
if (fExporterActive != NULL)
lResult = fProtocolProxy->Resume();
return lResult;
}
// ********************************************************************************
// IInternetProtocol : public IInternetProtocolRoot
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Read(
/* [length_is][size_is][out][in] */ void __RPC_FAR *pv,
/* [in] */ ULONG cb,
/* [out] */ ULONG __RPC_FAR *pcbRead)
{
if (m_HandleError || m_Redirecting)
{
// If the data came from the error handler
return ReadFromErrorString(pv, cb, pcbRead);
}
if (!fExporterActive)
return fProtocolProxy->Read(pv,cb,pcbRead);
if (!fExportSucceeded)
return INET_E_DOWNLOAD_FAILURE;
// Here data will be read from exported file
if (fReadSFalseOccurred)
{
// In the case we are called after having returned S_FALSE
*pcbRead = 0;
return S_FALSE;
}
if (!fExportedFile)
{
fExportedFile = new CFile(fExportedFileName, CFile::modeRead | CFile::shareDenyNone);
m_DocSize = fExportedFile->GetLength();
}
unsigned long dataRead = 0;
dataRead = fExportedFile->Read(pv,cb);
*pcbRead = (ULONG)dataRead;
m_ReadState += dataRead;
TRACE(_T("TSevenixOfficeMimeFilter::Read (%d / %d) File (%d / %d)\n"), dataRead, cb, m_ReadState, m_DocSize);
if (m_ReadState == m_DocSize)
{
// The EOF has been reached
fReadSFalseOccurred = true;
fExportedFile->Close();
return S_FALSE;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Seek(
/* [in] */ LARGE_INTEGER dlibMove,
/* [in] */ DWORD dwOrigin,
/* [out] */ ULARGE_INTEGER __RPC_FAR *plibNewPosition)
{
TRACE(_T("TSevenixOfficeMimeFilter::Seek\n"));
HRESULT lResult = E_FAIL;
if (fExporterActive)
{
// Could be implementable since we use a plain file to do the export
// so we could just Seek in it... Later...
lResult = E_FAIL;
}
else
{
if (fProtocolProxy)
lResult = fProtocolProxy->Seek(dlibMove,dwOrigin,plibNewPosition);
}
return lResult;
}
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::LockRequest(
/* [in] */ DWORD dwOptions)
{
TRACE(_T("TSevenixOfficeMimeFilter::LockRequest\n"));
m_IsLocked = TRUE;
if (fProtocolProxy != NULL)
return fProtocolProxy->LockRequest(dwOptions);
return S_OK;
}
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::UnlockRequest( void)
{
TRACE(_T("TSevenixOfficeMimeFilter::UnlockRequest\n"));
HRESULT lResult;
if (fProtocolProxy != NULL)
{
lResult = fProtocolProxy->UnlockRequest();
}
m_IsLocked = FALSE;
if (m_IsTerminate)
{
CloseAll();
ReleaseAll();
}
return lResult = S_OK;
}
// ********************************************************************************
// IInternetBindInfo
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::GetBindInfo(
DWORD __RPC_FAR *grfBINDF, BINDINFO __RPC_FAR *pbindinfo)
{
// Do we pass here ?
TRACE(_T("TSevenixOfficeMimeFilter::GetBindInfo"));
// set required flags.
*grfBINDF = BINDF_NO_UI | BINDF_SILENTOPERATION;
return S_OK;
}
HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::GetBindString(
ULONG ulStringType, LPOLESTR __RPC_FAR *ppwzStr,
ULONG cEl, ULONG __RPC_FAR *pcElFetched)
{
// Do we pass here ?
TRACE(_T("TSevenixOfficeMimeFilter::GetBindString"));
// I'm not sure what to do here ???
return S_OK;
}
// ********************************************************************************
//
//
//
HRESULT TSevenixOfficeMimeFilter::ReadFromErrorString(void *pv, ULONG cb, ULONG *pcbRead)
{
ASSERT(m_HandleError || m_Redirecting);
// Read from error string
DWORD lStillToRead = m_ErrorHtmlString.GetLength() - m_CurrentRead;
if (lStillToRead == 0)
return S_FALSE;
// ASSERT(cb <= lStillToRead);
LONG lGoingToRead = min(cb, lStillToRead);
CString lSubString = m_ErrorHtmlString.Mid(m_CurrentRead, lGoingToRead);
memcpy(pv, lSubString.GetBuffer(0), lGoingToRead);
lSubString.ReleaseBuffer();
*pcbRead = lGoingToRead;
m_CurrentRead += lGoingToRead;
return S_OK;
}
void TSevenixOfficeMimeFilter::CreateNewFile()
{
if (fNonExportedFile)
return ;
// I didn't receive the ReportProgress specifying the name
// of the cached file.
// Either something went wrong with this message, or the url
// isn't cached because it is a local file
// Let's check if the file is local
boolean bLocalFile = false;
TString lLocalFilePath("");
ULONG ulCount;
LPOLESTR rgwzStr = NULL; // Wide Char
HRESULT gbsRes = m_SupBindInfo->GetBindString(
BINDSTRING_URL,
&rgwzStr,
1,
&ulCount);
if( gbsRes == S_OK && ulCount == 1)
{
TUrl lUrl(rgwzStr);
if (lUrl.getProtocol().CompareNoCase(_T("file")) == 0)
{
bLocalFile = true;
lLocalFilePath = lUrl.getFile();
}
TSevenixUrlInfo* lInfo;
lInfo = (TSevenixUrlInfo*)lUrl.getExtendedInfo();
if (lInfo)
{
if (lInfo->haveProperty(T_NO_RELOAD_PROPERTY))
m_CanReload = FALSE;
if (lInfo->haveProperty(T_ROOT_PROPERTY))
m_RootDocument = TRUE;
if (lInfo->haveProperty(T_SEARCH_PROPERTY))
m_IsSearch = TRUE;
}
}
/*
if (bLocalFile)
{
// The File is LOCAL, so I don't have to cache it myself
// and I can consider it is cached in some way
fNonExportedFileName = lLocalFilePath;
fNonExportedFileCached = true;
}
else
*/
{
// The File is NOT LOCAL, and as I haven't receive any 'cached file path'
// notification, I have to cache it myself somewhere
// We put the copy in the Temp Folder
TString filePath;
#if defined(_DEBUG) && defined(DEBUG_MIME_FILTER)
filePath = TString("d:\\temp\\export\\");
#else
filePath = TSystemInfo::GetTempPath();
ASSERT(!filePath.IsEmpty());
#endif
CString lExtension;
lExtension = ::PathFindExtension(fNonExportedFileName);
TPath::CreateRandomFilePath(filePath, NULL, fNonExportedFileName);
if (lExtension.IsEmpty())
{
USES_CONVERSION;
TSystemMimeHelper* lSystemHelper;
lSystemHelper = new TSystemMimeHelper();
lSystemHelper->getFirstFileExtensionsFromMimeType(W2CT(m_SourceMime), lExtension);
delete lSystemHelper;
}
if (lExtension.CompareNoCase(_T(".ps")) == 0)
{
lExtension = _T(".eps");
}
fNonExportedFileName += lExtension;
fNonExportedFile = new CFile(fNonExportedFileName, CFile::modeCreate | CFile::modeWrite);
}
}
HRESULT TSevenixOfficeMimeFilter::ConvertFile()
{
LPWSTR lMime = NULL;
// do IMPORTANT stuff here
HRESULT exportRes = launchExportProcessing();
if (exportRes == S_OK)
{
CFileStatus lStatus;
if (CFile::GetStatus(fExportedFileName, lStatus))
m_DocSize = lStatus.m_size;
lMime = m_TargetMime;
}
// Handle Error
if (!m_ErrorHtmlString.IsEmpty())
{
m_DocSize = m_ErrorHtmlString.GetLength();
// We simulate that the export succeeded to be able
// to display our custom error page
fExportSucceeded = true;
// Let's set the Mime to HTML
lMime = L"text/html";
}
if (m_DocSize)
{
HRESULT lResult;
if (lMime)
{
// Since the output data won't have the same MIME, let's tell the
// client which one it'll be
lResult = m_SupSink->ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, lMime); // necessary ??
ATLASSERT(SUCCEEDED(lResult));
lResult = m_SupSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, lMime);
ATLASSERT(SUCCEEDED(lResult));
// This is used by a pluggable MIME filter to report a change in the MIME type after it
// has processed the resource.
// This value was added for Internet Explorer 5
lResult = m_SupSink->ReportProgress(BINDSTATUS_FILTERREPORTMIMETYPE, lMime);
ATLASSERT(SUCCEEDED(lResult));
}
// Let's then report all the data we have
lResult = m_SupSink->ReportData(BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE, m_DocSize, m_DocSize);
ATLASSERT(SUCCEEDED(lResult));
// At last, we report that everything went right...
lResult = m_SupSink->ReportResult(lResult, 0, NULL);
return lResult;
}
// If everything went wrong, we assume a failure at last
fExportSucceeded = false;
HRESULT repResultRes = m_SupSink->ReportResult(E_FAIL, 0, NULL);
return E_FAIL;
}
// ********************************************************************************
// IInternetProtocolSink
HRESULT TSevenixOfficeMimeFilter::ReportData(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
{
USES_CONVERSION;
TRACE(_T("TSevenixOfficeMimeFilter::ReportData: %d/%d\n"), ulProgress, ulProgressMax);
HRESULT lResult;
if (fExporterActive)
{
if (fReportDataSFalseOccurred == TRUE)
{
// We already did receive a S_FALSE from the underlying protocol's Read()
return S_OK;
}
// FIRST TIME STUFF
CreateNewFile();
const unsigned long bufferSize = 4096;
TCHAR buffer[bufferSize];
ULONG dataRead = 0;
for (;;)
{
lResult = fProtocolProxy->Read(&buffer,bufferSize,&dataRead);
m_ReportDataReadState += dataRead;
if (lResult == S_OK)
{
TRACE(_T("TSevenixOfficeMimeFilter::ReportData -- Read returned S_OK - m_ReportDataReadState: %d\n"), m_ReportDataReadState);
if ((dataRead != 0))
{
fNonExportedFile->Write(&buffer, dataRead);
}
}
else if (lResult == E_PENDING)
{
TRACE(_T("TSevenixOfficeMimeFilter::ReportData -- Read returned E_PENDING - m_ReportDataReadState: %d\n"), m_ReportDataReadState);
if ((dataRead != 0))
{
fNonExportedFile->Write(&buffer, dataRead);
}
return S_OK;
}
else if (lResult == S_FALSE)
{
TRACE(_T("TSevenixOfficeMimeFilter::ReportData -- Read returned S_FALSE - m_ReportDataReadState: %d\n"), m_ReportDataReadState);
if ((dataRead != 0))
{
fNonExportedFile->Write(&buffer, dataRead);
}
fNonExportedFile->Flush();
fNonExportedFile->Close();
delete fNonExportedFile;
fNonExportedFile = NULL;
fReportDataSFalseOccurred = true;
lResult = ConvertFile();
ATLASSERT(SUCCEEDED(lResult) || m_IsSearch);
return S_OK;
}
else
{
// FAILURE
TRACE(_T("TSevenixOfficeMimeFilter::ReportData -- Read FAILED\n"));
return E_FAIL;
}
}
// If I am here, that means that I have read all the data reported, and
// not encountered S_FALSE yet...
return S_OK;
}
else
{
return m_SupSink->ReportData(grfBSCF,ulProgress,ulProgressMax);
}
}
LONG gExportErrorTranslationTable[] =
{
EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME, 0, IDR_HTML_MIMEFILTER_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME,
EXPORTENGINE_E_MICROSOFT_OFFICE_CONVERTER_NOT_IMPLEMENTED, 0, IDR_HTML_MIMEFILTER_CONVERTER_GENERIC_ERROR/*IDR_HTML_MIMEFILTER_OFFICE_CONVERTER_NOT_IMPLEMENTED*/,
EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_CREATION_FAILED, 0, IDR_HTML_MIMEFILTER_CONVERTER_APPLICATION_CREATION_FAILED,
EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED, 0, IDR_HTML_MIMEFILTER_CONVERTER_OPEN_DOCUMENT_FAILED,
EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED, 0, IDR_HTML_MIMEFILTER_CONVERTER_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED,
EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED, 0, IDR_HTML_MIMEFILTER_CONVERTER_SAVE_DOCUMENT_FAILED,
EXPORTENGINE_E_OFFICECONVERTER_GENERIC_ERROR, 0, IDR_HTML_MIMEFILTER_CONVERTER_GENERIC_ERROR,
EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_EXTENSION, 0, IDR_HTML_MIMEFILTER_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME,
EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME_EXCEL97_HTMLCONVERTER_MISSING_CASE, 0, IDR_HTML_MIMEFILTER_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME_EXCEL97_HTMLCONVERTER_MISSING_CASE,
};
LONG TSevenixOfficeMimeFilter::TranslateError(HRESULT hrResult, DWORD dwError)
{
for (long lIndex = 0; lIndex < sizeof(gExportErrorTranslationTable) / sizeof(LONG); lIndex += 3)
{
if (gExportErrorTranslationTable[lIndex] == hrResult)
{
if ((gExportErrorTranslationTable[lIndex + 1] == 0)
|| (gExportErrorTranslationTable[lIndex + 1] == dwError))
return gExportErrorTranslationTable[lIndex + 2];
}
}
return 0;
}
HRESULT TSevenixOfficeMimeFilter::HandleError(HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
{
LONG lErrorID;
// HRESULT lResult;
lErrorID = TranslateError(hrResult, dwError);
THTMLString lErrorString;
USES_CONVERSION;
if (szResult)
lErrorString.StdFormat(lErrorID, hrResult, (LPCTSTR)CString(szResult), W2CT(m_SourceMime), m_OfficeConvertingAppFullName);
else
lErrorString.StdFormat(lErrorID, hrResult, W2CT(m_SourceMime), m_OfficeConvertingAppFullName);
m_ErrorHtmlString = lErrorString;
m_HandleError = TRUE;
return S_OK;
}
HRESULT TSevenixOfficeMimeFilter::launchExportProcessing()
{
HRESULT hr = E_FAIL;
// Here I need the URL I process in order to create an entry
// in the filtered documents cache.
CString nonExportedFileURL;
ULONG ulCount;
LPOLESTR rgwzStr = NULL; // Wide Char
HRESULT gbsRes;
gbsRes = m_SupBindInfo->GetBindString( BINDSTRING_URL, &rgwzStr, 1, &ulCount);
if (gbsRes == S_OK && ulCount == 1)
{
nonExportedFileURL = rgwzStr;
if (!nonExportedFileURL.IsEmpty())
{
CComPtr lFilterCache;
if ( SUCCEEDED(hr = GetCache(T_FILTER_CACHE_NAME, &lFilterCache)) )
{
CComBSTR bstr_nonExportedFileURL = nonExportedFileURL;
hr = lFilterCache->createEntry(bstr_nonExportedFileURL, &fCacheEntry);
}
}
}
else
{
// FAILURE
// After all, I went down here without problem, so let's just not cache the
// file and just export and output it...
nonExportedFileURL.Empty();
}
if (FAILED(hr) || fCacheEntry == NULL)
{
TString filePath;
filePath = TSystemInfo::GetTempPath();
ASSERT(!filePath.IsEmpty());
TPath::CreateRandomFilePath(filePath, NULL, fExportedFileName);
}
else
{
CComBSTR bstr_lFileName;
fCacheEntry->getFileName(&bstr_lFileName);
fExportedFileName = TString(bstr_lFileName);
}
HRESULT exportRes;
TExportEngine* lEngine;
lEngine = new TOfficeToHTMLExportEngine(m_SourceMime);
exportRes = lEngine->export(fNonExportedFileName, fExportedFileName, nonExportedFileURL);
m_TargetMime = lEngine->getExportedMime();
m_OfficeConvertingAppFullName = ((TOfficeToHTMLExportEngine *)lEngine)->getOfficeConverterFullName();
delete lEngine;
if (FAILED(exportRes))
{
// FAILURE
fExportSucceeded = false;
// clean up the cache so that an invalid entry
// is not insert
if (fCacheEntry)
{
fCacheEntry->remove();
fCacheEntry = NULL;
}
if (!m_IsSearch)
{
HRESULT handleErrorRes = HandleError(exportRes,0,NULL);
ATLASSERT(SUCCEEDED(handleErrorRes));
}
return E_FAIL;
}
else
{
fExportSucceeded = true;
// Since the output data won't have the same MIME, let's tell the
// client which one it'll be
if (fCacheEntry)
{
fCacheEntry->addHeader(T_HEADER_CONTENT_TYPE, m_TargetMime);
// validate cache entry, so that it can be saved and used
fCacheEntry->commit();
fCacheEntry = NULL;
}
// If we should DELETE the entry in the Native Cache,
// here should it be done...
if ((exportRes == EXPORTENGINE_S_PICTURE_RESULT) && m_RootDocument && m_CanReload)
return RedirectingTo(L"internal://neutral/picture.htm");
return S_OK;
}
}
HRESULT TSevenixOfficeMimeFilter::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatusText)
{
TRACE(_T("TSevenixOfficeMimeFilter::ReportProgress\n"));
HRESULT lResult;
if (fExporterActive)
{
if (ulStatusCode == BINDSTATUS_CACHEFILENAMEAVAILABLE)
{
fNonExportedFileName = szStatusText;
fNonExportedFileCached = true;
lResult = S_OK;
}
else if (ulStatusCode == BINDSTATUS_MIMETYPEAVAILABLE)
{
// We will set the MIME elsewhere
lResult = S_OK;
}
else if (ulStatusCode == BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE)
{
// We will set the Verified MIME elsewhere
lResult = S_OK;
}
else
{
lResult = S_OK;
}
}
else
{
lResult = m_SupSink->ReportProgress(ulStatusCode,szStatusText);
}
return lResult;
}
HRESULT TSevenixOfficeMimeFilter::ReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
{
HRESULT lResult;
TRACE(_T("TSevenixOfficeMimeFilter::ReportResult\n"));
if (fExporterActive)
{
if (hrResult == S_OK)
{
//hrResult = m_SupSink->ReportData(BSCF_DATAFULLYAVAILABLE | BSCF_LASTDATANOTIFICATION, 0, 0);
hrResult = S_OK;
dwError = 0;
szResult = NULL;
}
}
return S_OK;
}
HRESULT TSevenixOfficeMimeFilter::Switch(PROTOCOLDATA *pPROTOCOLDATA)
{
TRACE(_T("TSevenixOfficeMimeFilter::Switch\n"));
HRESULT lResult;
if (fExporterActive)
{
lResult = fProtocolProxy->Continue(pPROTOCOLDATA);
//lResult = m_SupSink->Switch(pPROTOCOLDATA);
if (lResult != S_OK)
return E_FAIL;
else
return S_OK;
}
else
{
lResult = m_SupSink->Switch(pPROTOCOLDATA);
return lResult;
}
}
void TSevenixOfficeMimeFilter::CloseAll()
{
TRACE(_T("TSevenixOfficeMimeFilter::CloseAll\n"));
if (fExporterActive)
{
if (fExportedFile != null)
{
delete fExportedFile;
fExportedFile = null;
}
if (!fNonExportedFileName.IsEmpty())
{
TRY
{
CFile::Remove(fNonExportedFileName);
}
CATCH(CFileException, e)
{
TRACE1("File %s cannot be removed\n",fNonExportedFileName);
}
END_CATCH
}
if (fNonExportedFile != null)
{
delete fNonExportedFile;
fNonExportedFile = null;
}
}
}
void TSevenixOfficeMimeFilter::ReleaseAll()
{
TRACE(_T("TSevenixOfficeMimeFilter::ReleaseAll\n"));
m_SupBindInfo.Release();
if (!m_IsLocked)
{
m_SupSink.Release();
fProtocolProxy.Release();
}
#ifdef _DEBUG
else
{
TRACE(_T(" - MimeFilter is Locked, so do not Release Interfaces\n"));
}
#endif // _DEBUG
}
HRESULT TSevenixOfficeMimeFilter::RedirectingTo(LPCWSTR szStatusText)
{
USES_CONVERSION;
LPCTSTR theString = "";
m_ErrorHtmlString.FormatMessage(theString, W2CT(szStatusText));
m_Redirecting = TRUE;
m_HandleError = TRUE;
return S_OK;
}/*------------ TSOfficeMimeFilter.h ------------*/
#ifndef T_OFFICE_MIME_FILTER
#define T_OFFICE_MIME_FILTER
// DEFINES
// INCLUDES
#include "KBFilter.h"
#include "Cache.h"
#include "FilterResource.h"
// IMPORTS
class TString;
interface ISevenixCacheEntry;
/////////////////////////////////////////////////////////////////////////////
// TSevenixMimeFilter
class ATL_NO_VTABLE TSevenixOfficeMimeFilter :
public CComObjectRootEx,
public CComCoClass,
public IInternet,
public IInternetProtocol,
public IInternetProtocolSink,
public IInternetBindInfo
{
public:
HRESULT FinalConstruct();
void FinalRelease();
DECLARE_REGISTRY(CLSID_TSevenixOfficeMimeFilter, KEEBOO_COMPANY".Net.MimeFilter.1", KEEBOO_COMPANY".Net.MimeFilter", 0, THREADFLAGS_BOTH )
BEGIN_COM_MAP(TSevenixOfficeMimeFilter)
COM_INTERFACE_ENTRY(IInternet)
COM_INTERFACE_ENTRY2(IUnknown, IInternet)
COM_INTERFACE_ENTRY(IInternetProtocolRoot)
COM_INTERFACE_ENTRY(IInternetProtocol)
COM_INTERFACE_ENTRY(IInternetProtocolSink)
COM_INTERFACE_ENTRY(IInternetBindInfo)
END_COM_MAP()
// IInternetProtocolRoot
STDMETHOD(Start)(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink,
IInternetBindInfo *pOIBindInfo, DWORD grfPI, DWORD dwReserved);
STDMETHOD(Continue)(PROTOCOLDATA *pProtocolData);
STDMETHOD(Abort)(HRESULT hrReason, DWORD dwOptions);
STDMETHOD(Terminate)(DWORD dwOptions);
STDMETHOD(Suspend)();
STDMETHOD(Resume)();
// IInternetProtocol : public IInternetProtocolRoot
STDMETHOD(Read)(void *pv, ULONG cb, ULONG *pcbRead);
STDMETHOD(Seek)(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition);
STDMETHOD(LockRequest)(DWORD dwOptions);
STDMETHOD(UnlockRequest)();
// IInternetBindInfo
STDMETHOD(GetBindInfo)(DWORD *grfBINDF, BINDINFO *pbindinfo);
STDMETHOD(GetBindString)(ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched);
// IInternetProtocolSink
STDMETHOD(ReportData)(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax);
STDMETHOD(ReportProgress)(ULONG ulStatusCode, LPCWSTR szStatusText);
STDMETHOD(ReportResult)(HRESULT hrResult, DWORD dwError, LPCWSTR szResult);
STDMETHOD(Switch)(PROTOCOLDATA *pPROTOCOLDATA);
private:
CComPtr m_SupSink;
CComPtr fProtocolProxy;
CComPtr m_SupBindInfo;
// Personnal variables
boolean fReportDataSFalseOccurred;
CComPtr fCacheEntry;
// This field assure an exporter is behind all this and
// that the filter will be used
boolean fExporterActive;
CFile* fExportedFile;
CFile* fNonExportedFile;
boolean fNonExportedFileCached;
TString fExportedFileName;
TString fNonExportedFileName;
boolean fExportSucceeded;
boolean fReadSFalseOccurred;
CComBSTR m_TargetMime;
CComBSTR m_SourceMime;
CString m_ErrorHtmlString;
CString m_OfficeConvertingAppFullName;
LONG m_ReportDataReadState;
LONG m_ReadState;
LONG m_DocSize;
LONG m_CurrentRead;
BOOL m_IsLocked:2;
BOOL m_IsTerminate:2;
BOOL m_HaveAbort:2;
BOOL m_HandleError:2;
BOOL m_Redirecting:2;
BOOL m_RootDocument:2;
BOOL m_CanReload:2;
BOOL m_IsSearch:2;
private:
void CloseAll();
void ReleaseAll();
HRESULT launchExportProcessing();
HRESULT ConvertFile();
void CreateNewFile();
HRESULT RedirectingTo(LPCWSTR szStatusText);
LONG TranslateError(HRESULT hrResult, DWORD dwError);
HRESULT HandleError(HRESULT hrResult, DWORD dwError, LPCWSTR szResult);
HRESULT ReadFromErrorString(void *pv, ULONG cb, ULONG *pcbRead);
};
#endif // T_OFFICE_MIME_FILTER
/*------------ BookBrowser.cpp ------------*/
#include "StdAfx.h"
// *** MAIN INCLUDE
#include "BookBrowser.h"
// *** OTHER INCLUDE
#include "TBookModel.h"
#include "TSummaryModel.h"
#include "TIndexModel.h"
#include "TMediaShelfModel.h"
#include "TContextModel.h"
#include "TModelIterator.h"
#include "TModelNames.h"
#include "TModelHelpers.h"
#include "BackGround.h"
#include "TabsViewer.h"
#include "ArrowBand.h"
#include "BinderView.h"
#include "BookUtils.h"
#include "PagemarksViewer.h"
#include "PropertyChangeEvent.h"
#include "TBoolean.h"
#include "TErr.h"
#include "TPageEditor.h"
#include "TPageModel.h"
#include "TPtrArray.h"
#include "TString.h"
#include "TInteger.h"
#include "TPageletViewManager.h"
#include "SharedlookAndFeelRes.h"
#include "TGlobalsDB.h"
#include "PrintingEngine.h"
#include "ResBookBrowser.h"
#include "eViewMode.h"
#include "Pagelet.h"
#include "Controler.h"
#include "TUserMessage.h"
// ************************************************************************************************
class TBrowserBookListener : public TPropertyChangeListener
{
TBookBrowser* m_pBookBrowser;
public:
TBrowserBookListener(TBookBrowser* pBookBrowser);
~TBrowserBookListener();
virtual void propertyChange(TPropertyChangeEvent *evt);
};
class TBrowserShelfListener : public TPropertyChangeListener
{
TBookBrowser* m_pBookBrowser;
public:
TBrowserShelfListener(TBookBrowser* pBookBrowser);
~TBrowserShelfListener();
virtual void propertyChange(TPropertyChangeEvent *evt);
};
// *** Message map
BEGIN_MESSAGE_MAP(TBookBrowser, TWnd)
//{{AFX_MSG_MAP(TWnd)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_SHOWWINDOW()
// ON_WM_LBUTTONDOWN()
// ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_USER_SET_NAME, OnSetName)
ON_MESSAGE(WM_USER_ADD_PAGE, OnAddPage)
ON_MESSAGE(WM_USER_INSERT_PAGE, OnInsertPage)
ON_MESSAGE(WM_USER_REMOVE_PAGE, OnRemovePage)
ON_MESSAGE(WM_USER_SET_WRITABLE, OnSetWritable)
ON_MESSAGE(WM_USER_ADD_PAGE_BEFORE_SUMMARY, OnAddPageBeforeSummary)
ON_MESSAGE(WM_USER_REMOVE_PAGE_BEFORE_SUMMARY, OnRemovePageBeforeSummary)
ON_MESSAGE(WM_USER_WANT_TO_BE_DESTROYED, OnWantToBeDestroyed)
ON_MESSAGE(WM_USER_SET_PROPERTY, OnSetProperty)
ON_MESSAGE(WM_USER_REMOVE_PROPERTY, OnRemoveProperty)
ON_MESSAGE(WM_USER_SET_LOCATION, OnSetLocation)
ON_MESSAGE(WM_USER_SET_IS_ALIASED, OnSetIsAliased)
ON_MESSAGE(WM_USER_SET_BOOK_STYLE, OnSetBookStyle)
ON_MESSAGE(WM_USER_CHANGE_PRIMARY_PAGE, OnChangePrimaryPage)
ON_MESSAGE(WM_USER_CHANGE_SECONDARY_PAGE, OnChangeSecondaryPage)
ON_MESSAGE(WM_USER_CHANGE_SELECTED_PAGE, OnChangeSelectedPage)
ON_MESSAGE(WM_USER_CHANGE_BOOK, OnChangeBook)
ON_MESSAGE(ID_UM_CHANGE_ACTIVE_VIEW, OnModeChange)
ON_MESSAGE(WM_USER_UPDATE_PAGES, OnUpdatePages)
ON_MESSAGE(WM_USER_SHOW_BOOK_VIEWS, OnShowBookViews)
END_MESSAGE_MAP()
IMPLEMENT_DYNAMIC(TBookBrowser, TWnd);
// ************************************************************************************************
// *** BookBrowser Constructor
TBookBrowser::TBookBrowser()
: TWnd(),
m_DisplayAnnotations(FALSE),
m_SupportFlying(FALSE),
m_IsVisible(FALSE),
m_BookLogicalRect(0,0,0,0),
m_SelectedSide(T_NONE),
m_TotalTabsNb(0),
m_pBinderView(NULL),
m_PageletManager(NULL),
m_ModeView(T_UNDEFINED_MODE),
m_Resources("BOOK_BROWSER"),
m_pPrintingEngine(NULL)
{
memset(&m_Primary, 0, sizeof(m_Primary));
memset(&m_Secondary, 0, sizeof(m_Secondary));
initResources();
}
// ************************************************************************************************
// *** BookBrowser Destructor
TBookBrowser::~TBookBrowser()
{
// *** Remove book listener and release book
removeBook();
exitResources();
}
// ************************************************************************************************
// *** Initialisation of resources used by the book browser
void TBookBrowser::initResources()
{
AFX_MANAGE_STATE(AfxGetAppModuleState());
m_Resources.LoadInfo();
CSize lLogicalSize(m_Resources.m_pInfo->m_Width, m_Resources.m_pInfo->m_Height);
setBookLogicalRect(CRect(CPoint(0,0), lLogicalSize));
}
void TBookBrowser::exitResources()
{
}
// ************************************************************************************************
BOOL TBookBrowser::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs.style & WS_VISIBLE)
{
m_IsVisible = TRUE;
}
cs.lpszName = _T("TBookBrowser");
return TWnd::PreCreateWindow(cs);
}
int TBookBrowser::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
int result;
// long lCode;
if ((result = TWnd::OnCreate(lpCreateStruct)) != 0)
return result;
if (m_pBookControler == NULL)
m_pBookControler.CoCreateInstance(CLSID_TBookControler);
ASSERT(m_pBookControler);
if (m_pBookControler == NULL)
{
DestroyWindow();
return -1;
}
// *** Create all the views used to display the book
createBookViews(T_PRIMARY);
createBookViews(T_SECONDARY);
m_pPrintingEngine = new CPrintingEngine();
VERIFY(m_pPrintingEngine->Create( this, 1));
return result;
}
void TBookBrowser::OnDestroy()
{
m_pBookControler.Release();
/*
if (m_Primary.m_Page)
m_Primary.m_Page->removePageletView();
if (m_Secondary.m_Page)
m_Secondary.m_Page->removePageletView();
*/
if (m_PageletManager)
{
m_PageletManager->cleanAllViews();
m_PageletManager->OnDestroyBook();
// *** Delete pagelet manager
m_PageletManager->Release();
m_PageletManager = NULL;
}
m_Primary.m_Page = NULL;
m_Primary.m_TabsViewer = NULL;
m_Secondary.m_Page = NULL;
m_Secondary.m_TabsViewer = NULL;
m_pBinderView = NULL;
m_pPrintingEngine = NULL;
TWnd::OnDestroy();
}
void TBookBrowser::OnShowWindow( BOOL pShow, UINT )
{
m_IsVisible = pShow;
}
// ************************************************************************************************
void TBookBrowser::createBookViews(ePageSide pSide)
{
HRESULT lResult;
if (m_pBinderView == NULL)
{
lResult = createBinder();
ASSERT(SUCCEEDED(lResult));
}
lResult = createPageEditor(pSide);
ASSERT(SUCCEEDED(lResult));
lResult = createTabsViewer(pSide);
ASSERT(SUCCEEDED(lResult));
#ifdef SUPPORT_PAGEMARK
lResult = createPagemarksViewer(pSide);
ASSERT(SUCCEEDED(lResult));
#endif // SUPPORT_PAGEMARK
#ifdef SUPPORT_FLYING_PAGE
if (m_SupportFlying)
{
lResult = createFlyingPage(pSide);
ASSERT(SUCCEEDED(lResult));
m_Primary.m_FlyingPage->setFlying(TRUE);
}
#endif // SUPPORT_FLYING_PAGE
}
// ************************************************************************************************
// ***
// *** Create the page editor correspondig to the position 'pPageSide' (Primary or secondary)
// *** Also creates the associated tabs viewer
// ***
HRESULT TBookBrowser::createPageEditor(ePageSide pSide)
{
t_Side_Data* lSideData;
CRect lLogicalRect;
TPageEditor* lPageEditor;
lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary;
// *** Verify that the tabs viewer to create doesn't exist yet
ASSERT(lSideData->m_Page == NULL);
GetPageLogicalRect(lLogicalRect, pSide);
lPageEditor = new TPageEditor();
VERIFY(lPageEditor);
lPageEditor->setLogicalPoint(lLogicalRect.TopLeft());
lPageEditor->setLogicalSize(lLogicalRect.Size());
lPageEditor->setLogicalSpace(lLogicalRect.Size());
// *** Create the page editor
LPtoDP(&lLogicalRect);
if (!lPageEditor->Create(NULL, NULL, WS_CHILD, lLogicalRect, this, 0))
return E_FAIL;
addChild(lPageEditor);
// *** Set view to be refreshed
lPageEditor->setViewToRefresh(lPageEditor);
// *** Set book browser and position
lPageEditor->setBookBrowser(this);
lPageEditor->setPageSide(pSide);
CDC* lDC = GetDC();
ASSERT_VALID(lDC);
setDCMappingMode(lDC);
lPageEditor->logicalResizeAndPos(lDC);
ReleaseDC(lDC);
lPageEditor->LoadBackground(m_Resources.m_pInfo);
// *** Set the good page editor
lSideData->m_Page = lPageEditor;
return S_OK;
}
// ************************************************************************************************
HRESULT TBookBrowser::createTabsViewer(ePageSide pPageSide)
{
t_Side_Data* lSideData;
TPageEditor* lPageEditor;
TTabsViewer* lTabsViewer;
CRect lLogicalRect;
lSideData = (pPageSide == T_PRIMARY) ? &m_Primary : &m_Secondary;
// *** Verify that the tabs viewer to create doesn't exist yet
ASSERT(lSideData->m_TabsViewer == NULL);
ASSERT(lSideData->m_Page != NULL);
lPageEditor = lSideData->m_Page;
GetTabsLogicalRect(lLogicalRect, pPageSide);
lTabsViewer = new TTabsViewer();
VERIFY( lTabsViewer);
CPoint lPosition(lLogicalRect.TopLeft());
CSize lSize(lLogicalRect.Size());
lTabsViewer->setLogicalPoint(lPosition);
lTabsViewer->setLogicalSize(lSize);
lTabsViewer->setLogicalSpace(lSize);
// --- CtrlId will be overridded by his WM_HELPHITTEST
LPtoDP(&lLogicalRect);
lTabsViewer->Create(NULL, NULL, WS_CHILD, lLogicalRect, this, 0);
// lTabsViewer->setViewToRefresh(this);
lTabsViewer->setBookControler(m_pBookControler);
addChild(lTabsViewer);
CDC* lDC = GetDC();
ASSERT_VALID(lDC);
setDCMappingMode(lDC);
lTabsViewer->logicalResizeAndPos(lDC);
ReleaseDC(lDC);
lTabsViewer->setPageSide(pPageSide);
lTabsViewer->LoadBackground(m_Resources.m_pInfo->m_TabZoneBitmap);
lSideData->m_TabsViewer = lTabsViewer;
return S_OK;
}
// ************************************************************************************************
HRESULT TBookBrowser::createBinder()
{
CRect lLogicalRect;
GetBinderLogicalRect(lLogicalRect);
m_pBinderView = new TBinderView(this);
VERIFY(m_pBinderView);
CPoint lPosition(lLogicalRect.TopLeft());
CSize lSize(lLogicalRect.Size());
m_pBinderView->setLogicalPoint(lPosition);
m_pBinderView->setLogicalSize(lSize);
m_pBinderView->setLogicalSpace(lSize);
LPtoDP(&lLogicalRect);
m_pBinderView->Create(NULL, NULL, WS_CHILD, lLogicalRect, this, 0);
addChild(m_pBinderView);
CDC* lDC = GetDC();
ASSERT_VALID(lDC);
setDCMappingMode(lDC);
m_pBinderView->logicalResizeAndPos(lDC);
ReleaseDC(lDC);
m_pBinderView->LoadBackground(m_Resources.m_pInfo->m_RWBinderBitmap,
m_Resources.m_pInfo->m_RBinderBitmap,
m_Resources.m_pInfo->m_DBinderBitmap);
CRect lArrowRect(CPoint(m_Resources.m_pInfo->m_ArrowX,
m_Resources.m_pInfo->m_ArrowY),
CSize(m_Resources.m_pInfo->m_ArrowWidth,
m_Resources.m_pInfo->m_ArrowHeight));
m_pBinderView->LoadToolbar(lArrowRect,
m_Resources.m_pInfo->m_ArrowUpID,
m_Resources.m_pInfo->m_ArrowDownID);
return S_OK;
}
// ************************************************************************************************
#ifdef SUPPORT_PAGEMARK
HRESULT TBookBrowser::createPagemarksViewer(ePageSide pPageSide)
{
t_Side_Data* lSideData;
TPageEditor* lPageEditor;
lSideData = (pPageSide == T_PRIMARY) ? &m_Primary : &m_Secondary;
// *** Verify that the pagemarks viewer to create doesn't exist yet
ASSERT(lSideData->m_PagemarksViewer == NULL);
ASSERT(lSideData->m_Page != NULL);
lPageEditor = lSideData->m_Page;
CSize lLogicalSize = lPageEditor->getLogicalSize();
CRect lRect(CPoint(0, 0), lLogicalSize);
lRect.bottom = lRect.top + 50; // *** TO DO : put in resources
long lShift = lSideData->m_TabsLogicalRect.Width();
if (pPageSide == T_PRIMARY)
lRect.left += lShift;
else
lRect.right -= lShift;
TPagemarksViewer* lPagemarksViewer;
lPagemarksViewer = new TPagemarksViewer();
VERIFY( lPagemarksViewer);
lPagemarksViewer->setViewToRefresh(lPageEditor);
lPagemarksViewer->setBookBrowser(this);
// lPagemarksViewer->setLogicalSpace(m_pBookBkgnd->getWidth() - m_Primary.m_TabsLogicalRect.Width(), 50); // *** TO DO : put in resources
lPagemarksViewer->setLogicalPoint(CPoint(lRect.left, lRect.top));
lPagemarksViewer->setLogicalSize(CSize(lRect.Width(), lRect.Height()));
lPagemarksViewer->Create(NULL, NULL, WS_CHILD, lRect, this, 0);
addChild(lPagemarksViewer);
CDC* lDC = GetDC();
ASSERT_VALID(lDC);
lPagemarksViewer->logicalResizeAndPos(lDC);
ReleaseDC(lDC);
lPagemarksViewer->setPageSide(pPageSide);
lSideData->m_PagemarksViewer = lPagemarksViewer;
return S_OK;
}
#endif // SUPPORT_PAGEMARK
// ************************************************************************************************
void TBookBrowser::showBookViews(long pShow)
{
// *** Validity of parameters
ASSERT(pShow == SW_HIDE || pShow == SW_SHOW);
// *** Validity of views
ASSERT(m_Primary.m_Page && m_Primary.m_TabsViewer);
ASSERT(m_Secondary.m_Page && m_Secondary.m_TabsViewer);
if (!m_Primary.m_Page || !m_Primary.m_TabsViewer)
return ;
if (!m_Secondary.m_Page || !m_Secondary.m_TabsViewer)
return ;
m_Primary.m_TabsViewer->ShowWindow(pShow);
// In Page mode, the Show / Hide is only apply to the selected page
if ((m_ModeView != T_PAGE_MODE)
|| m_Primary.m_Page->isSelected()
|| ((m_Book == NULL) && (pShow == SW_HIDE)))
{
m_Primary.m_Page->ShowWindow(pShow);
}
m_pBinderView->ShowWindow(pShow);
// In Page mode, the Show / Hide is only apply to the selected page
if ((m_ModeView != T_PAGE_MODE)
|| m_Secondary.m_Page->isSelected()
|| ((m_Book == NULL) && (pShow == SW_HIDE)))
{
m_Secondary.m_Page->ShowWindow(pShow);
}
m_Secondary.m_TabsViewer->ShowWindow(pShow);
// *** Refresh background if hidden, in order to restore it.
if (pShow == SW_HIDE)
{
ASSERT(!m_Primary.m_TabsViewer->IsWindowVisible());
ASSERT(!m_Primary.m_Page->IsWindowVisible());
ASSERT(!m_pBinderView->IsWindowVisible());
ASSERT(!m_Secondary.m_Page->IsWindowVisible());
ASSERT(!m_Secondary.m_TabsViewer->IsWindowVisible());
if (!m_WasEmpty)
{
CRect lDeviceRect(getDevicePoint(), getDeviceSize());
GetParent()->InvalidateRect(lDeviceRect);
GetParent()->UpdateWindow();
}
}
}
// ************************************************************************************************
//
// Compute the size of all the views.
//
HRESULT TBookBrowser::GetPageLogicalRect(CRect& pRect, ePageSide pSide)
{
long lTotalSpace;
long lPageSpace;
lTotalSpace = m_BookLogicalRect.Width() - (m_Resources.m_pInfo->m_TabWidth * 2) - m_Resources.m_pInfo->m_BinderWidth;
if (m_ModeView == T_PAGE_MODE)
lPageSpace = lTotalSpace;
else
lPageSpace = lTotalSpace / 2;
pRect.top = 0;
pRect.bottom = m_BookLogicalRect.Height();
if (pSide == T_PRIMARY)
{
pRect.left = m_Resources.m_pInfo->m_TabWidth;
pRect.right = pRect.left + lPageSpace;
}
else if (pSide == T_SECONDARY)
{
pRect.right = m_BookLogicalRect.Width() - m_Resources.m_pInfo->m_TabWidth;
pRect.left = pRect.right - lPageSpace;
}
return S_OK;
}
HRESULT TBookBrowser::GetTabsLogicalRect(CRect& pRect, ePageSide pSide)
{
pRect.top = 0;
pRect.bottom = m_BookLogicalRect.Height();
if (pSide == T_PRIMARY)
{
pRect.left = 0;
pRect.right = m_Resources.m_pInfo->m_TabWidth;
}
else if (pSide == T_SECONDARY)
{
pRect.right = m_BookLogicalRect.Width();
pRect.left = pRect.right - m_Resources.m_pInfo->m_TabWidth;
}
return S_OK;
}
HRESULT TBookBrowser::GetBinderLogicalRect(CRect& pRect, ePageSide pSide)
{
pRect.top = 0;
pRect.bottom = m_BookLogicalRect.Height();
if (m_ModeView == T_PAGE_MODE)
{
if (pSide == T_SECONDARY)
pRect.left = m_Resources.m_pInfo->m_TabWidth;
else
pRect.left = m_BookLogicalRect.Width() - m_Resources.m_pInfo->m_TabWidth - m_Resources.m_pInfo->m_BinderWidth;
}
else
pRect.left = m_BookLogicalRect.Width() / 2 - m_Resources.m_pInfo->m_BinderWidth / 2;
pRect.right = pRect.left + m_Resources.m_pInfo->m_BinderWidth;
return S_OK;
}
// *****************************************************************************
//
//
//
void TBookBrowser::OnSize(UINT nType, int cx, int cy)
{
TWnd::OnSize(nType, cx, cy);
constraintLogicalResize();
}
// *****************************************************************************
//
//
//
void TBookBrowser::constraintLogicalResize()
{
CRect lPrevDeviceRect;
CRect lDeviceRect;
CRect lPrevLogicalRect;
CRect lLogicalRect;
m_Primary.m_TabsViewer->GetWindowRect(&lPrevDeviceRect);
ScreenToClient(&lPrevDeviceRect);
lPrevLogicalRect = CRect(m_Primary.m_TabsViewer->getLogicalPoint(), m_Primary.m_TabsViewer->getLogicalSize());
m_Primary.m_Page->GetWindowRect(&lDeviceRect);
ScreenToClient(&lDeviceRect);
lLogicalRect = CRect(m_Primary.m_Page->getLogicalPoint(), m_Primary.m_Page->getLogicalSize());
if (lPrevDeviceRect.right < lDeviceRect.left)
{
long lDelta = lDeviceRect.left - lPrevDeviceRect.right;
m_Primary.m_Page->SetWindowPos(0, lDeviceRect.left - lDelta, lDeviceRect.top, lDeviceRect.Width() + lDelta, lDeviceRect.Height(), SWP_NOOWNERZORDER);
m_Primary.m_Page->GetWindowRect(&lDeviceRect);
ScreenToClient(&lDeviceRect);
ASSERT(lPrevDeviceRect.right >= lDeviceRect.left);
}
lPrevLogicalRect = lLogicalRect;
lPrevDeviceRect = lDeviceRect;
m_pBinderView->GetWindowRect(&lDeviceRect);
ScreenToClient(&lDeviceRect);
lLogicalRect = CRect(m_pBinderView->getLogicalPoint(), m_pBinderView->getLogicalSize());
if (lPrevDeviceRect.right < lDeviceRect.left)
{
long lDelta = lDeviceRect.left - lPrevDeviceRect.right;
m_Primary.m_Page->SetWindowPos(0, lPrevDeviceRect.left, lPrevDeviceRect.top, lPrevDeviceRect.Width() + lDelta, lPrevDeviceRect.Height(), SWP_NOOWNERZORDER);
m_Primary.m_Page->GetWindowRect(&lPrevDeviceRect);
ScreenToClient(&lPrevDeviceRect);
ASSERT(lPrevDeviceRect.right >= lDeviceRect.left);
}
lPrevLogicalRect = lLogicalRect;
lPrevDeviceRect = lDeviceRect;
m_Secondary.m_Page->GetWindowRect(&lDeviceRect);
ScreenToClient(&lDeviceRect);
lLogicalRect = CRect(m_Secondary.m_Page->getLogicalPoint(), m_Secondary.m_Page->getLogicalSize());
if (lPrevDeviceRect.right < lDeviceRect.left)
{
long lDelta = lDeviceRect.left - lPrevDeviceRect.right;
m_Secondary.m_Page->SetWindowPos(0, lDeviceRect.left - lDelta, lDeviceRect.top, lDeviceRect.Width() + lDelta, lDeviceRect.Height(), SWP_NOOWNERZORDER);
m_Secondary.m_Page->GetWindowRect(&lDeviceRect);
ScreenToClient(&lDeviceRect);
ASSERT(lPrevDeviceRect.right >= lDeviceRect.left);
}
lPrevLogicalRect = lLogicalRect;
lPrevDeviceRect = lDeviceRect;
m_Secondary.m_TabsViewer->GetWindowRect(&lDeviceRect);
ScreenToClient(&lDeviceRect);
lLogicalRect = CRect(m_Secondary.m_TabsViewer->getLogicalPoint(), m_Secondary.m_TabsViewer->getLogicalSize());
if (lPrevDeviceRect.right < lDeviceRect.left)
{
long lDelta = lDeviceRect.left - lPrevDeviceRect.right;
m_Secondary.m_Page->SetWindowPos(0, lPrevDeviceRect.left, lPrevDeviceRect.top, lPrevDeviceRect.Width() + lDelta, lPrevDeviceRect.Height(), SWP_NOOWNERZORDER);
m_Secondary.m_Page->GetWindowRect(&lPrevDeviceRect);
ScreenToClient(&lPrevDeviceRect);
ASSERT(lPrevDeviceRect.right >= lDeviceRect.left);
}
}
#ifdef SUPPORT_PAGEMARK
HRESULT TBookBrowser::GetPagemarkLogicalRect(CRect& pRect, ePageSide pSide)
{
return S_OK;
}
#endif // SUPPORT_PAGEMARK
// -------------------------------------------------------------------
//
//
void TBookBrowser::setPrimaryPage(TPageModel* pPage)
{
// ASSERT(pPageModel);
if (pPage == NULL)
return ; // Invalid Arguments
ASSERT_VALID(this);
// ASSERT(fBook);
m_Primary.m_Page->setPage(pPage);
}
// -------------------------------------------------------------------
//
//
void TBookBrowser::setSecondaryPage(TPageModel* pPage)
{
// ASSERT(pPageModel);
if (pPage == NULL)
return ; // Invalid Arguments
ASSERT_VALID(this);
// ASSERT(fBook);
m_Secondary.m_Page->setPage(pPage);
}
// ********************************************************************
void TBookBrowser::computeTabsViewerNbTabs() // TPageModel* pPage)
{
ASSERT_VALID(this);
ATLASSERT(m_Book);
if (m_Book == NULL)
return ;
ATLASSERT(m_Summary);
if (m_Summary == NULL)
return ;
ATLASSERT(m_Index);
if (m_Index == NULL)
return ;
TPageModelArray lPrimaryPages;
TPageModelArray lSecondaryPages;
TModelPtr lPrimaryPage;
TModelPtr lPrimaryChapter;
TModelPtr lSecondaryPage;
TModelIterator* lPages = NULL;
BOOL lPrimaryCount = TRUE;
m_Primary.m_TabsViewer->cleanTab();
m_Secondary.m_TabsViewer->cleanTab();
lPrimaryPage = m_Primary.m_Page->getPage();
lSecondaryPage = m_Secondary.m_Page->getPage();
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_READONLY);
m_Summary->getPages(&lPages);
if (lSecondaryPage == m_Summary)
{
lSecondaryPages.push_back(m_Summary.p);
lPrimaryCount = FALSE;
}
else
{
lPrimaryPages.push_back(m_Summary.p);
if (lPrimaryPage == m_Summary)
lPrimaryCount = FALSE;
else if (lPrimaryPage)
{
lPrimaryPage->getChapter(&lPrimaryChapter);
while (lPrimaryChapter
&& (lPrimaryChapter != m_Summary))
{
lPrimaryPage = lPrimaryChapter;
lPrimaryChapter.Release();
lPrimaryPage->getChapter(&lPrimaryChapter);
}
// now PrimaryPage is a first level chapter !!!
// or is NULL
}
}
if (lPages != NULL)
{
while (lPages->hasMoreElements())
{
TModelPtr lPage;
lPages->nextElement((TObjectModel**)&lPage);
if (lPage->getID() == T_CHAPTER_MODEL_NAME)
{
if (lPrimaryCount)
lPrimaryPages.push_back(lPage);
else
lSecondaryPages.push_back(lPage);
}
if (lPage == lPrimaryPage)
lPrimaryCount = FALSE;
}
}
delete lPages;
lSecondaryPages.push_back(m_Index.p);
TGlobalsDB::getLibraryDBManager()->commitTransaction();
long lIndex;
long lPrimarySize = lPrimaryPages.size();
long lSecondarySize = lSecondaryPages.size();
for (lIndex = 0; lIndex < lPrimarySize; lIndex++)
m_Primary.m_TabsViewer->addTab(lIndex, lPrimaryPages[lIndex]);
for (lIndex = 0; lIndex < lSecondarySize; lIndex++)
m_Secondary.m_TabsViewer->addTab(lIndex, lSecondaryPages[lIndex]);
m_TotalTabsNb = lPrimarySize + lSecondarySize;
m_Primary.m_TabsViewer->setTotalTabs(m_TotalTabsNb);
m_Secondary.m_TabsViewer->setTotalTabs(m_TotalTabsNb);
m_Primary.m_TabsViewer->calcTabsData();
m_Secondary.m_TabsViewer->calcTabsData();
if (IsWindowVisible())
{
m_Primary.m_TabsViewer->refresh();
m_Secondary.m_TabsViewer->refresh();
}
lPrimaryPages.erase(lPrimaryPages.begin(), lPrimaryPages.end());
lSecondaryPages.erase(lSecondaryPages.begin(), lSecondaryPages.end());
}
long TBookBrowser::getFirstLevelChapterCount()
{
long lCount = 0;
TModelIterator* lPages = NULL;
m_Summary->getPages(&lPages);
while (lPages->hasMoreElements())
{
TModelPtr lPage;
lPages->nextElement((TObjectModel**)&lPage);
ASSERT(lPages);
// *** Count the number of first level chapters
if (lPage->getID() == T_CHAPTER_MODEL_NAME)
lCount++;
}
delete lPages;
return lCount;
}
// ************************************************************************************************
BOOL TBookBrowser::setBook(TBookModel* pBook)
{
m_WasEmpty = FALSE;
// *** Doesn't change book --> nothing to do
if (pBook == m_Book)
return FALSE;
if (m_Book == NULL)
m_WasEmpty = TRUE;
showBookViews(SW_HIDE);
// *** Remove previous book
removeBook();
m_pBookControler->put_book((long)pBook);
if(pBook == NULL)
{
ShowWindow(SW_HIDE);
return TRUE;
}
else
ShowWindow(SW_SHOW);
if (!addBook(pBook))
return FALSE;
#ifdef _DEBUG
CString stgName = pBook->getName();
TRACE("TBookBrowser::setBook - Open Book: %s\n", stgName);
#endif
UpdatePages();
computeTabsViewerNbTabs();
// *** Show the views
PostMessage(WM_USER_SHOW_BOOK_VIEWS);
return TRUE;
}
// *******************************************************************************
BOOL TBookBrowser::addBook(TBookModel* pBook)
{
ASSERT(m_PageletManager == NULL);
if (m_PageletManager == NULL)
{
// *** Create pagelet view manager
m_PageletManager = new TPageletViewManager();
ASSERT(m_PageletManager);
if (m_PageletManager)
m_PageletManager->AddRef();
}
// *** Set new book
m_Book = pBook;
m_Book->getSummary(&m_Summary);
m_Book->getIndex(&m_Index);
m_BookIsWritable = !IsModifyProtected(pBook);
// *** Add new listener
m_BookListener = new TBrowserBookListener(this);
VERIFY(m_BookListener != NULL);
m_Book->addPropertyChangeListener(m_BookListener);
// *** Reset the book browser
m_TotalTabsNb = 0;
ASSERT(m_Primary.m_TabsViewer && m_Secondary.m_TabsViewer);
if ((m_Primary.m_TabsViewer == NULL) || (m_Secondary.m_TabsViewer == NULL))
return FALSE;
m_Secondary.m_TabsViewer->setTotalTabs(0);
m_Primary.m_TabsViewer->setTotalTabs(0);
return TRUE;
}
// *********************************************************************************
BOOL TBookBrowser::removeBook()
{
if (m_Book == NULL)
return FALSE;
// *** Remove listener
if (m_BookListener)
{
m_Book->removePropertyChangeListener(m_BookListener);
m_BookListener->setInvalid();
m_BookListener = NULL;
}
TMetaManager::flushCachedData(m_Book);
m_Book.Release();
m_Summary.Release();
m_Index.Release();
// *** Show the views
if (GetSafeHwnd())
{
showBookViews(SW_HIDE);
refresh();
}
if (m_Primary.m_Page)
m_Primary.m_Page->setPage(NULL);
if (m_Secondary.m_Page)
m_Secondary.m_Page->setPage(NULL);
if (m_Primary.m_TabsViewer)
m_Primary.m_TabsViewer->cleanTab();
if (m_Secondary.m_TabsViewer)
m_Secondary.m_TabsViewer->cleanTab();
if (m_PageletManager)
{
m_PageletManager->cleanAllViews();
m_PageletManager->OnDestroyBook();
m_PageletManager->Release();
m_PageletManager = NULL;
}
return TRUE;
}
LRESULT TBookBrowser::OnShowBookViews(WPARAM, LPARAM)
{
showBookViews(SW_SHOW);
return S_OK;
}
void TBookBrowser::UpdatePages(BOOL pLoop)
{
// *** Get the primary and secondary pages
TModelPtr lPrimaryPage;
TModelPtr lSecondaryPage;
TModelPtr lSelectedPage;
TModelPtr lNextPage;
m_Book->getPrimaryPage(&lPrimaryPage);
m_Book->getSecondaryPage(&lSecondaryPage);
m_Book->getSelectedPage(&lSelectedPage);
TModelPtr lPageBook;
if (lPrimaryPage != NULL)
{
lPrimaryPage->getBook(&lPageBook);
if (lPageBook == m_Book)
{
GetNextPage(lPrimaryPage, &lNextPage);
}
}
if ((lPrimaryPage == NULL)
|| (lPageBook != m_Book)
|| (lNextPage == NULL))
{
// *** We open the book on the property page
m_pBookControler->ChangePageTo(T_CPT_SUMMARY, T_SIDE_SECONDARY, CComVariant(1));
if (!pLoop)
PostMessage(WM_USER_UPDATE_PAGES);
}
else
{
ASSERT(lPrimaryPage);
ASSERT(lNextPage);
if (lNextPage != lSecondaryPage)
{
// *** We open the book on the property page
m_pBookControler->ChangePageTo(T_CPT_PAGE, T_SIDE_PRIMARY, CComVariant((long)lPrimaryPage.p));
if (!pLoop)
PostMessage(WM_USER_UPDATE_PAGES);
}
else
{
ASSERT(lSecondaryPage);
ASSERT((lSelectedPage == lPrimaryPage) || (lSelectedPage == lSecondaryPage));
m_Primary.m_Page->setPage(lPrimaryPage);
m_Secondary.m_Page->setPage(lSecondaryPage);
m_Primary.m_Page->Select(lSelectedPage == lPrimaryPage);
m_Secondary.m_Page->Select(lSelectedPage != lPrimaryPage);
ePageSide lSelectedSide;
lSelectedSide = (lSelectedPage == lPrimaryPage) ? T_PRIMARY : T_SECONDARY;
if (m_WasEmpty || (lSelectedSide != m_SelectedSide))
{
m_SelectedSide = lSelectedSide;
if (m_ModeView == T_PAGE_MODE)
ResizeView(m_SelectedSide, FALSE);
}
}
}
}
LRESULT TBookBrowser::OnUpdatePages(WPARAM, LPARAM)
{
UpdatePages(TRUE);
return S_OK;
}
// ************************************************************************************************
void TBookBrowser::setModeView(long pModeView)
{
m_ModeView = pModeView;
}
// ************************************************************************************************
TBookModel* TBookBrowser::getBook()
{
return m_Book;
}
// ************************************************************************************************
void TBookBrowser::setFlyingPage(TPageModel* /*pPage*/)
{
}
long TBookBrowser::GetPageBehaviour(ePageSide pSide)
{
t_Side_Data* lSideData;
lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary;
ASSERT(lSideData->m_Page);
if (lSideData->m_Page)
return lSideData->m_Page->GetPageBehaviour();
return 0;
}
// ************************************************************************************************
void TBookBrowser::setSelectedPage(TPageModel* pPage)
{
TModelPtr lPrimaryPage = m_Primary.m_Page->getPage();
TModelPtr lSecondaryPage = m_Secondary.m_Page->getPage();
// Selected page must be primary or secondary page
ASSERT((lPrimaryPage == pPage) || (lSecondaryPage == pPage));
if (lPrimaryPage == pPage)
{
m_Primary.m_Page->Select(TRUE);
m_Secondary.m_Page->Select(FALSE);
}
else if (lSecondaryPage == pPage)
{
m_Primary.m_Page->Select(FALSE);
m_Secondary.m_Page->Select(TRUE);
}
}
TPageEditor* TBookBrowser::getPageEditor(ePageSide pPageSide)
{
return ((pPageSide == T_PRIMARY) ? m_Primary.m_Page
: m_Secondary.m_Page);
}
TTabsViewer* TBookBrowser::getTabsViewer(ePageSide pPageSide)
{
return ((pPageSide == T_PRIMARY) ? m_Primary.m_TabsViewer
: m_Secondary.m_TabsViewer);
}
// ************************************************************************************************
void TBookBrowser::getTabScreenRect(TPageEditor* pPageEditor, long pIndex, CRect* pRect)
{
TTabsViewer* lTabsViewer;
if (pPageEditor == m_Primary.m_Page)
lTabsViewer = m_Primary.m_TabsViewer;
else
lTabsViewer = m_Secondary.m_TabsViewer;
lTabsViewer->getTabScreenRect(pIndex, pRect);
}
// ************************************************************************************************
void TBookBrowser::changeSelectedPage(TPageModel* pPage)
{
if (pPage == NULL)
{
m_Primary.m_Page->Select(FALSE);
m_Secondary.m_Page->Select(FALSE);
m_SelectedSide = T_NONE;
return ;
}
ASSERT_VALID(this);
ASSERT(m_Book);
ASSERT(m_pBookControler);
TModelPtr lPrimaryPage = m_Primary.m_Page->getPage();
TModelPtr lSecondaryPage = m_Secondary.m_Page->getPage();
#ifdef Pierre
ASSERT(lPrimaryPage == pPage || lSecondaryPage == pPage);
#endif
if (pPage == lPrimaryPage)
{
SwitchSelectedPage(T_PRIMARY);
m_SelectedSide = T_PRIMARY;
}
else if (pPage == lSecondaryPage)
{
SwitchSelectedPage(T_SECONDARY);
m_SelectedSide = T_SECONDARY;
}
computeTabsViewerNbTabs();
} // *** changeSelectedPage
// ************************************************************************************************
// *** EVENTS HANDLER ON BOOK CHANGE PROPERTIES
// ************************************************************************************************
void TBookBrowser::addPageEvt(TPageModel* pPage)
{
ASSERT(pPage);
if (pPage == NULL)
return ;
ASSERT_VALID(this);
ASSERT(m_Book);
if (TBookUtils::isFirstLevelChapter(pPage))
computeTabsViewerNbTabs();
}
// ************************************************************************************************
void TBookBrowser::insertPageEvt(TPageModel* pPage)
{
addPageEvt(pPage);
}
// ************************************************************************************************
void TBookBrowser::removePageEvt(TPageModel* pPage)
{
ASSERT(pPage);
if (pPage == NULL)
return ;
if (pPage->isInstanceOf(T_CHAPTER_MODEL_NAME))
computeTabsViewerNbTabs();
}
// ************************************************************************************************
void TBookBrowser::changeWritableEvt()
{
ASSERT_VALID(this);
ASSERT(m_Book);
BOOL lWritable = m_Book->isWritable();
m_Primary.m_Page->changeWritable(lWritable);
m_Secondary.m_Page->changeWritable(lWritable);
}
// ************************************************************************************************
void TBookBrowser::addPageBeforeSummaryEvt(TPageModel* /*pPage*/)
{
TRACE("(TBookBrowser) : handle add page before summary event\n");
}
// ************************************************************************************************
void TBookBrowser::removePageBeforeSummaryEvt(TPageModel* /*pPage*/)
{
TRACE("(TBookBrowser) : handle remove page before summary event\n");
}
// ************************************************************************************************
void TBookBrowser::destroyBookModelEvt()
{
// *** Remove the book
removeBook();
}
// ************************************************************************************************
#ifdef SUPPORT_FLYING_PAGE
void TBookBrowser::attachDivider(ePageSide pPageSide)
{
ASSERT(m_SupportFlying);
TPageEditor* lPageEditor;
TPageEditor* lFlyingPageEditor;
TModelPtr lPage;
lPageEditor = (pPageSide == T_PRIMARY ? m_Primary.m_Page : m_Secondary.m_Page);
ASSERT(lPageEditor);
lFlyingPageEditor = (pPageSide == T_PRIMARY ? m_Primary.m_FlyingPage : m_Secondary.m_FlyingPage);
ASSERT(lFlyingPageEditor);
lPage = lFlyingPageEditor->getPage();
lFlyingPageEditor->setPage(NULL);
lFlyingPageEditor->ShowWindow(SW_HIDE);
lPageEditor->showContent(TRUE);
if (lPageEditor->getPage() == lPage)
{
// ?????
lPageEditor->setPageViewParent(lPage);
lPageEditor->setPage(lPage, TRUE);
}
}
// ************************************************************************************************
void TBookBrowser::detachDivider(ePageSide pPageSide)
{
ASSERT(m_SupportFlying);
TPageEditor* lPageEditor;
TPageEditor* lFlyingPageEditor;
TModelPtr lPage;
lPageEditor = (pPageSide == T_PRIMARY ? m_Primary.m_Page : m_Secondary.m_Page);
ASSERT(lPageEditor);
lFlyingPageEditor = (pPageSide == T_PRIMARY ? fPrimaryFlyingPageEditor : fSecondaryFlyingPageEditor);
ASSERT(lFlyingPageEditor);
lPage = lPageEditor->getPage();
ASSERT(lPage);
lPageEditor->showContent(FALSE);
lFlyingPageEditor->ShowWindow(SW_SHOW);
lFlyingPageEditor->setPageViewParent(lPage);
lFlyingPageEditor->setPage(lPage);
}
#endif // SUPPORT_FLYING_PAGE
// ************************************************************************************************
BOOL TBookBrowser::isFlying(TPageModel* pPage)
{
#ifdef SUPPORT_FLYING_PAGE
// This function might be call even if Flying is not supported ?
ASSERT(m_SupportFlying);
if (pPage == NULL)
return FALSE;
if (m_Primary.m_FlyingPage)
if (m_Primary.m_FlyingPage->getPage() == pPage)
return TRUE;
if (m_Secondary.m_FlyingPage)
if (m_Secondary.m_FlyingPager->getPage() == pPage)
return TRUE;
#endif // SUPPORT_FLYING_PAGE
return FALSE;
}
// ------------------------------------------------------------------------------
//
//
TPageEditor* TBookBrowser::getSelectedPageEditor()
{
if (m_Primary.m_Page->isSelected())
return m_Primary.m_Page;
return m_Secondary.m_Page;
}
// ------------------------------------------------------------------------------
//
//
void TBookBrowser::setBookLogicalRect(CRect pLogicalRect)
{
m_BookLogicalRect = pLogicalRect;
setLogicalSpace(pLogicalRect.Size());
recalcTabsRect();
}
// ------------------------------------------------------------------------------
//
//
void TBookBrowser::recalcTabsRect()
{
// *** Set the rectangle of the tabs viewer
TBackGround lBmp(TTabsViewer::gIDBTabTopLeftMask); // *** Used to set width of tabs viewer
long lWidth = lBmp.getWidth();
// *** Primary side
CPoint lTopLeft(0, 0);
CSize lSize(lWidth, m_BookLogicalRect.Height());
m_Primary.m_TabsLogicalRect = CRect(lTopLeft, lSize);
// *** Secondary side
lTopLeft = CPoint(m_BookLogicalRect.Width() - lWidth, 0);
m_Secondary.m_TabsLogicalRect = CRect(CPoint(m_BookLogicalRect.Width() / 2 - lSize.cx, lTopLeft.y), lSize);
}
// ------------------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnModeChange(WPARAM pMode, LPARAM)
{
if (!m_IsVisible && getBook())
ShowWindow(SW_SHOW);
if (pMode == m_ModeView)
return S_FALSE;
long lOldMode = m_ModeView;
if ((pMode == T_PAGE_MODE) || (pMode == T_BOOK_MODE))
{
ShowToolbar(T_PRIMARY);
ShowToolbar(T_SECONDARY);
}
else
{
HideToolbar(T_PRIMARY);
HideToolbar(T_SECONDARY);
}
m_ModeView = pMode;
if (pMode == T_PAGE_MODE)
SwitchToPage();
if (lOldMode == T_PAGE_MODE)
SwitchFromPage();
if (m_Primary.m_Page)
m_Primary.m_Page->OnModeChange(pMode);
if (m_Secondary.m_Page)
m_Secondary.m_Page->OnModeChange(pMode);
return S_OK;
}
void TBookBrowser::SwitchFromPage()
{
ASSERT(m_Primary.m_Page);
ASSERT(m_Secondary.m_Page);
if ((m_Primary.m_Page == NULL) || (m_Secondary.m_Page == NULL))
return ;
/*
if (m_Primary.m_Page->isSelected())
{
m_Secondary.m_Page->ShowWindow(SW_SHOW);
}
else
{
m_Primary.m_Page->ShowWindow(SW_SHOW);
}
*/
ResizeView();
}
void TBookBrowser::SwitchToPage()
{
ASSERT(m_Primary.m_Page);
ASSERT(m_Secondary.m_Page);
if ((m_Primary.m_Page == NULL) || (m_Secondary.m_Page == NULL))
return ;
if (m_Primary.m_Page->isSelected())
{
ResizeView(T_PRIMARY);
}
else
{
ResizeView(T_SECONDARY);
}
}
void TBookBrowser::SwitchSelectedPage(ePageSide pSide)
{
m_Primary.m_Page->Select(pSide == T_PRIMARY);
m_Secondary.m_Page->Select(pSide == T_SECONDARY);
if (m_ModeView != T_PAGE_MODE)
return ;
ResizeView(pSide);
}
void TBookBrowser::ResizeView(ePageSide pSide, BOOL pShow)
{
CRect lLogicalRect;
GetBinderLogicalRect(lLogicalRect, pSide);
m_pBinderView->setLogicalPoint(lLogicalRect.TopLeft());
m_pBinderView->setLogicalSize(lLogicalRect.Size());
m_pBinderView->setLogicalSpace(lLogicalRect.Size());
if (pSide != T_SECONDARY)
{
GetPageLogicalRect(lLogicalRect, T_PRIMARY);
m_Primary.m_Page->setLogicalPoint(lLogicalRect.TopLeft());
m_Primary.m_Page->setLogicalSize(lLogicalRect.Size());
if (pSide != T_NONE)
{
if (pShow)
m_Secondary.m_Page->ShowWindow(SW_HIDE);
m_Primary.m_Page->setLogicalSpace(lLogicalRect.Width() / 2, lLogicalRect.Height());
}
else
m_Primary.m_Page->setLogicalSpace(lLogicalRect.Size());
if (pShow)
m_Primary.m_Page->ShowWindow(SW_SHOW);
}
if (pSide != T_PRIMARY)
{
GetPageLogicalRect(lLogicalRect, T_SECONDARY);
m_Secondary.m_Page->setLogicalPoint(lLogicalRect.TopLeft());
m_Secondary.m_Page->setLogicalSize(lLogicalRect.Size());
if (pSide != T_NONE)
{
if (pShow)
m_Primary.m_Page->ShowWindow(SW_HIDE);
m_Secondary.m_Page->setLogicalSpace(lLogicalRect.Width() / 2, lLogicalRect.Height());
}
else
m_Secondary.m_Page->setLogicalSpace(lLogicalRect.Size());
if (pShow)
m_Secondary.m_Page->ShowWindow(SW_SHOW);
}
CDC* lDC = GetDC();
ASSERT_VALID(lDC);
setDCMappingMode(lDC);
m_pBinderView->logicalResizeAndPos(lDC);
m_Primary.m_Page->logicalResizeAndPos(lDC);
m_Secondary.m_Page->logicalResizeAndPos(lDC);
ReleaseDC(lDC);
constraintLogicalResize();
}
void TBookBrowser::ShowToolbar(ePageSide pSide)
{
t_Side_Data* lSideData;
lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary;
if (lSideData->m_Page && lSideData->m_Page->haveToolbar())
{
if (lSideData->m_Page->showToolbar())
m_pBinderView->ShowToolbar(pSide);
}
}
void TBookBrowser::HideToolbar(ePageSide pSide)
{
t_Side_Data* lSideData;
lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary;
if (lSideData->m_Page->haveToolbar())
{
if (lSideData->m_Page->hideToolbar())
m_pBinderView->HideToolbar(pSide);
}
}
void TBookBrowser::OnBeforeLoad(ePageSide pSide)
{
t_Side_Data* lSideData;
lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary;
BOOL lHaveToolbar;
lHaveToolbar = lSideData->m_Page->haveToolbar();
m_pBinderView->SetHaveToolbar(pSide, lHaveToolbar, lSideData->m_Page->isToolbarUp());
if (lHaveToolbar)
{
if ((m_ModeView == T_PAGE_MODE)
|| (m_ModeView == T_BOOK_MODE))
{
ShowToolbar(pSide);
}
else
{
HideToolbar(pSide);
}
}
}
// --------------------------------------------------------------------
// Book Controls
// --------------------------------------------------------------------
void TBookBrowser::getBookControler(IBookControler** pBookControler)
{
ASSERT(pBookControler);
if (pBookControler == NULL)
return ;
*pBookControler = m_pBookControler;
(*pBookControler)->AddRef();
}
void TBookBrowser::setBookControler(IBookControler* pBookControler)
{
m_pBookControler = pBookControler;
if (m_Primary.m_TabsViewer)
m_Primary.m_TabsViewer->setBookControler(pBookControler);
if (m_Secondary.m_TabsViewer)
m_Secondary.m_TabsViewer->setBookControler(pBookControler);
}
// -------------------------------------------------------------------
//
//
void TBookBrowser::goToPage(TPageModel* pPage, ePageSide pSide, BOOL pSelect)
{
ASSERT_VALID(this);
ASSERT(m_pBookControler);
ePageSide2 lSide = T_SIDE_SECONDARY;
if (pSide == T_PRIMARY)
lSide = T_SIDE_PRIMARY;
m_pBookControler->ChangePageTo(T_CPT_PAGE, lSide, CComVariant((long)pPage));
}
#ifdef _DEBUG
void TBookBrowser::AssertValid( ) const
{
// ASSERT(fBook);
ASSERT(m_Primary.m_Page);
if (m_ModeView != T_PAGE_MODE)
{
ASSERT(m_Secondary.m_Page);
if (m_Primary.m_Page->getPage())
ASSERT(!m_Primary.m_Page->isIndex());
}
// if (m_Primary.m_Page->getPage() && m_Secondary.m_Page->getPage())
// ASSERT(m_Primary.m_Page->getPage() != m_Secondary.m_Page->getPage());
ASSERT(m_Primary.m_TabsViewer);
ASSERT(m_Secondary.m_TabsViewer);
}
#endif
// --------------------------------------------------------------------
// Event Handlers
// --------------------------------------------------------------------
LRESULT TBookBrowser::OnSetName(WPARAM, LPARAM)
{
// changeBookManeEvt();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnAddPage(WPARAM wParam, LPARAM )
{
TPageModel* lPage = (TPageModel*)wParam;
ASSERT(lPage);
ASSERT_VALID(this);
addPageEvt(lPage);
ASSERT_VALID(this);
if (lPage)
lPage->Release();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnInsertPage(WPARAM wParam, LPARAM )
{
TPageModel* lPage = (TPageModel*)wParam;
ASSERT(lPage);
ASSERT_VALID(this);
insertPageEvt(lPage);
ASSERT_VALID(this);
if (lPage)
lPage->Release();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnRemovePage(WPARAM wParam, LPARAM )
{
TPageModel* lPage = (TPageModel*)wParam;
ATLASSERT(lPage);
if (m_Book)
{
ASSERT_VALID(this);
removePageEvt(lPage);
ASSERT_VALID(this);
}
if (lPage)
lPage->Release();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnSetWritable(WPARAM , LPARAM )
{
changeWritableEvt();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnAddPageBeforeSummary(WPARAM wParam, LPARAM lParam)
{
TPageModel* lPage = (TPageModel*)wParam;
ASSERT(lPage);
ASSERT_VALID(this);
addPageBeforeSummaryEvt(lPage);
ASSERT_VALID(this);
if (lPage)
lPage->Release();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnRemovePageBeforeSummary(WPARAM wParam, LPARAM lParam)
{
TPageModel* lPage = (TPageModel*)wParam;
ASSERT(lPage);
ASSERT_VALID(this);
removePageBeforeSummaryEvt(lPage);
ASSERT_VALID(this);
if (lPage)
lPage->Release();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnWantToBeDestroyed(WPARAM , LPARAM )
{
destroyBookModelEvt();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnSetProperty(WPARAM, LPARAM)
{
return E_NOTIMPL;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnRemoveProperty(WPARAM, LPARAM)
{
return E_NOTIMPL;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnSetLocation(WPARAM, LPARAM)
{
return E_NOTIMPL;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnSetIsAliased(WPARAM, LPARAM)
{
return E_NOTIMPL;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnSetBookStyle(WPARAM, LPARAM)
{
return E_NOTIMPL;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnChangePrimaryPage(WPARAM wParam, LPARAM )
{
TPageModel* lPage = (TPageModel*)wParam;
// ASSERT(lPage);
ASSERT_VALID(this);
setPrimaryPage(lPage);
ASSERT_VALID(this);
if (lPage)
lPage->Release();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnChangeSecondaryPage(WPARAM wParam, LPARAM )
{
TPageModel* lPage = (TPageModel*)wParam;
// ASSERT(lPage);
ASSERT_VALID(this);
setSecondaryPage(lPage);
ASSERT_VALID(this);
if (lPage)
lPage->Release();
return S_OK;
}
// --------------------------------------------------------------------
//
//
LRESULT TBookBrowser::OnChangeSelectedPage(WPARAM wParam, LPARAM )
{
TPageModel* lPage = (TPageModel*)wParam;
ASSERT_VALID(this);
changeSelectedPage(lPage);
ASSERT_VALID(this);
if (lPage)
lPage->Release();
return S_OK;
}
LONG TBookBrowser::OnChangeBook(UINT wParam, LONG )
{
TBookModel *lBook = (TBookModel *)wParam;
setBook(lBook);
if (lBook)
lBook->Release();
return S_OK;
}
// ************************************************************************************************
// *** Listen to associated book changes
TBrowserBookListener::TBrowserBookListener(TBookBrowser* pBookBrowser)
{
m_pBookBrowser = pBookBrowser;
}
TBrowserBookListener::~TBrowserBookListener()
{
m_pBookBrowser = NULL;
}
void TBrowserBookListener::propertyChange(TPropertyChangeEvent *evt)
{
ASSERT(evt); // *** Event should not be null
CString lPropertyName(evt->getPropertyName());
if (lPropertyName == TBookModel::T_ADD_PAGE_PROPERTY)
{
TPageModel* lPage = (TPageModel*)evt->getNewValue();
ASSERT(lPage);
if (lPage)
lPage->AddRef();
m_pBookBrowser->PostMessage(WM_USER_ADD_PAGE, (WPARAM)lPage);
}
else if (lPropertyName == TBookModel::T_CHANGE_PRIMARY_PAGE)
{
TPageModel* lPage = (TPageModel*)evt->getNewValue();
// ASSERT(lPage);
if (lPage)
lPage->AddRef();
m_pBookBrowser->PostMessage(WM_USER_CHANGE_PRIMARY_PAGE, (WPARAM)lPage);
}
else if (lPropertyName == TBookModel::T_CHANGE_SECONDARY_PAGE)
{
TPageModel* lPage = (TPageModel*)evt->getNewValue();
// ASSERT(lPage);
if (lPage)
lPage->AddRef();
m_pBookBrowser->PostMessage(WM_USER_CHANGE_SECONDARY_PAGE, (WPARAM)lPage);
}
else if (lPropertyName == TBookModel::T_CHANGE_SELECTED_PAGE)
{
TPageModel* lPage = (TPageModel*)evt->getNewValue();
if (lPage)
lPage->AddRef();
m_pBookBrowser->PostMessage(WM_USER_CHANGE_SELECTED_PAGE, (WPARAM)lPage);
}
else if (lPropertyName == TBookModel::T_INSERT_PAGE_PROPERTY)
{
TPageModel* lPage = (TPageModel*)evt->getNewValue();
ASSERT(lPage);
if (lPage)
lPage->AddRef();
m_pBookBrowser->PostMessage(WM_USER_INSERT_PAGE, (WPARAM)lPage);
}
else if (lPropertyName == TBookModel::T_REMOVE_PAGE_PROPERTY)
{
TPageModel* lPage = (TPageModel*)evt->getOldValue();
ASSERT(lPage);
if (lPage)
lPage->AddRef();
m_pBookBrowser->PostMessage(WM_USER_REMOVE_PAGE, (WPARAM)lPage);
}
else if (lPropertyName == TBookModel::T_ADD_PAGE_BEFORE_SUMMARY_PROPERTY)
{
TPageModel* lPage = (TPageModel*)evt->getNewValue();
ASSERT(lPage);
if (lPage)
lPage->AddRef();
m_pBookBrowser->PostMessage(WM_USER_ADD_PAGE_BEFORE_SUMMARY, (WPARAM)lPage);
}
else if (lPropertyName == TBookModel::T_REMOVE_PAGE_BEFORE_SUMMARY_PROPERTY)
{
TPageModel* lPage = (TPageModel*)evt->getOldValue();
ASSERT(lPage);
if (lPage)
lPage->AddRef();
m_pBookBrowser->PostMessage(WM_USER_REMOVE_PAGE_BEFORE_SUMMARY, (WPARAM)lPage);
}
else
{
if (lPropertyName == TMediumModel::T_SET_NAME_PROPERTY)
m_pBookBrowser->PostMessage(WM_USER_SET_NAME);
else if (lPropertyName == TBookModel::T_SET_WRITABLE_PROPERTY)
m_pBookBrowser->PostMessage(WM_USER_SET_WRITABLE);
else if (lPropertyName == TObjectModel::T_WANT_TO_BE_DESTROYED)
m_pBookBrowser->PostMessage(WM_USER_WANT_TO_BE_DESTROYED);
else if (lPropertyName == TObjectModel::T_SET_PROPERTY)
m_pBookBrowser->PostMessage(WM_USER_SET_PROPERTY);
else if (lPropertyName == TObjectModel::T_REMOVE_PROPERTY)
m_pBookBrowser->PostMessage(WM_USER_REMOVE_PROPERTY);
else if (lPropertyName == TMediumModel::T_SET_LOCATION_PROPERTY)
m_pBookBrowser->PostMessage(WM_USER_SET_LOCATION);
else if (lPropertyName == TMediumModel::T_SET_IS_ALIASED_PROPERTY)
m_pBookBrowser->PostMessage(WM_USER_SET_IS_ALIASED);
else if (lPropertyName == TBookModel::T_SET_BOOK_STYLE_PROPERTY)
m_pBookBrowser->PostMessage(WM_USER_SET_BOOK_STYLE);
}
}
TBrowserShelfListener::TBrowserShelfListener(TBookBrowser* pBookBrowser)
{
m_pBookBrowser = pBookBrowser;
}
TBrowserShelfListener::~TBrowserShelfListener()
{
m_pBookBrowser = NULL;
}
void TBrowserShelfListener::propertyChange(TPropertyChangeEvent *evt)
{
ASSERT(evt);
CString lPropertyName(evt->getPropertyName());
/*
if (lPropertyName == TMediaContainerModel::T_REMOVE_MEDIUM_PROPERTY)
{
if (fBook == (TBookModel*)(evt->getOldValue()))
removeBook();
if (TContextModel::gContext->getCurrentModeNumber() == T_BOOK_MODE ||
TContextModel::gContext->getCurrentModeNumber() == T_PAGE_MODE)
TContextModel::gContext->setCurrentModeNumber(T_BOOK_STAND_MODE);
}
*/
}
/*------------ IEHelperObject.h ------------*/
// IEHelperObject.h : Declaration of the CIEHelperObject
#ifndef __IEHelperObject_H_
#define __IEHelperObject_H_
#include "ExDisp.h"
#include "ExDispID.h"
#include "dispex.h"
#include "mshtml.h"
//#include "IEVersion.h"
/*
#define DISPID_BEFORENAVIGATE 100 // this is sent before navigation to give a chance to abort
#define DISPID_NAVIGATECOMPLETE 101 // in async, this is sent when we have enough to show
#define DISPID_STATUSTEXTCHANGE 102
#define DISPID_QUIT 103
#define DISPID_DOWNLOADCOMPLETE 104
#define DISPID_COMMANDSTATECHANGE 105
#define DISPID_DOWNLOADBEGIN 106
#define DISPID_NEWWINDOW 107 // sent when a new window should be created
#define DISPID_PROGRESSCHANGE 108 // sent when download progress is updated
#define DISPID_WINDOWMOVE 109 // sent when main window has been moved
#define DISPID_WINDOWRESIZE 110 // sent when main window has been sized
#define DISPID_WINDOWACTIVATE 111 // sent when main window has been activated
#define DISPID_PROPERTYCHANGE 112 // sent when the PutProperty method is called
#define DISPID_TITLECHANGE 113 // sent when the document title changes
#define DISPID_TITLEICONCHANGE 114 // sent when the top level window icon may have changed.
#define DISPID_FRAMEBEFORENAVIGATE 200
#define DISPID_FRAMENAVIGATECOMPLETE 201
#define DISPID_FRAMENEWWINDOW 204
#define DISPID_BEFORENAVIGATE2 250 // hyperlink clicked on
#define DISPID_NEWWINDOW2 251
#define DISPID_NAVIGATECOMPLETE2 252 // UIActivate new document
#define DISPID_ONQUIT 253
#define DISPID_ONVISIBLE 254 // sent when the window goes visible/hidden
#define DISPID_ONTOOLBAR 255 // sent when the toolbar should be shown/hidden
#define DISPID_ONMENUBAR 256 // sent when the menubar should be shown/hidden
#define DISPID_ONSTATUSBAR 257 // sent when the statusbar should be shown/hidden
#define DISPID_ONFULLSCREEN 258 // sent when kiosk mode should be on/off
#define DISPID_DOCUMENTCOMPLETE 259 // new document goes ReadyState_Complete
#define DISPID_ONTHEATERMODE 260 // sent when theater mode should be on/off
#define DISPID_ONADDRESSBAR 261 // sent when the address bar should be shown/hidden
*/
/////////////////////////////////////////////////////////////////////////////
// CIEHelperObject
class ATL_NO_VTABLE CIEHelperObject :
public CComObjectRootEx,
public IObjectWithSiteImpl,
public IDispatchImpl
{
public:
DECLARE_NOT_AGGREGATABLE(CIEHelperObject)
BEGIN_COM_MAP(CIEHelperObject)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IObjectWithSite)
END_COM_MAP()
// IIEHelperObject
public:
// CIEHelperObject Methods
CIEHelperObject() : m_dwCookie(0) {}
~CIEHelperObject() {};
STDMETHOD(Invoke)(DISPID id, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS * pdp, VARIANT * pvarResult,
EXCEPINFO * pexcepinfo, UINT * puArgErr)
{
USES_CONVERSION;
HRESULT lResult = S_OK;
if (!pdp)
return E_INVALIDARG;
switch (id)
{
//
// The parameters for this DISPID are as follows:
// [0]: Cancel flag - VT_BYREF|VT_BOOL
// [1]: HTTP headers - VT_BYREF|VT_VARIANT
// [2]: Address of HTTP POST data - VT_BYREF|VT_VARIANT
// [3]: Target frame name - VT_BYREF|VT_VARIANT
// [4]: Option flags - VT_BYREF|VT_VARIANT
// [5]: URL to navigate to - VT_BYREF|VT_VARIANT
// [6]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event.
//
case DISPID_BEFORENAVIGATE2:
ATLASSERT(pdp->cArgs == 7);
OnBeforeNavigate2(pdp->rgvarg[6].pdispVal,
pdp->rgvarg[5].pvarVal,
pdp->rgvarg[4].pvarVal,
pdp->rgvarg[3].pvarVal,
pdp->rgvarg[2].pvarVal,
pdp->rgvarg[1].pvarVal,
pdp->rgvarg[0].pboolVal);
break;
//
// The parameters for this DISPID:
// [0]: URL navigated to - VT_BYREF|VT_VARIANT
// [1]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event.
//
case DISPID_NAVIGATECOMPLETE2:
ATLASSERT(pdp->cArgs == 2);
OnNavigateComplete2(pdp->rgvarg[1].pdispVal,
pdp->rgvarg[0].pvarVal);
break;
//
// The parameters for this DISPID:
// [0]: New status bar text - VT_BSTR
//
case DISPID_STATUSTEXTCHANGE:
ATLASSERT(pdp->cArgs == 1);
OnStatusTextChange(W2CT(pdp->rgvarg[0].bstrVal));
break;
//
// The parameters for this DISPID:
// [0]: Maximum progress - VT_I4
// [1]: Amount of total progress - VT_I4
//
case DISPID_PROGRESSCHANGE:
ATLASSERT(pdp->cArgs == 2);
OnProgressChange(pdp->rgvarg[1].lVal,
pdp->rgvarg[0].lVal);
break;
//
// The parameters for this DISPID:
// [0]: URL navigated to - VT_BYREF|VT_VARIANT
// [1]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event.
//
case DISPID_DOCUMENTCOMPLETE:
ATLASSERT(pdp->cArgs == 2);
OnDocumentComplete(pdp->rgvarg[1].pdispVal,
pdp->rgvarg[0].pvarVal);
if (pdp->rgvarg[1].pdispVal == m_spWebBrowser2)
OnLoad();
break;
case DISPID_DOWNLOADBEGIN:
ATLASSERT(pdp->cArgs == 0);
OnDownloadBegin();
break;
case DISPID_DOWNLOADCOMPLETE:
ATLASSERT(pdp->cArgs == 0);
OnDownloadComplete();
break;
//
// The parameters for this DISPID:
// [0]: Enabled state - VT_BOOL
// [1]: Command identifier - VT_I4
//
case DISPID_COMMANDSTATECHANGE:
ATLASSERT(pdp->cArgs == 2);
OnCommandStateChange(pdp->rgvarg[1].lVal,
pdp->rgvarg[0].boolVal);
break;
//
// The parameters for this DISPID:
// [0]: Cancel flag - VT_BYREF|VT_BOOL
// [1]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event.
//
case DISPID_NEWWINDOW2:
ATLASSERT(pdp->cArgs == 2);
OnNewWindow2(pdp->rgvarg[1].ppdispVal,
pdp->rgvarg[0].pboolVal);
break;
//
// The parameters for this DISPID:
// [0]: Document title - VT_BSTR
//
case DISPID_TITLECHANGE:
ATLASSERT(pdp->cArgs == 1);
OnTitleChange(W2CT(pdp->rgvarg[0].bstrVal));
break;
//
// The parameters for this DISPID:
// [0]: Name of property that changed - VT_BSTR
//
case DISPID_PROPERTYCHANGE:
ATLASSERT(pdp->cArgs == 1);
OnPropertyChange(W2CT(pdp->rgvarg[0].bstrVal));
break;
//
// The parameters for this DISPID:
// [0]: Address of cancel flag - VT_BYREF|VT_BOOL
//
case DISPID_QUIT:
case DISPID_ONQUIT:
ATLASSERT(pdp->cArgs == 0);
OnQuit();
// SetSite(NULL);
break;
default:
ATLTRACE("--> CIEHelperObject::Invoke() --> Unknown Event %d\n", id);
break;
}
long lSubCount;
long lIndex = 0;
lSubCount = m_SubHelper.GetSize();
if (lSubCount)
{
CIEHelperObject* lHelper;
lHelper = m_SubHelper[lIndex];
lResult = lHelper->Invoke(id, riid, lcid, wFlags, pdp, pvarResult, pexcepinfo, puArgErr);
lIndex++;
}
return lResult;
}
// IOleObjectWithSite Methods
STDMETHOD(SetSite)(IUnknown *pUnkSite)
{
HRESULT lResult = S_OK;
if (pUnkSite == NULL)
{
if (m_spWebBrowser2 && FindHelper(m_spUnkSite))
{
ATLASSERT(FindHelper(m_spUnkSite) == this);
ATLASSERT(m_dwCookie);
RemoveHelper(m_spUnkSite);
lResult = ManageConnection(Unadvise);
}
}
else
{
CIEHelperObject* lHelper;
lHelper = FindHelper(pUnkSite);
// Do not register many time
if (lHelper == NULL)
{
// Query pUnkSite for the IWebBrowser2 interface.
m_spWebBrowser2 = pUnkSite;
AddHelper(pUnkSite, this);
if (m_spWebBrowser2 == NULL)
return E_INVALIDARG;
// Connect to the browser in order to handle events.
lResult = ManageConnection(Advise);
}
/*
else if (lHelper != this)
{
lHelper->AddSubHelper(this);
}
*/
IObjectWithSiteImpl::SetSite(pUnkSite);
}
ATLASSERT(SUCCEEDED(lResult));
return lResult;
}
// DWebBrowserEvents2 methods
virtual void OnProgressChange(long Progress, long ProgressMax)
{
// ATLTRACE("OnProgressChange\n");
}
virtual void OnDownloadBegin()
{
// ATLTRACE("OnDownloadBegin\n");
}
virtual void OnDownloadComplete()
{
// ATLTRACE("OnDownloadComplete\n");
}
virtual void OnBeforeNavigate2(LPDISPATCH pDisp,
VARIANT* URL,
VARIANT* Flags,
VARIANT* TargetFrameName,
VARIANT* PostData,
VARIANT* Headers,
VARIANT_BOOL* Cancel)
{
// ATLTRACE("OnBeforeNavigate2\n");
}
virtual void OnNavigateComplete2(LPDISPATCH pDisp, VARIANT* URL)
{
// ATLTRACE("OnNavigateComplete2\n");
}
virtual void OnDocumentComplete(LPDISPATCH pDisp, VARIANT* URL)
{
// ATLTRACE("OnDocumentComplete\n");
}
virtual void OnStatusTextChange(LPCTSTR Text)
{
// ATLTRACE("OnStatusTextChange\n");
}
virtual void OnCommandStateChange(long Command, BOOL Enable)
{
// ATLTRACE("OnCommandStateChange\n");
}
virtual void OnTitleChange(LPCTSTR Text)
{
// ATLTRACE("OnTitleChange\n");
}
virtual void OnPropertyChange(LPCTSTR szProperty)
{
// ATLTRACE("OnPropertyChange\n");
}
virtual void OnNewWindow2(LPDISPATCH* ppDisp, VARIANT_BOOL* Cancel)
{
// ATLTRACE("OnNewWindow2\n");
// return E_NOTIMPL;
}
virtual void OnQuit()
{
// ATLTRACE("OnQuit\n");
}
virtual void OnLoad()
{
// ATLTRACE("OnLoad\n");
}
HRESULT AddProperty(LPOLESTR nameDisp, LPDISPATCH pDisp)
{
HRESULT hResult = S_OK;
if (!m_spWebBrowser2)
return E_INVALIDARG;
CComPtr spDispatch;
hResult = m_spWebBrowser2->get_Document(&spDispatch);
CComQIPtr spDocument(spDispatch);
ATLASSERT(SUCCEEDED(hResult) && spDocument);
if (SUCCEEDED(hResult) && spDocument)
{
CComPtr pWindow;
hResult = spDocument->get_parentWindow(&pWindow);
ATLASSERT(SUCCEEDED(hResult) && pWindow);
if (FAILED(hResult) || !pWindow)
return E_FAIL;
DISPID lDispID;
{
CComVariant lVariant;
CComBSTR bstrCode(nameDisp);
bstrCode.Append("=0;");
hResult = pWindow->execScript(bstrCode, L"JScript", &lVariant);
ATLASSERT(SUCCEEDED(hResult));
hResult = pWindow->GetIDsOfNames(IID_NULL, &nameDisp, 1, LOCALE_SYSTEM_DEFAULT, &lDispID);
ATLASSERT(SUCCEEDED(hResult));
}
if (SUCCEEDED(hResult) && (lDispID != DISPID_UNKNOWN))
{
CComVariant lVariant(pDisp);
hResult = CComDispatchDriver::PutProperty(pWindow, lDispID, &lVariant);
ATLASSERT(SUCCEEDED(hResult));
}
}
return hResult;
}
protected:
DWORD m_dwCookie; // Connection Token - used for Advise and Unadvise
CComQIPtr m_spWebBrowser2;
CSimpleArray m_SubHelper;
static CSimpleMap* g_Map;
enum ConnectType { Advise, Unadvise }; // What to do when managing the connection
HRESULT ManageConnection(enum ConnectType eConnectType)
{
ATLASSERT(m_spWebBrowser2);
if (m_spWebBrowser2 == NULL)
return E_INVALIDARG;
HRESULT lResult;
// If eConnectType is Advise then we are advising IE that we want to handle events.
// If eConnectType is Unadvise, we are telling IE that we no longer want to handle events.
if (eConnectType == Advise)
lResult = AtlAdvise(m_spWebBrowser2, (IDispatch*)this, DIID_DWebBrowserEvents2, &m_dwCookie);
else
{
lResult = AtlUnadvise(m_spWebBrowser2, DIID_DWebBrowserEvents2, m_dwCookie);
m_dwCookie = 0;
}
return lResult;
}
void AddSubHelper(CIEHelperObject* pHelper)
{
m_SubHelper.Add(pHelper);
}
static BOOL AddHelper(IUnknown* pUnk, CIEHelperObject* pHelper)
{
if (pUnk && pHelper)
{
if (g_Map == NULL)
g_Map = new CSimpleMap();
ATLTRACE(" + AddHelper(0x%x, 0x%x)\n", pUnk, pHelper);
return g_Map->Add(pUnk, pHelper);
}
return FALSE;
}
static void RemoveHelper(IUnknown* pUnk)
{
if (g_Map)
{
ATLTRACE(" - RemoveHelper(0x%x)\n", pUnk);
g_Map->Remove(pUnk);
if (g_Map->GetSize() == 0)
{
delete g_Map;
g_Map = NULL;
}
}
}
public:
static CIEHelperObject* FindHelper(IUnknown* pUnk)
{
if (g_Map)
return g_Map->Lookup(pUnk);
return NULL;
}
};
__declspec(selectany) CSimpleMap* CIEHelperObject::g_Map = NULL;
#endif //__IEHelperObject_H_
/*------------ KbChapterToc.cpp ------------*/
// KbChapterToc.cpp : implementation file
//
#include "stdafx.h"
#include
#include "KbChapterToc.h"
#include "KbModelItem.h"
#include "Controler.h"
#include "ResRgbInfo.h"
#include "ResTocTextColorInfo.h"
#include "InterfaceUtils.h"
#include "WmUserMsgListener.h"
#include "DragAndDropPageData.h"
#include "ProgressDlg.h"
#include "KbStickerTocWnd.h"
#include "PageletToolbar.h"
#include "TMain.h"
#include "TModelIterator.h"
#include "TModelPtr.h"
#include "TChapterModel.h"
#include "TSummaryModel.h"
#include "TPageModel.h"
#include "TPropertyObjectModel.h"
#include "TModelPtr.h"
#include "TBookModel.h"
#include "TMediaLibraryModel.h"
#include "TMetaManager.h"
#include "TModelNames.h"
#include "TSoundManager.h"
#include "TContextModel.h"
#include "TModelHelpers.h"
#include "TTocBookListener.h"
#include "TOleDataObject.h"
#include "TGlobalsDB.h"
#include "TBrowseDir.h"
#include "TBooxFrame.h"
#include "TKeeBooKeyController.h"
#include "TPagePropertiesConstants.h"
#include "TBoolean.h"
#include "TPath.h"
#include "TPageIdentifiersConstants.h"
#include "TUserMessage.h"
#include "SharedLookAndFeelRes.h"
#include "SharedSoundAndFeelRes.h"
#include "SharedResource.h"
#include "TGlobalResource.h"
// Interfaces
#include "Pagelet.h"
// D&D
#include "TOleDataObject.h"
#include "DragAndDropAnnotationData.h"
// Utils
#include "TSoundManager.h"
#include "TUrl.h"
#include "ProgressDlg.h"
#include "TGlobalResource.h"
#include "TBrowseDir.h"
#include "TNetHelpers.h"
#include "TSevenixUrl.h"
#include "TPath.h"
#include "TErr.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define IDC_POSTIT 2
/////////////////////////////////////////////////////////////////////////////
// CKbChapterToc
CKbChapterToc::CKbChapterToc( TChapterModel *pChapterModel)
{
m_pChapterModel = pChapterModel;
m_pChapterModel->getBook( &m_pBookModel);
m_pTocChapterListener = NULL;
m_pTocBookListener = NULL;
m_pPostItWnd = NULL;
m_dropEffectPage = DROPEFFECT_NONE;
}
CKbChapterToc::~CKbChapterToc()
{
}
BEGIN_MESSAGE_MAP(CKbChapterToc, CKbTreeTocWnd)
//{{AFX_MSG_MAP(CKbChapterToc)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_INITMENUPOPUP()
//}}AFX_MSG_MAP
ON_COMMAND( IDA_SUPPR, OnEditDel)
ON_COMMAND( IDA_TOC_DELETE, OnEditDel)
ON_COMMAND( IDM_TOC_RENAME, OnTocRename)
ON_COMMAND( IDM_TOC_NEWCHAPTER, OnTocNewChapter)
ON_COMMAND( IDM_TOC_NEWOSFILES, OnTocNewOsFiles)
ON_COMMAND( IDM_TOC_NEWURL, OnTocNewUrl)
ON_COMMAND( IDM_EDIT_COPY, OnEditCopy)
ON_COMMAND( IDM_EDIT_CUT, OnEditCut)
ON_COMMAND( IDM_EDIT_PASTE, OnEditPaste)
ON_COMMAND( IDM_EDIT_DEL, OnEditDel)
ON_MESSAGE( WM_USER_CHAPTER_REMOVE_PAGE, OnChapterRemovePage)
ON_MESSAGE( WM_USER_CHAPTER_ADD_PAGE, OnChapterAddPage)
ON_MESSAGE( WM_USER_NEW_CHAPTER, OnNewChapter)
ON_NOTIFY( WM_DESTROY, IDC_POSTIT, OnNotifyDestroy)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CKbChapterToc creation destruction message handlers
int CKbChapterToc::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CKbTreeTocWnd::OnCreate(lpCreateStruct) == -1) return -1;
// --- initialize image list
{
AFX_MANAGE_STATE( AfxGetAppModuleState());
CResRgbInfo resBkColor( _T("TOC_BK_COLOR"));
resBkColor.LoadInfo();
SetBkNormalColor( resBkColor.m_color);
m_tocIl.SetBkColor( resBkColor.m_color);
CResRgbInfo resBkSelColor( _T("TOC_BK_SELECT_COLOR"));
if (resBkSelColor.LoadInfo())
{
SetBkSelectedColor( resBkSelColor.m_color);
}
CResTocTextColorInfo resTextColor( _T("TOC_TEXT_COLOR"));
if (resTextColor.LoadInfo())
{
SetItemTextNormalColor( resTextColor.m_pInfo->m_normalColor);
SetItemTextDropHilitedColor( resTextColor.m_pInfo->m_dropHilitedColor);
SetItemTextSelectedColor( resTextColor.m_pInfo->m_selectedColor);
SetItemTextCutColor( resTextColor.m_pInfo->m_cutColor);
}
m_treeCtrl.SetImageList( &(m_tocIl.m_ilSmall), TVSIL_NORMAL);
}
// --- initialize columns
m_headerCtrl.InsertColumn( 0, _T(""), // --- Title
HDF_STRING | HDF_LEFT, 100, KBF_EX_TABLEADER); // --- 100 %
m_headerCtrl.InsertColumn( 1, _T(""), // --- Page number
HDF_STRING | HDF_RIGHT, 32, KBF_EX_ABSOLUTEWIDTH | KBF_EX_INTEGER);
m_headerCtrl.InsertColumn( 2, _T(""), // --- annotation
HDF_BITMAP | HDF_CENTER, 32, KBF_EX_ABSOLUTEWIDTH | KBF_EX_INTEGER, &(m_tocIl.m_ilSmall));
// --- fill the list with 1 level children page
FillList( m_pChapterModel);
// --- add a listener for this chapter
m_pTocChapterListener = new TTocChapterListener( GetSafeHwnd(), m_pChapterModel);
ASSERT( m_pTocChapterListener);
m_pChapterModel->addPropertyChangeListener( m_pTocChapterListener);
m_pTocBookListener = new TTocBookListener( GetSafeHwnd());
ASSERT( m_pTocBookListener);
m_pBookModel->addPropertyChangeListener( m_pTocBookListener);
// --- check if i need to show empty sticker
if( m_treeCtrl.GetCount() == 0) CreateSticker();
return 0;
}
void CKbChapterToc::OnDestroy()
{
// --- remove the listener
ASSERT( m_pTocChapterListener);
// Just in case
// Don't want to crash in Release mode
if (m_pTocChapterListener)
{
m_pChapterModel->removePropertyChangeListener( m_pTocChapterListener);
m_pTocChapterListener->setInvalid();
//delete m_pTocChapterListener; // --- listener can't be delete
m_pTocChapterListener = NULL;
}
ASSERT( m_pTocBookListener);
// Just in case
// Don't want to crash in Release mode
if (m_pTocBookListener)
{
m_pBookModel->removePropertyChangeListener( m_pTocBookListener);
m_pTocBookListener->setInvalid();
//delete m_pTocBookListener; // --- listener can't be delete
m_pTocBookListener = NULL;
}
CKbTreeTocWnd::OnDestroy();
}
/////////////////////////////////////////////////////////////////////////////
// CKbChapterToc Fill List
void CKbChapterToc::FillList( TChapterModel* pChapterParent, HTREEITEM hTiParent)
{
ASSERT( pChapterParent);
// --- first be sure that the list is empty.
// --- use a safe loop, get always the first item
for( HTREEITEM hTi = m_treeCtrl.GetChildItem( hTiParent); hTi;
hTi = m_treeCtrl.GetChildItem( hTiParent))
{
m_treeCtrl.DeleteBranch( hTi);
}
// --- iteration on pages in this chapter
TGlobalsDB::getLibraryDBManager()->beginTransaction( t_transaction_types::TRANSACTION_READONLY);
TModelIterator* iter = NULL;
pChapterParent->getPages( &iter);
while( iter && iter->hasMoreElements())
{
// --- get the page model
TModelPtr page;
iter->nextElement( (TObjectModel**) &page);
// --- insert item in the list
HTREEITEM hTiInserted = InsertItem( page, hTiParent);
if (hTiInserted == NULL)
continue;
if (page->isInstanceOf( T_CHAPTER_MODEL_NAME))
{
// --- read the expand state
TModelPtr pPropModel;
pPropModel = page->getDefaultProperty();
ASSERT( pPropModel);
boolean bSet;
if (pPropModel->getBooleanField( T_PAGE_DEFAULT_PROPERTY_TOC_EXPANDED, &bSet))
{
if (bSet)
m_treeCtrl.Expand( hTiInserted, TVE_EXPAND);
}
}
}
delete iter;
TGlobalsDB::getLibraryDBManager()->commitTransaction();
}
/////////////////////////////////////////////////////////////////////////////
// CKbChapterToc tree list notification
BOOL CKbChapterToc::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
NMTREEVIEW* pNMTreeView = (NMTREEVIEW*) lParam;
int nCode = pNMTreeView->hdr.code;
int nId = pNMTreeView->hdr.idFrom;
// --- handle the tree item expansion
if( nCode == TVN_ITEMEXPANDING && nId == IDC_TREE)
{
TRACE( _T("*** CKbChapterToc::OnNotify TVN_ITEMEXPANDING\n"));
HTREEITEM hTiNew = pNMTreeView->itemNew.hItem;
CKbModelItem* pItem = (CKbModelItem*) pNMTreeView->itemNew.lParam;
ASSERT( pItem);
if( !m_treeCtrl.IsItemExpandedOnce( hTiNew))
{
// --- it's the first time expansion
TChapterModel* pChapterModel = (TChapterModel*) pItem->GetPageModel();
FillList( pChapterModel, hTiNew);
}
// --- update expand state in the db
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE);
if( pItem->IsItemContainer())
{
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiNew);
ASSERT( pItem);
TPageModel* pPageModel = pItem->GetPageModel();
TModelPtr pPropModel;
pPageModel->getDefaultProperty( &pPropModel);
ASSERT( pPropModel);
boolean bSet = !m_treeCtrl.IsItemExpanded( hTiNew);
pPropModel->putBooleanField( T_PAGE_DEFAULT_PROPERTY_TOC_EXPANDED, bSet);
}
TGlobalsDB::getLibraryDBManager()->commitTransaction();
*pResult = FALSE; // --- continue
}
// --- handle this end of the inplace edition
else if( nCode == TVN_ENDLABELEDIT && nId == IDC_TREE)
{
TRACE( _T("*** CKbChapterToc::OnNotify TVN_ENDLABELEDIT\n"));
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*) lParam;
// --- get the result of the edition
LPCTSTR szText = pTVDispInfo->item.pszText;
if( szText)
{
// --- and update the title in the database
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( pTVDispInfo->item.hItem);
TPageModel* pPageModel = pItem->GetPageModel();
pPageModel->setTitle( szText);
AddBehaviour( pPageModel, F_PAGE_DEFINED_TITLE);
}
*pResult = FALSE; // --- don't update the tree item
}
return CKbTreeTocWnd::OnNotify(wParam, lParam, pResult);
}
/////////////////////////////////////////////////////////////////////////////
// CKbChapterToc message handlers
BOOL CKbChapterToc::PreTranslateMessage(MSG* pMsg)
{
return CKbTreeTocWnd::PreTranslateMessage(pMsg);
}
void CKbChapterToc::OnNotifyDestroy( NMHDR *pNotifyStruct, LRESULT *result)
{
m_pPostItWnd = NULL;
}
/////////////////////////////////////////////////////////////////////////////
// CKbTreeWndDrag and drop handlers
DROPEFFECT CKbChapterToc::OnDragEnter( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
m_dropEffect = CKbTreeTocWnd::OnDragEnter( pDataObject, dwKeyState, point);
/*
CPoint pt( point);
ClientToScreen( &pt);
CImageList::DragEnter( this, pt);
*/
return CheckDragOver(pDataObject, dwKeyState, point);
}
void CKbChapterToc::OnDragLeave()
{
/*
CImageList::DragLeave( this);
*/
CKbTreeTocWnd::OnDragLeave();
}
DROPEFFECT CKbChapterToc::OnDragOver( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
/*
CPoint pt( point);
ClientToScreen( &pt);
CImageList::DragMove( pt);
*/
CKbTreeTocWnd::OnDragOver( pDataObject, dwKeyState, point);
return CheckDragOver(pDataObject, dwKeyState, point);
}
DROPEFFECT CKbChapterToc::CheckDragOver( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
if (m_dropEffect && m_keyState == dwKeyState)
return m_dropEffect;
m_keyState = dwKeyState;
// --- if the book is protected, no modification is allowed
if ( IsModifyProtected())
return DROPEFFECT_NONE;
TOleDataObject lDataObject;
lDataObject.Attach(pDataObject->m_lpDataObject, FALSE);
#ifdef DEBUG_DRAG_FORMAT
DumpDragFormat(lDataObject);
#endif
if (lDataObject.HaveData(E_DATA_TYPE_KEEBOO_NEW_CHAPTER))
{
m_dropEffect = DROPEFFECT_COPY;
}
else if (lDataObject.HaveData(E_DATA_TYPE_BROWSER_URL))
{
// *** Drop files from ie or Netscape in the WebBrowser
CString lUrl = lDataObject.GetUrlData();
// Do not allow script or mailto url
if ((lUrl.Find("script:") != -1)
|| (lUrl.Find("mailto:") != -1))
m_dropEffect = DROPEFFECT_NONE;
else
m_dropEffect = DROPEFFECT_COPY;
}
else if (lDataObject.HaveData(E_DATA_TYPE_KEEBOO_PAGE))
{
if( (dwKeyState & MK_CONTROL) == MK_CONTROL)
m_dropEffect = DROPEFFECT_COPY;
else
m_dropEffect = DROPEFFECT_MOVE;
// --- don't allow to drop inside the drag selection and inside the selection
for( HTREEITEM hTiInc = m_treeCtrl.m_hTiDragOver;
hTiInc;
hTiInc = m_treeCtrl.GetParentItem( hTiInc))
{
int nMax = m_treeCtrl.m_arrayHtiDragged.GetSize();
for( int n=0; nIsDataAvailable(CF_HDROP))
{
m_dropEffect = DROPEFFECT_LINK;
}
else
{
m_dropEffect = DROPEFFECT_NONE;
}
return m_dropEffect;
}
DROPEFFECT CKbChapterToc::OnDragScroll( DWORD dwKeyState, CPoint point )
{
return CKbTreeTocWnd::OnDragScroll( dwKeyState, point );
}
BOOL CKbChapterToc::OnDrop( COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
{
(void) CKbTreeTocWnd::OnDrop( pDataObject, dropEffect, point);
BOOL bResult = TRUE;
// --- Disable any drop at the top of an unmovable page !!
// --- This is used for instance in the Surf Book not to be able to insert anything BEFORE the Web Search page...
// !!! THIS IS WRONG BUT IT WORKS... CHANGE IT QUICKLY TO THE RIGHT TEST !!!
HTREEITEM hTiDrop = m_treeCtrl.m_hTiOnDrop;
if( hTiDrop == TVI_FIRST)
{
hTiDrop = m_treeCtrl.m_hTiOnDropParent;
if (hTiDrop == TVI_ROOT)
{
hTiDrop = m_treeCtrl.GetRootItem();
}
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDrop);
TModelPtr pPageModel;
pPageModel = pItem->GetPageModel();
if( !IsMovable( pPageModel))
{
TSoundManager::PlayFromResource( IDSOUND_ALERT);
return FALSE;
}
}
TOleDataObject lDataObject;
lDataObject.Attach(pDataObject->m_lpDataObject, FALSE);
if (lDataObject.HaveData(E_DATA_TYPE_KEEBOO_NEW_CHAPTER))
{
bResult = OnTocDropChapter( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent);
}
else if (lDataObject.HaveData(E_DATA_TYPE_BROWSER_URL))
{
bResult = OnTocDropUrl( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject);
}
else if (lDataObject.HaveData(E_DATA_TYPE_KEEBOO_PAGE))
{
// --- store dropEffect to avoid use moving page
m_dropEffectPage = dropEffect;
bResult = OnTocDropPages(
m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject, dropEffect
);
}
#ifdef CAN_DRAG_MAIL
else if (lDataObject.HaveData(E_DATA_TYPE_EMAIL))
{
bResult = OnTocDropMail( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject);
}
#endif // CAN_DRAG_MAIL
#ifdef CAN_DRAG_TEXT
else if (lDataObject.HaveData(E_DATA_TYPE_TEXT))
{
bResult = OnTocDropText( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject);
}
#endif // CAN_DRAG_TEXT
else if (pDataObject->IsDataAvailable(CF_HDROP))
{
bResult = OnTocDropOsFiles( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject);
}
else
{
bResult = FALSE;
TSoundManager::PlayFromResource( IDSOUND_ALERT);
}
return bResult;
}
/////////////////////////////////////////////////////////////////////////////
// CKbTreeWnd message drop handlers
BOOL CKbChapterToc::OnTocDropChapter( HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent)
{
TRACE( _T("CKbChapterToc::OnTocDropChapter\n"));
// --- get the chapter controler
CComPtr pChapterControler;
HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler);
if( FAILED( hResult))
return FALSE;
long lPos;
TModelPtr pPageSelected;
TModelPtr pChapterParent;
if( hTiDropped == TVI_FIRST)
{
// --- put in the begin of the chapter
if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT)
{
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent);
ASSERT( pItem);
TChapterModel *pChapterModel = (TChapterModel*) pItem->GetPageModel();
ASSERT( pChapterModel);
pChapterControler->put_chapter( (long) pChapterModel);
}
else
{
pChapterControler->put_chapter( (long) GetChapterModel());
}
lPos = 0;
}
else if( hTiDropped == TVI_LAST)
{
// --- put in the end of the chapter
pChapterControler->put_chapter( (long) GetChapterModel());
lPos = T_POS_LAST;
}
else if( hTiDropped)
{
// --- get item data
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped);
ASSERT( pItem);
pPageSelected = pItem->GetPageModel();
HRESULT hResult = pPageSelected->getPagePosition( &lPos);
ASSERT( SUCCEEDED( hResult));
pPageSelected->getChapter( &pChapterParent);
pChapterControler->put_chapter( (long) pChapterParent.p);
}
else
{
// --- the tree ctrl is empty, or no item is selected
pChapterControler->put_chapter( (long) GetChapterModel());
lPos = 0;
}
// --- create a new chapter
AFX_MANAGE_STATE( AfxGetAppModuleState());
TModelPtr pNewChapter;
TMetaManager::createModelInstance( T_CHAPTER_MODEL_NAME, (void**) &pNewChapter);
CString stgChapterTitle;
KBLoadString( IDS_TOC_NEW_CHAPTER, stgChapterTitle);
pNewChapter->setTitle( stgChapterTitle);
// --- add it in the database
CComVariant varChapter( (long) pNewChapter.p);
long lNotUsed;
if( SUCCEEDED( pChapterControler->Add( varChapter, lPos, (long *) &lNotUsed)))
{
// Play sound when inserting a chapter in the toc
TSoundManager::PlayFromResource( IDSOUND_DROP_PAGE);
TSoundManager::PlayFromResource( IDSOUND_NEW_ITEM);
// --- keep chapter to edit it later, release when page arrive in the listener
m_pPageToEdit = pNewChapter;
m_pPageToEdit.p->AddRef();
return TRUE;
}
return FALSE;
}
BOOL CKbChapterToc::OnTocDropOsFiles( HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject)
{
// --- get the page model from the htreeItem
int nPosition = T_POS_LAST;
TModelPtr pPageModel;
if ( hTiDropped == TVI_FIRST)
{
if ( hTiDroppedParent && hTiDroppedParent != TVI_ROOT)
{
// --- get item data
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent);
ASSERT( pItem);
pPageModel = pItem->GetPageModel();
}
else
{
pPageModel = (TPageModel *) GetChapterModel();
}
nPosition = 0;
}
else if ( hTiDropped == TVI_LAST)
{
// --- it's the last item, so insert it to the end of this chapter
pPageModel = (TPageModel *) GetChapterModel();
}
else if ( hTiDropped != NULL)
{
CKbModelItem* pItem;
if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT)
{
// --- get item data
pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent);
ASSERT( pItem);
pPageModel = pItem->GetPageModel();
}
else
{
pPageModel = (TPageModel *) GetChapterModel();
}
// --- get item data
pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped);
ASSERT( pItem);
TPageModel* pPageModelTmp = pItem->GetPageModel();
ASSERT( pPageModelTmp);
HRESULT hResult = pPageModelTmp->getPagePosition( (long*) &nPosition);
ASSERT( SUCCEEDED( hResult));
}
else
{
// --- the tree ctrl is empty, or no item is selected
pPageModel = (TPageModel *) GetChapterModel();
}
// --- get the number of file dropped
STGMEDIUM* pStgMedium = new STGMEDIUM;
memset( pStgMedium, 0, sizeof( STGMEDIUM));
pDataObject->GetData( CF_HDROP, pStgMedium);
HDROP pFileData = (HDROP) ::GlobalLock( pStgMedium->hGlobal);
ASSERT( pFileData);
int nFileNameCount = DragQueryFile( pFileData, 0xFFFFFFFF, NULL, 0);
// --- prepare the progress dialog
// TBooxFrame::GetMainWnd()->EnableWindow( FALSE);
CProgressDlg* pDlg;
CString stgFormatStep;
long lPosition;
{
AFX_MANAGE_STATE( AfxGetAppModuleState());
pDlg = new CProgressDlg;
VERIFY( pDlg->Create(
_T("CProgressDlg"), WS_CHILD/* | WS_VISIBLE*/, CRect( 0, 0, 10, 10), AfxGetMainWnd(), 1
));
CString stgTmp;
VERIFY( KBLoadString( IDS_PROGDLG_COPY_FILE_TITLE, stgTmp));
pDlg->SetTitle( stgTmp);
VERIFY( KBLoadString( IDS_CANCEL, stgTmp));
pDlg->SetCancel( stgTmp);
KBLoadString( IDS_PROGDLG_STEP, stgFormatStep);
pDlg->ChangeAnimation( 1 /*FILECOPY*/);
pDlg->SetUpper( (short) nFileNameCount);
lPosition = 1;
}
// --- insert all the pages
CWaitCursor waitCursor;
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE);
for(int n = 0; n < nFileNameCount; n++)
{
// --- get the filename
CString stgFileName;
LPTSTR szBuffer = stgFileName.GetBuffer( _MAX_PATH);
DragQueryFile( pFileData, n, szBuffer, _MAX_PATH);
stgFileName.ReleaseBuffer();
// --- update the progress dialog
{
// AFX_MANAGE_STATE( AfxGetAppModuleState());
if( pDlg->IsProcessCanceled())
break;
// --- get the kind of the file
UINT uStringId = IDS_PROGDLG_COPY_FILE_NAME;
CFileStatus fileStatus;
if( CFile::GetStatus( stgFileName, fileStatus))
{
if( fileStatus.m_attribute & CFile::directory)
{
uStringId = IDS_PROGDLG_COPY_DIR_NAME;
}
}
CString stgTmp;
KBLoadString( uStringId, stgTmp);
stgTmp.FormatMessage( stgTmp, (LPCTSTR) stgFileName);
pDlg->SetComment( (LPCTSTR) stgTmp);
stgTmp.FormatMessage( stgFormatStep, lPosition, nFileNameCount);
pDlg->SetStep( stgTmp);
pDlg->SetPosition( (short) lPosition++);
}
CString stgExt;
TPath::FindExtension( stgFileName, stgExt);
if( stgExt.CompareNoCase( _T(".7xB")))
{
// --- insert all file under this filename
TBrowseDir browseDir;
browseDir.SetCallback(NULL);
browseDir.Reset();
browseDir.Run( stgFileName, pPageModel, TRUE, nPosition);
}
}
TGlobalsDB::getLibraryDBManager()->commitTransaction();
::GlobalUnlock( pStgMedium->hGlobal);
delete pStgMedium;
pStgMedium = NULL;
// --- close the progress bar
{
AFX_MANAGE_STATE( AfxGetAppModuleState());
pDlg->DestroyWindow();
pDlg = NULL;
}
// TBooxFrame::GetMainWnd()->EnableWindow( TRUE);
return TRUE;
}
BOOL CKbChapterToc::OnTocDropUrl( HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject)
{
CString stgTitle, stgUrl;
TOleDataObject lDataObject;
lDataObject.Attach(pDataObject->m_lpDataObject, FALSE);
// --- get the url string
stgUrl = lDataObject.GetUrlData();
// --- get the link name if any
if (lDataObject.HaveData(E_DATA_TYPE_SHELL_LINK_NAME))
{
// --- Get url name
stgTitle = lDataObject.GetLinkName();
}
else
{
stgTitle = stgUrl;
}
// --- get the chapter controler
CComPtr pChapterControler;
HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler);
if( FAILED( hResult))
return FALSE;
// --- get the page model from the htreeItem
long lPos = 0;
TModelPtr pPageSelected;
TModelPtr pChapterParent;
if( hTiDropped == TVI_FIRST)
{
if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT)
{
// --- get item data
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent);
ASSERT( pItem);
TChapterModel* pChapterModel = (TChapterModel *) pItem->GetPageModel();
ASSERT( pChapterModel);
pChapterControler->put_chapter( (long) pChapterModel);
}
else
{
pChapterControler->put_chapter( (long) GetChapterModel());
}
lPos = 0;
}
else if( hTiDropped == TVI_LAST)
{
pChapterControler->put_chapter( (long) GetChapterModel());
lPos = T_POS_LAST;
}
else if( hTiDropped != NULL)
{
// --- get item data
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped);
ASSERT( pItem);
pPageSelected = pItem->GetPageModel();
HRESULT hResult = pPageSelected->getPagePosition( &lPos);
ASSERT( SUCCEEDED( hResult));
pPageSelected->getChapter( &pChapterParent);
pChapterControler->put_chapter( (long) pChapterParent.p);
}
else
{
// --- the tree ctrl is empty, or no item is selected
pChapterControler->put_chapter( (long) GetChapterModel());
}
// --- add it in the database
CComBSTR bstr( stgUrl);
CComVariant varPage( (BSTR) bstr);
TPageModel* pPageModelAdded;
CWaitCursor waitCursor;
BOOL bResult = FALSE;
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE);
if( SUCCEEDED( pChapterControler->Add( varPage, lPos, (long *) &pPageModelAdded)))
{
// Play sound when inserting a chapter in the toc
TSoundManager::PlayFromResource( IDSOUND_DROP_PAGE);
TSoundManager::PlayFromResource( IDSOUND_NEW_ITEM);
ASSERT( pPageModelAdded);
pPageModelAdded->setTitle( stgTitle);
bResult = TRUE;
}
TGlobalsDB::getLibraryDBManager()->commitTransaction();
return bResult;
}
BOOL CKbChapterToc::OnTocDropPages(HTREEITEM hTiDropped,
HTREEITEM hTiDroppedParent,
COleDataObject* pDataObject,
DROPEFFECT dropEffect)
{
TRACE( _T("CKbChapterToc::OnTocDropPages\n"));
// --- get the chapter controler
CComPtr pChapterControler;
HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler);
if( FAILED( hResult))
{
TSoundManager::PlayFromResource( IDSOUND_ALERT);
return FALSE;
}
long lPos = 0;
TModelPtr pPageSelected;
TModelPtr pChapterParent;
if( hTiDropped == TVI_FIRST)
{
if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT)
{
// --- get item data
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent);
ASSERT( pItem);
TChapterModel* pChapterModel = (TChapterModel *) pItem->GetPageModel();
ASSERT( pChapterModel);
pChapterControler->put_chapter( (long) pChapterModel);
}
else
{
// --- put in the begin of the chapter
pChapterControler->put_chapter( (long) GetChapterModel());
}
lPos = 0;
}
else if( hTiDropped == TVI_LAST)
{
// --- put in the end of the chapter
TModelPtr pChapter;
pChapter = GetChapterModel();
pChapterControler->put_chapter( (long) pChapter.p);
TModelPtr pPage;
int nPageCount = pChapter->getPageCount();
if( nPageCount == 0)
{
lPos = 0;
}
else
{
pChapter->getPage( nPageCount, &pPage);
if (pPage)
{
pPage->getPagePosition( &lPos);
}
else
{
// Error value
lPos = 0;
}
}
}
else if( hTiDropped != NULL)
{
// --- get item data
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped);
ASSERT( pItem);
pPageSelected = pItem->GetPageModel();
HRESULT hResult = pPageSelected->getPagePosition( &lPos);
ASSERT( SUCCEEDED( hResult));
pPageSelected->getChapter( &pChapterParent);
pChapterControler->put_chapter( (long) pChapterParent.p);
}
else
{
// --- the tree ctrl is empty, or no item is selected
pChapterControler->put_chapter( (long) GetChapterModel());
}
TOleDataObject lDataObject;
lDataObject.Attach(pDataObject->m_lpDataObject, FALSE);
// --- get drag and drop data
TDragAndDropPageData* pPageData;
pPageData = lDataObject.GetPageData();
ASSERT( pPageData);
// --- browse all page
CWaitCursor waitCursor;
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE);
TPtrArray* pArray = pPageData->getPagesList();
ASSERT( pArray);
TPtrIterator *pIter = pArray->elements();
while( pIter->hasMoreElements())
{
TPageModel *pPageModel = (TPageModel*) pIter->nextElement();
// --- add it in the database
CComVariant varChapter( (long) pPageModel);
long lNotUsed;
if( dropEffect == DROPEFFECT_COPY)
{
hResult = pChapterControler->Copy( varChapter, lPos, (long *) &lNotUsed);
}
else if( dropEffect == DROPEFFECT_MOVE)
{
hResult = pChapterControler->Move( varChapter, lPos);
}
else
{
ASSERT( false); // --- can't be another value
}
}
delete pIter;
TGlobalsDB::getLibraryDBManager()->commitTransaction();
// Play sound when inserting a chapter in the toc
if (SUCCEEDED( hResult))
{
TSoundManager::PlayFromResource( IDSOUND_DROP_PAGE);
TSoundManager::PlayFromResource( IDSOUND_NEW_ITEM);
}
return SUCCEEDED( hResult);
}
HRESULT CKbChapterToc::OnTocDropMail(HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject)
{
HRESULT lResult;
HGLOBAL lHGlobal;
TOleDataObject lDataObject;
lDataObject.Attach(pDataObject->m_lpDataObject, FALSE);
lHGlobal = lDataObject.GetGlobalData(TOleDataObject::GetClipFormat(E_DATA_TYPE_EMAIL));
lResult = CreateFakeFile( hTiDropped, hTiDroppedParent, pDataObject, (LPBYTE)::GlobalLock(lHGlobal), ::GlobalSize(lHGlobal));
::GlobalUnlock(lHGlobal);
return lResult;
}
HRESULT CKbChapterToc::OnTocDropText(HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject)
{
HRESULT lResult = S_OK;
HGLOBAL lHGlobal = NULL;
LPCTSTR lMime = NULL;
LPBYTE lData = NULL;
DWORD dwSize = 0;
TOleDataObject lDataObject;
lDataObject.Attach(pDataObject->m_lpDataObject, FALSE);
TString lTitle = _T("");
CHtmlClipFormat lHtmlFormat;
if (lDataObject.HaveData(E_DATA_TYPE_TEXT_HTML))
{
// Do HTML handling
lMime = _T("text/html");
lHtmlFormat = lDataObject.GetHTMLFormat();
lData = lHtmlFormat.AllocHtml(dwSize);
lTitle = lHtmlFormat.GetSourceUrl();
}
else if (lDataObject.HaveData(E_DATA_TYPE_TEXT_RTF))
{
lMime = _T("text/rtf");
lHGlobal = lDataObject.GetGlobalData(TOleDataObject::GetClipFormat(E_DATA_TYPE_TEXT_RTF));
}
else if (lDataObject.HaveData(E_DATA_TYPE_TEXT))
{
lMime = _T("text/plain");
lHGlobal = lDataObject.GetGlobalData(TOleDataObject::GetClipFormat(E_DATA_TYPE_TEXT));
}
if (lHGlobal || lData)
{
if (lData == NULL)
{
lData = (LPBYTE)::GlobalLock(lHGlobal);
dwSize = ::GlobalSize(lHGlobal);
}
lResult = CreateFakeFile(hTiDropped, hTiDroppedParent, pDataObject, lData, dwSize, lMime, lTitle );
if (lHGlobal)
::GlobalUnlock(lHGlobal);
}
return lResult;
}
HRESULT CKbChapterToc::CreateFakeFile(HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject, LPBYTE pData, DWORD dwSize, LPCTSTR pMime, TString lTitle )
{
USES_CONVERSION;
CComPtr lCache;
HRESULT lResult;
TOleDataObject lDataObject;
lDataObject.Attach(pDataObject->m_lpDataObject, FALSE);
// Create Fake URL
CString lStrUrl;
lStrUrl.Format("internal://cache/filecontent/%d", time(0));
TSevenixUrl lUrl(lStrUrl);
// Create Cache Entry
if (pData && SUCCEEDED(GetCache(T_NETWORK_CACHE_NAME, &lCache)))
{
CComPtr lEntry;
if (SUCCEEDED(lCache->createEntry(CComBSTR(lUrl.extendedUrlString()), &lEntry)))
{
CComBSTR lFileName;
// Fill Cache File
if (SUCCEEDED(lEntry->getFileName(&lFileName)))
{
CFile lFile;
if (lFile.Open(W2CT(lFileName), CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite))
{
TRY
{
lFile.Write(pData, dwSize);
}
CATCH_ALL(e)
{
}
END_CATCH_ALL
lFile.Flush();
lFile.Close();
/*
CComPtr lBookControler;
lBookControler.CoCreateInstance(CLSID_TBookControler);
ATLASSERT(lBookControler);
if (lBookControler)
{
TModelPtr lNewPage;
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE);
lResult = lBookControler->Add(COleVariant(lUrl.extendedUrlString(), VT_BSTR), T_POS_REPLACE_SELECTED, (long*)&lNewPage);
ATLASSERT(SUCCEEDED(lResult) && lNewPage);
if (SUCCEEDED(lResult) && lNewPage)
{
lNewPage->setTitle(lUrl.simpleUrlString());
// Cast because model are not COM interface !!!
lBookControler->ChangePageTo(T_CPT_PAGE, T_SIDE_SELECTED, CComVariant((long)lNewPage.p));
}
TGlobalsDB::getLibraryDBManager()->commitTransaction();
if (pMime)
lEntry->addHeader(L"Content-Type", T2CW(pMime));
lEntry->commit();
return S_OK;
}
*/
// --- get the chapter controler
CComPtr pChapterControler;
HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler);
if( FAILED( hResult))
return FALSE;
// --- get the page model from the htreeItem
long lPos = 0;
TModelPtr pPageSelected;
TModelPtr pChapterParent;
if( hTiDropped == TVI_FIRST)
{
if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT)
{
// --- get item data
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent);
ASSERT( pItem);
TChapterModel* pChapterModel = (TChapterModel *) pItem->GetPageModel();
ASSERT( pChapterModel);
pChapterControler->put_chapter( (long) pChapterModel);
}
else
{
pChapterControler->put_chapter( (long) GetChapterModel());
}
lPos = 0;
}
else if( hTiDropped == TVI_LAST)
{
pChapterControler->put_chapter( (long) GetChapterModel());
lPos = T_POS_LAST;
}
else if( hTiDropped != NULL)
{
// --- get item data
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped);
ASSERT( pItem);
pPageSelected = pItem->GetPageModel();
HRESULT hResult = pPageSelected->getPagePosition( &lPos);
ASSERT( SUCCEEDED( hResult));
pPageSelected->getChapter( &pChapterParent);
pChapterControler->put_chapter( (long) pChapterParent.p);
}
else
{
// --- the tree ctrl is empty, or no item is selected
pChapterControler->put_chapter( (long) GetChapterModel());
}
// --- add it in the database
CComBSTR bstr( lUrl.extendedUrlString() );
CComVariant varPage( (BSTR) bstr);
TPageModel* pPageModelAdded;
CWaitCursor waitCursor;
BOOL bResult = FALSE;
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE);
if( SUCCEEDED( pChapterControler->Add( varPage, lPos, (long *) &pPageModelAdded)))
{
// Play sound when inserting a chapter in the toc
TSoundManager::PlayFromResource( IDSOUND_DROP_PAGE);
TSoundManager::PlayFromResource( IDSOUND_NEW_ITEM);
ASSERT( pPageModelAdded);
pPageModelAdded->setTitle( lTitle );
bResult = TRUE;
}
TGlobalsDB::getLibraryDBManager()->commitTransaction();
if (pMime)
lEntry->addHeader(L"Content-Type", T2CW(pMime));
lEntry->commit();
return S_OK;
}
}
lEntry->remove();
}
}
return E_FAIL;
}
/////////////////////////////////////////////////////////////////////////////
// CKbTreeWnd message menu handlers
void CKbChapterToc::OnInitMenuPopup( CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CKbTreeTocWnd::OnInitMenuPopup( pPopupMenu, nIndex, bSysMenu);
if( IsModifyProtected())
{
VERIFY( pPopupMenu->EnableMenuItem( IDM_TOC_NEWCHAPTER, MF_BYCOMMAND | MF_GRAYED) != -1);
VERIFY( pPopupMenu->EnableMenuItem( IDM_TOC_NEWURL, MF_BYCOMMAND | MF_GRAYED) != -1);
VERIFY( pPopupMenu->EnableMenuItem( IDM_TOC_NEWOSFILES, MF_BYCOMMAND | MF_GRAYED) != -1);
}
}
void CKbChapterToc::OnTocRename()
{
TRACE( _T("CKbChapterToc::OnTocRename\n"));
HTREEITEM hTiToEdit;
if( m_treeCtrl.m_hTiRButtonDown)
{
hTiToEdit = m_treeCtrl.m_hTiRButtonDown;
}
else
{
ASSERT( m_treeCtrl.m_listHtiSelected.GetCount() == 1);
hTiToEdit = (HTREEITEM) m_treeCtrl.m_listHtiSelected.GetHead();
}
(void) m_treeCtrl.EditLabel( hTiToEdit);
}
void CKbChapterToc::OnTocNewChapter()
{
TRACE( _T("CKbChapterToc::OnTocNewChapter\n"));
HTREEITEM hTi = m_treeCtrl.m_hTiRButtonDown ? m_treeCtrl.m_hTiRButtonDown : TVI_LAST;
m_treeCtrl.ClearSelection();
BOOL bResult = OnTocDropChapter( hTi, NULL);
if (!bResult)
TSoundManager::PlayFromResource( IDSOUND_ALERT);
}
void CKbChapterToc::OnTocNewOsFiles()
{
TRACE( _T("CKbChapterToc::OnTocNewOsFiles\n"));
// --- get the page model for this item
HTREEITEM hTi = m_treeCtrl.m_hTiRButtonDown;
TModelPtr pPageModel;
if( hTi)
{
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTi);
pPageModel = pItem->GetPageModel();
// --- open the item if it's a colappe chapter
if( pItem->IsItemContainer() && !m_treeCtrl.IsItemExpanded( hTi))
{
m_treeCtrl.Expand( hTi, TVE_EXPAND);
}
}
m_treeCtrl.ClearSelection();
// --- call the dialog
AFX_MANAGE_STATE( AfxGetAppModuleState());
TBooxFrame::GetActiveBooxView()->OnFileFile( pPageModel);
}
void CKbChapterToc::OnTocNewUrl()
{
TRACE( _T("CKbChapterToc::OnTocNewUrl\n"));
// --- get the page model for this item
TModelPtr pPageModel;
if( m_treeCtrl.m_hTiRButtonDown)
{
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( m_treeCtrl.m_hTiRButtonDown);
pPageModel = pItem->GetPageModel();
}
m_treeCtrl.ClearSelection();
// --- call the dialog
AFX_MANAGE_STATE( AfxGetAppModuleState());
TBooxFrame::GetActiveBooxView()->OnFileNavigate( pPageModel);
}
void CKbChapterToc::OnEditCopy()
{
TRACE( _T("CKbChapterToc::OnEditCopy\n"));
CKbTreeTocWnd::OnEditCopy();
}
void CKbChapterToc::OnEditCut()
{
TRACE( _T("CKbChapterToc::OnEditCut\n"));
CKbTreeTocWnd::OnEditCut();
}
void CKbChapterToc::OnEditPaste()
{
TRACE( _T("CKbChapterToc::OnEditPaste\n"));
CKbTreeTocWnd::OnEditPaste();
}
void CKbChapterToc::OnEditDel()
{
TRACE( _T("CKbChapterToc::OnEditDel\n"));
CKbTreeTocWnd::OnEditDel();
}
/////////////////////////////////////////////////////////////////////////////
// CKbTreeWnd listener handlers
LRESULT CKbChapterToc::OnChapterAddPage( WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = TRUE;
TPageModel* pPageModel = (TPageModel*) lParam;
TChapterModel* pChapterModel = (TChapterModel*) wParam;
TRACE( _T("### CKbChapterToc::OnChapterAddPage (%s)\n"), pPageModel->getTitle());
/*
// --- get the parent model,
TModelPtr pChapterModel;
pPageModel->getParentChapter( (TPageModel **) &pChapterModel);
ASSERT( pChapterModel);
*/
// --- then the parent item
HTREEITEM hTiParent = GetItemFromModel( pChapterModel);
if( hTiParent == NULL)
hTiParent = TVI_ROOT;
HTREEITEM hTiInserted;
if (hTiParent == TVI_ROOT || pChapterModel == m_pChapterModel
|| m_treeCtrl.IsItemExpanded( hTiParent))
{
// --- get the page model after this new, then item
HTREEITEM hTiAfter = m_treeCtrl.GetChildItem( hTiParent);
if( hTiAfter == NULL)
{
// --- there no child, so just insert it
hTiAfter = TVI_LAST;
// --- and reset the chid flag to have the indent button
if (hTiParent != TVI_ROOT)
m_treeCtrl.SetItemChildren( hTiParent, 1);
}
else
{
// --- parent has children, so search the insertion position
int nRef = m_pBookModel->getPageIndex( pPageModel);
HTREEITEM hTiCur = hTiAfter;
HTREEITEM hTiBefore = TVI_FIRST;
hTiAfter = TVI_LAST;
do
{
if (m_dropEffectPage == DROPEFFECT_MOVE)
{
// --- don't use item candidate to move because
// --- I'm not sure that they will be at the right place du to the asynchronous event
bool bIsFound = false;
int nMax = m_treeCtrl.m_arrayHtiDragged.GetSize();
for (int n=0; nGetPageModel();
int nCur = m_pBookModel->getPageIndex( pPageModelCur);
TRACE( _T("*** ::OnChapterAddPage Browse %d (%s)\n"), nCur, pItem->GetSubText(0));
if( nCur >= nRef+1)
{
hTiAfter = hTiBefore;
break;
}
hTiBefore = hTiCur;
}
while ((hTiCur = m_treeCtrl.GetNextSiblingItem( hTiCur)) != NULL);
}
// --- item can be visible, so do changement
hTiInserted = InsertItem( pPageModel, hTiParent, hTiAfter);
if (hTiInserted)
{
// --- check if this item is a chapter
CKbModelItem *pItem = (CKbModelItem *) m_treeCtrl.GetKbItemData( hTiInserted);
if (pItem->IsItemContainer())
{
AddPagesIntoChapter( hTiInserted);
}
// --- check if this item is to edit
//if( hTiParent != TVI_ROOT) m_treeCtrl.Expand( hTiParent, TVE_EXPAND);
if (pPageModel == m_pPageToEdit.p)
{
m_treeCtrl.SelectItem( hTiInserted);
m_treeCtrl.EditLabel( hTiInserted);
}
else
{
// --- auto selected the new page
m_treeCtrl.SetItemSelected( hTiInserted, true);
}
}
}
else
{
// --- item is collapsed, so set the flag to refresh his children
if (hTiParent != TVI_ROOT)
{
m_treeCtrl.SetItemExpandedOnce( hTiParent, FALSE);
m_treeCtrl.SetItemChildren( hTiParent, 1);
}
hTiInserted = hTiParent;
}
// --- release the page to edit if any
if (pPageModel == m_pPageToEdit.p)
m_pPageToEdit.Release();
// --- now reset the page number
while ((hTiInserted = m_treeCtrl.GetNextItem( hTiInserted)) != NULL)
{
// --- get the page number
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiInserted);
TPageModel* pPageModel = pItem->GetPageModel();
int nPage = m_pBookModel->getPageIndex( pPageModel);
pItem->SetSubInteger( 1, nPage);
m_treeCtrl.RedrawItem( hTiInserted);
}
// --- now reset the parent annotation flag
long lAnnoPage, lAnnoParent;
pPageModel->getGlobalSubAnnotationsCount( &lAnnoPage);
if (pChapterModel)
pChapterModel->getGlobalSubAnnotationsCount( &lAnnoParent);
if (lAnnoPage >= 1L)
{
// --- a new annotation has been inserted, so update the parent
while( hTiParent != TVI_ROOT && hTiParent != NULL)
{
CKbModelItem *pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiParent);
pItem->SetSubInteger( 2, ANNOTATION);
m_treeCtrl.RedrawItem( hTiParent);
hTiParent = m_treeCtrl.GetParentItem( hTiParent);
}
}
// --- remove empty sticker if any
{
AFX_MANAGE_STATE( AfxGetAppModuleState());
if (m_pPostItWnd)
{
m_pPostItWnd->SendMessage( WM_CLOSE);
m_pPostItWnd = NULL; // --- delete is made by Destroy Window
Invalidate();
}
}
// --- As this is a MESSAGE posting, an AddRef has been done before sending it,
// --- so we'll have to Release it when the processing is over.
pPageModel->Release();
if (pChapterModel)
pChapterModel->Release();
return lResult;
}
LRESULT CKbChapterToc::OnChapterRemovePage( WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = 0;
TPageModel* pPageModel = (TPageModel*) lParam;
TChapterModel* pChapterModel = (TChapterModel*) wParam;
TRACE( _T("### CKbChapterToc::OnChapterRemovePage (%s)\n"), pPageModel->getTitle());
HTREEITEM hTiPage = GetItemFromModel( pPageModel);
if (pChapterModel)
{
HTREEITEM hTiParent = GetItemFromModel( pChapterModel);
if( hTiParent == NULL)
hTiParent = TVI_ROOT;
TVITEM item;
item.hItem = hTiParent;
item.mask = TVIF_CHILDREN;
item.cChildren = pChapterModel->getPageCount() != 0;
m_treeCtrl.SendMessage(TVM_SETITEM, 0, (LPARAM)&item);
}
// --- if the item is not found, it's because a tree was deleted
if (hTiPage)
{
// --- now reset the page number
HTREEITEM hTiInc = hTiPage;
while ((hTiInc = m_treeCtrl.GetNextItem( hTiInc)) != NULL)
{
// --- get the page number
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiInc);
TPageModel* pPageModel = pItem->GetPageModel();
int nPage = m_pBookModel->getPageIndex( pPageModel);
pItem->SetSubInteger( 1, nPage);
TRACE( _T("*** ::OnChapterRemovePage Update %d (%s)\n"), nPage, pItem->GetSubText(0));
m_treeCtrl.RedrawItem( hTiInc);
}
// --- delete branch if the item is in the first level or on a chapter expanded
HTREEITEM hTiParent = m_treeCtrl.GetParentItem( hTiPage);
if (hTiParent == NULL || m_treeCtrl.IsItemExpanded( hTiParent))
{
// --- item can be visible, so do changement
if (hTiPage) m_treeCtrl.DeleteBranch( hTiPage);
// --- check if the chapter is now empty, to reset the expandedOnce flag
if (hTiParent && m_treeCtrl.GetChildItem( hTiParent) == NULL)
{
// --- collapse the chapter to redraw icons
m_treeCtrl.Expand( hTiParent, TVE_COLLAPSE);
// --- and force the item to be collapsed, even when it has no children
m_treeCtrl.SetItemExpanded( hTiParent, false);
}
}
else
{
// --- item is collapsed, so set the flag to refresh his children
m_treeCtrl.SetItemExpandedOnce( hTiPage, TRUE);
}
// --- now reset the parent annotation flag
if (hTiParent != NULL)
{
long lAnnoPage, lAnnoParent;
pPageModel->getGlobalSubAnnotationsCount( &lAnnoPage);
if( lAnnoPage >= 1)
{
// --- all annotations has been deleted, so update the parent
while( hTiParent != TVI_ROOT && hTiParent != NULL)
{
CKbModelItem *pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiParent);
TModelPtr pPageModel;
pPageModel = pItem->GetPageModel();
pPageModel->getGlobalSubAnnotationsCount( &lAnnoParent);
pItem->SetSubInteger( 2, lAnnoParent >= 1L ? ANNOTATION : NONE);
m_treeCtrl.RedrawItem( hTiParent);
hTiParent = m_treeCtrl.GetParentItem( hTiParent);
}
}
}
}
// --- set empty sticker if this chapter is empty
if (m_treeCtrl.GetCount() == 0)
CreateSticker();
// --- As this is a MESSAGE posting, an AddRef has been done before sending it,
// --- so we'll have to Release it when the processing is over.
pPageModel->Release();
if (pChapterModel)
pChapterModel->Release();
return lResult;
}
void CKbChapterToc::CreateSticker()
{
// --- don't create sticker in a system chapter (ie trash)
AFX_MANAGE_STATE( AfxGetAppModuleState());
if (::IsModifyProtected(m_pBookModel) || ::IsSystem(m_pBookModel)) return;
CRect rect( 0, 0, 219, 199);
m_pPostItWnd = new CKbStickerTocWnd(
m_pChapterModel->isInstanceOf( T_SUMMARY_MODEL_NAME) ? IDS_STICKER_EMPTY_TOC : IDS_STICKER_EMPTY_CHAPTER
);
m_pPostItWnd->setLogicalPoint( rect.TopLeft());
m_pPostItWnd->setLogicalSize( rect.Size());
m_pPostItWnd->setLogicalSpace( rect.Size());
m_pPostItWnd->SetNotifyWnd( this);
VERIFY( m_pPostItWnd->Create( rect, &m_treeCtrl, IDC_POSTIT));
}
bool CKbChapterToc::IsModifyProtected( void)
{
return ::IsModifyProtected( m_pBookModel) == TRUE;
}
void CKbChapterToc::DelSelection( void)
{
// --- call by the activeX
OnEditDel();
}
void CKbChapterToc::SetAnnotationVisibility( bool bIsVisible)
{
CWaitCursor wait;
// --- for each page set his annotation visiblity property
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE);
boolean bSet = bIsVisible;
HTREEITEM hTiInc;
for( hTiInc = m_treeCtrl.GetRootItem(); hTiInc; hTiInc = m_treeCtrl.GetNextItem( hTiInc))
{
// --- set the visibility of the page
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiInc);
ASSERT( pItem);
TModelPtr pPageModel;
pPageModel = pItem->GetPageModel();
ASSERT( pPageModel);
TModelPtr pPropModel;
pPageModel->getDefaultProperty( &pPropModel);
ASSERT( pPropModel);
pPropModel->putBooleanField( T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY, bSet);
// --- set an overlay image
pItem->SetSubOverlay( 2, bIsVisible ? 0 : 1);
}
// --- add the chapter itshelf
TModelPtr pPropModel;
m_pChapterModel->getDefaultProperty( &pPropModel);
pPropModel->putBooleanField( T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY, bSet);
TGlobalsDB::getLibraryDBManager()->commitTransaction();
}
int CKbChapterToc::GetNbSubAnnotation()
{
long lCount = 0;
m_pChapterModel->getGlobalSubAnnotationsCount( &lCount);
return (int) lCount;
}
//
// To Remove when the transition to the new Toolbar Button
// is complete
//
void CKbChapterToc::SendEvent( LPCTSTR szEvent)
{
CKbTreeTocWnd::SendEvent( szEvent);
if( strcmp( szEvent, T_EVENT_NEW_CHAPTER) == 0)
{
// --- Create a new chapter
AddNewChapter();
}
else
{
// --- no interesting event
return;
}
// --- update only interesting item
for( HTREEITEM hTiVisible = m_treeCtrl.GetFirstVisibleItem(); hTiVisible;
hTiVisible = m_treeCtrl.GetNextVisibleItem( hTiVisible))
{
int nImageList = m_treeCtrl.GetItemInteger( hTiVisible, 2);
if( nImageList == ANNOTATION) m_treeCtrl.RedrawItem( hTiVisible);
}
}
LONG CKbChapterToc::OnNewChapter(LONG, LONG)
{
// --- Create a new chapter
AddNewChapter();
// --- update only interesting item
for( HTREEITEM hTiVisible = m_treeCtrl.GetFirstVisibleItem(); hTiVisible;
hTiVisible = m_treeCtrl.GetNextVisibleItem( hTiVisible))
{
int nImageList = m_treeCtrl.GetItemInteger( hTiVisible, 2);
if( nImageList == ANNOTATION) m_treeCtrl.RedrawItem( hTiVisible);
}
return S_OK;
}
void CKbChapterToc::AddNewChapter()
{
// --- select an item to insert a chapter
BOOL bIsSelEmpty = m_treeCtrl.m_listHtiSelected.IsEmpty();
HTREEITEM hTiSelected = NULL, hTiParent = NULL;
if( bIsSelEmpty)
{
// --- get the item just before this one, because the insertion is made after a reference
HTREEITEM hTiFirstVisible = m_treeCtrl.GetFirstVisibleItem();
hTiSelected = m_treeCtrl.GetPrevSiblingItem( hTiFirstVisible);
if( hTiSelected)
{
hTiParent = m_treeCtrl.GetParentItem( hTiSelected);
}
else
{
hTiSelected = TVI_FIRST;
hTiParent = m_treeCtrl.GetParentItem( hTiFirstVisible);
}
TRACE( _T("Selected (%s)\n"), m_treeCtrl.GetItemText( hTiSelected));
TRACE( _T("Parent (%s)\n"), m_treeCtrl.GetItemText( hTiParent));
}
else
{
// --- select the item with the lowerpage number in the selection
POSITION pos;
int nPage;
int nPageMax = INT_MAX;
for( pos = m_treeCtrl.m_listHtiSelected.GetHeadPosition(); pos != NULL; )
{
HTREEITEM hTi = (HTREEITEM) m_treeCtrl.m_listHtiSelected.GetNext( pos);
ASSERT( hTi);
nPage = m_treeCtrl.GetItemInteger( hTi, 1);
if( nPage < nPageMax)
{
nPageMax = nPage;
hTiSelected = hTi;
}
}
TRACE( _T("CKbChapterToc::AddNewChapter PageSelected %d\n"), m_treeCtrl.GetItemInteger( hTiSelected, 1));
hTiParent = m_treeCtrl.GetParentItem( hTiSelected);
// --- copy the selection in a separate list.
// --- Don't use m_arrayHtiDragged because element are not use to place the new chapter
m_listHtiToInsert.RemoveAll();
m_listHtiToInsert.AddTail( &(m_treeCtrl.m_listHtiSelected));
}
// --- insert the chapter
m_treeCtrl.ClearSelection();
while (!OnTocDropChapter( hTiSelected, hTiParent))
{
if (hTiSelected == TVI_FIRST)
hTiSelected = m_treeCtrl.GetFirstVisibleItem();
else
hTiSelected = m_treeCtrl.GetNextItem(hTiSelected, TVGN_NEXTVISIBLE);
if (hTiSelected == NULL)
break;
}
}
void CKbChapterToc::AddPagesIntoChapter( HTREEITEM hTiTarget)
{
ASSERT( hTiTarget);
if( m_listHtiToInsert.IsEmpty()) return;
// --- get the chapter controler
CComPtr pChapterControler;
HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler);
if( FAILED( hResult))
{
TSoundManager::PlayFromResource( IDSOUND_ALERT);
return;
}
// --- get item data
CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiTarget);
ASSERT( pItem);
TModelPtr pPageSelected;
pPageSelected = pItem->GetPageModel();
pChapterControler->put_chapter( (long) pPageSelected.p);
// --- translate item to insert into insert to dragged
m_treeCtrl.SetDraggedSelection( &m_listHtiToInsert);
SortModelItem( m_treeCtrl.m_arrayHtiDragged);
m_listHtiToInsert.RemoveAll();
// --- prepare the progress dialog
CPtrArray ptrArray;
ptrArray.Append( m_treeCtrl.m_arrayHtiDragged);
m_treeCtrl.m_arrayHtiDragged.RemoveAll();
// TBooxFrame::GetMainWnd()->EnableWindow( FALSE);
long lPosition = 1;
int nMax = ptrArray.GetSize();
CProgressDlg dlg;
CString stgFormatStep, stgFormatComment;
{
AFX_MANAGE_STATE( AfxGetAppModuleState());
VERIFY( dlg.Create(
_T("CProgressDlg"), WS_CHILD/* | WS_VISIBLE*/, CRect( 0, 0, 10, 10), AfxGetMainWnd(), 1
));
CString stgTmp;
VERIFY( KBLoadString( IDS_PROGDLG_MOVE_FILE_TITLE, stgTmp));
dlg.SetTitle( stgTmp);
VERIFY( KBLoadString( IDS_CANCEL, stgTmp));
dlg.SetCancel( stgTmp);
KBLoadString( IDS_PROGDLG_STEP, stgFormatStep);
dlg.ChangeAnimation( 2 /*FILEMOVE*/);
KBLoadString( IDS_PROGDLG_MOVE_FILE_NAME, stgFormatComment);
dlg.SetUpper( nMax);
}
// --- browse all page
CWaitCursor waitCursor;
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE);
for( int n = 0; n < nMax; n++)
{
HTREEITEM hTi = (HTREEITEM) ptrArray[n];
CKbModelItem *pItem = (CKbModelItem *) m_treeCtrl.GetKbItemData( hTi);
TModelPtr pPageModel;
pPageModel = pItem->GetPageModel();
// --- update the progress dialog
{
// AFX_MANAGE_STATE( AfxGetAppModuleState());
if( dlg.IsProcessCanceled()) break;
CString stgTmp;
stgTmp.FormatMessage( stgFormatComment, (LPCTSTR) pPageModel->getTitle());
dlg.SetComment( stgTmp);
stgTmp.FormatMessage( stgFormatStep, lPosition, nMax);
dlg.SetStep( stgTmp);
dlg.SetPosition( lPosition++);
}
// --- move it in the database
CComVariant varChapter( (long) pPageModel.p);
hResult = pChapterControler->Move( varChapter, 0);
}
TGlobalsDB::getLibraryDBManager()->commitTransaction();
// --- close the progress bar
{
// AFX_MANAGE_STATE( AfxGetAppModuleState());
dlg.DestroyWindow();
}
// TBooxFrame::GetMainWnd()->EnableWindow( TRUE);
}/*------------ TBaseWBPageletCtl.cpp ------------*/
#include "StdAfx.h"
#include "mshtmcid.h"
#include "Dom.h"
#include "Controler.h"
// TBaseWBPageletCtl.cpp : Implementation of the TBaseWebBrowserPageletCtrl ActiveX Control class.
#include "Pagelet.h"
#include "PageletCtrl.h"
#include "TBaseWBPageletCtl.h"
#include "TPageletDll.h"
#include "TPageModel.h"
#include "TChapterModel.h"
#include "TContentModel.h"
#include "TAnnotationModel.h"
#include "TContentsBagModel.h"
#include "TStickerModel.h"
#include "TMetaManager.h"
#include "TModelNames.h"
#include "TModelHelpers.h"
#include "TModelPtr.h"
#include "TPageNumbering.h"
#include "TBooxFrame.h"
#include "TPreferences.h"
#include "TUrl.h"
#include "SharedResource.h"
#include "TPageletSearchView.h"
#include "TWebToolBar.h"
#include "TUserMessage.h"
#include "PropertyChangeEvent.h"
#include "TPropertyObjectModel.h"
#include "TPagePropertiesConstants.h"
#include "TContentPropertiesConstants.h"
#include "TKeeBooKeyController.h"
#include "TWebBrowser.h"
#include "TErr.h"
#include "TAppVersionInfo.h"
#include "TAppBrandingInfo.h"
#include "TWBDropTarget.h"
#include "TWBStretchSink.h"
#include "Net.h"
#include "IEVersion.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(TBaseWebBrowserPageletCtrl, TPageletCtrl)
// ****************************************************************
// Message map
BEGIN_MESSAGE_MAP(TBaseWebBrowserPageletCtrl, TPageletCtrl)
// Window
ON_WM_SIZE()
ON_WM_DESTROY()
// Ole
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
// User Message
ON_MESSAGE(WM_USER_SET_CONTENT, OnSetContent)
ON_MESSAGE(WM_USER_ADD_ANNOTATION, OnAddAnnotation)
ON_MESSAGE(WM_USER_CHANGE_ANNOTATION_VISIBILITY, OnChangeAnnotationVisibility)
ON_MESSAGE(WM_USER_RELOAD_PAGE, OnReloadPage)
ON_MESSAGE(WM_USER_REMOVE_PAGE, OnRemovePage)
ON_MESSAGE(WM_USER_NEED_DESTROY_PAGELET, OnNeedDestroy)
ON_MESSAGE(WM_USER_LOAD_URL, OnLoadUrl)
ON_MESSAGE(WM_USER_REDIRECT, OnRedirect)
ON_MESSAGE(WM_USER_REMOVE_SUB_BROWSER, OnRemoveSubBrowser)
ON_COMMAND_RANGE( IDM_UNKNOWN, IDM_JUSTIFYNONE, OnWebBrowserCommand)
ON_COMMAND_RANGE( IDM_OPEN, IDM_MENUEXT_COUNT, OnWebBrowserCommand)
ON_COMMAND(IDM_PAGELET_NEXT, OnPageletNext)
ON_COMMAND(IDM_PAGELET_PREVIOUS, OnPageletPrevious)
ON_COMMAND(IDM_PAGELET_VIEWINBROWSER, OnPageletViewInBrowser)
END_MESSAGE_MAP()
// ****************************************************************
// Dispatch map
BEGIN_DISPATCH_MAP(TBaseWebBrowserPageletCtrl, TPageletCtrl)
END_DISPATCH_MAP()
// ****************************************************************
// Event map
BEGIN_EVENT_MAP(TBaseWebBrowserPageletCtrl, TPageletCtrl)
END_EVENT_MAP()
// ****************************************************************
// TBaseWebBrowserPageletCtrl interfaces
BEGIN_INTERFACE_MAP(TBaseWebBrowserPageletCtrl, TPageletCtrl)
INTERFACE_PART(TBaseWebBrowserPageletCtrl, IID_IPageletWebBrowser, WebBrowser)
INTERFACE_PART(TBaseWebBrowserPageletCtrl, IID_IPageletHighlight, Highlight)
INTERFACE_PART(TBaseWebBrowserPageletCtrl, IID_IPageletSticker, Sticker)
END_INTERFACE_MAP()
// ****************************************************************
//
// Description:
// TBaseWebBrowserPageletCtrl - Constructor.
//
// Set all default variable values
//
TBaseWebBrowserPageletCtrl::TBaseWebBrowserPageletCtrl()
: m_bIsCreated(FALSE),
m_bFirstNavigate(TRUE),
m_bReload(FALSE),
m_bUserClick(FALSE),
m_bRedirected(FALSE),
m_bDoStretch(FALSE),
m_bDoImageFit(FALSE),
m_bReloadForBmp(FALSE),
m_bAnnotationAllowed(FALSE),
m_bNoStretch(FALSE),
m_bStoreTitle(TRUE),
m_bDynamicPage(FALSE),
m_bCanceling(FALSE),
m_bFullStaticKeeBook(FALSE),
m_bNeedReload(FALSE),
m_bStopReload(FALSE),
fWebBrowser(NULL),
m_DropTarget(NULL),
fContentListener(NULL),
m_RefreshForce(0),
m_RootDispatch(NULL),
m_pNetStatus(NULL),
m_StretchSink(NULL),
m_ExternalAdBanner(0),
m_NavigateCount(0),
m_pDropTarget(NULL)
{
SetLoaded(FALSE);
m_pEvents = NULL;
}
// ****************************************************************
//
// Description:
// TBaseWebBrowserPageletCtrl - Destructor
//
TBaseWebBrowserPageletCtrl::~TBaseWebBrowserPageletCtrl()
{
#ifdef DEBUG_PAGELET_LEAK
TRACE(_T(" ~TBaseWebBrowserPageletCtrl(0x%x)\n"), this);
#endif
}
// ************************************************************************************************
//
// Description:
// This function is a CCmdTarget hook to allow implementation of COM
// interface without adding them to the INTERFACE_MAP.
//
// It is used here to
//
/*
LPUNKNOWN TBaseWebBrowserPageletCtrl::GetInterfaceHook(const void* piid)
{
GUID* lIID = (GUID*)piid;
// if (InlineIsEqualGUID(*lIID, IID_IDropTarget))
// return &m_xDropTarget;
// if (InlineIsEqualGUID(*lIID, IID_IPageletWebBrowser))
// return &m_xWebBrowser;
return TPageletCtrl::GetInterfaceHook(piid);
}
*/
// ************************************************************************************************
//
// Description:
// Call during the Windows Destroy process, in response to WM_DESTROY message.
//
// Should free all GDI ressources associated with this Control,
// and optionaly other resources.
//
void TBaseWebBrowserPageletCtrl::OnDestroy()
{
#ifdef DEBUG_PAGELET_LEAK
CString lWndName(GetRuntimeClass()->m_lpszClassName);
TRACE(_T(" TBaseWebBrowserPageletCtrl(%s)::OnDestroy (0x%x)\n"), lWndName, this);
#endif
if (m_StretchSink && m_StretchSink->getStretching())
{
m_StretchSink->setStretching(FALSE);
}
m_DropTarget.Release();
if (fModel)
removeListeners();
if (fWebBrowser)
{
fWebBrowser->Stop();
fWebBrowser = NULL;
}
m_pNetStatus.Release();
m_BrowserTree.Release();
m_SoftReloadTree.Release();
#if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL)
m_BeforeTree.Release();
#endif
long lCount;
lCount = m_AdBannerList.GetSize();
while (lCount)
{
CWnd* lWnd;
lCount--;
lWnd = m_AdBannerList[0];
if (lWnd && lWnd->m_hWnd)
{
lWnd = lWnd->GetParent();
if (lWnd && (lWnd != this))
lWnd->DestroyWindow();
}
if (m_AdBannerList.GetSize() && (lWnd == m_AdBannerList[0]))
m_AdBannerList.RemoveAt(0);
}
TPageletCtrl::OnDestroy();
}
LRESULT TBaseWebBrowserPageletCtrl::OnRemoveSubBrowser(WPARAM pHwnd, LPARAM)
{
long lCount;
lCount = m_AdBannerList.GetSize();
while (lCount)
{
CWnd* lWnd;
lCount--;
lWnd = m_AdBannerList[lCount];
if (lWnd && lWnd->m_hWnd == (HWND)pHwnd)
{
m_AdBannerList.RemoveAt(lCount);
return S_OK;
}
}
return S_FALSE;
}
#ifdef _DEBUG
// ****************************************************************
//
// Description:
// Creating function.
//
// Just here for debug purpose ( to set break point !!!)
//
int TBaseWebBrowserPageletCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
return TPageletCtrl::OnCreate(lpCreateStruct);
}
// ****************************************************************
// TBaseWebBrowserPageletCtrl::OnDraw - Drawing function
//
void TBaseWebBrowserPageletCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
TPageletCtrl::OnDraw(pdc, rcBounds, rcInvalid);
}
// ****************************************************************
// TBaseWebBrowserPageletCtrl::OnResetState - Reset control to default state
void TBaseWebBrowserPageletCtrl::OnResetState()
{
TPageletCtrl::OnResetState(); // Resets defaults found in DoPropExchange
// TODO: Reset any other control state here.
}
// ************************************************************************************************
//
//
//
void TBaseWebBrowserPageletCtrl::ReportResult(long pResult)
{
TPageletCtrl::ReportResult(pResult);
// fIsLoaded = TRUE;
}
// ************************************************************************************************
//
//
//
void TBaseWebBrowserPageletCtrl::OnSize(UINT nType, int cx, int cy)
{
TPageletCtrl::OnSize(nType, cx, cy);
}
#endif
BOOL TBaseWebBrowserPageletCtrl::PreTranslateMessage(MSG* pMsg)
{
if ((pMsg->message >= WM_MOUSEFIRST) && (pMsg->message <= WM_MOUSELAST) && MinimumIEVersion(5, 5))
{
if (pMsg->message == WM_LBUTTONUP)
UserClick();
}
/*
AfxLockTempMaps();
BOOL lIsDialogMsg = IsDialogMessage(pMsg);
AfxUnlockTempMaps();
if (lIsDialogMsg)
{
//TRACE( "\n{AC} ISDialogMessage true\n" );
return TRUE;
}
else
*/
{
return TPageletCtrl::PreTranslateMessage(pMsg);
}
}
// ****************************************************************
//
// Description:
// Create Browser function
//
void TBaseWebBrowserPageletCtrl::CreateBrowser()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CRect lLogicalRect;
CRect lDeviceRect;
CComBSTR lUserAgentExtension;
lLogicalRect = GetPageletLogicalRect();
lDeviceRect = lLogicalRect;
LPtoDP(&lDeviceRect);
fWebBrowser = new TWebBrowser(0);
fWebBrowser->setLogicalPoint(lLogicalRect.TopLeft());
fWebBrowser->setLogicalSize(lLogicalRect.Size());
fWebBrowser->setLogicalSpace(lLogicalRect.Size());
#ifdef T_NEW_WEB_EVENT_HANDLER
fWebBrowser->SetBrowserEventsSink(m_pEvents);
#else // T_NEW_WEB_EVENT_HANDLER
fWebBrowser->SetBrowserEventsSink(this);
#endif // T_NEW_WEB_EVENT_HANDLER
fWebBrowser->Create(NULL, "web_browser_control", WS_CHILD|WS_VISIBLE, lDeviceRect, this, 0);
CComPtr lUnk;
InternalQueryInterface(&IID_IUnknown, (void**)&lUnk);
fWebBrowser->GetControlSite()->setPageletControl(lUnk);
TAppVersionInfo lAppInfo;
lUserAgentExtension = lAppInfo.GetSKU();
#ifdef T_ADD_PARTNER_SKU_TO_USER_AGENT
TAppBrandingInfo lBrandingInfo;
lUserAgentExtension.Append("/");
lUserAgentExtension.Append(lBrandingInfo.GetPartnerID());
#endif
fWebBrowser->SetUserAgentExtension(lUserAgentExtension);
fWebBrowser->SetRegisterAsDropTarget(TRUE);
insertChildAt(fWebBrowser, GetBrowserPos());
SetResizable(*fWebBrowser);
showView(*fWebBrowser);
m_bIsCreated = true;
}
LONG TBaseWebBrowserPageletCtrl::GetBrowserPos()
{
return childCount();
}
void TBaseWebBrowserPageletCtrl::DestroyBrowser()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
removeChild(fWebBrowser);
if (fWebBrowser)
fWebBrowser->DestroyWindow();
fWebBrowser = NULL;
m_bIsCreated = false;
}
// ****************************************************************
// TBaseWebBrowserPageletCtrl::DoPropExchange - Persistence support
void TBaseWebBrowserPageletCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
TPageletCtrl::DoPropExchange(pPX);
// TODO: Call PX_ functions for each persistent custom property.
}
// ****************************************************************
//
// Description:
// Signal the navigation stop.
//
HRESULT TBaseWebBrowserPageletCtrl::Stop()
{
ReportResult(S_FALSE);
m_bAnnotationAllowed = TRUE;
return S_OK;
}
// ****************************************************************
//
// Description:
//
//
HTMLFocusPlacement TBaseWebBrowserPageletCtrl::FindRealActiveElementOnContent( IHTMLDocument2* pDocument )
{
USES_CONVERSION;
CComPtr lActive;
if( pDocument->get_activeElement( &lActive ) == S_OK )
{ VARIANT_BOOL lIsTextEdit = FALSE;
CComBSTR lTagName;
lActive->get_tagName( &lTagName );
#ifdef _DEBUG
// for( int k = 0;k < lNbDecal;k++ ) { TRACE( " " ); }
TRACE( "Element actif classe %s\n", W2CT( lTagName ) );
#endif
// directly test if it is a text edit
lActive->get_isTextEdit( &lIsTextEdit );
if( lIsTextEdit && !(lTagName == CComBSTR( _T("BODY") )))
{
return OnEditElement;
}
// no : test if t's an input or a select : To complete
CComBSTR lActiveTagName;
lActive->get_tagName( &lActiveTagName );
if( (lActiveTagName == CComBSTR( _T("SELECT") )) ||(lActiveTagName == CComBSTR( "INPUT" )) )
{
return OnEditElement;
}
// to detect strange objects : not text
CComQIPtr lInput( lActive );
if( lInput != NULL )
{ CComBSTR lInputType; // ex : text textarea password
lInput->get_type( &lInputType );
TRACE( "input Type %s\n", W2CT( lInputType ) );
return OnEditElement;
}
// Test other objects who can eat keys
CComQIPtr lObject( lActive );
if( lObject != NULL ) // It's something like an ActiveX
{ CComBSTR lType;
long lState;
lObject->get_type( &lType );
// An object can eat all keys If it is ready to do it
TRACE( "Object Type %s\n", W2CT( lType ) );
lObject->get_readyState( &lState );
if( (lState == READYSTATE_INTERACTIVE) || (lState == READYSTATE_COMPLETE) )
{
return OnObjectElement;
}
}
}
return NotOnEditElement;
}
// ****************************************************************
//
// Description:
// Search for the current focused element in a web page if any.
//
// Remarks:
// This custom version of a Frame Crawler should be replaced by
// a standard one. This one is not able of of crawling frames in
// different domain names, for security reason.
//
HTMLFocusPlacement TBaseWebBrowserPageletCtrl::FindRealActiveElementOnFrame( IHTMLDocument2* pDocument )
{ bool lNoFrame = false;
CComPtr lCollec2;
long lNbItems = 0;
#ifdef _DEBUG
static lNbDecal = 0;
#endif
if( (pDocument->get_frames( &lCollec2 ) != S_OK) || !lCollec2 )
{
lNoFrame = true;
}
else
{
if( (lCollec2->get_length( &lNbItems ) != S_OK) || (lNbItems <= 0) )
{
lNoFrame = true;
}
}
if( lNoFrame )
{
// Return the final decision;
return FindRealActiveElementOnContent( pDocument );
}
// Don't forget the case where there is frame but the active element is not on a frame
HTMLFocusPlacement lRes = FindRealActiveElementOnContent( pDocument );
if( lRes != NotOnEditElement )
{
return lRes;
}
CComVariant lI;
for( short i = 0; i < lNbItems;i++,lI = i )
{ CComVariant lFrameVariant;
#ifdef _DEBUG
static lNbDecal = 0;
for( int k = 0;k < lNbDecal;k++ ) { TRACE( " " ); }
TRACE( "%d / %d\n",i,lNbItems );
#endif
if( (lCollec2->item( &lI,&lFrameVariant) == S_OK) && (lFrameVariant.vt == VT_DISPATCH) )
{ CComPtr lDispFrame = lFrameVariant.pdispVal;
CComQIPtr lWinFrame( lDispFrame );
if( lWinFrame )
{ CComPtr lFrameDocument;
if( (lWinFrame->get_document( &lFrameDocument ) == S_OK) && lFrameDocument && !lFrameDocument.IsEqualObject( pDocument ) )
{
#ifdef _DEBUG
lNbDecal++;
#endif
lRes = FindRealActiveElementOnFrame( lFrameDocument );
#ifdef _DEBUG
lNbDecal--;
#endif
if( lRes != NotOnEditElement )
{
return lRes;
}
}
}
}
}
return NotOnEditElement;
}
HTMLFocusPlacement TBaseWebBrowserPageletCtrl::FocusPlacement( void )
{
if( !m_IsLoaded )
{
return CannotFind; // TKeeBooKeyController::OnStandardWebPage;
}
// Get the ITHMLDocument2
CComPtr lDispatch;
if( fWebBrowser->GetHtmlDocument( &lDispatch ) != S_OK)
{
TRACE( "Ce n'est pas un document html\n" );
return CannotFind;
}
CComQIPtr lDoc(lDispatch);
if( lDoc == NULL )
return CannotFind;
return FindRealActiveElementOnFrame( lDoc );
}
// ************************************************************************************************
//
// Description:
// Get all the accelerator information for the sub-control.
//
// This is called by the container framework.
//
void TBaseWebBrowserPageletCtrl::OnGetControlInfo(LPCONTROLINFO pControlInfo)
{
if (fWebBrowser)
{
IUnknown* lUnk = fWebBrowser->GetControlUnknown();
CComQIPtr lControl(lUnk);
if (lControl)
{
lControl->GetControlInfo(pControlInfo);
}
}
else
{
TPageletCtrl::OnGetControlInfo(pControlInfo);
}
}
// ************************************************************************************************
//
// Description:
// Hook to get the opportunity to change the drop target of a pagelet
//
// We store the old
//
// Inputs:
// pDropTarget - The original drop target
// ppDropTarget - The new drop target if we want to change it.
//
// Return Value:
// S_OK - A new drop target was specified
//
STDMETHODIMP TBaseWebBrowserPageletCtrl::GetDropTarget(IDropTarget* pDropTarget, IDropTarget** ppDropTarget)
{
HRESULT lResult;
if (m_DropTarget == NULL)
{
lResult = CComObject::CreateInstance(&m_pDropTarget);
if (FAILED(lResult))
return lResult;
ATLASSERT(m_pDropTarget);
lResult = m_pDropTarget->QueryInterface(&m_DropTarget);
if (FAILED(lResult))
return lResult;
ATLASSERT(m_DropTarget);
m_pDropTarget->m_Pagelet = this;
lResult = InternalQueryInterface(&IID_IPageletLoadControl, (void**)&m_pDropTarget->m_PageletLoadControl);
ATLASSERT(SUCCEEDED(lResult));
}
if (m_pDropTarget)
{
m_pDropTarget->m_Page = fModel;
m_pDropTarget->m_StubDropTarget = pDropTarget;
}
*ppDropTarget = m_DropTarget;
(*ppDropTarget)->AddRef();
return S_OK;
}
// ************************************************************************************************
//
// Description:
// Called in response to a WM_USER_NEED_DESTROY_PAGELET message.
// This is to make sure the web browser interface are release before this control
// is destroy.
//
LRESULT TBaseWebBrowserPageletCtrl::OnNeedDestroy(UINT wParam, LONG lParam)
{
m_BrowserTree.Release();
return TPageletCtrl::OnNeedDestroy(wParam, lParam);
}
// ************************************************************************************************
//
// Description:
// Add the page listener to the model
//
void TBaseWebBrowserPageletCtrl::addListeners()
{
ASSERT(fModel);
if (fModel == NULL)
return ;
if (fMode == 0)
return ;
if (fMode == T_PRINT_MODE)
return ;
fContentListener = new TBaseWebContentListener();
fContentListener->fThis = this;
fModel->addPropertyChangeListener(fContentListener);
TModelPtr lProperty;
fModel->getDefaultProperty(&lProperty);
ASSERT(lProperty);
if (lProperty != NULL)
{
lProperty->addPropertyChangeListener(fContentListener);
}
}
// ************************************************************************************************
//
// Description:
// Remove the page listener to the model
//
void TBaseWebBrowserPageletCtrl::removeListeners()
{
if (fContentListener == NULL)
return ;
ASSERT(fModel);
if (fModel == NULL)
return ;
fContentListener->fThis = NULL;
fModel->removePropertyChangeListener(fContentListener);
TModelPtr lProperty;
fModel->getDefaultProperty(&lProperty);
ASSERT(lProperty);
if (lProperty != NULL)
{
lProperty->removePropertyChangeListener(fContentListener);
}
fContentListener->setInvalid();
fContentListener = NULL;
}
// ************************************************************************************************
//
// Description:
// Hook function to add some processing before loading a page
//
// The default implementation do nothing
//
void TBaseWebBrowserPageletCtrl::beforeLoad()
{
#ifdef ALLOW_PDF_FILE
m_PdfObject.Release();
#endif // ALLOW_PDF_FILE
}
// ****************************************************************
//
// Description:
// AddRef, Release and QueryInterface stuff for the IPageletWebBrowser interface
//
T_IMPLEMENT_EXTERNAL_INTERFACE(TBaseWebBrowserPageletCtrl, WebBrowser)
// ****************************************************************
//
// Description:
// This function Search in the pagelet the focused object
//
// Inputs:
// pPlacement - possible return value: CannotFind / NotOnEditElement / OnEditElement / OnObjectElement
//
// Return Value:
// E_INVALIDARG - If the argument is invalid
// S_OK - If the web browser is available
// S_FALSE - If the web browser is not available !!! ( should be E_FAIL ? )
//
HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::FocusPlacement( int* pPlacement )
{
ASSERT( pPlacement );
if( pPlacement == NULL )
return E_INVALIDARG;
METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser);
if (pThis->fWebBrowser )
{
*pPlacement = (int)pThis->FocusPlacement();
return S_OK;
}
return S_FALSE;
}
HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::IsInternalPage(BOOL* pResult, BSTR* pType)
{
ASSERT( pResult );
if( pResult == NULL )
return E_INVALIDARG;
METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser);
if (pThis->fWebBrowser )
{
*pResult = pThis->CheckIsInternalPage(pType) == S_OK ? TRUE : FALSE;
return S_OK;
}
return E_FAIL;
}
// ****************************************************************
//
// Description:
// This function retrieve the selected text in a pagelet web browser
//
// Remarks:
// This function is not FRAME compatible !!!!
//
// We should make this Pagelet specific, not WebBrowser specific
//
// Inputs:
// pSelectedText - A pointer to the returned BSTR
//
// Return Value:
// E_FAIL - If fail
// S_OK - If the text was retrieved
//
HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::get_SelectedText( BSTR* pSelectedText )
{
USES_CONVERSION;
CComPtr lDispatch;
METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser);
if (pThis->fWebBrowser->GetHtmlDocument(&lDispatch) == S_OK )
{
CComQIPtr lDoc(lDispatch);
if (lDoc )
{
// get the active selection
CComPtr lSelection;
lDoc->get_selection( &lSelection );
if (lSelection )
{
CComPtr lRangeDispatch;
lSelection->createRange( &lRangeDispatch );
if (lRangeDispatch )
{
CComQIPtr lRange( lRangeDispatch );
lRange->get_text( pSelectedText );
TRACE( "Texte selectionne %s\n", W2CT( *pSelectedText ) );
return S_OK;
}
}
}
}
return E_FAIL;
}
// ****************************************************************
//
// Description:
//
//
STDMETHODIMP TBaseWebBrowserPageletCtrl::XWebBrowser::GetDropTarget(IDropTarget* pDropTarget, IDropTarget** ppDropTarget)
{
METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser);
return pThis->GetDropTarget(pDropTarget, ppDropTarget);
}
// ****************************************************************
//
// Description:
//
//
HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::UserClick()
{
METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser);
return pThis->UserClick();
}
// ****************************************************************
//
// Description:
//
//
HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::TranslateUrl(BSTR pUrl, BSTR* pUrlOut)
{
METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser);
return pThis->TranslateUrl(pUrl, pUrlOut);
}
// ****************************************************************
//
// Description:
// Called in response to WM_USER_SET_CONTENT message.
//
// Reload the pagelet if the WParam is TRUE
//
// Return Value:
// Always S_OK !!!!
//
LRESULT TBaseWebBrowserPageletCtrl::OnSetContent(WPARAM wParam, LPARAM)
{
if (wParam)
Reload(REFRESH_NORMAL);
return S_OK;
}
// ****************************************************************
//
// Description:
// Called in response to WM_USER_RELOAD_PAGE message.
//
// Force the Reload of the pagelet.
// The refresh rate is specified in the WParam.
//
// Return Value:
// Always S_OK !!!!
//
LRESULT TBaseWebBrowserPageletCtrl::OnReloadPage(WPARAM pRefreshRate, LPARAM)
{
Reload(pRefreshRate);
return S_OK;
}
LRESULT TBaseWebBrowserPageletCtrl::OnRemovePage(WPARAM , LPARAM)
{
TModelPtr lPage;
TModelPtr lBook;
lPage = getModel();
ATLASSERT(lPage);
if (lPage == NULL)
return E_FAIL;
lPage->getBook(&lBook);
ATLASSERT(lBook);
if (lBook == NULL)
return E_FAIL;
CComPtr lBookControl;
lBookControl.CoCreateInstance(CLSID_TBookControler);
ASSERT(lBookControl);
if (lBookControl == NULL)
return E_FAIL;
lBookControl->put_book((long)lBook.p);
return lBookControl->Remove(CComVariant((LONG)lPage.p));
}
// ****************************************************************
//
// Description:
// Called in response to WM_USER_REDIRECT message.
//
// Inputs:
// pDisp - An IDispatch pointer ( must implemente the IWebBrowser2 interface )
// pBstr - The redirected URL
//
// Return Value:
// E_INVALIDARG - if any parameter is invalid
// S_OK - else
//
LRESULT TBaseWebBrowserPageletCtrl::OnRedirect(WPARAM pDisp, LPARAM pBstr)
{
USES_CONVERSION;
ATLASSERT(pDisp);
ATLASSERT(pBstr);
if ((pDisp == NULL) || (pBstr == NULL))
return E_INVALIDARG;
IDispatch* lDispatch = (IDispatch*)pDisp;
CComQIPtr lBrowser(lDispatch);
ATLASSERT(lBrowser);
if (lBrowser == NULL)
return E_INVALIDARG;
CComBSTR lUrl;
lUrl.Attach((BSTR)pBstr);
#ifdef DEBUG_EXTENDED_URL
TUrl lBaseUrl(lUrl);
CString lScheme = lBaseUrl.getScheme();
if (StorableProtocol(lScheme))
ATLASSERT(lBaseUrl.getExtendedInfo() != NULL);
#endif
InitFlags(lDispatch);
m_bRedirected = TRUE;
DWORD lNavOptions;
lNavOptions = getNavigationFlags();
if (fWebBrowser->m_pBrowserApp == lBrowser)
Navigate(W2CT(lUrl), lNavOptions);
else
{
CComVariant lFlags(lNavOptions, VT_I4);
lBrowser->Navigate(lUrl, &lFlags, NULL, NULL, NULL);
}
lDispatch->Release();
return S_OK;
}
#include "mshtml.h"
// ****************************************************************
//
//
//
LRESULT TBaseWebBrowserPageletCtrl::OnAddAnnotation(WPARAM pAnnotation, LPARAM)
{
if (m_BrowserTree == NULL)
return S_FALSE;
TAnnotationModel* lAnnotation;
LRESULT lResult;
// As this is a MESSAGE posting, an AddRef has been done on pAnnotation
// before sending it, so we'll have to Release it when the processing is over.
lAnnotation = (TAnnotationModel*)pAnnotation;
ASSERT(lAnnotation);
lResult = AddAnnotation(m_BrowserTree, lAnnotation);
ASSERT(SUCCEEDED(lResult));
lAnnotation->Release();
return lResult;
}
// ****************************************************************
//
//
//
LRESULT TBaseWebBrowserPageletCtrl::OnChangeAnnotationVisibility(WPARAM pField, LPARAM)
{
BSTR lField = (BSTR)pField;
TPageModel* lPage;
TModelPtr lProp;
boolean lBool;
lPage = getModel();
ATLASSERT(lPage);
lPage->getDefaultProperty(&lProp);
ATLASSERT(lProp);
lProp->getBooleanField(CString(lField), &lBool);
::SysFreeString(lField);
if (lBool)
showAnnotation(TRUE);
else
hideAnnotation(TRUE);
return S_OK;
}
void TBaseWebBrowserPageletCtrl::OnModeChange(long pMode)
{
#ifdef USE_IE_ZOOM
if (MinimumIEVersion(5,5))
{
doStretch();
}
else
#endif // USE_IE_ZOOM
{
if ((m_bDoStretch == NeedStretch())) // && (m_bDoImageFit == NeedImageFit()))
return ;
if (m_StretchSink)
{
m_StretchSink->setStretching(FALSE);
PostMessage(WM_USER_RELOAD_PAGE, REFRESH_NORMAL);
}
else
{
Reload(REFRESH_NORMAL);
}
}
}
void TBaseWebBrowserPageletCtrl::Reload(long pRefreshForce)
{
m_bReloadForBmp = FALSE;
m_RefreshForce = pRefreshForce;
m_bReload = TRUE;
initPagelet();
if (fWebBrowser)
fWebBrowser->Stop();
if (m_StretchSink)
{
m_StretchSink->setStretching(FALSE);
// TO DO: we might need an Asynchrone Reload here ????
}
/*
if (fRefreshForce == REFRESH_COMPLETELY)
{
HRESULT lResult;
CString lStrUrl = "about:sevenix";
// get url can be hooked
lResult = getUrl(lStrUrl);
if (lResult != S_OK)
return ;
TModelPtr lContentsBag;
TModelPtr lContent;
TUrl lUrl(lStrUrl);
TMetaManager::createModelInstance(T_CONTENTS_BAG_MODEL_NAME, (void**)&lContentsBag);
lContentsBag->getContent( lUrl.extendedUrlString(), &lContent);
ASSERT( lContent);
fModel->setContent( lContent, true);
}
else
*/
{
if (MinimumIEVersion(5,5))
{
DestroyBrowser();
CreateBrowser();
}
Load();
}
m_bReload = FALSE;
}
//IMPLEMENT_DYNAMIC(TBaseWebContentListener, TPropertyChangeListener);
// ************************************************************************************************
//
//
//
void TBaseWebContentListener::propertyChange(TPropertyChangeEvent *evt)
{
if (!fThis)
return ;
CString lEvent = evt->getPropertyName();
if (!lEvent.Compare(TPageModel::T_SET_CONTENT_PROPERTY))
{
fThis->PostMessage(WM_USER_SET_CONTENT, !fThis->m_bInDocumentComplete);
}
if (!lEvent.Compare(TPageModel::T_ADD_ANNOTATION_PROPERTY))
{
TAnnotationModel* lAnnotation = (TAnnotationModel*)evt->getNewValue();
lAnnotation->AddRef();
fThis->PostMessage(WM_USER_ADD_ANNOTATION, (UINT)lAnnotation);
}
else if (!lEvent.Compare(TPropertyObjectModel::T_PUT_FIELD_PROPERTY))
{
CString lField = evt->getNewStringValue();
if (lField == T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY)
{
fThis->PostMessage(WM_USER_CHANGE_ANNOTATION_VISIBILITY, (UINT)lField.AllocSysString());
}
}
}
STDMETHODIMP TBaseWebBrowserPageletCtrl::OnNewBackWnd(HWND hWnd)
{
if (!m_bIsCreated)
{
CreateBrowser();
fWebBrowser->SetRegisterAsBrowser(TRUE);
}
fWebBrowser->setViewToRefresh(hWnd);
return S_OK;
}
BOOL TBaseWebBrowserPageletCtrl::NeedStretch()
{
BOOL bResult = FALSE;
if (IsStretchable(fModel) && !m_bNoStretch)
{
TPreferences lPref("Stretcher");
// We can desactivate Stretching ...
int lBool;
if (fMode == T_BOOK_MODE)
{
// if key present and active
if ((lPref.GetInt("Book", &lBool) == S_OK) && lBool)
bResult = TRUE;
}
else if (fMode == T_BOOK_STAND_MODE)
{
// if key present and active
if ((lPref.GetInt("BookStand", &lBool) == S_OK) && lBool)
bResult = TRUE;
}
else if (fMode == T_PAGE_MODE)
{
// if key present and active
if ((lPref.GetInt("Page", &lBool) == S_OK) && lBool)
bResult = TRUE;
}
}
return bResult;
}
BOOL TBaseWebBrowserPageletCtrl::NeedImageFit()
{
if (IsStretchable(fModel))
{
TPreferences lPref("Stretcher");
// We can desactivate Stretching ...
int lBool;
if (fMode == T_BOOK_MODE)
{
// if key present and active
if ((lPref.GetInt("BookImage", &lBool) == S_OK) && lBool)
return TRUE;
}
else if (fMode == T_BOOK_STAND_MODE)
{
// if key present and active
if ((lPref.GetInt("BookStandImage", &lBool) == S_OK) && lBool)
return TRUE;
}
else if (fMode == T_PAGE_MODE)
{
// if key present and active
if ((lPref.GetInt("PageImage", &lBool) == S_OK) && lBool)
return TRUE;
}
}
return FALSE;
}
BOOL TBaseWebBrowserPageletCtrl::IsPostPage(TContentModel* pContentModel)
{
TModelPtr lContent(pContentModel);
if (lContent == NULL)
{
getModel()->getContent(&lContent);
if (lContent == NULL)
return FALSE;
}
TModelPtr lNetworkProp;
CString lPostData;
GetModelProperty(lContent, T_CONTENT_NETWORK_PROPERTIES, &lNetworkProp);
//
// Is this a Post
if (lNetworkProp && lNetworkProp->getStringField(T_CONTENT_NETWORK_POST_DATA, &lPostData))
return TRUE;
return FALSE;
}
BOOL TBaseWebBrowserPageletCtrl::CanReload()
{
TModelPtr lContent;
getModel()->getContent(&lContent);
if (lContent == NULL)
return FALSE;
//
// Is this a Post
if (IsPostPage(lContent))
return FALSE;
CString lUrlString;
TUrl lUrl;
lUrlString = lContent->getUrl();
lUrl = lUrlString;
#ifdef T_GENERIC_CHECK_LOCAL_RELOAD
DWORD lUseNetwork = 1;
DWORD lSize;
DWORD lAccess;
HRESULT lResult;
lResult = CoInternetQueryInfo(CComBSTR(m_CurrentUrl), QUERY_USES_NETWORK, 0, &lUseNetwork, sizeof(lUseNetwork), &lSize, 0);
if (FAILED(lResult))
lUseNetwork = 0;
if (!lUseNetwork)
{
lResult = CheckDocumentLocalAccessibility(CComBSTR(m_CurrentUrl), &lAccess);
// and if we do not have the document.
if (!(lAccess & DOCUMENT_CAN_ACCESS))
{
// TO DO
}
}
#endif
if (lUrl.getScheme() == "file")
{
CString lFileName;
CFileStatus lStatus;
lFileName = lUrl.getFile();
if (CFile::GetStatus(lFileName, lStatus))
{
return TRUE;
}
return FALSE;
}
return TRUE;
}
// ****************************************************************
HRESULT TBaseWebBrowserPageletCtrl::Hide()
{
TPageletCtrl::Hide();
if (fWebBrowser)
fWebBrowser->SetSilent(TRUE);
return S_OK;
}
// ****************************************************************
HRESULT TBaseWebBrowserPageletCtrl::Show()
{
TPageletCtrl::Show();
if (fWebBrowser)
fWebBrowser->SetSilent(FALSE);
return S_OK;
}
void TBaseWebBrowserPageletCtrl::OnWebBrowserCommand(UINT nID)
{
ASSERT(fWebBrowser);
if (fWebBrowser)
fWebBrowser->GetDescendantWindow(0)->SendMessage(WM_COMMAND, nID);
}
void TBaseWebBrowserPageletCtrl::OnPageletNext()
{
CComPtr lBookControler;
lBookControler.CoCreateInstance(CLSID_TBookControler);
lBookControler->ChangePageTo(T_CPT_NEXT_PAGE, T_SIDE_SECONDARY,
CComVariant(1));
}
void TBaseWebBrowserPageletCtrl::OnPageletPrevious()
{
CComPtr lBookControler;
lBookControler.CoCreateInstance(CLSID_TBookControler);
lBookControler->ChangePageTo(T_CPT_PREV_PAGE, T_SIDE_PRIMARY,
CComVariant(1));
}
void TBaseWebBrowserPageletCtrl::OnPageletViewInBrowser()
{
TBooxFrame::GetActiveBooxView()->SendMessage(WM_COMMAND,
IDM_VIEW_INBROWSER);
}/*------------ TBaseWBPageletCtl.h ------------*/
#ifndef T_BASE_WEBBROWSER_PAGELET_CTL
#define T_BASE_WEBBROWSER_PAGELET_CTL
// --- STL
#include "xstddef"
#pragma warning(disable: 4663)
#pragma warning(disable: 4244)
#pragma warning(disable: 4018)
#include "vector"
#include
using namespace std;
// --- End STL
#include "TPageletCtl.h"
#include "mshtml.h"
#include "PropertyChangeListener.h"
//#include "Dom.h"
#include "TKeeBooKeyController.h"
#include "TBaseWebBrowserEvents.h"
#include "TWebBrowser.h"
//#define SEARCH_FOR_HIDDEN_EVENT
#define NEW_NET_INTERFACE
#define WM_USER_LOAD_URL WM_USER + 461
#define WM_USER_REDIRECT WM_USER + 462
#define WM_USER_RELOAD_PAGE WM_USER + 463
class TPageletSearchView;
class TWebBrowser;
class TPageModel;
class TBookModel;
class TContentModel;
class TAnnotationModel;
class TString;
class TStringToPtrHashTable;
class TStickerModel;
class THighlighterModel;
class TWebContentListener;
class TBaseWebBrowserPageletCtrl;
interface IInternetStatus;
interface IWebBrowserTreeNode;
interface IDomAnnotationInfo;
class TWebBrowserStretchSink;
//
// Description:
// Listener for PageModel events
//
class TBaseWebContentListener : public TPropertyChangeListener
{
public:
virtual void propertyChange(TPropertyChangeEvent *evt);
TBaseWebBrowserPageletCtrl* fThis;
};
enum AdviseType
{
Advise,
Unadvise
};
/////////////////////////////////////////////////////////////////////////////
// TBaseWebBrowserPageletCtrl : See TBaseWBPageletCtl.cpp for implementation.
//
// Description:
// This is the base class for Web Pagelet Control.
// It does not instanciate any toolbar, as the toolbar should become
// a separate service.
//
// It just handle basic navigation.
//
// Some Hook function are available to customize this class:
// * beforeLoad():
// * OnModeChange(long):
// * BeforeNavigate(LPDISPATCH , VARIANT* , VARIANT* , VARIANT* , VARIANT* , VARIANT* , BOOL* )
// * NeedStretch(): return a BOOL telling if stretch is needed.
// default implementation return the preferences mode flag
//
class TBaseWebBrowserPageletCtrl : public TPageletCtrl, TWebBrowserEvents
{
DECLARE_DYNAMIC(TBaseWebBrowserPageletCtrl)
DECLARE_INTERFACE_MAP();
DECLARE_MESSAGE_MAP()
DECLARE_DISPATCH_MAP()
DECLARE_EVENT_MAP()
friend class TBaseWebContentListener;
friend class TWebBrowser;
friend class TWBDropTarget;
// Constructor
public:
TBaseWebBrowserPageletCtrl();
// Overrides
public:
#ifdef _DEBUG
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
virtual void OnResetState();
afx_msg void OnSize(UINT nType, int cx, int cy);
#endif // _DEBUG
afx_msg void OnDestroy();
virtual void DoPropExchange(CPropExchange* pPX);
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual void addListeners();
virtual void removeListeners();
// User messages
LRESULT OnSetContent(WPARAM , LPARAM);
LRESULT OnAddAnnotation(WPARAM , LPARAM);
LRESULT OnChangeAnnotationVisibility(WPARAM , LPARAM);
LRESULT OnReloadPage(WPARAM , LPARAM);
LRESULT OnRemovePage(WPARAM, LPARAM);
LRESULT OnLoadUrl(WPARAM, LPARAM);
LRESULT OnRedirect(WPARAM, LPARAM);
LRESULT OnRemoveSubBrowser(WPARAM, LPARAM);
LRESULT OnNeedDestroy(UINT, LONG);
STDMETHOD(OnNewBackWnd)(HWND hWnd);
void OnWebBrowserCommand(UINT nID);
void OnPageletNext();
void OnPageletPrevious();
void OnPageletViewInBrowser();
virtual BOOL NeedImageFit();
virtual BOOL NeedStretch();
virtual BOOL CanReload();
BOOL IsPostPage(TContentModel* = NULL);
// Implementation
protected:
virtual ~TBaseWebBrowserPageletCtrl();
void CreateBrowser();
void DestroyBrowser();
virtual LONG GetBrowserPos();
#ifdef ALLOW_PDF_FILE
HRESULT CheckPDFFile();
#endif // ALLOW_PDF_FILE
HTMLFocusPlacement FindRealActiveElementOnContent( IHTMLDocument2* pDocument );
HTMLFocusPlacement FindRealActiveElementOnFrame( IHTMLDocument2* pDocument );
// Sink maps
virtual void OnWebProgressChange(long Progress, long ProgressMax);
virtual void OnWebDownloadBegin();
virtual void OnWebDownloadComplete();
virtual void OnWebBeforeNavigate2(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel);
virtual void OnWebNavigateComplete2(LPDISPATCH pDisp, VARIANT FAR* URL);
virtual void OnWebDocumentComplete(LPDISPATCH pDisp, VARIANT FAR* URL);
virtual void OnWebStatusTextChange(LPCTSTR Text);
virtual void OnWebCommandStateChange(long Command, BOOL Enable);
virtual void OnWebTitleChange(LPCTSTR Text);
virtual void OnWebPropertyChange(LPCTSTR szProperty);
virtual void OnWebNewWindow2(LPDISPATCH FAR* ppDisp, BOOL FAR* Cancel);
virtual void OnWebQuit();
virtual void OnWebVisible(BOOL Visible);
virtual void OnWebToolBar(BOOL ToolBar);
virtual void OnWebMenuBar(BOOL MenuBar);
virtual void OnWebStatusBar(BOOL StatusBar);
virtual void OnWebFullScreen(BOOL FullScreen);
virtual void OnWebTheaterMode(BOOL TheaterMode);
virtual void OnWebMouseMove(short a, short b, long x, long y);
#ifdef SEARCH_FOR_HIDDEN_EVENT
virtual void OnEmpty();
virtual void OnBstr(LPCTSTR lString);
#endif // SEARCH_FOR_HIDDEN_EVENT
// Hook
virtual void beforeLoad();
virtual void OnModeChange(long pMode);
virtual void BeforeNavigate(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel);
virtual void Reload(long pRefreshForce);
void OnGetControlInfo(LPCONTROLINFO pControlInfo);
public:
STDMETHOD(OnNewPageModel)();
STDMETHOD(Hide)();
STDMETHOD(Show)();
STDMETHOD(PrintPage)( int nCmd);
STDMETHOD(Load)();
STDMETHOD(UserClick)();
STDMETHOD(TranslateUrl)(BSTR pUrl, BSTR* pUrlOut);
STDMETHOD(getUrl)(CString& pUrl);
virtual DWORD getNavigationFlags();
BEGIN_INTERFACE_PART(Highlight, IPageletHighlight)
STDMETHOD(HighlightSelection)(DWORD pColor);
STDMETHOD(RemoveSelectionHighlight)();
END_INTERFACE_PART(Highlight)
BEGIN_INTERFACE_PART(Sticker, IPageletSticker)
STDMETHOD(AddSticker)(DWORD pColor);
END_INTERFACE_PART(Sticker)
BEGIN_INTERFACE_PART(WebBrowser, IPageletWebBrowser)
STDMETHOD(get_SelectedText)( BSTR* pSelectedText );
STDMETHOD(FocusPlacement)(int*);
STDMETHOD(IsInternalPage)(BOOL* , BSTR* pType);
STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget);
STDMETHOD(UserClick)();
STDMETHOD(TranslateUrl)(BSTR pUrl, BSTR* pUrlOut);
END_INTERFACE_PART(WebBrowser)
public:
STDMETHOD(Stop)();
STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget);
#ifdef _DEBUG
virtual void ReportResult(long pResult);
#endif
TWebBrowser* GetWebBrowser() { return fWebBrowser; }
void hideAnnotation(BOOL pForce = FALSE);
void showAnnotation(BOOL pForce = FALSE);
BOOL NeedCreateNewPage(IWebBrowser2* pBrowser, BSTR, long, BSTR, VARIANT*, BSTR, BOOL* );
void CreateNewPage(IWebBrowser2* pBrowser, BSTR URL, long Flags, BSTR TargetFrameName, VARIANT* PostData, BSTR Headers);
void webAddTrashImage(IHTMLDocument2* pDocument);
void webAddAnnotations(BSTR pUrl);
void webUpdateContent(CString pUrl);
HRESULT MakeAnnotationInfo(TAnnotationModel* pAnnotation, IDomAnnotationInfo** pInfo);
HRESULT AddAnnotation(IWebBrowserTreeNode* pNode, TAnnotationModel* pAnnotation, BOOL = TRUE);
HRESULT Highlight(long pColor);
HRESULT UpdateHighlight(IWebBrowserTreeNode* pNode);
HRESULT CreateSticker(CPoint pPosition, long pColor);
CString CheckTargetFrame(IWebBrowser2* pBrowser, CString pUrl, CString pTarget);
HRESULT CheckIsInternalPage(BSTR* pType);
HRESULT CheckMetaTags();
HRESULT CheckBaseHref(IHTMLDocument2* pDocument, LPCTSTR pUrl, BOOL* pBaseHref);
void webSaveSubContentsInDb(IWebBrowser2* pBrowser);
HRESULT doStretch(DWORD pFlags = PI_FORCE_ASYNC);
BOOL TryReloadForBmp(IWebBrowser2* pBrowser, LPCTSTR pUrl);
void InitFlags(IDispatch* = NULL);
void Navigate(LPCTSTR pUrl, DWORD pFlags = -1, LPCTSTR pTargetName = NULL, LPCTSTR pHeaders = NULL, LPVOID pPost = NULL);
// Special Case for Dynamic KeeBook
// Added in 2.2
HRESULT HookDynamicKeeBook(IWebBrowser2* pBrowser, BOOL* pCancel);
void LaunchExportDynamicKeeBook(BSTR pUrl, BSTR pCode);
virtual HTMLFocusPlacement FocusPlacement( void ); // [AC]
// Need a special test for IE 5.5
BOOL IsAutomaticRenavigation(BSTR*);
HRESULT GetMetaCollection(IHTMLElementCollection** pCollec, IHTMLDocument2* = NULL);
void ManageAnchorsEventSink(AdviseType adviseType);
HRESULT GetConnectionPoint(LPUNKNOWN pUnk, REFIID riid, LPCONNECTIONPOINT* ppCP);
// Picture Handler
// Added in 2.3
HRESULT CheckPicturePage(IHTMLDocument2* pDocument);
void RedirectTo(LPCTSTR pUrl, IWebBrowser2* pBrowser = NULL);
void RemoveBanner(CWnd* pBanner)
{
m_AdBannerList.Remove(pBanner);
m_ExternalAdBanner--;
}
public:
BOOL m_bFirstNavigate:2;
BOOL m_bUserClick:2;
BOOL m_bInDocumentComplete:2;
BOOL m_bDoStretch:2;
BOOL m_bDynamicPage:2;
BOOL m_bDoImageFit:2;
BOOL m_bFullStaticKeeBook:2;
protected:
TWebBrowser* fWebBrowser;
TBaseWebContentListener* fContentListener;
TBaseWebBrowserEvents* m_pEvents;
CString m_InitialUrl;
CString m_CurrentUrl;
long m_RefreshForce;
DWORD m_StretchFlags;
WORD m_ExternalAdBanner;
WORD m_NavigateCount;
CComObject* m_pDropTarget;
CComPtr m_DropTarget;
CComPtr m_pNetStatus;
CComPtr m_RootDispatch;
CComPtr m_SoftReloadTree;
CComPtr m_BrowserTree;
#if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL)
CComPtr m_BeforeTree;
#endif
CSimpleArray m_NavigatingFramesList;
CSimpleArray m_AdBannerList;
stack _stackAnchorCookies;
// Cannot use a bit field for this one,
// has it is passed by reference in function call
TWebBrowserStretchSink* m_StretchSink;
#ifdef ALLOW_PDF_FILE
CComDispatchDriver m_PdfObject;
#endif // ALLOW_PDF_FILE
BOOL m_bRedirected:2;
BOOL m_bIsCreated:2;
BOOL m_bReload:2;
BOOL m_bReloadForBmp:2;
BOOL m_bAnnotationAllowed:2;
BOOL m_bStoreTitle:2;
BOOL m_bPictureChecked:2;
BOOL m_bNoStretch:2;
BOOL m_bCanceling:2;
BOOL m_bNeedReload:2;
BOOL m_bStopReload:2;
};
#endif // T_BASE_WEBBROWSER_PAGELET_CTL/*------------ TBrowserModeView.cpp ------------*/
#include "StdAfx.h"
#include "TBrowserModeView.h"
#include "TLibraryModeView.h"
#include "PropertyChangeEvent.h"
#include "TContextModel.h"
#include "TModelNames.h"
#include "TMetaManager.h"
#include "TMediaLibraryModel.h"
#include "TPageModel.h"
#include "TUserMessage.h"
#include "TBookModel.h"
#include "TPageModel.h"
#include "TMain.h"
#include "BackGround.h"
#include "TCustomPalette.h"
#include "BookBrowser.h"
#include "PrintingCmd.h"
#include "TSoundManager.h"
#include "SharedSoundAndFeelRes.h"
#include "ArrowBand.h"
// *** TO DO : remove --- TEST DRAWING ON MODE VIEW
#include "TPageEditor.h"
#include "Pagelet.h"
#include "Controler.h"
#include "ResBookMode.h"
#include "SharedResource.h"
#include "SharedLookAndFeelRes.h"
#include "LookHelpMapId.h"
IMPLEMENT_DYNAMIC(TBrowserModeView, TBooxView)
BEGIN_MESSAGE_MAP(TBrowserModeView, TBooxView)
//{{AFX_MSG_MAP(TBrowserModeView)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_COMMAND(IDA_BOOK_NEXT_PAGE, OnBookNextPage)
ON_COMMAND(IDA_BOOK_PREV_PAGE, OnBookPrevPage)
ON_COMMAND(IDA_BOOK_SUMMARY, OnBookSummary)
ON_COMMAND(IDA_BOOK_INDEX, OnBookIndex)
ON_COMMAND(IDA_BOOK_NEXT_CHAPTER, OnBookNextChapter)
ON_COMMAND(IDA_BOOK_PREV_CHAPTER, OnBookPrevChapter)
ON_COMMAND(IDA_PAGE_PARENT_CHAPTER, OnPageParentChapter)
ON_COMMAND(IDA_PAGE_FIRST_SUB_CHAPTER, OnPageFirstSubChapter)
ON_COMMAND(IDA_DOC_SCROLL_UP, OnDocScrollUp)
ON_COMMAND(IDA_DOC_SCROLL_DOWN, OnDocScrollDown)
ON_COMMAND(IDA_DOC_PAGE_UP, OnDocPageUp)
ON_COMMAND(IDA_DOC_PAGE_DOWN, OnDocPageDown)
ON_COMMAND(IDA_DOC_BEGIN, OnDocBegin)
ON_COMMAND(IDA_DOC_END, OnDocEnd)
ON_COMMAND(IDA_NAVIGATE, OnFileNavigate)
ON_COMMAND(IDA_SEARCH, OnEditFind)
ON_COMMAND(IDA_HIGHLIGHTER, OnEditHighlighter)
ON_COMMAND(IDA_STICKER, OnEditSticker)
ON_COMMAND(IDM_FILE_NAVIGATE, OnFileNavigate)
ON_COMMAND(IDM_VIEW_URL, OnFileNavigate)
ON_COMMAND(IDM_FILE_NEWDOC, OnNewDoc)
ON_COMMAND(IDM_FILE_CLOSE, OnCloseBook)
ON_COMMAND(IDM_EDIT_HIGHLIGHT, OnEditHighlighter)
ON_COMMAND(IDM_EDIT_STICKER, OnEditSticker)
ON_COMMAND(IDM_EDIT_MODIFY, OnEditModify)
ON_COMMAND(IDM_FILE_PRINT, OnFilePrint)
ON_COMMAND(IDA_PRINT, OnFilePrint)
ON_COMMAND(IDM_EDIT_FIND, OnEditFind)
ON_COMMAND(IDM_EDIT_PAGEFIND, OnEditPageFind)
ON_COMMAND(IDM_EDIT_BOOKFIND, OnEditBookFind)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//
// TBrowserModeView Constructor
//
TBrowserModeView::TBrowserModeView()
: TBooxView()
{
m_pBackGround = NULL;
m_pBookBrowser = NULL;
m_NewBrowser = FALSE;
m_FirstActivation = TRUE;
// --- initialize resource Id
m_nIdIcon = IDI_BOOK_ICON;
m_nIdTitle = IDS_BOOK_TITLE;
m_nModeView = T_BOOK_MODE;
// --- initialize contextuel help
static const DWORD dwTabHelpIds[] =
{
AFX_IDW_PANE_FIRST, HIDC_MAIN_MODE_BOOK,
0, 0
};
m_pDwHelpIds = (DWORD *) dwTabHelpIds;
m_ContextListener = NULL;
m_pContextControl.CoCreateInstance(CLSID_TContextControler);
ASSERT(m_pContextControl);
}
//
// TBrowserModeView Destructor
//
TBrowserModeView::~TBrowserModeView()
{
if (m_ContextListener)
{
// *** Verify global context exists
ASSERT(TContextModel::gContext);
// *** Subscribe to context listener
TContextModel::gContext->removePropertyChangeListener(m_ContextListener);
m_ContextListener->setInvalid();
m_ContextListener = NULL;
}
}
// ************************************************************************************************
int TBrowserModeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
int result;
if ((result = TBooxView::OnCreate(lpCreateStruct)) != 0)
return result;
createContextListener();
if (m_ContextListener)
{
// *** Verify global context exists
ASSERT(TContextModel::gContext);
// *** Subscribe to context listener
TContextModel::gContext->addPropertyChangeListener(m_ContextListener);
}
m_pBookControler.CoCreateInstance(CLSID_TBookControler);
ASSERT(m_pBookControler);
if (m_pBookControler == NULL)
{
DestroyWindow();
return -1;
}
m_pBookControler->RegisterAsListener();
CDC* lDC = GetDC();
ASSERT_VALID(lDC);
setDCMappingMode(lDC);
createBookBrowser(lDC);
createArrowBand(lDC);
ReleaseDC(lDC);
CheckBook();
VERIFY(m_OleDropTarget.Register(this));
return result;
}
// ************************************************************************************************
void TBrowserModeView::OnDestroy()
{
m_OleDropTarget.Revoke();
TBooxView::OnDestroy();
}
// ************************************************************************************************
void TBrowserModeView::createArrowBand(CDC* pDC)
{
CSize lSize;
// --- Arrow Band
CRect lArrowBandRect(CPoint(m_BookBrowserLogicalRect.left, m_BookBrowserLogicalRect.bottom), m_ArrowBandSize);
TArrowBand* lArrowBand = new TArrowBand();
lArrowBand->setArrow(T_PRIMARY, m_pPrimaryArrow);
lArrowBand->setArrow(T_SECONDARY, m_pSecondaryArrow);
lArrowBand->setArrowLogicalRect(T_PRIMARY, m_PrimaryArrowLogicalRect);
lArrowBand->setArrowLogicalRect(T_SECONDARY, m_SecondaryArrowLogicalRect);
ASSERT(m_pBookControler);
lArrowBand->setBookControler(m_pBookControler);
lSize = lArrowBandRect.Size();
lArrowBand->setLogicalSpace(lSize);
lArrowBand->setLogicalPoint(lArrowBandRect.TopLeft());
lArrowBand->setLogicalSize(lSize);
// --- CtrlID may be change by the HtmlHelpHook
lArrowBand->Create(NULL, NULL, WS_CHILD | WS_VISIBLE, lArrowBandRect, this, 0);
addChild(lArrowBand);
lArrowBand->logicalResizeAndPos(pDC);
lArrowBand->setViewToRefresh(this);
}
void TBrowserModeView::createBookBrowser(CDC* pDC)
{
// *** Create the book browser
if (m_pBookBrowser == NULL)
{
m_pBookBrowser = new TBookBrowser();
m_NewBrowser = TRUE;
}
ASSERT(m_pBookControler);
m_pBookBrowser->setBookControler(m_pBookControler);
CSize lSize;
lSize = m_BookBrowserLogicalRect.Size();
m_pBookBrowser->setLogicalPoint(m_BookBrowserLogicalRect.TopLeft());
m_pBookBrowser->setLogicalSize(lSize);
if (m_NewBrowser)
{
m_pBookBrowser->Create(NULL, NULL, WS_CHILD | WS_VISIBLE, CRect(CPoint(0, 0), getLogicalSize()), this, 0);
}
else
{
m_pBookBrowser->SetParent(this);
}
m_pBookBrowser->PostMessage(ID_UM_CHANGE_ACTIVE_VIEW, GetActiveMode());
addChild(m_pBookBrowser);
m_pBookBrowser->logicalResizeAndPos(pDC);
// m_pBookBrowser->setViewToRefresh(this);
}
// ----------------------------------------------------------------------
// afx message handler
void TBrowserModeView::OnFilePrint()
{
TPageEditor* lPageEditor;
lPageEditor = getSelectedPageEditor();
ASSERT(lPageEditor);
if (lPageEditor)
{
lPageEditor->printPage( CPrintingCmd::PROMPT_USER);
}
}
void TBrowserModeView::OnPrint( CDC* pDC, CPrintInfo* pInfo )
{
ASSERT_VALID(pDC);
OnFilePrint();
}
void TBrowserModeView::OnEditPageFind()
{
TPageEditor* lPageEditor;
TModelPtr lPage;
lPageEditor = getSelectedPageEditor();
lPage = lPageEditor->getPage();
// Try to show Search view
IUnknown* lUnk = lPageEditor->getPageletControl();
BOOL lResult = FALSE;
CComQIPtr lPagelet(lUnk);
if (lPagelet)
{
if (lPagelet->ShowSearch() == S_OK)
lResult = TRUE;
}
}
void TBrowserModeView::OnEditBookFind()
{
// --- put in the page mode
TContextModel::gContext->setCurrentModeNumber( T_PAGE_MODE);
m_pBookControler->ChangePageTo(T_CPT_INDEX, T_SIDE_SECONDARY, CComVariant(1));
}
void TBrowserModeView::OnEditFind()
{
TPageEditor* lPageEditor;
TModelPtr lPage;
lPageEditor = getSelectedPageEditor();
lPage = lPageEditor->getPage();
if( lPage == NULL || lPage->isInstanceOf(T_INDEX_MODEL_NAME))
{
// Go to Thesaurus
TModelPtr lCatalogBook;
TModelPtr mlm;
mlm = (TMediaLibraryModel *)TMetaManager::createModelInstance(T_MEDIA_LIBRARY_MODEL_NAME);
lCatalogBook = (TBookModel*)mlm->getSpecialMediumInLibrary(TMediaLibraryModel::E_CATALOG_BOOK);
if (lCatalogBook)
{
CComPtr lBookControler;
lBookControler.CoCreateInstance(CLSID_TBookControler);
// --- put in the page mode
TContextModel::gContext->setCurrentModeNumber( T_PAGE_MODE);
lBookControler->put_book((long)lCatalogBook.p);
lBookControler->ChangePageTo(T_CPT_INDEX, T_SIDE_SECONDARY, CComVariant(1));
TContextModel::gContext->setCurrentBook(lCatalogBook);
}
}
else
{
// Try to show Search view
IUnknown* lUnk = lPageEditor->getPageletControl();
BOOL lResult = FALSE;
CComQIPtr lPagelet(lUnk);
if (lPagelet)
{
if (lPagelet->ShowSearch() == S_OK)
lResult = TRUE;
}
// If show search fail,
// search is already shown
// so go to index page
if (!lResult)
{
// --- put in the page mode
TContextModel::gContext->setCurrentModeNumber( T_PAGE_MODE);
m_pBookControler->ChangePageTo(T_CPT_INDEX, T_SIDE_SECONDARY, CComVariant(1));
}
}
}
void TBrowserModeView::OnBookNextPage()
{
m_pBookControler->ChangePageTo(T_CPT_NEXT_PAGE, T_SIDE_SECONDARY, CComVariant(1));
}
void TBrowserModeView::OnBookPrevPage()
{
m_pBookControler->ChangePageTo(T_CPT_PREV_PAGE, T_SIDE_PRIMARY, CComVariant(1));
}
void TBrowserModeView::OnBookSummary()
{
m_pBookControler->ChangePageTo(T_CPT_SUMMARY, T_SIDE_SECONDARY, CComVariant(1));
}
void TBrowserModeView::OnBookIndex()
{
m_pBookControler->ChangePageTo(T_CPT_INDEX, T_SIDE_SECONDARY, CComVariant(1));
}
void TBrowserModeView::OnBookNextChapter()
{
m_pBookControler->ChangePageTo(T_CPT_NEXT_IN_HIERARCHIE, T_SIDE_SECONDARY, CComVariant(1));
}
void TBrowserModeView::OnBookPrevChapter()
{
m_pBookControler->ChangePageTo(T_CPT_PREV_IN_HIERARCHIE, T_SIDE_PRIMARY, CComVariant(1));
}
void TBrowserModeView::OnPageParentChapter()
{
m_pBookControler->ChangePageTo(T_CPT_PARENT_CHAPTER, T_SIDE_PRIMARY, CComVariant(1));
}
void TBrowserModeView::OnPageFirstSubChapter()
{
m_pBookControler->ChangePageTo(T_CPT_FIRST_SUB_CHAPTER, T_SIDE_SECONDARY, CComVariant(1));
}
void TBrowserModeView::OnDocScrollUp()
{
// TODO: Add your command handler code here
TRACE("TBrowserModeView::DocScrollUp\n");
}
void TBrowserModeView::OnDocScrollDown()
{
// TODO: Add your command handler code here
TRACE("TBrowserModeView::DocScrollDown\n");
}
void TBrowserModeView::OnDocPageUp()
{
// TODO: Add your command handler code here
TRACE("TBrowserModeView::DocPageUp\n");
}
void TBrowserModeView::OnDocPageDown()
{
// TODO: Add your command handler code here
TRACE("TBrowserModeView::DocPageDown\n");
}
void TBrowserModeView::OnDocBegin()
{
// TODO: Add your command handler code here
TRACE("TBrowserModeView::DocBegin\n");
}
void TBrowserModeView::OnDocEnd()
{
// TODO: Add your command handler code here
TRACE("TBrowserModeView::DocEnd\n");
}
void TBrowserModeView::OnNewHighlighter( WORD wFilter)
{
TPageEditor* lPageEditor;
lPageEditor = getSelectedPageEditor();
newHighlighter(lPageEditor, wFilter);
}
void TBrowserModeView::OnNewSticker( WORD wFilter)
{
TPageEditor* lPageEditor;
lPageEditor = getSelectedPageEditor();
newSticker(lPageEditor, wFilter);
}
void TBrowserModeView::SetOldBooxView(TBooxView* pView)
{
if (pView->IsKindOf(RUNTIME_CLASS(TBrowserModeView)))
{
m_pBookBrowser = ((TBrowserModeView*)pView)->getBookBrowser();
}
if (pView->IsKindOf(RUNTIME_CLASS(TLibraryModeView)))
{
m_pBookBrowser = ((TLibraryModeView*)pView)->getBookBrowser();
if (m_pBookBrowser)
{
TModelPtr lBook;
TContextModel::gContext->getCurrentBook(&lBook);
m_pBookBrowser->setBook(lBook);
}
}
}
void TBrowserModeView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView )
{
/*
TBooxView::OnActivateView(bActivate, pActivateView, pDeactiveView );
if (m_pBookBrowser && bActivate)
{
if (m_FirstActivation)
{
m_pBookBrowser->ModeChange(GetActiveMode());
m_FirstActivation = FALSE;
}
}
*/
}
HRESULT TBrowserModeView::ChangeBook(TBookModel* pBook)
{
if (m_pBookBrowser)
{
if (pBook)
pBook->AddRef();
m_pBookBrowser->PostMessage(WM_USER_CHANGE_BOOK, (WPARAM)pBook);
return S_OK;
}
return S_FALSE;
}
void TBrowserModeView::CheckBook()
{
TModelPtr lCurrentBook;
TContextModel::gContext->getCurrentBook(&lCurrentBook);
if (lCurrentBook && m_NewBrowser && !TContextModel::gContext->isBeforeFire())
{
ChangeBook(lCurrentBook);
}
}
void TBrowserModeView::createContextListener()
{
}
TPageEditor* TBrowserModeView::getSelectedPageEditor()
{
ASSERT(m_pBookBrowser);
return m_pBookBrowser->getSelectedPageEditor();
}
void TBrowserModeView::OnSetFocus(CWnd* pOldWnd)
{
if( TCustomPalette::m_pPalette)
{
m_pBookBrowser->getPageEditor(T_PRIMARY)->Invalidate();
m_pBookBrowser->getPageEditor(T_SECONDARY)->Invalidate();
}
}
/*------------ TPageEditor.cpp ------------*/
#include "StdAfx.h"
// *** MAIN INCLUDE
#include "TPageEditor.h"
// *** OTHER INCLUDE
#include "TChapterModel.h"
#include "TContextModel.h"
#include "TContentModel.h"
#include "TAnnotationModel.h"
#include "TBookModel.h"
#include "TIndexModel.h"
#include "TPageModel.h"
#include "TSummaryModel.h"
#include "TModelIterator.h"
#include "TModelNames.h"
#include "TModelHelpers.h"
#include "TMetaManager.h"
#include "TPropertyObjectModel.h"
#include "BackGround.h"
#include "BookBrowser.h"
#include "TBrowseDir.h"
//#include "CreateBookWizard.h"
#include "DragAndDropPageData.h"
#include "TOleDataObject.h"
#include "NameEdit.h"
#include "NameStatic.h"
#include "PageletToolbar.h"
#include "PropertyChangeEvent.h"
#include "SharedLookAndFeelRes.h"
#include "TabsViewer.h"
#include "TBooxFrame.h"
#include "TGlobalsDB.h"
#include "TPageletContainerView.h"
#include "TPageletViewManager.h"
#include "TPagePropertiesConstants.h"
#include "TPropertyObjectModel.h"
#include "Dib.h"
#include "IconView.h"
#include "IconView.h"
#include "ResButtonInfo.h"
#include "ProgressDlg.h"
#include "TUrl.h"
#include "TTFont.h"
#include "MemDC.h"
#include "TString.h"
#include "TCustomPalette.h"
#include "InPlaceEdit.h"
#include "PrintingEngine.h"
#include "TSoundManager.h"
#include "SharedSoundAndFeelRes.h"
#include "SharedLookAndFeelRes.h"
#include "SharedResource.h"
#include "TShellUtils.h"
#include "Controler.h"
#include "TUserMessage.h"
//#define ID_NAME_EDIT 100
// TEMP
// this is the space betwen the binding and the page
#define T_BINDING_MARGE 5
#define T_TITLE_MARGIN 8
#define T_TITLE_HEIGHT (29 + T_TITLE_MARGIN)
#define TIMER_EDIT_TITLE 1
class TPEBookListener : public TPropertyChangeListener
{
TPageEditor* m_pPageEditor;
public:
TPEBookListener(TPageEditor* pPageEditor);
~TPEBookListener();
virtual void propertyChange(TPropertyChangeEvent *evt);
};
class TPEPageListener : public TPropertyChangeListener
{
TPageEditor* m_pPageEditor;
public:
TPEPageListener(TPageEditor* pPageEditor);
~TPEPageListener();
virtual void propertyChange(TPropertyChangeEvent *evt);
};
#define IDC_EDIT_INPLACE 100
// ************************************************************************************************
IMPLEMENT_DYNAMIC(TPageEditor, TWnd)
// *** Message map
BEGIN_MESSAGE_MAP(TPageEditor, TWnd)
//{{AFX_MSG_MAP(CChildFrame)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_CTLCOLOR()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDBLCLK()
ON_WM_SIZE()
ON_WM_TIMER()
ON_WM_SETFOCUS()
ON_WM_MOUSEACTIVATE()
ON_EN_KILLFOCUS( IDC_EDIT_INPLACE, OnEnKillFocus)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_USER_UPDATE_TITLE, OnUpdateTitle)
ON_MESSAGE(WM_USER_REMOVE_CHILD, OnRemoveChild)
ON_MESSAGE(WM_USER_REFRESH_PAGE_CONTENT, OnRefreshPageContent)
END_MESSAGE_MAP()
// ************************************************************************************************
// *** PageEditor Constructor
TPageEditor::TPageEditor()
: TWnd(),
fNeedTabBody(FALSE),
fShowContent(TRUE),
fFlying(FALSE),
fSelected(TRUE),
fIsIndex(FALSE),
fIsSummary(FALSE),
fIsProperty(FALSE),
fIsChapter(FALSE),
m_Side(T_SECONDARY),
m_pBkgnd(NULL),
m_pTopBkgnd(NULL),
m_pTitleBkgnd(NULL),
fPageListener(NULL),
fBookListener(NULL),
m_PageView(NULL),
fPageIndex(-1),
fTabIndex(0),
m_HaveToolbar(FALSE),
m_pBookBrowser(NULL),
m_bIsAlreadySelected( FALSE),
m_TabsViewerComputed(FALSE),
m_InMouseDown(FALSE),
m_JustCloseEdit(FALSE),
#ifdef DO_NOT_DISPLAY_AUTHOR_TITLE
m_bIsAuthorPage(FALSE),
#endif // DO_NOT_DISPLAY_AUTHOR_TITLE
m_pInPlaceEditCtrl(NULL),
m_pTitleFont(NULL),
m_pNumberFont(NULL),
m_BackBrushID(0),
m_BkColor(0),
m_Behaviour(0),
m_pPrintingEngine(NULL),
fPageCount(0)
{
initResources();
m_TitleRect.SetRectEmpty();
setOpaque(true);
m_bIsDblClk = false;
m_TitleNormalColor = RGB(0,0,0);
m_TitleSelectedColor = RGB(0,0,0);
}
// ************************************************************************************************
// *** PageEditor Destructor
TPageEditor::~TPageEditor()
{
exitResources();
// *** Delete pagelet manager
// if (fPageletManager)
// delete fPageletManager;
removePage();
}
// ************************************************************************************************
int TPageEditor::OnCreate(LPCREATESTRUCT lpCreateStruct )
{
if (TWnd::OnCreate(lpCreateStruct) == -1)
return -1;
addToolTip();
m_xLogicalSpaceConstraint.fThis = this;
// *** Create and select font
// m_pTitleFont = new CTTFont( IDS_FONT_PAGE_TITLE);
// VERIFY( m_pTitleFont->CreateFontFromString());
return 0;
}
// ************************************************************************************************
void TPageEditor::OnDestroy( )
{
// --- if the tooltips control is not yet deleted
CToolTipCtrl* pToolTip = TBooxFrame::GetToolTip();
if( pToolTip && ::IsWindow( pToolTip->m_hWnd) )
{
// --- remove this from the tooltip list
// pToolTip->DelTool( this);
}
delete m_pTopBkgnd;
m_pTopBkgnd = NULL;
delete m_pBkgnd;
m_pBkgnd = NULL;
delete m_pTitleBkgnd;
m_pTitleBkgnd = NULL;
delete m_pTitleFont;
m_pTitleFont = NULL;
delete m_pNumberFont;
m_pNumberFont = NULL;
removePageletView();
TWnd::OnDestroy();
}
// ************************************************************************************************
void TPageEditor::addToolTip()
{
CToolTipCtrl* pToolTip = TBooxFrame::GetToolTip();
if( pToolTip)
{
/*
CRect lDeviceRect;
GetClientRect(&lDeviceRect);
CRect lClientRect;
GetClientRect(&lClientRect);
lDeviceRect.left += T_BINDING_MARGE;
lDeviceRect.right -= T_BINDING_MARGE;
CRect lLogicalRect = lDeviceRect;
DPtoLP(&lLogicalRect);
long lWidth;
lWidth = GetPageNumberWidth(pDC);
if (getPageSide() == T_SECONDARY)
lLogicalRect.left = lLogicalRect.right - lWidth;
else
lLogicalRect.right = lLogicalRect.left + lWidth;
lLogicalRect.bottom = lLogicalRect.top + gTitleBkgnd->getHeight();
LPtoDP(&lLogicalRect);
pToolTip->AddTool( this, "Ici, bientôt le numéro de la page...", &lClientRect, 2123);
*/
}
}
// ************************************************************************************************
void TPageEditor::excludeCustomRgn(CDC* pDC, CWnd* pWndTo)
{
if (m_PageView)
{
//m_PageView->excludeCustomRgn(pDC, pWndTo);
/*
ATLASSERT(pDC->GetSafeHdc());
ATLASSERT(pWndTo->GetSafeHwnd());
CRect lRect = CRect(m_PageView->getLogicalPoint(), m_PageView->getLogicalSize());
MapWindowPoints(pWndTo, &lRect);
//pDC->Rectangle(lRect);
if (pDC->RectVisible(lRect))
{
TRACE(" *** TPageEditor::excludeCustomRgn lRect t %d, l %d, b %d, r %d\n",
lRect.top, lRect.left, lRect.bottom, lRect.right);
pDC->ExcludeClipRect(lRect);
}
*/
}
}
// ************************************************************************************************
t_view_mode TPageEditor::getMode()
{
return (t_view_mode) TBooxFrame::GetActiveMode();
}
// ************************************************************************************************
STDMETHODIMP TPageEditorConstraint::ConstraintLogicalResize(HDC pDC)
{
if (fThis)
{
((TPageEditor*)fThis)->constraintLogicalResize();
return S_OK;
}
return S_FALSE;
}
// ************************************************************************************************
LPUNKNOWN TPageEditor::GetInterfaceHook(const void* piid)
{
if (InlineIsEqualGUID(*(GUID*)piid, IID_ILogicalSpaceConstraint))
return &m_xLogicalSpaceConstraint;
return TWnd::GetInterfaceHook(piid);
}
// *** Overrides logicalResizeAndPos from TView because we need to set constraints
void TPageEditor::constraintLogicalResize()
{
}
void TPageEditor::logicalResizeAndPos(CDC* pDC)
{
logicalResize(pDC);
if (m_pBookBrowser)
{
/*
if ((getPageSide() == T_SECONDARY) && (!fFlying))
{
TPageEditor* lPage = m_pBookBrowser->getPrimaryPageEditor();
getDevicePoint().x = lPage->getDevicePoint().x + lPage->getDeviceSize().cx;
}
*/
}
setLogicalWindowPos();
}
// ************************************************************************************************
void TPageEditor::OnSetFocus( CWnd* pOldWnd )
{
TWnd::OnSetFocus(pOldWnd);
}
// ************************************************************************************************
void TPageEditor::OnMouseActivate( CWnd* pDesktopWnd, UINT nHitTest, UINT message )
{
ATLASSERT(m_pBookBrowser);
if (m_pBookBrowser)
{
CComPtr lBookControler;
m_pBookBrowser->getBookControler(&lBookControler);
ATLASSERT(lBookControler);
if (lBookControler)
{
ePageSide2 lSide;
lSide = m_Side == T_PRIMARY ? T_SIDE_PRIMARY : T_SIDE_SECONDARY;
lBookControler->ChangePageTo(T_CPT_SELECTED_PAGE, lSide, CComVariant(1));
}
}
TWnd::OnMouseActivate(pDesktopWnd, nHitTest, message );
}
// ************************************************************************************************
void TPageEditor::OnLButtonDown( UINT nFlags, CPoint point)
{
TRACE("TPageEditor::OnLButtonDown\n");
m_InMouseDown = TRUE;
m_bIsDblClk = false;
TWnd::OnLButtonDown( nFlags, point);
m_bIsAlreadySelected = fSelected;
if( !onBeginDragPage())
{
// --- generate a button up, because DoDragDrop eat it
PostMessage( WM_LBUTTONUP, (WPARAM) nFlags, MAKELPARAM( point.x, point.y));
}
}
void TPageEditor::OnLButtonDblClk( UINT nFlags, CPoint point )
{
TRACE( _T("*** TPageEditor::OnLButtonDblClk\n"));
m_bIsDblClk = true;
CRect lRect;
lRect = m_TitleRect;
LPtoDP(&lRect);
if (lRect.PtInRect(point))
{
if (TContextModel::gContext->getCurrentModeNumber() == T_BOOK_STAND_MODE)
TContextModel::gContext->setCurrentModeNumber(T_BOOK_MODE);
else if (TContextModel::gContext->getCurrentModeNumber() == T_BOOK_MODE)
TContextModel::gContext->setCurrentModeNumber(T_PAGE_MODE);
}
}
void TPageEditor::OnLButtonUp( UINT nFlags, CPoint point)
{
TRACE("TPageEditor::OnLButtonUp\n");
m_InMouseDown = FALSE;
TWnd::OnLButtonUp( nFlags, point);
// --- if no drag and drop made, check for edition
CRect rectTitle( CPoint(0, 0), CSize (getLogicalSize().cx, T_TITLE_HEIGHT));
LPtoDP(&rectTitle);
if( m_bIsAlreadySelected && rectTitle.PtInRect( point))
{
// --- put in selected mode
if( isSummary() || isIndex() || isPropertyPage() || ::IsSystem< TPageModel>( m_Page))
{
TSoundManager::PlayFromResource( IDSOUND_ALERT);
}
else
{
if (!m_JustCloseEdit)
{
TRACE("TPageEditor::OnLButtonUp Call SetTimer(TIMER_EDIT_TITLE)\n");
// --- delay the edition in case where a double click follow
if( SetTimer( TIMER_EDIT_TITLE, 500, NULL) != TIMER_EDIT_TITLE)
{
// --- no more timer is available, so edit immediatly
EditTitle();
}
}
}
}
m_JustCloseEdit = FALSE;
}
// ************************************************************************************************
TBackGround* TPageEditor::getBkgnd()
{
if (!isFlying())
return m_pBkgnd;
return m_pBkgnd;
}
// ************************************************************************************************
BOOL TPageEditor::canSetPage(TPageModel* pPage, BOOL pForced)
{
BOOL lCanSetPage = FALSE;
if ((m_Page != pPage) || pForced)
lCanSetPage = TRUE;
ATLASSERT(m_pBookBrowser);
if (m_pBookBrowser == NULL)
return lCanSetPage;
lCanSetPage = lCanSetPage && (m_pBookBrowser->getBook() || (pPage == NULL));
if (m_pBookBrowser->GetSupportFlying())
lCanSetPage = lCanSetPage && !m_pBookBrowser->isFlying(pPage);
return lCanSetPage;
}
void TPageEditor::refreshPageContent()
{
if (m_pBookBrowser)
{
if (fShowContent && IsWindowVisible())
refresh();
loadPagelet();
m_JustCloseEdit = FALSE;
// SetDlgItemText(ID_NAME_EDIT, m_Page->getTitle());
}
}
void TPageEditor::getPageletLogicalRect(CRect& pRect)
{
CRect lDeviceContentRect;
GetClientRect(&lDeviceContentRect);
CRect lLogicalContentRect = lDeviceContentRect;
DPtoLP(&lLogicalContentRect);
#ifdef DO_NOT_DISPLAY_AUTHOR_TITLE
if (!m_bIsAuthorPage)
#endif // DO_NOT_DISPLAY_AUTHOR_TITLE
lLogicalContentRect.top += T_TITLE_HEIGHT;
// lLogicalContentRect.bottom -= 5;
// lLogicalContentRect.right -= 3;
pRect = lLogicalContentRect;
if (fNeedTabBody)
{
long lBobyWidth = 0;
lBobyWidth = TTabsViewer::gTabBodyLeft->getWidth();
if (getPageSide() == T_PRIMARY)
pRect.left += lBobyWidth;
else
pRect.right -= lBobyWidth;
}
}
// ************************************************************************************************
void TPageEditor::Select(BOOL pActive)
{
if (fSelected != pActive)
{
fSelected = pActive;
if (IsWindowVisible())
{
// *** Refresh title bar
CRect lTitleRect(CPoint(0, 0), CSize (getLogicalSize().cx, T_TITLE_HEIGHT));
LPtoDP(&lTitleRect);
refresh(&lTitleRect);
}
}
// *** If the page is active, we need to update the context
// *** Should always be done, even if the page stay in the same state
}
// ************************************************************************************************
void TPageEditor::setPageViewParent(TPageModel* pPage)
{
TPageletContainerView* lPagelet = getPageletManager()->findPageletViewFor(pPage);
if (lPagelet)
{
TWnd* lView = (TWnd*) lPagelet->GetParent();
ATLASSERT(lView-IsKindOf(RUNTIME_CLASS(TWnd)));
lView->removeChild(lPagelet);
lPagelet->SetParent(this);
m_PageView = lPagelet;
addChild(lPagelet);
}
}
// ************************************************************************************************
// *** EVENTS HANDLER ON PAGE PROPERTIES CHANGE
// ************************************************************************************************
// ************************************************************************************************
void TPageEditor::sendEvent(LPCTSTR pEvt)
{
}
// ************************************************************************************************
TPageletViewManager* TPageEditor::getPageletManager()
{
TPageletViewManager* lManager;
lManager = m_pBookBrowser->getPageletManager();
ATLASSERT(lManager);
return lManager;
}
// ************************************************************************************************
// ************************************************************************************************
void TPageEditor::initResources()
{
}
// ************************************************************************************************
void TPageEditor::exitResources()
{
delete m_pTitleBkgnd; m_pTitleBkgnd = NULL;
}
BOOL TPageEditor::RectVisible(CDC* pDC, LPRECT pRect)
{
/*
CRect lRect;
if (m_pPaintStruct)
lRect = m_pPaintStruct->rcPaint;
else
GetClientRect(&lRect);
// TRACE("(x:%d, y:%d, w:%d, h:%d)\n", lRect.left, lRect.top, lRect.Width(), lRect.Height());
lRect.IntersectRect(pRect, lRect);
return !lRect.IsRectEmpty();
*/
return TRUE; // pDC->RectVisible(pRect);
}
// ************************************************************************************************
void TPageEditor::OnDraw(CDC* pDC)
{
ATLASSERT(pDC->GetSafeHdc());
#ifndef DRAW_ON_BACKGROUND
drawBookSheet(pDC);
#endif
if (m_Page)
{
CRect lTitleRect;
GetTitleRect( lTitleRect);
#ifdef DO_NOT_DISPLAY_AUTHOR_TITLE_TEXT
if (!fIsProperty)
#endif DO_NOT_DISPLAY_AUTHOR_TITLE_TEXT
if (!lTitleRect.IsRectEmpty() && RectVisible(pDC, lTitleRect))
drawTitle(pDC, &lTitleRect);
if (fNeedTabBody)
{
TBackGround* lTabBodyBack;
CRect lTabBodyRect;
lTabBodyBack = GetTabBody();
lTabBodyRect = GetTabBodyRect(lTabBodyBack);
if (lTabBodyBack && RectVisible(pDC, &lTabBodyRect))
drawTabBody(pDC, lTabBodyBack, &lTabBodyRect);
}
CRect lPageNumberRect;
GetPageNumRect(lPageNumberRect);
if (RectVisible(pDC, &lPageNumberRect))
drawPageNumber(pDC, &lPageNumberRect);
}
/*
#ifdef DEBUG_BOOK_WND_POSITION
CRect lRect;
GetClientRect(&lRect);
pDC->DPtoLP(&lRect);
pDC->FrameRect(lRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
#endif
*/
}
// ************************************************************************************************
void TPageEditor::GetTitleRect( CRect& rect)
{
#ifdef DO_NOT_DISPLAY_AUTHOR_TITLE
if (m_bIsAuthorPage)
{
rect.SetRectEmpty();
return ;
}
#endif // DO_NOT_DISPLAY_AUTHOR_TITLE
GetClientRect( &rect);
long lWidth;
lWidth = GetPageNumberWidth();
DPtoLP(&rect);
if (getPageSide() == T_PRIMARY)
rect.left += lWidth;
else
rect.right -= lWidth;
rect.left += T_BINDING_MARGE;
rect.right -= T_BINDING_MARGE;
rect.top = T_TITLE_MARGIN;
rect.bottom = T_TITLE_HEIGHT;
LPtoDP(&rect);
}
void TPageEditor::drawTitle(CDC* pDC, LPRECT pTitleRect)
{
AFX_MANAGE_STATE(AfxGetAppModuleState());
ASSERT_VALID(pDC);
// *** Prepare the device context
int nSavedDC = pDC->SaveDC();
(void) pDC->SetMapMode( MM_TEXT);
(void) pDC->SelectObject( m_pTitleFont);
(void) pDC->SetBkMode(TRANSPARENT);
COLORREF lTextColor;
if (isSelected())
lTextColor = m_TitleSelectedColor;
else
lTextColor = m_TitleNormalColor;
(void) pDC->SetTextColor(lTextColor);
// *** draw it
pDC->DrawText(
m_Page->getTitle(), pTitleRect,
DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX | DT_WORD_ELLIPSIS
);
#ifdef DEBUG_BOOK_WND_POSITION
pDC->FrameRect(pTitleRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
#endif
// *** Restore the DC
VERIFY( pDC->RestoreDC( nSavedDC));
}
// ************************************************************************************************
long TPageEditor::GetPageNumberWidth(CDC* pDC)
{
CDC* lDC = pDC;
int lSavedDC = 0;
if (lDC == NULL)
{
lDC = GetDC();
// *** Initialize the DC
lSavedDC = lDC->SaveDC();
(void) lDC->SelectObject( m_pNumberFont);
(void) lDC->SetMapMode( MM_TEXT);
}
CSize lSize;
lSize = lDC->GetTextExtent(GetPageNumberString());
if (lSavedDC)
{
VERIFY( lDC->RestoreDC( lSavedDC));
ReleaseDC(lDC);
}
DPtoLP(&lSize);
long lOffset = 0;
if (fNeedTabBody)
lOffset = GetTabBodyRect(NULL).Width();
return lSize.cx + lOffset + 3;
}
void TPageEditor::GetPageNumRect( CRect& rect, CDC* pDC)
{
GetClientRect( &rect);
long lWidth;
DPtoLP(&rect);
lWidth = GetPageNumberWidth(pDC);
if (getPageSide() == T_PRIMARY)
rect.right = rect.left + lWidth;
else
rect.left = rect.right - lWidth;
rect.top = T_TITLE_MARGIN;
rect.bottom = T_TITLE_HEIGHT;
LPtoDP(&rect);
}
CString TPageEditor::GetPageNumberString()
{
// *** Get page number
CString lNumStr;
if (!isPropertyPage() && !isIndex())
{
int lNum;
lNum = fPageIndex;
lNumStr.Format("%d/%d", lNum, fPageCount);
}
return lNumStr;
}
void TPageEditor::drawPageNumber(CDC* pDC, LPRECT pPageNumberRect)
{
ASSERT_VALID(pDC);
// *** Initialize the DC
int nSavedDC = pDC->SaveDC();
(void) pDC->SetMapMode( MM_TEXT);
(void) pDC->SelectObject( m_pNumberFont);
(void) pDC->SetBkMode(TRANSPARENT);
COLORREF lTextColor;
if (isSelected())
lTextColor = m_TitleSelectedColor;
else
lTextColor = m_TitleNormalColor;
(void) pDC->SetTextColor(lTextColor);
// *** Get page number
CString lNumStr;
long lJustify = DT_CENTER;
lNumStr = GetPageNumberString();
if (getPageSide() == T_SECONDARY)
lJustify = DT_LEFT;
else
lJustify = DT_RIGHT;
pDC->DrawText(lNumStr, pPageNumberRect, lJustify | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
#ifdef DEBUG_BOOK_WND_POSITION
pDC->FrameRect(pPageNumberRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
#endif
// *** Restore the DC
VERIFY( pDC->RestoreDC( nSavedDC));
}
// ************************************************************************************************
TBackGround* TPageEditor::GetTabBody()
{
TBackGround* lBody = NULL;
if (isIndex()
|| isSummary())
{
lBody = TTabsViewer::gTabBodyLeft;
}
else
{
long lTabNb;
TTabDesc* lTabDesc;
ATLASSERT(fTabIndex >= 0);
if (fTabIndex < 0)
fTabIndex = 0;
lTabNb = fTabIndex % TTabsViewer::gNbDifferentTabs;
lTabDesc = (TTabDesc*)TTabsViewer::gTabsDesc->elementAt(lTabNb);
ATLASSERT(lTabDesc);
if (lTabDesc)
{
if (lTabDesc->fBkgndBody == NULL)
lTabDesc->fBkgndBody = new TBackGround(lTabDesc->m_TabDesc.fIDBodyLeft);
lBody = lTabDesc->fBkgndBody;
}
}
ATLASSERT(lBody);
return lBody;
}
CRect TPageEditor::GetTabBodyRect(TBackGround* pBody)
{
if (pBody == NULL)
pBody = GetTabBody();
CRect lRect(0,0,0,0);
if (pBody == NULL)
return lRect;
long lLeft = 0;
if (getPageSide() != T_PRIMARY)
{
lLeft = getLogicalSize().cx - pBody->getWidth();
if (m_pBookBrowser && (m_pBookBrowser->GetModeView() == T_PAGE_MODE))
lLeft = lLeft / 2;
}
// WARN: top Should be in the Resources !!!!
lRect.top = 8;
lRect.bottom = getLogicalSize().cy; // {PS (A quoi ça sert ?)} - getLogicalPoint().y;
lRect.left = lLeft; // lTabsViewer->getLogicalPoint().x + lOffset;
lRect.right = lRect.left + pBody->getWidth();
return lRect;
}
void TPageEditor::drawTabBody(CDC* pDC, TBackGround* pBody, LPRECT pRect)
{
ASSERT_VALID(pDC);
ATLASSERT(m_Page);
// *** Trace body tab, if this page is a top level chapter, and if it stands in
// *** a book browser
// *** Need to find the index of this chapter in order to get coordinates of tab
if (pBody == NULL)
return ;
WORD lMode = BK_NORMAL;
CRect lRect(*pRect);
if (getPageSide() != T_PRIMARY)
{
long lWidth;
lMode = BK_REVERSE_Y_AXIS;
if (getBookBrowser()->GetModeView() == T_PAGE_MODE)
lWidth = pBody->getWidth() / 2 + 1;
else
lWidth = pBody->getWidth();
lRect.left += lWidth;
lRect.right += lWidth;
}
pBody->stretch(pDC, lRect, lMode);
// Draw a Black Frame arrond the tab body
#ifdef DEBUG_BOOK_WND_POSITION
if (getPageSide() != T_PRIMARY)
{
lRect.right = lRect.left;
lRect.left = lRect.left - pBody->getWidth();
}
pDC->FrameRect(lRect, CBrush::FromHandle((HBRUSH)GetStockObject(GRAY_BRUSH)));
#endif // DEBUG_BOOK_WND_POSITION
}
// ************************************************************************************************
//
// see in PageEditor
//
long TPageEditor::GetDrawClipRect(CDC* pDC, LPRECT pClipRect)
{
CRect lClipRect;
CRect lClientRect;
int lClipResult;
lClipResult = pDC->GetClipBox(&lClipRect);
if (lClipResult == NULLREGION)
return lClipResult;
GetClientRect(&lClientRect);
pDC->DPtoLP(&lClientRect);
if (lClipResult == ERROR)
{
lClipRect = lClientRect;
lClipResult = SIMPLEREGION;
}
else
{
CRect lUnionRect;
// Due to a problem of refresh !!!!!
lClipRect.InflateRect(4, 4);
lUnionRect.UnionRect(lClientRect, lClipRect);
if (!lUnionRect.EqualRect(lClientRect))
lClipRect = lClientRect;
}
#ifdef _DEBUG
CRect lUnionRect;
lUnionRect.UnionRect(lClientRect, lClipRect);
ATLASSERT(lUnionRect.EqualRect(lClientRect));
#endif
*pClipRect = lClipRect;
return lClipResult;
}
// ************************************************************************************************
void TPageEditor::drawBackground(CDC* pDC)
{
drawBookSheet(pDC);
}
// ************************************************************************************************
void TPageEditor::drawBookSheet(CDC* pDC)
{
// *** Draw the sheet
ASSERT_VALID(pDC);
ATLASSERT(m_pTitleBkgnd);
CPalette* lOldPalette = NULL;
if( TCustomPalette::m_pPalette)
lOldPalette = pDC->SelectPalette( TCustomPalette::m_pPalette, TRUE);
CRect lRect;
if (m_pBkgnd)
{
GetClientRect(&lRect);
DPtoLP(&lRect);
m_pBkgnd->stretch(pDC, lRect);
}
else
{
if (GetDrawClipRect(pDC, &lRect) != NULLREGION)
pDC->FillSolidRect(lRect, m_BkColor | 0x02000000);
}
CRect lTopRect(CPoint(0, 0), CSize(getLogicalSize().cx, m_pTopBkgnd->getHeight()));
// LPtoDP(&lTopRect);
if (m_pTopBkgnd && RectVisible(pDC, &lTopRect))
m_pTopBkgnd->stretch(pDC, lTopRect);
if (isSelected()
#ifdef DO_NOT_DISPLAY_AUTHOR_TITLE
&& !m_bIsAuthorPage
#endif // DO_NOT_DISPLAY_AUTHOR_TITLE
&& RectVisible(pDC, &m_TitleRect))
m_pTitleBkgnd->stretch(pDC, m_TitleRect);
if (lOldPalette)
pDC->SelectPalette(lOldPalette, TRUE);
}
// ************************************************************************************************
void TPageEditor::showContent(BOOL pShow)
{
if (fShowContent == pShow)
return;
fShowContent = pShow;
if (fShowContent)
{
ShowWindow(SW_SHOW);
//m_PageView->ShowWindow(SW_SHOW);
}
else
{
ShowWindow(SW_HIDE);
//m_PageView->ShowWindow(SW_HIDE);
}
}
// ************************************************************************************************
HBRUSH TPageEditor::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_STATIC)
{
pDC->SetBkMode(TRANSPARENT);
CBrush lBrush;
lBrush.CreateStockObject(NULL_BRUSH);
return (HBRUSH)lBrush;
}
// TODO: Change any attributes of the DC here
// TODO: Return a different brush if the default is not desired
return hbr;
}
// ************************************************************************************************
class TPageDropSource : public COleDropSource
{
public:
TPageDropSource() : m_First(TRUE) {}
virtual SCODE GiveFeedback( DROPEFFECT dropEffect );
protected:
BOOL m_First:2;
};
SCODE TPageDropSource::GiveFeedback( DROPEFFECT dropEffect )
{
// Play sound when beginning to drag the page
if (m_First)
{
TSoundManager::PlayFromResource( IDSOUND_DRAG_PAGE);
m_First = FALSE;
}
return COleDropSource::GiveFeedback(dropEffect);
}
BOOL TPageEditor::onBeginDragPage()
{
ATLASSERT(m_Page);
// *** Verify, it is not property page, summary or index
if (/*isSummary() || */isIndex() || isPropertyPage())
return FALSE;
// *** Create an OLE data source, Fill with the page
TDragAndDropPageData data;
TModelPtr lChapter;
m_Page->getChapter(&lChapter);
data.setChapter(lChapter);
data.addPage( m_Page);
// --- Allocate global memory for the data
STGMEDIUM lKeeBooStg;
memset( (void*) &lKeeBooStg, 0, sizeof( STGMEDIUM));
lKeeBooStg.tymed = TYMED_HGLOBAL;
UINT uSize = sizeof( TDragAndDropPageData);
lKeeBooStg.hGlobal = ::GlobalAlloc( GMEM_SHARE, uSize);
memcpy( lKeeBooStg.hGlobal, &data, uSize);
TOleDataSource lDataSource;
lDataSource.CacheDataType( E_DATA_TYPE_KEEBOO_PAGE, &lKeeBooStg);
TModelPtr lContent;
TUrl lUrl;
CString lStringUrl;
HGLOBAL lUrlGlobal;
HGLOBAL lNBookmarkGlobal;
HGLOBAL lTextGlobal;
m_Page->getContent(&lContent);
if (lContent)
{
lUrl = lContent->getUrl();
lStringUrl = lUrl.simpleUrlString();
if (lStringUrl.GetLength())
{
lUrlGlobal = ::GlobalAlloc( GMEM_SHARE, lStringUrl.GetLength() + 1);
memcpy( lUrlGlobal, lStringUrl.GetBuffer(0), lStringUrl.GetLength() + 1);
lNBookmarkGlobal = ::GlobalAlloc( GMEM_SHARE, lStringUrl.GetLength() + 1);
memcpy( lNBookmarkGlobal, lStringUrl.GetBuffer(0), lStringUrl.GetLength() + 1);
lTextGlobal = ::GlobalAlloc( GMEM_SHARE, lStringUrl.GetLength() + 1);
memcpy( lTextGlobal, lStringUrl.GetBuffer(0), lStringUrl.GetLength() + 1);
lStringUrl.ReleaseBuffer();
lDataSource.CacheGlobalDataType( E_DATA_TYPE_BROWSER_URL, lUrlGlobal);
lDataSource.CacheGlobalDataType( E_DATA_TYPE_BROWSER_BOOKMARK, lNBookmarkGlobal);
lDataSource.CacheGlobalData( CF_TEXT, lTextGlobal);
}
}
TPageDropSource lDropSource;
// *** Do the drag and drop...
DROPEFFECT lDropEffect = lDataSource.DoDragDrop(DROPEFFECT_MOVE | DROPEFFECT_COPY, NULL, &lDropSource);
// ::GlobalFree(lHGlobal);
return lDropEffect == DROPEFFECT_NONE ? FALSE : TRUE;
}
// ************************************************************************************************
void TPageEditor::OnSize( UINT nType, int cx, int cy )
{
delete m_pTitleFont;
m_pTitleFont = new CTTFont( IDS_FONT_PAGE_TITLE);
CPoint point( 0, T_TITLE_HEIGHT - T_TITLE_MARGIN);
LPtoDP( &point);
m_pTitleFont->SetHeight( point.y);
VERIFY( m_pTitleFont->CreateFontFromString());
delete m_pNumberFont;
m_pNumberFont = new CTTFont( IDS_FONT_PAGE_NUMBER);
m_pNumberFont->SetHeight((point.y * 3) / 4);
VERIFY( m_pNumberFont->CreateFontFromString());
TWnd::OnSize( nType, cx, cy);
}
// ************************************************************************************************
BOOL TPageEditor::isBookModifiable()
{
if (m_Page)
{
TModelPtr lBook;
m_Page->getBook(&lBook);
if (lBook)
{
if (!IsModifyProtected(lBook))
return true;
}
}
return false;
}
// ************************************************************************************************
long TPageEditor::getPageIndex()
{
if (!m_Page)
return 0;
if (isIndex())
return -1;
TModelPtr lBook;
m_Page->getBook(&lBook);
long lIndex = lBook->getPageIndex(m_Page);
return lIndex;
// return fPageIndex;
}
// ************************************************************************************************
void TPageEditor::setPageAndSelect(TPageModel* pPage, BOOL pActive)
{
// *** Should be done in this order
setPage(pPage);
Select(pActive);
}
// ************************************************************************************************
void TPageEditor::changeWritable(BOOL pWritable)
{
/*
// *** Must change the state of the binder
CRect lRect;
if (getPageSide() == T_PRIMARY)
lRect = CRect(getLogicalSize().cx - gRWBinderBkgnd->getWidth(), 0, getLogicalSize().cx, getLogicalSize().cy);
else
lRect = CRect(0, 0, gRWBinderBkgnd->getWidth(), getLogicalSize().cy);
LPtoDP(&lRect);
refresh(&lRect);
*/
}
// ************************************************************************************************
void TPageEditor::removePage()
{
if (m_Page)
{
// *** Remove listener
if (fPageListener)
{
//delete fListener;
m_Page->removePropertyChangeListener(fPageListener);
fPageListener->setInvalid();
fPageListener = NULL;
}
m_Page = NULL;
if (fBookListener)
{
//delete fListener;
m_Book->removePropertyChangeListener(fBookListener);
fBookListener->setInvalid();
fBookListener = NULL;
}
m_Book = NULL;
removePageletView();
}
}
// ************************************************************************************************
LRESULT TPageEditor::OnRemoveChild(WPARAM wParam, LPARAM lParam)
{
if ((CWnd*)wParam == m_PageView)
{
removePageletView();
return S_OK;
}
return S_FALSE;
}
void TPageEditor::removePageletView()
{
// This clean the last Pagelet we had in this View
if ((m_PageView == NULL) || (m_PageView->m_hWnd == NULL))
return ;
if (m_PageView->GetParent() == this)
m_PageView->quitParent();
else
m_PageView->Release();
removeChild(m_PageView);
m_PageView = NULL;
}
void TPageEditor::setPage(TPageModel* pPage, BOOL pForced)
{
if (!canSetPage(pPage, pForced))
return ;
removePage();
m_Page = pPage;
if (pPage == NULL)
{
refresh();
return;
}
fPageIndex = -1;
fPageCount = 0;
// Retrieve the persistance property
TModelPtr lProp;
m_Page->getDefaultProperty(&lProp);
lProp->getLongField(T_PAGE_PROPERTY_PERSISTANCE, &m_Behaviour);
// *** Store page index to be more efficient during navigation
m_Page->getBook(&m_Book);
ATLASSERT(m_Book);
TModelID lPageID = m_Page->getID();
fIsIndex = (lPageID == T_INDEX_MODEL_NAME);
fIsSummary = (lPageID == T_SUMMARY_MODEL_NAME);
fIsProperty = m_Book->isPageBeforeSummary(m_Page);
fIsChapter = m_Page->isInstanceOf(T_CHAPTER_MODEL_NAME);
#ifdef DO_NOT_DISPLAY_AUTHOR_TITLE
m_bIsAuthorPage = fIsProperty;
#endif // DO_NOT_DISPLAY_AUTHOR_TITLE
if (!isIndex())
fPageIndex = m_Book->getPageIndex(m_Page);
fPageCount = m_Book->getPageCount();
// *** Add new listener
fPageListener = new TPEPageListener(this);
m_Page->addPropertyChangeListener(fPageListener);
// *** 10/12/98 Add listener on the book in order to update the page number
// *** Set in TPageEditor::setPage and TPageEditor::setPage
// *** remove in TPageEditor::removePage()
// *** We need to keep a reference on the book model, because when a page is removed
// *** it is no more attached to a book but we need to retreive it in order to remove the listener.
// *** It will be released in TPageEditor::removePage()
fBookListener = new TPEBookListener(this);
m_Book->addPropertyChangeListener(fBookListener);
TModelPtr lChapter;
TModelPtr lSummary;
m_Page->getChapter(&lChapter);
m_Book->getSummary(&lSummary);
ATLASSERT(lSummary);
fNeedTabBody = ((fIsChapter && (lChapter == lSummary))
|| (fIsSummary)
|| (fIsIndex));
if (fNeedTabBody)
{
fTabIndex = 0; // *** 0-based
TModelIterator* lPages;
lSummary->getPages(&lPages);
// int i = 0;
if (isSummary())
{
fTabIndex = -1;
}
else
{
if (lPages != NULL)
{
while (lPages->hasMoreElements())
{
TModelPtr lPageModel;
lPages->nextElement((TObjectModel**)&lPageModel);
if (lPageModel->getID() == T_CHAPTER_MODEL_NAME)
{
if (lPageModel == m_Page)
break;
fTabIndex++;
}
}
}
}
delete lPages;
}
PostMessage(WM_USER_REFRESH_PAGE_CONTENT);
}
LRESULT TPageEditor::OnRefreshPageContent(WPARAM, LPARAM)
{
// *** Refresh the page content
refreshPageContent();
return 0;
}
/*
void TPageEditor::Select(BOOL pActive)
{
}
*/
// ************************************************************************************************
/*
void TPageEditor::setPageViewParent(TPageModel* pPage)
{
TPageletContainerView* lPagelet = fPageletManager->findPageletViewFor(pPage);
if (lPagelet)
{
TWnd* lView = (TWnd*) lPagelet->GetParent();
ATLASSERT(lView-IsKindOf(RUNTIME_CLASS(TWnd)));
lView->removeChild(lPagelet);
lPagelet->SetParent(this);
m_PageView = lPagelet;
addChild(lPagelet);
}
}
*/
// ************************************************************************************************
BOOL TPageEditor::isSummary()
{
return fIsSummary;
}
// ************************************************************************************************
BOOL TPageEditor::isIndex()
{
return fIsIndex;
}
// ************************************************************************************************
BOOL TPageEditor::isChapter()
{
return fIsChapter;
}
// ************************************************************************************************
BOOL TPageEditor::isPropertyPage()
{
return fIsProperty;
}
long TPageEditor::GetPageBehaviour()
{
return m_Behaviour;
}
// ************************************************************************************************
// *** EVENTS HANDLER ON PAGE PROPERTIES CHANGE
// ************************************************************************************************
// *** Listen to associated page changes
// ************************************************************************************************
/*
void TPageEditor::sendEvent(LPCTSTR pEvt)
{
}
*/
// ************************************************************************************************
// ************************************************************************************************
// ***
// *** DRAG AND DROP MESSAGE HANDLERS
// ***
// ************************************************************************************************
BOOL TPageEditor::addPageFromOsDrop(HDROP pDrop)
{
CString lFileName;
CFileStatus lStat;
// *** get the number of file dropped
int lFileNumber = DragQueryFile( pDrop, 0xFFFFFFFF, NULL, 0);
ATLASSERT(m_Page);
TModelPtr lBook;
TModelPtr lSummary;
TModelPtr lIndex;
m_Page->getBook(&lBook);
ATLASSERT(lBook);
lBook->getSummary(&lSummary);
ATLASSERT(lSummary);
lBook->getIndex(&lIndex);
ATLASSERT(lIndex);
// --- prepare the progress dialog
CProgressDlg* pDlg;
// TBooxFrame::GetMainWnd()->EnableWindow( FALSE);
CString stgFormatStep;
long lPosition;
{
AFX_MANAGE_STATE( AfxGetAppModuleState());
pDlg = new CProgressDlg();
VERIFY( pDlg->Create(
_T("CProgressDlg"), WS_CHILD/* | WS_VISIBLE*/, CRect( 0, 0, 10, 10), AfxGetMainWnd(), 1
));
CString stgTmp;
VERIFY( stgTmp.LoadString( IDS_PROGDLG_COPY_FILE_TITLE));
pDlg->SetTitle( stgTmp);
VERIFY( stgTmp.LoadString( IDS_CANCEL));
pDlg->SetCancel( stgTmp);
stgFormatStep.LoadString( IDS_PROGDLG_STEP);
pDlg->ChangeAnimation( 1 /*FILECOPY*/);
pDlg->SetUpper( lFileNumber);
lPosition = 1;
}
TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE);
// *** insert all the pages
for(int i = 0; i < lFileNumber; i++)
{
// *** get the filename
LPTSTR lBuffer = lFileName.GetBuffer( _MAX_PATH);
DragQueryFile( pDrop, i, lBuffer, _MAX_PATH);
lFileName.ReleaseBuffer();
// --- update the progress dialog
{
AFX_MANAGE_STATE( AfxGetAppModuleState());
if( pDlg->IsProcessCanceled()) break;
// --- get the kind of the file
UINT uStringId = IDS_PROGDLG_COPY_FILE_NAME;
CFileStatus fileStatus;
if( CFile::GetStatus( lFileName, fileStatus))
{
if( fileStatus.m_attribute & CFile::directory)
{
uStringId = IDS_PROGDLG_COPY_DIR_NAME;
}
}
CString stgTmp;
stgTmp.LoadString( uStringId);
stgTmp.FormatMessage( stgTmp, (LPCTSTR) lFileName);
pDlg->SetComment( (LPCTSTR) stgTmp);
stgTmp.FormatMessage( stgFormatStep, lPosition, lFileNumber);
pDlg->SetStep( stgTmp);
pDlg->SetPosition( lPosition++);
}
TBrowseDir lBrowser; // !!!!
lBrowser.SetCallback(NULL);
lBrowser.Reset();
lBrowser.Run(lFileName, m_Page);
}
TGlobalsDB::getLibraryDBManager()->commitTransaction();
// --- close the progress bar
{
AFX_MANAGE_STATE( AfxGetAppModuleState());
pDlg->DestroyWindow();
pDlg = NULL;
}
// TBooxFrame::GetMainWnd()->EnableWindow( TRUE);
// *** Go one the last inserted page
// *** One page at least has been created
// *** --> Active page becomes the one previous current page
int lPageIndex = lBook->getPageIndex(m_Page);
TModelPtr lActivePage;
lBook->getPage(lPageIndex - 1, &lActivePage);
CComPtr lBookControl;
lBookControl.CoCreateInstance(CLSID_TBookControler);
ATLASSERT(lBookControl);
if (lBookControl)
{
// Cast because model are not COM interface !!!
CComVariant lPageVariant((long)lActivePage.p);
lBookControl->ChangePageTo(T_CPT_PAGE, T_SIDE_SECONDARY, lPageVariant);
}
return true;
}
// ************************************************************************************************
// *** Note : 'point' are client coordinates
void TPageEditor::OnDragLeave( )
{
}
// ************************************************************************************************
DROPEFFECT TPageEditor::OnDragEnter( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
{
if (!isBookModifiable())
return DROPEFFECT_NONE;
ATLASSERT(pDataObject);
if( pDataObject->IsDataAvailable(CF_HDROP))
{
if (!isSummary() && !isPropertyPage())
{
// *** Set target active
ATLASSERT(m_pBookBrowser);
if (m_pBookBrowser)
{
CComPtr lBookControler;
m_pBookBrowser->getBookControler(&lBookControler);
ATLASSERT(lBookControler);
if (lBookControler)
{
ePageSide2 lSide;
lSide = m_Side == T_PRIMARY ? T_SIDE_PRIMARY : T_SIDE_SECONDARY;
lBookControler->ChangePageTo(T_CPT_SELECTED_PAGE, lSide, CComVariant(1));
}
}
return DROPEFFECT_COPY;
}
}
return DROPEFFECT_NONE;
}
// ************************************************************************************************
DROPEFFECT TPageEditor::OnDragOver( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
{
if (!isBookModifiable())
return DROPEFFECT_NONE;
ATLASSERT(pDataObject);
if( pDataObject->IsDataAvailable(CF_HDROP))
{
if (!isSummary() && !isPropertyPage())
return DROPEFFECT_COPY;
}
return DROPEFFECT_NONE;
}
// ************************************************************************************************
BOOL TPageEditor::OnDrop( COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point )
{
if (!isBookModifiable())
return FALSE;
ATLASSERT(pDataObject);
if( pDataObject->IsDataAvailable(CF_HDROP))
{
// *** The files are inserted before the drop page --> we can not drop on a summary
if (!isSummary() && !isPropertyPage())
{
// *** Drop files from OS in the shelf
HGLOBAL hGlobal = pDataObject->GetGlobalData( CF_HDROP);
HDROP hDrop = (HDROP) GlobalLock( hGlobal);
// --- expand dir link
HGLOBAL hGlobalDropExpanded = NULL;
TShellExpandDroppedDirLink( hDrop, &hGlobalDropExpanded);
HDROP hDropExpanded = (HDROP) GlobalLock( hGlobalDropExpanded);
addPageFromOsDrop( hDropExpanded);
GlobalUnlock( hGlobalDropExpanded);
GlobalFree( hGlobalDropExpanded);
GlobalUnlock( hGlobal);
return TRUE;
}
}
return FALSE;
}
// ************************************************************************************************
/*
void TPageEditor::OnShowToolbar()
{
if (!m_PageView || !m_HaveToolbar)
return ;
if (m_ToolbarUp)
m_PageView->showToolbar();
else
m_PageView->hideToolbar();
m_ToolbarUp = !m_ToolbarUp;
ChangeToolbarTooltip();
CRect lArrowRect = m_ArrowRect;
LPtoDP(&lArrowRect);
refresh(&lArrowRect);
}
*/
BOOL TPageEditor::showToolbar()
{
if (m_PageView)
return m_PageView->showToolbar();
return FALSE;
}
BOOL TPageEditor::hideToolbar()
{
if (m_PageView)
return m_PageView->hideToolbar();
return FALSE;
}
CPrintingEngine* TPageEditor::GetPrintingEngine()
{
if (m_pBookBrowser)
return m_pBookBrowser->GetPrintingEngine();
if (m_pPrintingEngine == NULL)
{
m_pPrintingEngine = new CPrintingEngine();
VERIFY(m_pPrintingEngine->Create( this, 1));
}
return m_pPrintingEngine;
}
void TPageEditor::printPage( int nCmd)
{
if (m_PageView)
{
CPrintingEngine* lEngine;
lEngine = GetPrintingEngine();
lEngine->PrintPage(m_PageView, nCmd);
}
}
void TPageEditor::showSearch()
{
if (m_PageView)
m_PageView->showSearchView();
}
IUnknown* TPageEditor::getPageletControl()
{
if (m_PageView)
return m_PageView->getPageletControl();
return NULL;
}
// User messages
LRESULT TPageEditor::OnUpdateTitle(WPARAM , LPARAM)
{
if (m_pInPlaceEditCtrl)
{
m_pInPlaceEditCtrl->SendMessage(WM_KILLFOCUS);
m_JustCloseEdit = FALSE;
}
if (m_Book)
{
fPageCount = m_Book->getPageCount();
if (m_Page && (!isIndex()))
fPageIndex = m_Book->getPageIndex(m_Page);
}
CRect lTitleRect(CPoint(0, 0), CSize (getLogicalSize().cx, T_TITLE_HEIGHT));
LPtoDP(&lTitleRect);
refresh(&lTitleRect);
return S_OK;
}
LRESULT TPageEditor::OnSetChapter(WPARAM , LPARAM)
{
TRACE("(TPageEditor) : handle set chapter event\n");
return E_NOTIMPL;
}
LRESULT TPageEditor::OnAddAnnotation(WPARAM , LPARAM)
{
TRACE("(TPageEditor) : handle add annotation event\n");
return E_NOTIMPL;
}
LRESULT TPageEditor::OnRemoveAnnotation(WPARAM , LPARAM)
{
TRACE("(TPageEditor) : handle remove annotation event\n");
return E_NOTIMPL;
}
LRESULT TPageEditor::OnSetContent(WPARAM , LPARAM)
{
TRACE("(TPageEditor) : handle set content event\n");
return E_NOTIMPL;
}
LRESULT TPageEditor::OnPageDestroy(WPARAM , LPARAM)
{
TRACE("(TPageEditor) : handle destroy page event\n");
return E_NOTIMPL;
}
// ************************************************************************************************
BOOL TPageEditor::OnEraseBkgnd(CDC* pDC)
{
#ifdef DRAW_ON_BACKGROUND
OnPrepareDC(pDC);
drawBackground(pDC);
return TRUE;
#else
return TWnd::OnEraseBkgnd(pDC);
#endif
}
// ------------------------------------------------------------------------------
//
//
void TPageEditor::OnModeChange(long pMode)
{
IUnknown* lUnknown = NULL;
lUnknown = getPageletControl();
if (lUnknown)
{
CComQIPtr lPagelet(lUnknown);
if (lPagelet)
lPagelet->put_Mode(pMode);
}
if (m_pInPlaceEditCtrl)
m_pInPlaceEditCtrl->SendMessage(WM_KILLFOCUS);
m_JustCloseEdit = FALSE;
}
void TPageEditor::LoadBackground(tBookBrowserRes* pRes)
{
AFX_MANAGE_STATE(AfxGetAppModuleState());
if (pRes->m_TopBitmap)
{
m_pTopBkgnd = new TBackGround(pRes->m_TopBitmap);
ATLASSERT(m_pTopBkgnd != NULL);
}
if (pRes->m_MiddleBitmap)
{
m_pBkgnd = new TBackGround(pRes->m_MiddleBitmap);
ATLASSERT(m_pBkgnd != NULL);
}
m_BackBrushID = pRes->m_BackBrush;
if (pRes->m_TitleBitmap)
{
m_pTitleBkgnd = new TBackGround(pRes->m_TitleBitmap);
ATLASSERT(m_pTitleBkgnd != NULL);
}
m_TitleRect = CRect(CPoint(3, 9), CSize(getLogicalSize().cx - 6, 28));
m_BkColor = pRes->m_MiddleColor;
m_TitleNormalColor = pRes->m_TitleNormalColor;
m_TitleSelectedColor = pRes->m_TitleSelectedColor;
}
void TPageEditor::OnTimer( UINT nIDEvent)
{
if( nIDEvent == TIMER_EDIT_TITLE)
{
TRACE( _T("TPageEditor::OnTimer\n"));
if( !m_bIsDblClk)
EditTitle();
KillTimer( nIDEvent);
}
else
{
TWnd::OnTimer( nIDEvent);
}
}
void TPageEditor::EditTitle()
{
if (!m_Page)
return ;
TRACE("TPageEditor::EditTitle\n");
// --- create a edit control auto deleted
m_stgInPlaceEditBuffer = m_Page->getTitle();
m_bInPlaceEditIsEscaped = false;
LOGFONT logFont;
m_pTitleFont->GetLogFont( &logFont);
CRect rectTitle;
GetTitleRect( rectTitle);
if (rectTitle.IsRectEmpty())
return ;
m_pInPlaceEditCtrl = new CInPlaceEdit( m_stgInPlaceEditBuffer, m_bInPlaceEditIsEscaped, &logFont);
m_pInPlaceEditCtrl->Create( WS_CHILD | WS_VISIBLE, rectTitle, this, IDC_EDIT_INPLACE);
}
void TPageEditor::OnEnKillFocus()
{
if( m_bInPlaceEditIsEscaped )
{
// --- need a refresh
CRect rectTitle;
GetTitleRect( rectTitle);
refresh( &rectTitle);
}
else
{
// --- refresh by the listener
if (m_Page)
{
m_Page->setTitle( m_stgInPlaceEditBuffer);
AddBehaviour(m_Page, F_PAGE_DEFINED_TITLE);
}
}
TRACE("TPageEditor::OnEnKillFocus\n");
m_JustCloseEdit = TRUE;
m_pInPlaceEditCtrl = NULL;
}
// ----------------------------------------------------------------------------
// ------------------------------- Listener ----------------------------------
// ----------------------------------------------------------------------------
TPEBookListener::TPEBookListener(TPageEditor* pPageEditor)
{
m_pPageEditor = pPageEditor;
}
TPEBookListener::~TPEBookListener()
{
m_pPageEditor = NULL;
}
void TPEBookListener::propertyChange(TPropertyChangeEvent *evt)
{
ATLASSERT(evt); // *** Event should not be null
ATLASSERT(m_pPageEditor);
ATLASSERT(getValidState());
if ((m_pPageEditor == NULL)
|| !getValidState())
return ;
TString lPropertyName(evt->getPropertyName());
if ((lPropertyName == TBookModel::T_ADD_PAGE_PROPERTY) ||
(lPropertyName == TBookModel::T_INSERT_PAGE_PROPERTY) ||
(lPropertyName == TBookModel::T_REMOVE_PAGE_PROPERTY))
{
// *** listener on the book in order to update the page number
m_pPageEditor->PostMessage(WM_USER_UPDATE_TITLE);
// changePageTitleEvt(NULL);
}
}
TPEPageListener::TPEPageListener(TPageEditor* pPageEditor)
{
m_pPageEditor = pPageEditor;
}
TPEPageListener::~TPEPageListener()
{
m_pPageEditor = NULL;
}
void TPEPageListener::propertyChange(TPropertyChangeEvent *evt)
{
ATLASSERT(evt); // *** Event should not be null
ATLASSERT(m_pPageEditor);
ATLASSERT(getValidState());
if ((m_pPageEditor == NULL)
|| !getValidState())
return ;
TString lPropertyName(evt->getPropertyName());
if (lPropertyName == TPageModel::T_SET_TITLE_PROPERTY)
{
m_pPageEditor->PostMessage(WM_USER_UPDATE_TITLE);
}
}/*------------ TPageletCtl.cpp ------------*/
// PageletCtl.cpp : Implementation of the TPageletCtrl ActiveX Control class.
#include "StdAfx.h"
#include "Pagelet.h"
#include "TPageletCtl.h"
#include "TPageletDll.h"
#include "ColorPaletteHook.h"
#include "TMetaManager.h"
#include "eViewMode.h"
#include "MfcOccImpl.h"
#include "TPageModel.h"
#include "TUserMessage.h"
#include "TAppInfo.h"
#include "TBookModel.h"
#include "TPath.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(TPageletCtrl, TOleControl)
/////////////////////////////////////////////////////////////////////////////
// Message map
BEGIN_MESSAGE_MAP(TPageletCtrl, TOleControl)
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_NCDESTROY()
ON_MESSAGE(WM_USER_NEED_DESTROY_PAGELET, OnNeedDestroy)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Dispatch map
BEGIN_DISPATCH_MAP(TPageletCtrl, TOleControl)
DISP_STOCKFUNC_REFRESH()
DISP_STOCKPROP_CAPTION()
DISP_STOCKPROP_BACKCOLOR()
DISP_STOCKPROP_APPEARANCE()
DISP_STOCKPROP_BORDERSTYLE()
DISP_STOCKPROP_READYSTATE()
END_DISPATCH_MAP()
/////////////////////////////////////////////////////////////////////////////
// Event map
BEGIN_EVENT_MAP(TPageletCtrl, TOleControl)
END_EVENT_MAP()
/////////////////////////////////////////////////////////////////////////////
// Interface map
BEGIN_INTERFACE_MAP(TPageletCtrl, TOleControl)
INTERFACE_PART(TPageletCtrl, IID_IPageletControl, PageletControl)
INTERFACE_PART(TPageletCtrl, IID_IPageletWnd, PageletWnd)
INTERFACE_PART(TPageletCtrl, IID_IPageletLoadControl, PageletLoadControl)
END_INTERFACE_MAP()
#ifdef DEBUG_PAGELET_LEAK
LONG gPageletCount = 0;
class TPageletCounter
{
public:
~TPageletCounter()
{
ATLASSERT(gPageletCount == 0);
}
};
TPageletCounter gCounter;
#endif
/////////////////////////////////////////////////////////////////////////////
// TPageletCtrl::TPageletCtrl - Constructor
TPageletCtrl::TPageletCtrl()
{
#ifdef DEBUG_PAGELET_LEAK
CString lWndName(GetRuntimeClass()->m_lpszClassName);
TRACE(_T("+ TPageletCtrl(%s)\n"), lWndName);
#endif
fCreateLoadTabDone = false;
fMode = 0;
m_pColorPaletteHook = NULL;
m_Resizable = NULL;
m_InPreTanslate = FALSE;
m_IsLoaded = FALSE;
fState = 0;
initPagelet();
#ifdef DEBUG_PAGELET_LEAK
gPageletCount++;
#endif
}
void TPageletCtrl::initPagelet()
{
fReportResultDone = false;
}
/////////////////////////////////////////////////////////////////////////////
// TPageletCtrl::~TPageletCtrl - Destructor
TPageletCtrl::~TPageletCtrl()
{
#ifdef DEBUG_PAGELET_LEAK
CString lWndName(GetRuntimeClass()->m_lpszClassName);
TRACE(_T("- TPageletCtrl(%s)\n"), lWndName);
#endif
#ifdef DEBUG_PAGELET_LEAK
gPageletCount--;
#endif
}
int TPageletCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (TOleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// --- handle the colorpalette changement
m_pColorPaletteHook = new CColorPaletteHook();
ATLASSERT(m_pColorPaletteHook);
m_pColorPaletteHook->HookWindow( this);
return 0;
}
void TPageletCtrl::OnDestroy()
{
#ifdef DEBUG_PAGELET_LEAK
CString lWndName(GetRuntimeClass()->m_lpszClassName);
TRACE(_T(" TPageletCtrl(%s)::OnDestroy (0x%x)\n"), lWndName, this);
#endif
if (m_pColorPaletteHook)
{
// --- unregister the color palette
m_pColorPaletteHook->HookWindow( NULL);
delete m_pColorPaletteHook;
m_pColorPaletteHook = NULL;
}
fModel = NULL;
TOleControl::OnDestroy();
}
void TPageletCtrl::PostNcDestroy()
{
#ifdef DEBUG_PAGELET_LEAK
CString lWndName(GetRuntimeClass()->m_lpszClassName);
TRACE(_T(" TPageletCtrl(%s)::PostNcDestroy\n"), lWndName);
#endif
TOleControl::PostNcDestroy();
ExternalRelease();
}
/////////////////////////////////////////////////////////////////////////////
// TPageletCtrl::OnDraw - Drawing function
void TPageletCtrl::OnDraw(CDC* pDC, const CRect& rcBounds, const CRect& rcInvalid)
{
TOleControl::OnDraw(pDC, rcBounds, rcInvalid);
#ifdef DEBUG_BOOK_WND_POSITION
CRect lRect;
GetClientRect(&lRect);
// DPtoLP(&lRect);
pDC->FrameRect(lRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
#endif
}
/////////////////////////////////////////////////////////////////////////////
// TPageletCtrl::DoPropExchange - Persistence support
void TPageletCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
// TODO: Call PX_ functions for each persistent custom property.
}
/////////////////////////////////////////////////////////////////////////////
// TPageletCtrl::OnResetState - Reset control to default state
void TPageletCtrl::OnResetState()
{
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
// TODO: Reset any other control state here.
}
// ************************************************************************************************
//
//
//
LPUNKNOWN TPageletCtrl::GetInterfaceHook(const void* piid)
{
GUID* lIID = (GUID*)piid;
if (InlineIsEqualGUID(*lIID, IID_IPageletControl))
return &m_xPageletControl;
if (InlineIsEqualGUID(*lIID, IID_IPageletLoadControl))
return &m_xPageletLoadControl;
return TOleControl::GetInterfaceHook(piid);
}
void TPageletCtrl::OnFinalRelease()
{
TOleControl::OnFinalRelease();
}
void TPageletCtrl::OnEventAdvise( BOOL bAdvise )
{
TOleControl::OnEventAdvise(bAdvise);
}
// ************************************************************************************************
//
//
//
HRESULT TPageletCtrl::Stop()
{
return S_OK;
}
// ************************************************************************************************
//
//
//
void TPageletCtrl::CreateLoadTab()
{
if (fCreateLoadTabDone)
return ;
if (!m_PageletSink)
m_PageletSink = m_pControlSite;
if (m_PageletSink)
{
m_PageletSink->CreateLoadTab(&m_xPageletLoadControl);
fCreateLoadTabDone = true;
}
}
// ************************************************************************************************
//
//
//
void TPageletCtrl::ReportProgress(long pProgress, long pMax)
{
if (!m_PageletSink)
m_PageletSink = m_pControlSite;
if (m_PageletSink)
{
m_PageletSink->ReportProgress(pProgress, pMax);
}
}
// ************************************************************************************************
//
//
//
void TPageletCtrl::SetStatus(LPCTSTR pStatus)
{
if (!m_PageletSink)
m_PageletSink = m_pControlSite;
if (m_PageletSink)
m_PageletSink->put_Status(CComBSTR(pStatus));
}
// ************************************************************************************************
//
//
//
void TPageletCtrl::ReportResult(long pResult)
{
// if (fReportResultDone)
// return ;
if (pResult == S_OK)
SetLoaded(TRUE);
if (!m_PageletSink)
m_PageletSink = m_pControlSite;
if (m_PageletSink)
{
m_PageletSink->ReportResult(pResult);
// fReportResultDone = true;
}
}
// ************************************************************************************************
//
//
//
STDMETHODIMP TPageletCtrl::GetDropTarget(IDropTarget* pDropTarget, IDropTarget** ppDropTarget)
{
ATLASSERT(ppDropTarget);
if (ppDropTarget == NULL)
return E_INVALIDARG;
*ppDropTarget = NULL;
return E_NOTIMPL;
}
/////////////////////////////////////////////////////////////////////////////
// TPageletCtrl message handlers
// AddRef, Release and QueryInterface stuff ....
T_IMPLEMENT_EXTERNAL_INTERFACE(TPageletCtrl, PageletControl)
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::put_PageModel(long pModel)
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
HRESULT lResult = S_FALSE;
if (TMetaManager::checkModelPointerValidity((void*)pModel))
{
pThis->fModel = (TPageModel*)pModel;
// TEMP
// As sometime, there's still one more release on a PageModel,
// add a ref on this model so that the destruction don't crash
((TPageModel*)pModel)->AddRef();
// TEMP
lResult = S_OK;
}
else
{
pThis->fModel = NULL;
ATLASSERT(NULL);
TRACE(_T("\n-- TPageletCtrl::put_PageModel: Invalid Model Pointer\n"));
}
pThis->OnNewPageModel();
return lResult;
}
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::get_PageModel(long* pModel)
{
ATLASSERT(pModel);
if (pModel == NULL)
return E_INVALIDARG;
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
// Cast because model are not COM interface !!!
*pModel = (long)pThis->getModel();
if (*pModel)
{
// Cast because model are not COM interface !!!
((TObjectModel*)*pModel)->AddRef();
return S_OK;
}
return S_FALSE;
}
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::put_Selected(BOOL pBool)
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
return pThis->put_Selected(pBool);
}
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::put_Current(BOOL pBool)
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
return pThis->put_Current(pBool);
}
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::Hide()
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
return pThis->Hide();
}
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::Show()
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
return pThis->Show();
}
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::PrintPage( int nCmd)
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
return pThis->PrintPage( nCmd);
}
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::put_Mode(long pMode)
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
long lOldMode = pThis->fMode;
if ((pMode != T_UNDEFINED_MODE)
&& (pThis->fMode != pMode))
{
pThis->fMode = pMode;
if (lOldMode != T_UNDEFINED_MODE)
pThis->OnModeChange(pMode);
pThis->removeListeners();
pThis->addListeners();
}
return S_OK;
}
// ****************************************************************
/*
HRESULT TPageletCtrl::XPageletControl::get_Mode(long* pMode)
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
*pMode = pThis->fMode;
return S_OK;
}
*/
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::Load()
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
return pThis->Load();
}
// ****************************************************************
HRESULT TPageletCtrl::XPageletControl::Unload()
{
METHOD_PROLOGUE(TPageletCtrl, PageletControl);
return pThis->Unload();
}
// AddRef, Release and QueryInterface stuff ....
T_IMPLEMENT_EXTERNAL_INTERFACE(TPageletCtrl, PageletWnd)
// ****************************************************************
HRESULT TPageletCtrl::XPageletWnd::Destroy()
{
METHOD_PROLOGUE(TPageletCtrl, PageletWnd);
return pThis->DestroyWindow();
}
HRESULT TPageletCtrl::XPageletWnd::PreTranslateMessage(MSG* pMsg, BOOL* pRetVal)
{
ATLASSERT(pRetVal);
if (pRetVal == NULL)
return E_INVALIDARG;
METHOD_PROLOGUE(TPageletCtrl, PageletWnd);
*pRetVal = pThis->PreTranslateMessage(pMsg);
return S_OK;
}
HRESULT TPageletCtrl::XPageletWnd::put_BackgroundWnd(HWND hWnd)
{
METHOD_PROLOGUE(TPageletCtrl, PageletWnd);
return pThis->OnNewBackWnd(hWnd);
}
BOOL TPageletCtrl::PreTranslateMessage(MSG* pMsg)
{
BOOL lResult = FALSE;
if (!m_InPreTanslate)
{
m_InPreTanslate = TRUE;
lResult = WalkPreTranslateTree(GetSafeHwnd(), pMsg);
if (!lResult)
{
if (m_xOleInPlaceActiveObject.TranslateAccelerator(pMsg) == S_OK)
{
m_InPreTanslate = FALSE;
return TRUE;
}
}
m_InPreTanslate = FALSE;
}
else
{
lResult = TOleControl::PreTranslateMessage(pMsg);
}
return lResult;
}
// ****************************************************************
// ****************************************************************
HRESULT TPageletCtrl::OnNewPageModel()
{
return S_OK;
}
// ****************************************************************
HRESULT TPageletCtrl::put_Selected(BOOL pBool)
{
if (pBool)
fState |= PAGELET_SELECTED;
else
fState &= ~PAGELET_SELECTED;
return S_OK;
}
// ****************************************************************
HRESULT TPageletCtrl::put_Current(BOOL pBool)
{
if (pBool)
fState |= PAGELET_CURRENT;
else
fState &= ~PAGELET_CURRENT;
return S_OK;
}
// ****************************************************************
HRESULT TPageletCtrl::Hide()
{
m_PageletSink.Release();
return E_NOTIMPL;
}
// ****************************************************************
HRESULT TPageletCtrl::Show()
{
return E_NOTIMPL;
}
// ****************************************************************
HRESULT TPageletCtrl::PrintPage( int nCmd)
{
return E_NOTIMPL;
}
// ****************************************************************
HRESULT TPageletCtrl::Load()
{
return E_NOTIMPL;
}
// ****************************************************************
HRESULT TPageletCtrl::Unload()
{
return E_NOTIMPL;
}
// ****************************************************************
// ****************************************************************
// AddRef, Release and QueryInterface stuff ....
T_IMPLEMENT_EXTERNAL_INTERFACE(TPageletCtrl, PageletLoadControl)
// ****************************************************************
HRESULT TPageletCtrl::XPageletLoadControl::Stop()
{
METHOD_PROLOGUE(TPageletCtrl, PageletLoadControl);
HRESULT hr = (HRESULT)pThis->Stop();
return hr;
}
// ****************************************************************
HRESULT TPageletCtrl::XPageletLoadControl::get_IsLoaded(BOOL* pBool)
{
ATLASSERT(pBool);
if (pBool == NULL)
return E_INVALIDARG;
METHOD_PROLOGUE(TPageletCtrl, PageletLoadControl);
*pBool = pThis->m_IsLoaded;
return S_OK;
}
// ****************************************************************
//
//
//
void TPageletCtrl::resizeWnd(CWnd* pWnd, CRect pRect)
{
CComPtr lLogicalSpace;
if (pWnd->InternalQueryInterface(&IID_ILogicalSpace, (void**)&lLogicalSpace) == S_OK)
{
DPtoLP(&pRect);
lLogicalSpace->put_LogicalSize(pRect.Size());
lLogicalSpace->put_LogicalPoint(pRect.TopLeft());
lLogicalSpace->put_LogicalSpace(pRect.Size());
CDC* lDC = GetDC();
ASSERT_VALID(lDC);
OnPrepareDC(lDC);
lLogicalSpace->LogicalResizeAndPos(lDC->m_hDC);
ReleaseDC(lDC);
}
else
{
pWnd->SetWindowPos(NULL, pRect.left, pRect.top, pRect.Width(), pRect.Height(), SWP_NOZORDER | SWP_NOCOPYBITS);
}
}
void TPageletCtrl::refreshWnd(CWnd* pWnd)
{
CComPtr lOpacity;
if (pWnd->InternalQueryInterface(&IID_IOpacity, (void**)&lOpacity) == S_OK)
{
HWND lBackgroundWnd = NULL;
lOpacity->get_BackgroundWnd(&lBackgroundWnd);
if (lBackgroundWnd)
{
CRect lBgRect;
::GetClientRect(lBackgroundWnd,&lBgRect);
lOpacity->UpdateBackground(lBgRect);
}
}
else
{
CRect lClientRect;
pWnd->GetClientRect(&lClientRect);
pWnd->InvalidateRect(lClientRect);
pWnd->UpdateWindow();
}
}
// ****************************************************************
//
//
BOOL TPageletCtrl::showView(HWND pWnd)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ATLASSERT(m_Resizable);
long lIndex = IndexOfChild(pWnd);
long lResizableViewIndex = IndexOfChild(m_Resizable);
ATLASSERT(lIndex >= 0);
if (lIndex < 0)
return FALSE;
if (IsWndVisible(lIndex))
return TRUE;
CWnd* lToBeShownWnd = CWnd::FromHandle(pWnd);
ATLASSERT(lToBeShownWnd);
if (lToBeShownWnd == NULL)
return FALSE;
CRect lToBeShownRect;
long lToBeShownHeight;
lToBeShownWnd->GetWindowRect(&lToBeShownRect);
lToBeShownHeight = lToBeShownRect.Height();
CRect lPageletRect;
GetClientRect(&lPageletRect);
long lCount;
long ii;
lCount = childCount();
// First, we check if everything can fit in the parent view
long lUsedHeight;
long lNeededHeight;
lUsedHeight = UsedHeight();
if (IsResizable(pWnd))
lNeededHeight = lUsedHeight;
else
lNeededHeight = lUsedHeight + lToBeShownHeight;
if (lNeededHeight > lPageletRect.Height())
{
// We have not enough space to show this view
// so it will not be shown.
ATLASSERT(FALSE);
return FALSE;
}
long lAvailableHeight;
lAvailableHeight = lPageletRect.Height() - lUsedHeight;
// Here we know that there will be enough place
CRect lAvailableRect = lPageletRect;
long lVerticalOffset = 0;
// long lTop = 0;
// First, let's handle child views above the resizable view
for (ii = 0; ii < lResizableViewIndex; ii++)
{
CWnd* lCurChildWnd = getChildAt(ii);
ATLASSERT(lCurChildWnd);
if ( IsWndVisible(ii) || (ii == lIndex))
{
CRect lRect;
ATLASSERT(lCurChildWnd->GetParent() == this);
lCurChildWnd->GetWindowRect(&lRect);
ScreenToClient(&lRect);
if ( IsWndVisible(ii))
{
if (lVerticalOffset != 0)
{
lRect.OffsetRect(0,lVerticalOffset);
resizeWnd(lCurChildWnd, lRect);
}
}
else if (ii == lIndex)
{
lRect.OffsetRect(-lRect.left,-lRect.top);
lRect.OffsetRect(lAvailableRect.left,lAvailableRect.top);
lVerticalOffset += lRect.Height();
resizeWnd(lCurChildWnd, lRect);
lCurChildWnd->ShowWindow(SW_SHOW);
}
lAvailableRect.top += lRect.Height();
}
}
lVerticalOffset = 0;
// Then, let's handle child views under the resizable view
for (ii = (lCount - 1); ii > lResizableViewIndex; ii--)
{
CWnd* lCurChildWnd = getChildAt(ii);
ATLASSERT(lCurChildWnd);
if ( IsWndVisible(ii) || (ii == lIndex))
{
CRect lRect;
ATLASSERT(lCurChildWnd->GetParent() == this);
lCurChildWnd->GetWindowRect(&lRect);
ScreenToClient(&lRect);
if ( IsWndVisible(ii))
{
if (lVerticalOffset != 0)
{
lRect.OffsetRect(0,lVerticalOffset);
resizeWnd(lCurChildWnd, lRect);
}
}
else if (ii == lIndex)
{
lRect.OffsetRect(-lRect.left,-lRect.top);
lRect.OffsetRect(lAvailableRect.left,lAvailableRect.bottom - lRect.Height());
lVerticalOffset -= lRect.Height();
resizeWnd(lCurChildWnd, lRect);
lCurChildWnd->ShowWindow(SW_SHOW);
}
lAvailableRect.bottom -= lRect.Height();
}
}
// Then, let's handle the resizable view
CWnd* lResizableChildWnd = getChildAt(lResizableViewIndex);
if (IsWndVisible(lResizableViewIndex))
{
resizeWnd(lResizableChildWnd, lAvailableRect);
}
else
{
if (lResizableViewIndex == lIndex)
{
resizeWnd(lResizableChildWnd, lAvailableRect);
lResizableChildWnd->ShowWindow(SW_SHOW);
}
}
refreshWnd(lToBeShownWnd);
m_Visibility.SetAt(lIndex, 1);
return TRUE;
}
// ****************************************************************
//
//
//
BOOL TPageletCtrl::hideView(HWND pWnd)
{
ATLASSERT(m_Resizable);
long lIndex = IndexOfChild(pWnd);
long lResizableViewIndex = IndexOfChild(m_Resizable);
ATLASSERT(lIndex >= 0);
if (lIndex < 0)
return FALSE;
if (!IsWndVisible(lIndex))
return TRUE;
CWnd* lToBeHideWnd = CWnd::FromHandle(pWnd);
ATLASSERT(lToBeHideWnd);
if (lToBeHideWnd == NULL)
return FALSE;
CRect lToBeHideRect;
long lToBeHideHeight;
lToBeHideWnd->GetWindowRect(&lToBeHideRect);
lToBeHideHeight = lToBeHideRect.Height();
CRect lPageletRect;
GetClientRect(&lPageletRect);
long lUsedHeight;
long lAvailableHeight;
long lVerticalOffset = 0;
long lCount;
int ii = 0;
lCount = childCount();
lUsedHeight = UsedHeight();
lAvailableHeight = lPageletRect.Height() - lUsedHeight;
CRect lAvailableRect = lPageletRect;
// First, let's handle child views above the resizable view
for (ii = 0; ii < lResizableViewIndex; ii++)
{
CWnd* lCurChildWnd = getChildAt(ii);
ATLASSERT(lCurChildWnd);
if ( IsWndVisible(ii) )
{
CRect lRect;
lCurChildWnd->GetWindowRect(&lRect);
if (ii == lIndex)
{
lCurChildWnd->ShowWindow(SW_HIDE);
lVerticalOffset -= lRect.Height();
}
else
{
ATLASSERT(lCurChildWnd->GetParent());
ScreenToClient(&lRect);
if (lVerticalOffset != 0)
{
lRect.OffsetRect(0, lVerticalOffset);
resizeWnd(lCurChildWnd, lRect);
}
lAvailableRect.top += lRect.Height();
}
}
}
lVerticalOffset = 0;
// Then, let's handle child views under the resizable view
for (ii = (lCount - 1); ii > lResizableViewIndex; ii--)
{
CWnd* lCurChildWnd = getChildAt(ii);
ATLASSERT(lCurChildWnd);
if ( IsWndVisible(ii) )
{
CRect lRect;
lCurChildWnd->GetWindowRect(&lRect);
if (ii == lIndex)
{
lCurChildWnd->ShowWindow(SW_HIDE);
lVerticalOffset += lRect.Height();
}
else
{
ScreenToClient(&lRect);
if (lVerticalOffset != 0)
{
lRect.OffsetRect(0,lVerticalOffset);
resizeWnd(lCurChildWnd, lRect);
}
lAvailableRect.bottom -= lRect.Height();
}
}
}
// Then, let's handle the resizable view
// which is always visible
CWnd* lResizableChildWnd = getChildAt(lResizableViewIndex);
resizeWnd(lResizableChildWnd, lAvailableRect);
m_Visibility.SetAt(lIndex, 0);
return TRUE;
}
void TPageletCtrl::OnModeChange(long pMode)
{
}
LRESULT TPageletCtrl::OnNeedDestroy(UINT, LONG)
{
DestroyWindow();
return S_OK;
}
CRect TPageletCtrl::GetPageletLogicalRect()
{
CRect lLogicalRect(CPoint(0,0), getLogicalSize());
lLogicalRect.DeflateRect(__min(lLogicalRect.Width()/2, 2), __min(lLogicalRect.Height()/2, 2));
return lLogicalRect;
}
STDMETHODIMP TPageletCtrl::OnNewBackWnd(HWND hWnd)
{
return E_NOTIMPL;
}
void TPageletCtrl::OnAddChild(CWnd* pChild, long pIndex)
{
BYTE lDefault = 0;
m_Visibility.InsertAt(pIndex, lDefault);
}
void TPageletCtrl::OnRemoveChild(CWnd* pChild, long pIndex)
{
if (pIndex < 0)
{
long lIndex = childCount();
while (lIndex)
{
if (pChild == getChildAt(lIndex - 1))
{
pIndex = lIndex - 1;
break;
}
lIndex--;
}
if (lIndex == 0)
return ;
}
m_Visibility.RemoveAt(pIndex);
}
BOOL TPageletCtrl::IsWndVisible(long pIndex)
{
return m_Visibility.GetAt(pIndex);
}
long TPageletCtrl::IndexOfChild(HWND pWnd)
{
long lIndex = childCount() - 1;
while (lIndex >= 0)
{
if ((HWND)(*getChildAt(lIndex)) == pWnd)
return lIndex;
lIndex--;
}
return lIndex;
}
void TPageletCtrl::SetResizable(HWND pWnd)
{
m_Resizable = pWnd;
}
BOOL TPageletCtrl::IsResizable(HWND pWnd)
{
if (m_Resizable == pWnd)
return TRUE;
return FALSE;
}
long TPageletCtrl::UsedHeight()
{
long lTotalNonResizableChildrenHeight = 0;
long lCount;
long ii;
lCount = childCount();
for (ii = 0; ii < lCount; ii++)
{
if (IsWndVisible(ii))
{
CWnd* lCurChildWnd = getChildAt(ii);
ATLASSERT(lCurChildWnd);
if (!IsResizable(*lCurChildWnd))
{
CRect lRect;
lCurChildWnd->GetWindowRect(&lRect);
ScreenToClient(&lRect);
lTotalNonResizableChildrenHeight += lRect.Height();
}
}
}
return lTotalNonResizableChildrenHeight;
}
void TPageletCtrl::SetLoaded(BOOL pLoaded)
{
m_IsLoaded = pLoaded;
}
CString TPageletCtrl::GetMyDocumentsFolder()
{
TAppInfo lAppInfo;
CString stgPath;
stgPath = lAppInfo.GetSessionNewDocumentPath();
// --- get the documents directory name
TModelPtr pBookModel;
fModel->getBook(&pBookModel);
ATLASSERT( pBookModel);
CString stgBookName = pBookModel->getName();
TPath::ReplaceForbiddenCharsInFileName(stgBookName, CString(_T('_')));
// --- concat the 2 paths
LPTSTR szPath = stgPath.GetBuffer( MAX_PATH);
VERIFY( PathAppend( szPath, (LPCTSTR) stgBookName));
stgPath.ReleaseBuffer();
// --- create the directory
TPath lPathHelper(stgPath);
BOOL lCreated = lPathHelper.CreateDirectory();
ATLASSERT(lCreated);
return stgPath;
}/*------------ TPageletCtl.h ------------*/
#ifndef T_PAGELET_CTL
#define T_PAGELET_CTL
#include "TOleControl.h"
#include "Pagelet.h"
#include "TModelPtr.h"
#include "TGenericArray.h"
#include "TIntIterator.h"
class TPageModel;
class CColorPaletteHook;
class TPageletCtrl : public TOleControl
{
DECLARE_DYNAMIC(TPageletCtrl)
DECLARE_INTERFACE_MAP();
DECLARE_MESSAGE_MAP()
DECLARE_DISPATCH_MAP()
DECLARE_EVENT_MAP()
// Constructor
public:
TPageletCtrl();
virtual ~TPageletCtrl();
// Overrides
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
afx_msg void DoPropExchange(CPropExchange* pPX);
afx_msg void OnResetState();
LRESULT OnNeedDestroy(UINT, LONG);
virtual LPUNKNOWN GetInterfaceHook(const void* piid);
virtual void OnEventAdvise( BOOL bAdvise );
virtual void PostNcDestroy();
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual void OnFinalRelease();
// Implementation
public:
enum
{
PAGELET_CURRENT = 1,
PAGELET_SELECTED
};
public:
TPageModel* getModel() { return fModel; }
long getState() { return fState; }
BEGIN_INTERFACE_PART(PageletControl, IPageletControl)
STDMETHOD(put_PageModel)(long pPage);
STDMETHOD(get_PageModel)(long* pPage);
STDMETHOD(put_Selected)(BOOL pVal);
STDMETHOD(put_Current)(BOOL pVal);
STDMETHOD(put_Mode)(long pMode);
// STDMETHOD(get_Mode)(long* pMode);
STDMETHOD(Hide)();
STDMETHOD(Show)();
STDMETHOD(PrintPage)( int nCmd);
STDMETHOD(Load)();
STDMETHOD(Unload)();
END_INTERFACE_PART(PageletControl)
BEGIN_INTERFACE_PART(PageletWnd, IPageletWnd)
STDMETHOD(Destroy)();
STDMETHOD(PreTranslateMessage)(MSG* pMsg, BOOL* pRetVal);
STDMETHOD(put_BackgroundWnd)(HWND);
END_INTERFACE_PART(PageletWnd)
BEGIN_INTERFACE_PART(PageletLoadControl, IPageletLoadControl)
STDMETHOD(get_IsLoaded)(BOOL *pVal);
STDMETHOD(Stop)();
END_INTERFACE_PART(PageletLoadControl)
public:
DWORD GetControlFlags()
{
return TOleControl::GetControlFlags();
}
virtual void CreateLoadTab();
virtual void ReportProgress(long pProgress, long pMax);
virtual void ReportResult(long pResult);
virtual void SetStatus(LPCTSTR pStatus);
virtual void OnModeChange(long pMode);
STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget);
STDMETHOD(Stop)();
STDMETHOD(OnNewPageModel)();
STDMETHOD(OnNewBackWnd)(HWND hWnd);
STDMETHOD(put_Selected)(BOOL pVal);
STDMETHOD(put_Current)(BOOL pVal);
STDMETHOD(Hide)();
STDMETHOD(Show)();
STDMETHOD(PrintPage)( int nCmd);
STDMETHOD(Load)();
STDMETHOD(Unload)();
BOOL hideView(HWND pWnd);
BOOL showView(HWND pWnd);
void resizeWnd(CWnd* pWnd, CRect pRect);
void refreshWnd(CWnd* pWnd);
void initPagelet();
CRect GetPageletLogicalRect();
virtual void addListeners() {}
virtual void removeListeners() {}
virtual void OnAddChild(CWnd* pChild, long pIndex);
virtual void OnRemoveChild(CWnd* pChild, long pIndex = -1);
long IndexOfChild(HWND pWnd);
BOOL IsWndVisible(long pIndex);
void SetResizable(HWND pWnd);
BOOL IsResizable(HWND pWnd);
long UsedHeight();
void SetLoaded(BOOL pLoaded);
CString GetMyDocumentsFolder();
protected:
CColorPaletteHook* m_pColorPaletteHook;
CByteArray m_Visibility;
HWND m_Resizable;
TModelPtr fModel;
CComQIPtr m_PageletSink;
long fState;
long fMode;
BOOL fReportResultDone:2;
BOOL fCreateLoadTabDone:2;
BOOL m_InPreTanslate:2;
BOOL m_IsLoaded:2;
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // T_PAGELET_CTL/*------------ TWBPageletCtl_WebEvent.cpp ------------*/
#include "StdAfx.h"
#include "TBaseWBPageletCtl.h"
#include "TWBPageletCtl_Utils.h"
#include "PageletCtrl.h"
//#include "TDispatchInfoDlg.h"
#include "TMetaManager.h"
#include "TModelNames.h"
#include "TAllModel.h"
#include "TPageModel.h"
#include "TChapterModel.h"
#include "TContentModel.h"
#include "TContentsBagModel.h"
#include "TPageNumbering.h"
#include "TModelHelpers.h"
#include "SharedResource.h"
#include "TWebBrowser.h"
#include "TUrl.h"
#include "TSevenixUrlInfo.h"
#include "TSevenixUrl.h"
#include "TInteger.h"
#include "TTime.h"
#include "TErr.h"
// Net Stuff
#include "TNetHelpers.h"
#include "IEVersion.h"
#include "Net.h"
#include "Dom.h"
//#include "TDomStretcher.h"
#include "TWBStretchSink.h"
#include "TNewHtmlWindow.h"
#include "eViewMode.h"
#include "TBackgroundIndexer.h"
#include "TTrash.h"
#include "mshtml.h"
#include "mshtmcid.h"
#ifndef IE5_ZOOM
#define IDM_ZOOMRATIO 2344
#define IDM_GETZOOMNUMERATOR 2345
#define IDM_GETZOOMDENOMINATOR 2346
#endif // IE5_ZOOM
#define T_MAX_NEW_WINDOW 3
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
void findHTMLInterface(IDispatch* pDispatch);
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::BeforeNavigate(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel)
{
}
BOOL CancelUrl(LPCTSTR pUrl)
{
if (!_tcsnicmp(_T("res://"), pUrl, 6) && _tcsstr(pUrl, _T("navcancl.htm")))
return TRUE;
return FALSE;
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebBeforeNavigate2(LPDISPATCH pDisp, VARIANT* pURL, VARIANT* pFlags, VARIANT* pTargetFrameName, VARIANT* pPostData, VARIANT* pHeaders, BOOL* pCancel)
{
CString lUrl(pURL->bstrVal);
#ifdef _DEBUG
KB_LOG_INFO2(_T("[0x%1!x!]::BeforeNavigate(%2)"), pDisp, lUrl);
#endif // _DEBUG
m_bCanceling = CancelUrl(lUrl);
if (m_bCanceling)
return ;
// Let's keep the passed webBrowser for future use
CComQIPtr lBrowser(pDisp);
ATLASSERT(lBrowser);
ATLASSERT(pCancel);
TUrl lBaseUrl(lUrl);
CString lScheme;
lBaseUrl.canonicalize();
lScheme = lBaseUrl.getScheme();
// This Protocol will be stored into the base
if (StorableProtocol(lScheme))
{
// It does not have a extended scheme
if ((lBaseUrl.getExtendedInfo() == NULL))
{
// But it'is the wait we want it !!!
if ( (m_InitialUrl != lUrl) && (TUrl(m_InitialUrl).getExtendedInfo() != NULL) )
{
// try a cancel -> navigate
TUrl lCurrentUrl(m_CurrentUrl);
TSevenixUrlInfo* lInfo;
long lID = 0;
lInfo = (TSevenixUrlInfo*)lCurrentUrl.getExtendedInfo();
ATLASSERT(lInfo);
if (lInfo)
lID = lInfo->getID();
TSevenixUrl lNewUrl(lUrl, lID);
RedirectTo(lNewUrl.extendedUrlString(), lBrowser);
*pCancel = TRUE;
#ifdef _DEBUG
KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp);
#endif // _DEBUG
return ;
}
}
}
// If we navigate here for the first time
if (m_RootDispatch == NULL)
{
// store the IDispatch to know in the Document Complete
// that this is the main Frame
m_RootDispatch = pDisp;
m_bFirstNavigate = TRUE;
TRACE(_T(" >> >> First Before Nav with : this(0x%x), Disp(0x%x)\n"), this, lBrowser);
if (m_pNetStatus == NULL)
{
m_pNetStatus.CoCreateInstance(CLSID_TInternetStatus);
}
m_NavigatingFramesList.RemoveAll();
}
BOOL lRenavigateBeforeComplete = FALSE;
if (m_NavigatingFramesList.Find(lBrowser.p) < 0)
m_NavigatingFramesList.Add(lBrowser.p);
else
lRenavigateBeforeComplete = TRUE;
m_NavigateCount = m_NavigatingFramesList.GetSize();
CComVariant lPostData;
if (pPostData)
lPostData = *pPostData->pvarVal;
// Special Case for Dynamic KeeBook
// Added in 2.2
if (lPostData.vt != VT_EMPTY)
{
if (m_bUserClick || MinimumIEVersion(5, 5))
{
if (lScheme != "internal")
HookDynamicKeeBook(lBrowser, pCancel);
if (*pCancel == TRUE)
{
#ifdef _DEBUG
KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp);
#endif // _DEBUG
return ;
}
}
}
CComBSTR lBstrUrl;
CComBSTR lBstrTarget;
CComBSTR lBstrHeaders;
long lFlags = 0;
if (pURL)
lBstrUrl = pURL->bstrVal;
if (pTargetFrameName)
lBstrTarget = pTargetFrameName->bstrVal;
if (pHeaders)
lBstrHeaders = pHeaders->bstrVal;
if (pFlags)
lFlags = pFlags->lVal;
if (NeedCreateNewPage(lBrowser, lBstrUrl, lFlags, lBstrTarget, pPostData, lBstrHeaders, pCancel))
{
TUrl lCurrentUrl(m_CurrentUrl);
CString lNewExtra = lBaseUrl.getExtra();
CString lOldExtra = lCurrentUrl.getExtra();
BOOL lNewHaveOffset = lNewExtra.GetLength() && (lNewExtra[0] == '#');
BOOL lOldHaveOffset = lOldExtra.GetLength() && (lOldExtra[0] == '#');
CString lNewStrippedUrl = lUrl;
CString lOldStrippedUrl = m_CurrentUrl;
if (lNewHaveOffset)
lNewStrippedUrl = lUrl.Left(lUrl.GetLength() - lNewExtra.GetLength());
if (lOldHaveOffset)
lOldStrippedUrl = m_CurrentUrl.Left(m_CurrentUrl.GetLength() - lOldExtra.GetLength());
if (lNewStrippedUrl == lOldStrippedUrl)
{
#ifdef _DEBUG
if (*pCancel)
KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp);
#endif // _DEBUG
return ;
}
CreateNewPage(lBrowser, lBstrUrl, lFlags, lBstrTarget, pPostData, lBstrHeaders);
// do not load in page
*pCancel = TRUE;
}
else
{
if (m_RootDispatch == pDisp)
{
// We might have a redirection on a IFRAME
// for some kind of pub reload
// so we must be in the root document to set this flag
SetLoaded(FALSE);
}
BeforeNavigate(pDisp, pURL, pFlags, pTargetFrameName, pPostData, pHeaders, pCancel);
// If we do not cancel navigation,
// we store the interface so that we can use it
// for annotations and navigation in frames.
ATLASSERT(lBrowser);
if (lBrowser == NULL)
{
#ifdef _DEBUG
if (*pCancel)
KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp);
#endif // _DEBUG
return ;
}
// if in Root
CComPtr lDispatch;
lBrowser->get_Parent(&lDispatch);
if (lDispatch == NULL)
{
#ifdef UPDATE_SCROLL_AFTER_SOFT_RELOAD
BOOL lValue = FALSE;
if (m_BrowserTree && SUCCEEDED(m_BrowserTree->IsSoftReload(&lValue)) && lValue)
m_SoftReloadTree = m_BrowserTree;
#endif // UPDATE_SCROLL_AFTER_SOFT_RELOAD
if (!lRenavigateBeforeComplete)
{
// Clean-up all sub reference
m_BrowserTree.Release();
#if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL)
m_BeforeTree.Release();
#endif
}
}
TRACE(_T(" + Adding Ref WebBrowser(0x%x)\n"), lBrowser);
#if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL)
HRESULT lResult;
if (m_BeforeTree == NULL)
{
lResult = m_BeforeTree.CoCreateInstance(CLSID_WebBrowserTreeRoot);
ATLASSERT(SUCCEEDED(lResult));
if (FAILED(lResult))
{
#ifdef _DEBUG
if (*pCancel)
KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp);
#endif // _DEBUG
return ;
}
}
ATLASSERT(m_BeforeTree);
lResult = m_BeforeTree->Add(lBrowser, CComBSTR(lBaseUrl.extendedUrlString()));
// ATLASSERT(SUCCEEDED(lResult));
#endif
}
#ifdef _DEBUG
if (*pCancel)
KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp);
#endif // _DEBUG
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebProgressChange(long Progress, long ProgressMax)
{
if (Progress == 0)
{
CreateLoadTab();
}
ReportProgress(Progress, ProgressMax);
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebNavigateComplete2(LPDISPATCH pDisp, VARIANT* URL)
{
ATLASSERT(URL);
ATLASSERT(URL->vt == VT_BSTR);
HRESULT lResult;
CString lUrlString(URL->bstrVal);
#ifdef _DEBUG
KB_LOG_INFO2(_T("[0x%1!x!]::NavigateComplete(%2)"), pDisp, lUrlString);
#endif // _DEBUG
if (lUrlString.GetLength() == 0)
return ;
CComQIPtr lBrowser(pDisp);
TUrl lUrl(lUrlString);
BOOL lStorable;
lUrl.canonicalize();
ATLASSERT(lBrowser);
lStorable = StorableProtocol(lUrl.getScheme());
if (lStorable)
{
if (lUrl.getExtendedInfo() == NULL)
{
TUrl lBaseUrl(m_InitialUrl);
if (lBaseUrl.getExtendedInfo())
{
lUrl.setExtendedInfo(lBaseUrl.getExtendedInfo()->clone());
m_CurrentUrl.Empty();
m_CurrentUrl = lUrl.extendedUrlString();
if (lStorable && (m_RootDispatch == pDisp))
{
// Update DB
webUpdateContent(m_CurrentUrl);
}
RedirectTo(m_CurrentUrl, lBrowser);
return ;
}
}
//
#if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL)
CComPtr lTree;
ATLASSERT(m_BeforeTree);
lResult = m_BeforeTree->FindUrl(CComBSTR(lUrl.extendedUrlString()), &lTree);
ATLASSERT(lResult == S_OK);
#endif
}
#if _INDEX_SEARCH_USE_INDEXER_DLL
/////////////
// INDEXATION
CString lExtUrl = lUrl.extendedUrlString();
if (lStorable)
{
TBackgroundIndexer::addContent(lExtUrl);
}
/////////////
#endif // _INDEX_SEARCH_USE_INDEXER_DLL
/*
if (m_RootDispatch == pDisp)
{
CComPtr lDispatch;
CComQIPtr lDocument;
lResult = fWebBrowser->GetHtmlDocument(&lDispatch);
lDocument = lDispatch;
if (lDocument)
{
CheckPicturePage(lDocument);
}
}
*/
if (m_BrowserTree == NULL)
{
lResult = m_BrowserTree.CoCreateInstance(CLSID_WebBrowserTreeRoot);
ATLASSERT(SUCCEEDED(lResult));
if (FAILED(lResult))
return ;
m_BrowserTree->EnableSoftReload(!m_bDynamicPage);
}
ATLASSERT(m_BrowserTree);
lResult = m_BrowserTree->Add(lBrowser, CComBSTR(lUrl.extendedUrlString()));
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebDocumentComplete(LPDISPATCH pDisp, VARIANT* URL)
{
// ATLASSERT(m_BrowserTree);
m_bInDocumentComplete = TRUE;
// pDisp == IWebBrowser2
CComQIPtr lLocalWebBrowser(pDisp);
CComPtr lDocumentDispatch;
ATLASSERT(lLocalWebBrowser);
m_NavigatingFramesList.Remove(lLocalWebBrowser.p);
m_NavigateCount = m_NavigatingFramesList.GetSize();
lLocalWebBrowser->get_Document(&lDocumentDispatch);
ATLASSERT(URL);
ATLASSERT(URL->vt == VT_BSTR);
CComBSTR lBstrUrl(URL->bstrVal);
CString lUrlString(URL->bstrVal);
TUrl lUrl(lUrlString);
BOOL lStorable;
HRESULT lResult;
#ifdef _DEBUG
KB_LOG_INFO2(_T("[0x%1!x!]::DocumentComplete(%2)"), pDisp, lUrlString);
#endif // _DEBUG
if (m_BrowserTree)
{
CComQIPtr lRootNode(m_BrowserTree);
ATLASSERT(lRootNode);
// Very important: in order to add correctly annotations, we have to know at node level
// that we are in the document complete state
if (lRootNode)
lRootNode->SetState(lLocalWebBrowser, T_NODE_STATE_COMPLETE);
}
lStorable = StorableProtocol(lUrl.getScheme());
if (lStorable)
{
if (lUrl.getExtendedInfo() == NULL)
{
TUrl lBaseUrl(m_InitialUrl);
if (lBaseUrl.getExtendedInfo())
lUrl.setExtendedInfo(lBaseUrl.getExtendedInfo()->clone());
}
}
lUrl.canonicalize();
CString lExtUrl = lUrl.extendedUrlString();
CString lSimpleUrl = lUrl.simpleUrlString();
lBstrUrl = lExtUrl;
CComQIPtr lLocalDocument(lDocumentDispatch);
if ((lLocalDocument == NULL) || (lBstrUrl.Length() == 0))
{
m_bInDocumentComplete = FALSE;
return ;
}
BOOL lBaseHref = FALSE;
CheckBaseHref(lLocalDocument, lExtUrl, &lBaseHref);
// ATLASSERT(!lBaseHref);
if (lBaseHref)
{
// Reload(REFRESH_NORMAL);
// return ;
}
// Check url
if (TTrash::isPageInTrash(fModel))
{
webAddTrashImage(lLocalDocument);
}
if (m_NavigateCount > 0)
{
m_bInDocumentComplete = FALSE;
return ;
}
// Add Annotations
webAddAnnotations(lBstrUrl);
// We're in a Root WebBrowser
if (m_RootDispatch == pDisp)
{
m_bAnnotationAllowed = TRUE;
// CheckPicturePage(lLocalDocument);
CheckMetaTags();
// Stretch
m_bDoStretch = NeedStretch();
if (m_bDoStretch)
{
lResult = doStretch();
// If fail, do not store in DB
if (FAILED(lResult))
lStorable = FALSE;
}
if (lStorable)
{
// Update DB
webUpdateContent(lExtUrl);
webSaveSubContentsInDb(lLocalWebBrowser);
}
#ifdef ALLOW_PDF_FILE
CheckPDFFile();
#endif // ALLOW_PDF_FILE
#ifdef UPDATE_SCROLL_AFTER_SOFT_RELOAD
if (m_SoftReloadTree)
{
m_SoftReloadTree->AfterReloadUpdate(m_BrowserTree);
m_SoftReloadTree = NULL;
}
#endif // UPDATE_SCROLL_AFTER_SOFT_RELOAD
SetLoaded(TRUE);
ReportResult(S_OK);
}
m_bInDocumentComplete = FALSE;
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebTitleChange(LPCTSTR pText)
{
// modify the title only if not already present
if (!HaveUserDefinedTitle(getModel()) && m_bStoreTitle && !m_bCanceling)
{
CString lText(pText);
if (lText.Find(':') > 0)
{
TUrl lUrl(lText);
if (lUrl.getScheme(true).GetLength() == 0)
{
lText = lUrl.simpleUrlString();
if (lText.Find("internal:") == 0)
lText = " ";
}
else
lText.Empty();
}
if (lText.GetLength())
getModel()->setTitle(lText);
}
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebNewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel)
{
TNewHtmlWindow* lNewView;
if (m_ExternalAdBanner < T_MAX_NEW_WINDOW)
{
lNewView = new TNewHtmlWindow(getModel(), m_bUserClick);
if (lNewView->CreateBrowser(this, WS_CHILD))
{
m_ExternalAdBanner++;
// HRESULT lResult;
// lResult = m_BrowserTree->AddAdjacentTree(lNewView->m_pBrowserApp);
// ATLASSERT(SUCCEEDED(lResult));
CWnd* lWnd = lNewView;
m_AdBannerList.Add(lWnd);
*ppDisp = lNewView->m_pBrowserApp;
(*ppDisp)->AddRef();
*Cancel = FALSE;
return ;
}
}
*Cancel = TRUE;
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebStatusTextChange(LPCTSTR Text)
{
SetStatus(Text);
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebDownloadComplete()
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebDownloadBegin()
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebPropertyChange(LPCTSTR szProperty)
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebCommandStateChange(long Command, BOOL Enable)
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebQuit()
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebVisible(BOOL Visible)
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebToolBar(BOOL ToolBar)
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebMenuBar(BOOL MenuBar)
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebStatusBar(BOOL StatusBar)
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebFullScreen(BOOL FullScreen)
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebTheaterMode(BOOL TheaterMode)
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnWebMouseMove(short a, short b, long x, long y)
{
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
HRESULT TBaseWebBrowserPageletCtrl::doStretch(DWORD pFlags)
{
m_StretchFlags = pFlags;
HRESULT lResult = S_FALSE;
if (!m_BrowserTree)
return E_FAIL;
CComPtr lDocument;
CComPtr lDomUtils;
if (FAILED(m_BrowserTree->get_Document(&lDocument)))
return E_FAIL;
lResult = lDomUtils.CoCreateInstance(CLSID_DomUtils);
ATLASSERT(SUCCEEDED(lResult));
if (FAILED(lResult))
return lResult;
TRACE(_T(" -----------------------------\n"));
TRACE(_T(" ------ Starting Stretch -----\n"));
TRACE(_T(" -----------------------------\n"));
CComObject* lStretchSink;
CComPtr lSink;
CComObject::CreateInstance(&lStretchSink);
lStretchSink->setDom(lDocument);
lStretchSink->setPagelet(this);
lStretchSink->setStretching(TRUE);
m_StretchSink = lStretchSink;
lSink = lStretchSink;
lResult = lDomUtils->DomStretcher(m_BrowserTree, 0, lSink);
#ifndef USE_OLE_ZOOM
CComCmdTarget lTarget(lDocument);
ATLASSERT(lTarget);
// CComQIPtr lDoc(lDocument);
if (lTarget && lStretchSink->getStretching())
{
// Should be available under IE 5.5
if (lTarget.IsSupported(IDM_ZOOMRATIO, &CGID_MSHTML))
{
CComVariant lFactor(0.5f);
lResult = lTarget.Exec(IDM_ZOOMRATIO, OLECMDEXECOPT_DONTPROMPTUSER, &lFactor, NULL, &CGID_MSHTML);
}
else if (lTarget.IsSupported(OLECMDID_ZOOM))
{
VARIANT lVariant;
lResult = lTarget.Exec(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, NULL, &lVariant);
if (lResult == S_OK)
{
CComVariant lValue(lVariant);
if (lValue.ChangeType(VT_I4) == S_OK)
{
long lZoom = lValue.lVal;
if (lZoom)
{
lZoom--;
lValue.lVal = lZoom;
lValue.Detach(&lVariant);
lResult = lTarget.Exec(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &lVariant, NULL);
}
}
}
}
}
#endif // USE_OLE_ZOOM
TRACE(_T(" ----------------------------\n"));
TRACE(_T(" ----- Stopping Stretch -----\n"));
TRACE(_T(" ----------------------------\n"));
lStretchSink->setStretching(FALSE);
m_StretchSink = NULL;
return lResult;
}
#ifdef SEARCH_FOR_HIDDEN_EVENT
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnEmpty()
{
ATLASSERT(NULL);
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::OnBstr(LPCTSTR lString)
{
ATLASSERT(NULL);
}
#endif // SEARCH_FOR_HIDDEN_EVENT/*------------ TWBPageletCtl_WebUtils.cpp ------------*/
#include "StdAfx.h"
#include "ProductName.h"
#include "mshtml.h"
#include "TBaseWBPageletCtl.h"
#include "TWBPageletCtl_Utils.h"
#include "PageletCtrl.h"
#include "TGlobalsDB.h"
#include "TDBManager.h"
#include "TMetaManager.h"
#include "TModelNames.h"
#include "TBookModel.h"
#include "TSummaryModel.h"
#include "TContentModel.h"
#include "TContextModel.h"
#include "TContentsBagModel.h"
#include "TStickerModel.h"
#include "THighlighterModel.h"
#include "TPropertyObjectModel.h"
#include "TModelPtr.h"
#include "TPageNumbering.h"
#include "TModelIterator.h"
#include "TContentPropertiesConstants.h"
#include "TModelHelpers.h"
#include "SharedLookAndFeelRes.h"
#include "TPageletResource.h"
#include "MultipleButton.h"
#include "TWebToolbar.h"
#include "TWebBrowser.h"
#include "TScriptFunction.h"
#include "TWizardHelper.h"
#include "TStringToPtrHashTable.h"
#include "TInteger.h"
#include "TSevenixUrlInfo.h"
#include "TSevenixUrl.h"
#include "TUrl.h"
#include "TTime.h"
#include "TPoint.h"
#include "TLookAndFeel.h"
#include "TLanguage.h"
#include "TErr.h"
#include "TUserMessage.h"
#include "TAppInfo.h"
#include "IEVersion.h"
#include "Net.h"
#define _MIDL_USE_GUIDDEF_
//#include "Net_i.c"
#include "TNetHelpers.h"
#include "Dom.h"
#define _MIDL_USE_GUIDDEF_
//#include "Dom_i.c"
//#include "TFrameTargetGenerator.h"
//#include "TDomFrameCrawler.h"
#include "TDomHelper.h"
//#include "TDomSaver.h"
#include "TWBSaveFrameSink.h"
#include "TDeleteCacheEntryCallback.h"
#include "Controler.h"
//#include "Script.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// ****************************************************************
#ifdef _DEBUG
void FindInterface(IUnknown* pDispatch);
#endif
void CallOnload(IDispatch* pDisp)
{
CComQIPtr lBrowser(pDisp);
CComPtr lDocDisp;
CComQIPtr lDoc;
CComPtr lBodyElem;
CComQIPtr lBody;
CComVariant lOnloadVal;
lBrowser->get_Document(&lDocDisp);
lDoc = lDocDisp;
if (lDoc)
lDoc->get_body(&lBodyElem);
lBody = lBodyElem;
if (lBody)
lBody->get_onload(&lOnloadVal);
DISPPARAMS pdp;
CComVariant lResult;
EXCEPINFO lExcep;
UINT lErr;
if (lOnloadVal.vt == VT_DISPATCH)
lOnloadVal.pdispVal->Invoke(0, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &pdp, &lResult, &lExcep, &lErr);
}
BOOL TBaseWebBrowserPageletCtrl::IsAutomaticRenavigation(BSTR* pUrl)
{
// On IE 5.5 ( And after ? )
// Automatic renavigation must be handle in an other way !!!
// if (!m_bFirstNavigate || m_IsLoaded) // && MinimumIEVersion(5,5))
{
CComQIPtr lCollec;
CComQIPtr lMetaElement;
CComPtr lDispatch;
HRESULT lResult;
long lIndex = 0;
long lLength = 0;
lResult = GetMetaCollection(&lCollec);
if (SUCCEEDED(lResult) && lCollec)
{
lResult = lCollec->get_length(&lLength);
ASSERT(SUCCEEDED(lResult));
}
while (lIndex < lLength)
{
if (lCollec)
{
lResult = lCollec->item(CComVariant(lIndex), CComVariant(), &lDispatch);
lMetaElement = lDispatch;
lDispatch = NULL;
ASSERT(SUCCEEDED(lResult) && lMetaElement);
}
if (SUCCEEDED(lResult) && lMetaElement)
{
// Get the HTTP-EQUIV command
CComBSTR lValue;
lResult = lMetaElement->get_httpEquiv(&lValue);
// If it's a Refresh
if (SUCCEEDED(lResult)
&& lValue
&& !wcsicmp(L"REFRESH", lValue))
{
LPCWSTR lUrl;
CComBSTR lContent;
// If it contain and URL (ie: the string is of type "time; URL=url")
lResult = lMetaElement->get_content(&lContent);
if (SUCCEEDED(lResult)
&& lContent)
{
// USES_CONVERSION;
// KB_LOG_INFO1(_T("HTTP Refresh: %1"), W2CT(lContent));
lUrl = wcschr(lContent, L';');
if (lUrl && (lUrl - lContent <= 1))
{
lUrl++;
while (*lUrl == L' ')
lUrl++;
if (!wcsnicmp(L"URL=", lUrl, 4))
lUrl += 4;
else
lUrl = NULL;
if (lUrl && (*lUrl != L'\0'))
{
*pUrl = ::SysAllocString(lUrl);
return TRUE;
}
}
}
}
}
lIndex++;
}
// if (MinimumIEVersion(5,5))
return FALSE;
}
// automatic renavigation
// return (!m_bFirstNavigate && !m_bUserClick);
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
BOOL TBaseWebBrowserPageletCtrl::NeedCreateNewPage(IWebBrowser2* pBrowser, BSTR pUrl, long pFlags, BSTR pTargetFrameName, VARIANT* pPostData, BSTR pHeaders, BOOL* pCancel)
{
USES_CONVERSION;
CString lUrl(pUrl);
CString lHeaders(pHeaders);
CString lTargetFrame(pTargetFrameName);
CComVariant lPostData;
if (pPostData)
lPostData = *pPostData->pvarVal;
TUrl lUrlClass(lUrl);
CString lScheme = lUrlClass.getScheme();
ATLTRACE(_T(" >> BeforeNavigate: %s (%s)\n"), lUrl, lTargetFrame);
CComBSTR lRedirectUrl;
// automatic renavigation
if (IsAutomaticRenavigation(&lRedirectUrl))
{
CComQIPtr lDispatch(pBrowser);
if (!lUrlClass.equals(W2CT(lRedirectUrl)))
{
lUrlClass.CombineUrl(W2CT(lRedirectUrl));
// KB_LOG_INFO1(_T("RedirectTo: %1"), lUrlClass.extendedUrlString());
RedirectTo(lUrlClass.extendedUrlString(), pBrowser);
*pCancel = TRUE;
return FALSE;
}
// Is this the Root document ?
if (m_RootDispatch == lDispatch)
{
// Case of HTTP redirection ?
m_CurrentUrl.Empty();
m_CurrentUrl = lUrl;
m_bRedirected = TRUE;
}
// Do not create a new page
return FALSE;
}
if (m_NavigateCount > 1)
return FALSE;
TModelPtr lNetworkProp;
TModelPtr lContent;
boolean lPropBool;
getModel()->getContent(&lContent);
ATLASSERT(lContent);
if (lContent)
GetModelProperty(lContent, T_CONTENT_NETWORK_PROPERTIES, &lNetworkProp);
//
// Is this a Post
if (!m_bUserClick && (lPostData.vt != VT_EMPTY) && lNetworkProp && !m_bRedirected)
{
m_bDynamicPage = TRUE;
// If do have flag first time nav
if (lNetworkProp->getBooleanField("first-nav", &lPropBool) && lPropBool)
{
// Remove flag has this is not the first time anymore !!!
lNetworkProp->putBooleanField("first-nav", FALSE);
lNetworkProp->putStringField(T_CONTENT_NETWORK_POST_DATA, "null");
// lNetworkProp->removeField(T_CONTENT_NETWORK_HEADERS);
}
else
{
// Post UnAvailable
// IDR_HTML_ABOUT_POST_NOT_CACHED
CString lRedirectUrl(KEEBOO_NETWORK_PROTOCOL":internal://language/10023?");
lRedirectUrl += lUrlClass.getHost();
RedirectTo(lRedirectUrl);
m_bRedirected = TRUE;
m_bStoreTitle = FALSE;
*pCancel = TRUE;
return FALSE;
}
}
ATLASSERT(m_pNetStatus != NULL);
if ((m_pNetStatus != NULL)
&& (StorableProtocol(lScheme)
|| HaveNetworkFlags(getModel(), F_CONTENT_NETWORK_REMOTE_DATA)))
{
CComBSTR lBstrUrl(lUrlClass.extendedUrlString());
BOOL lBool = FALSE;
LONG lAskCount = 0;
HRESULT lResult;
lResult = m_pNetStatus->GetOnline(&lBool);
// if we're offline
if (lBool == FALSE)
{
DWORD lAccess;
int lChoice = 0;
lResult = CheckDocumentLocalAccessibility(lBstrUrl, &lAccess);
// and if we do not have the document.
if (!(lAccess & DOCUMENT_CAN_ACCESS))
{
lResult = m_pNetStatus->GetOnline(&lBool, &lAskCount);
if (lAskCount == 1)
{
AFX_MANAGE_STATE(AfxGetAppModuleState());
// Ask the user if he wants to switch online
CDialog lDlg(IDD_SWITCH_ONLINE);
lChoice = lDlg.DoModal();
}
else
lChoice = IDCANCEL;
}
if (lChoice == IDOK)
{
TModelPtr lContext;
m_pNetStatus->SetOnline(TRUE);
TMetaManager::createModelInstance(T_CONTEXT_MODEL_NAME, (void**)&lContext);
lContext->setCurrentOnLineSwitch(TRUE);
}
else if (lChoice == IDCANCEL)
{
// was KEEBOO_NETWORK_PROTOCOL":about:OfflineInformation"
// IDR_HTML_ABOUT_OFFLINE
CString lRedirectUrl(KEEBOO_NETWORK_PROTOCOL":internal://language/10022");
// and if we do not have the document.
if (!(lAccess & DOCUMENT_CAN_ACCESS))
{
CComPtr lEntry;
// check if we have an older version.
lResult = CacheGetEntry(lBstrUrl, T_NETWORK_CACHE_NAME, &lEntry, T_CACHE_FRESHEST_ELEMENT);
if (SUCCEEDED(lResult) && lEntry)
{
CComBSTR lEntryUrl;
lEntry->getUrl(&lEntryUrl);
lRedirectUrl = lEntryUrl;
}
}
if (!m_bUserClick && !m_bRedirected)
{
RedirectTo(lRedirectUrl);
}
m_bStoreTitle = FALSE;
*pCancel = TRUE;
return FALSE;
}
}
else
{
// we're online
if (lNetworkProp && lNetworkProp->getBooleanField("online-reload", &lPropBool) && lPropBool)
{
PostMessage(WM_USER_RELOAD_PAGE, REFRESH_COMPLETELY);
lNetworkProp->removeField("online-reload");
return FALSE;
}
else if (lNetworkProp && lNetworkProp->getBooleanField("online-flush", &lPropBool) && lPropBool)
{
CComPtr lCache;
// check if we have an older version.
lResult = GetCache(T_NETWORK_CACHE_NAME, &lCache);
if (SUCCEEDED(lResult) && lCache)
{
lResult = lCache->deleteEntry(lBstrUrl);
if (SUCCEEDED(lResult))
lNetworkProp->removeField("online-flush");
}
}
}
}
// If we've just click on an URL link
// this pointer is == -1
// We don't want to follow scripting link.
// We don't want to follow mailto link.
if (!m_bFirstNavigate && StorableProtocol(lScheme))
{
TRACE(_T(" >> >> Not First Before Nav with : this(0x%x), Disp(0x%x), fDisp(0x%x)\n"), this, pBrowser, m_RootDispatch);
return TRUE;
}
return FALSE;
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::CreateNewPage(IWebBrowser2* pBrowser, BSTR URL, long Flags, BSTR TargetFrameName, VARIANT* PostData, BSTR Headers)
{
TModelPtr lContentsBag;
TModelPtr lContent;
TModelPtr lNewPage;
TModelPtr lBook;
TString lUrl(URL);
TString lHeaders(Headers);
CString lTargetFrame(TargetFrameName);
BOOL lForceGotoPage = FALSE;
BOOL lGeneratedPage = FALSE;
HRESULT lResult;
ePageSide2 lSide = T_SIDE_SECONDARY;
CString lPostStr;
// If the user click on a link
// the target is a frame
if (m_bUserClick && lTargetFrame.GetLength())
{
//
// Generate a frameset in the Cache
// For the new page
//
CComPtr lDomUtils;
CComBSTR lNewUrl;
lResult = lDomUtils.CoCreateInstance(CLSID_DomUtils);
ASSERT(SUCCEEDED(lResult));
if (SUCCEEDED(lResult))
{
lResult = lDomUtils->GenerateTargetFrameSet(m_BrowserTree, CComBSTR(m_CurrentUrl), URL, TargetFrameName, &lNewUrl);
// S_FALSE == 'No change'
//
// If the new Frameset was generated
// change the URL
//
if (lResult == S_OK)
{
lUrl = lNewUrl;
lGeneratedPage = TRUE;
}
}
}
// Get the content bag ( the list of content )
TMetaManager::createModelInstance(T_CONTENTS_BAG_MODEL_NAME, (void**)&lContentsBag);
ASSERT(lContentsBag);
TUrl lFindContentUrl(lUrl); // ?????
// Do we allready have this page in the list
lContentsBag->findContent(lFindContentUrl.extendedUrlString(), &lContent);
long lPostDim = 0;
if (PostData)
{
CComVariant lPostData;
lPostData = *PostData->pvarVal;
if (lPostData.vt & VT_ARRAY)
{
COleSafeArray lArray((VARIANT&)lPostData);
lPostDim = lArray.GetDim();
if (lPostDim)
{
ASSERT(lPostDim == 1);
long lSize = lArray.GetOneDimSize();
LPTSTR lBuffer;
long lIndex = 0;
lArray.PtrOfIndex(&lIndex, (void**)&lBuffer);
lPostStr = CString(lBuffer, lSize);
}
}
}
// If Content exist and we have a Post Data
// We need to check if the data are equal
if ((lContent != NULL) && lPostDim)
{
TModelPtr lProp;
BOOL lSamePost = FALSE;
GetModelProperty(lContent, T_CONTENT_NETWORK_PROPERTIES, &lProp, TRUE);
if (lProp != NULL)
{
TString lStoredPostStr;
if (lProp->getStringField(T_CONTENT_NETWORK_POST_DATA, &lStoredPostStr))
{
if (lStoredPostStr == lPostStr)
lSamePost = TRUE;
}
}
if (!lSamePost)
{
TUrl lNewUrl(lUrl);
TSevenixUrlInfo* lInfo;
lContent = NULL;
lInfo = (TSevenixUrlInfo*)lNewUrl.getExtendedInfo();
lInfo->setUniqueID();
lUrl = lNewUrl.extendedUrlString();
}
}
getModel()->getBook(&lBook);
ASSERT(lBook);
if (lContent != NULL)
{
lBook->findFirstPageOfContent(lContent, &lNewPage);
lForceGotoPage = ((lNewPage == NULL) ? FALSE : TRUE);
if (!(getState() & PAGELET_CURRENT))
lSide = T_SIDE_SECONDARY;
else
lSide = T_SIDE_PRIMARY;
}
CComPtr lBookControl;
lResult = lBookControl.CoCreateInstance(CLSID_TBookControler);
ASSERT(SUCCEEDED(lResult) && lBookControl);
// This is for Release Build
// So that we don't crash !!!!!
if (lBookControl == NULL)
return ;
if (lNewPage == NULL)
{
CComBSTR lBstrUrl = lUrl;
CComVariant lUrlVariant(lBstrUrl);
lSide = T_SIDE_SECONDARY;
// Cast because model are not COM interface !!!
lResult = lBookControl->Add(lUrlVariant, T_POS_CURRENT, (long*)&lNewPage);
ASSERT(SUCCEEDED(lResult) && lNewPage);
if (FAILED(lResult) || (lNewPage == NULL))
return ;
long lBehaviour = 0;
if (lGeneratedPage)
{
lBehaviour |= F_PAGE_GENERATED;
}
// set the temporary persistance info
AddBehaviour(lNewPage, lBehaviour | F_PAGE_TEMPORARY);
if (lPostDim)
{
TModelPtr lProp;
lContent = 0;
lNewPage->getContent(&lContent);
GetModelProperty(lContent, T_CONTENT_NETWORK_PROPERTIES, &lProp, TRUE);
ASSERT(lProp);
if (lProp != NULL)
{
lProp->putStringField(T_CONTENT_NETWORK_POST_DATA, lPostStr);
lProp->putStringField(T_CONTENT_NETWORK_HEADERS, lHeaders);
lProp->putBooleanField("first-nav", TRUE);
}
}
}
if (lNewPage)
{
// Cast because model are not COM interface !!!
CComVariant lPageVariant((long)lNewPage.p);
lResult = lBookControl->ChangePageTo(T_CPT_PAGE, lSide, lPageVariant);
}
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::webAddTrashImage(IHTMLDocument2* pDocument)
{
ASSERT(pDocument);
if (pDocument == NULL)
return ;
CComPtr lElement;
if (FAILED(pDocument->get_body(&lElement)))
return ;
CComQIPtr lBody(lElement);
if (lBody)
{
CString lPath;
CString lImg;
if (TLookAndFeel::GetCurrentLookAndFeelDllPath(lPath))
{
lImg.FormatMessage("res://%1/%2!d!", lPath, IDG_TRASH_BACKGROUND);
HRESULT lResult;
lResult = lBody->put_background(CComBSTR(lImg));
ASSERT(lResult == S_OK);
}
}
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::webUpdateContent(CString pUrl)
{
UpdatePageContent(getModel(), pUrl);
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::webAddAnnotations(BSTR pUrl)
{
// Check if we need annotation
TModelPtr lProp;
TModelIterator* lIterator = NULL;
HRESULT lResult;
boolean lBool = true;
long lIndex = 0;
TUrl lUrl(pUrl);
ASSERT(m_BrowserTree != NULL);
if (m_BrowserTree == NULL)
return;
CComPtr lNode;
lResult = m_BrowserTree->FindUrl(pUrl, &lNode);
if ( (!SUCCEEDED(lResult)) || (!lNode) )
lNode = m_BrowserTree;
// --- open a transaction
TDBManager *dbm = TGlobalsDB::getLibraryDBManager();
dbm->beginTransaction(t_transaction_types::TRANSACTION_READONLY);
getModel()->getDefaultProperty(&lProp);
if (lProp && !lProp->getBooleanField(T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY, &lBool))
lBool = true;
lIterator = getModel()->getAnnotations();
while (lIterator->hasMoreElements())
{
TModelPtr lAnnotation;
TUrl lContentUrl;
lIterator->nextElement((TObjectModel**)&lAnnotation);
lContentUrl = lAnnotation->getContent();
if (lContentUrl.equals(lUrl, FALSE))
{
lResult = AddAnnotation(lNode, lAnnotation, lBool);
ASSERT(SUCCEEDED(lResult));
}
else
{
ASSERT(lContentUrl.simpleUrlString().GetLength());
if (lContentUrl.simpleUrlString().GetLength() == 0)
lResult = E_FAIL;
}
if (FAILED(lResult) && lAnnotation->isInstanceOf(T_HIGHLIGHTER_MODEL_NAME))
{
#ifdef WARN_USER_BEFORE_DELETING_HIGHLIGHT
// Ask the user if it want to keep the annotation.
CDialog lDialog(IDD_HIGHLIGHTER_NOT_FOUND);
long lAction = lDialog.DoModal();
if (lAction == IDOK)
#endif // WARN_USER_BEFORE_DELETING_HIGHLIGHT
{
getModel()->removeAnnotation(lAnnotation);
delete lIterator;
lIterator = getModel()->getAnnotations();
lIterator->skip(lIndex);
continue;
}
}
lIndex++;
}
delete lIterator;
// --- close the transaction
dbm->commitTransaction();
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
void TBaseWebBrowserPageletCtrl::webSaveSubContentsInDb(IWebBrowser2* pBrowser)
{
HRESULT lResult;
// ASSERT(m_BrowserTree.m_Document != NULL);
ASSERT(m_BrowserTree);
if (m_BrowserTree == NULL)
return ;
m_BrowserTree->Add(pBrowser, NULL);
// --- open a transaction
TDBManager *dbm = TGlobalsDB::getLibraryDBManager();
dbm->beginTransaction(t_transaction_types::TRANSACTION_READONLY);
TModelPtr lContent;
getModel()->getContent(&lContent);
CArray< TContentModel*, TContentModel*> lData;
CComObject* lSaveSink;
CComPtr lSink;
CComPtr lDomUtils;
lResult = lDomUtils.CoCreateInstance(CLSID_DomUtils);
ASSERT(SUCCEEDED(lResult));
lResult = CComObject::CreateInstance(&lSaveSink);
ASSERT(SUCCEEDED(lResult));
if (lSaveSink)
{
lSaveSink->SetBase(m_CurrentUrl);
lResult = lSaveSink->QueryInterface(&lSink);
ASSERT(SUCCEEDED(lResult));
}
lData.Add(lContent);
lResult = lDomUtils->FrameCrawler(m_BrowserTree, lSink, CComVariant((long)&lData, VT_I4));
ASSERT(SUCCEEDED(lResult));
// --- close the transaction
dbm->commitTransaction();
}
HRESULT TBaseWebBrowserPageletCtrl::GetMetaCollection(IHTMLElementCollection** pCollec, IHTMLDocument2* pDocument)
{
CComPtr lDispatch;
CComQIPtr lDocument;
HRESULT lResult;
if (pDocument == NULL)
{
if (!m_BrowserTree)
return E_FAIL;
lResult = m_BrowserTree->get_Document(&lDispatch);
lDocument = lDispatch;
lDispatch = NULL;
ASSERT(SUCCEEDED(lResult) && lDocument);
if (FAILED(lResult) || (lDocument == NULL))
return E_FAIL;
}
else
{
lDocument = pDocument;
}
CComPtr lCollec;
lResult = lDocument->get_all(&lCollec);
ASSERT(SUCCEEDED(lResult) && lCollec);
if (FAILED(lResult) || (lCollec == NULL))
return E_FAIL;
lResult = lCollec->tags(CComVariant("META"), &lDispatch);
return lDispatch->QueryInterface(pCollec);
}
HRESULT TBaseWebBrowserPageletCtrl::CheckMetaTags()
{
CComQIPtr lCollec;
CComQIPtr lMetaElement;
CComPtr lDispatch;
HRESULT lResult;
long lIndex = 0;
long lLength = 1;
lResult = GetMetaCollection(&lCollec);
if (SUCCEEDED(lResult) && lCollec)
{
lResult = lCollec->get_length(&lLength);
ASSERT(SUCCEEDED(lResult));
}
while (lIndex < lLength)
{
if (lCollec)
{
lResult = lCollec->item(CComVariant(lIndex), CComVariant(), &lDispatch);
lMetaElement = lDispatch;
lDispatch = NULL;
ASSERT(SUCCEEDED(lResult) && lMetaElement);
}
if (SUCCEEDED(lResult) && lMetaElement)
{
//
CComBSTR lName;
lResult = lMetaElement->get_name(&lName);
if (SUCCEEDED(lResult)
&& lName
&& (!wcsicmp(CComBSTR(KEEBOO_PRODUCT_NAME), lName)
|| !wcsicmp(CComBSTR(KEEBOO_COMPANY), lName)))
{
CComBSTR lMetaContent;
lResult = lMetaElement->get_content(&lMetaContent);
if (SUCCEEDED(lResult) && lMetaContent)
{
if (!wcsicmp(L"no-stretch", lMetaContent))
{
m_bNoStretch = TRUE;
}
else if (!wcsicmp(L"no-cache", lMetaContent))
{
CComQIPtr lPageletSink(m_pControlSite);
if (lPageletSink)
{
CComObject* lCallback;
CComQIPtr lCBInterface;
CComObject::CreateInstance(&lCallback);
lCallback->SetPage(getModel());
lCBInterface = lCallback;
lPageletSink->SetDestroyCallback(lCallback);
}
}
else
{
TModelPtr lProp;
TModelPtr lContentModel;
if (!wcsicmp(L"online-reload", lMetaContent))
{
getModel()->getContent(&lContentModel);
GetModelProperty(lContentModel, T_CONTENT_NETWORK_PROPERTIES, &lProp, TRUE);
ASSERT(lProp);
if (lProp)
lProp->putBooleanField("online-reload", true);
}
else if (!wcsicmp(L"online-flush", lMetaContent))
{
getModel()->getContent(&lContentModel);
GetModelProperty(lContentModel, T_CONTENT_NETWORK_PROPERTIES, &lProp, TRUE);
ASSERT(lProp);
if (lProp)
lProp->putBooleanField("online-flush", true);
}
}
}
}
}
lIndex++;
}
return S_OK;
}
HRESULT TBaseWebBrowserPageletCtrl::CheckIsInternalPage(BSTR* pType)
{
CComQIPtr lCollec;
CComQIPtr lMetaElement;
CComPtr lDispatch;
HRESULT lResult;
long lIndex = 0;
long lLength = 1;
lResult = GetMetaCollection(&lCollec);
if (SUCCEEDED(lResult) && lCollec)
{
lResult = lCollec->get_length(&lLength);
ASSERT(SUCCEEDED(lResult));
}
BOOL lIsError = FALSE;
while (lIndex < lLength)
{
CComQIPtr lMetaElement;
if (lCollec)
{
lResult = lCollec->item(CComVariant(lIndex), CComVariant(), &lDispatch);
lMetaElement = lDispatch;
lDispatch = NULL;
ASSERT(SUCCEEDED(lResult) && lMetaElement);
}
if (SUCCEEDED(lResult) && lMetaElement)
{
//
CComBSTR lValue;
lResult = lMetaElement->get_name(&lValue);
if (SUCCEEDED(lResult) && lValue)
{
if (!wcsicmp(CComBSTR(KEEBOO_PRODUCT_NAME), lValue)
|| !wcsicmp(CComBSTR(KEEBOO_COMPANY), lValue))
{
lValue.Empty();
lResult = lMetaElement->get_content(&lValue);
if (SUCCEEDED(lResult) && lValue
&& (!wcsicmp(L"internal", lValue)
|| !wcsicmp(L"error", lValue))) // For compatibility
{
lIsError = TRUE;
}
}
if (!wcsicmp(L"Type", lValue))
{
lValue.Empty();
lResult = lMetaElement->get_content(&lValue);
if (SUCCEEDED(lResult) && lIsError)
{
return CComBSTR(lValue).CopyTo(pType);
}
}
}
}
lIndex++;
}
if (lIsError)
return S_OK;
return S_FALSE;
}
// ****************************************************************
//
// Description:
//
//
// Inputs:
//
//
// Return Value:
//
//
// Remarks:
//
//
HRESULT TBaseWebBrowserPageletCtrl::CheckBaseHref(IHTMLDocument2* pDocument, LPCTSTR pUrl, BOOL* pBaseHref)
{
HRESULT lResult = S_OK;
ASSERT(pBaseHref);
if (pBaseHref == NULL)
return E_INVALIDARG;
*pBaseHref = FALSE;
ASSERT(pDocument);
if (pDocument == NULL)
return E_INVALIDARG;
// TEMP
// --- Check the that BASE Tag is not present
// If present, warn us that this page is not reliable
CComPtr lCollec;
lResult = pDocument->get_all(&lCollec);
ATLASSERT(SUCCEEDED(lResult) && lCollec);
if (FAILED(lResult))
return lResult;
COleVariant lVariant("BASE");
CComPtr lBase;
lResult = lCollec->tags(lVariant, &lBase);
if (FAILED(lResult))
return lResult;
CComQIPtr lCollec2(lBase);
if (lCollec2)
{
long lLength;
lCollec2->get_length(&lLength);
lBase.Release();
if (lLength)
{
COleVariant lNullVariant((long)0);
lResult = lCollec2->item(lNullVariant, lNullVariant, &lBase);
}
}
CComQIPtr