mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
919 lines
20 KiB
C++
919 lines
20 KiB
C++
#include "stdafx.h"
|
|
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include "MemoryUtils.h"
|
|
#include "StringExt.h"
|
|
#include "Object.h"
|
|
#include "Array.h"
|
|
#include "Dict.h"
|
|
#include "Link.h"
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// LinkAction
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
LinkAction *LinkAction::ParseDestination(Object *pObject)
|
|
{
|
|
LinkAction *pAction = new LinkGoTo( pObject );
|
|
|
|
if ( !pAction->CheckValidate() )
|
|
{
|
|
delete pAction;
|
|
return NULL;
|
|
}
|
|
return pAction;
|
|
}
|
|
|
|
LinkAction *LinkAction::ParseAction(Object *pObject, StringExt *seBaseURI)
|
|
{
|
|
LinkAction *pAction = NULL;
|
|
|
|
if ( !pObject->IsDict() )
|
|
{
|
|
// TO DO: Error "Bad annotation action"
|
|
return NULL;
|
|
}
|
|
|
|
// S (òèï Action)
|
|
Object oType;
|
|
pObject->DictLookup("S", &oType);
|
|
|
|
// GoTo action
|
|
if ( oType.IsName("GoTo") )
|
|
{
|
|
Object oD;
|
|
pObject->DictLookup("D", &oD);
|
|
pAction = new LinkGoTo(&oD);
|
|
oD.Free();
|
|
}
|
|
else if ( oType.IsName("GoToR") ) // GoToR action
|
|
{
|
|
Object oF, oD;
|
|
pObject->DictLookup("F", &oF);
|
|
pObject->DictLookup("D", &oD);
|
|
pAction = new LinkGoToR( &oF, &oD );
|
|
oF.Free();
|
|
oD.Free();
|
|
}
|
|
else if ( oType.IsName("Launch") ) // Launch action
|
|
{
|
|
pAction = new LinkLaunch(pObject);
|
|
}
|
|
else if ( oType.IsName("URI") ) // URI action
|
|
{
|
|
Object oURI;
|
|
pObject->DictLookup("URI", &oURI);
|
|
pAction = new LinkURI( &oURI, seBaseURI );
|
|
oURI.Free();
|
|
}
|
|
else if ( oType.IsName("Named") ) // Named action
|
|
{
|
|
Object oN;
|
|
pObject->DictLookup("N", &oN);
|
|
pAction = new LinkNamed(&oN);
|
|
oN.Free();
|
|
}
|
|
else if ( oType.IsName("Movie") ) // Movie action
|
|
{
|
|
Object oAnnot, oT;
|
|
pObject->DictLookupAndCopy("Annot", &oAnnot);
|
|
pObject->DictLookup("T", &oT);
|
|
pAction = new LinkMovie( &oAnnot, &oT );
|
|
oAnnot.Free();
|
|
oT.Free();
|
|
}
|
|
else if ( oType.IsName() ) // unknown action
|
|
{
|
|
pAction = new LinkUnknown(oType.GetName());
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Bad annotation action"
|
|
pAction = NULL;
|
|
}
|
|
|
|
oType.Free();
|
|
|
|
if ( pAction && !pAction->CheckValidate() )
|
|
{
|
|
delete pAction;
|
|
return NULL;
|
|
}
|
|
return pAction;
|
|
}
|
|
|
|
StringExt *LinkAction::GetFileSpecName(Object *pFileSpecObject)
|
|
{
|
|
StringExt *seName = NULL;
|
|
|
|
if ( pFileSpecObject->IsString() )
|
|
{
|
|
seName = pFileSpecObject->GetString()->Copy();
|
|
}
|
|
else if ( pFileSpecObject->IsDict() )
|
|
{
|
|
Object oTemp;
|
|
if ( !pFileSpecObject->DictLookup("DOS", &oTemp)->IsString() )
|
|
{
|
|
oTemp.Free();
|
|
pFileSpecObject->DictLookup("F", &oTemp);
|
|
}
|
|
if ( oTemp.IsString() )
|
|
{
|
|
seName = oTemp.GetString()->Copy();
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Illegal file spec in link"
|
|
}
|
|
oTemp.Free();
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Illegal file spec in link"
|
|
}
|
|
|
|
if ( seName )
|
|
{
|
|
// Ïðîèçâîäèì ïðåîáðàçîâàíèÿ, ñâÿçàííûå ñ ôîðìîé çàïèñè ïóòåé
|
|
|
|
// "//...." --> "\...."
|
|
// "/x/...." --> "x:\...."
|
|
// "/server/share/...." --> "\\server\share\...."
|
|
|
|
int nCurIndex = 0;
|
|
if ( seName->GetAt(0) == '/' )
|
|
{
|
|
if ( seName->GetLength() >= 2 && seName->GetAt(1) == '/' )
|
|
{
|
|
seName->Delete(0);
|
|
nCurIndex = 0;
|
|
}
|
|
else if ( seName->GetLength() >= 2 && ((seName->GetAt(1) >= 'a' && seName->GetAt(1) <= 'z') || (seName->GetAt(1) >= 'A' && seName->GetAt(1) <= 'Z')) && (seName->GetLength() == 2 || seName->GetAt(2) == '/') )
|
|
{
|
|
seName->SetAt( 0, seName->GetAt(1) );
|
|
seName->SetAt( 1, ':' );
|
|
nCurIndex = 2;
|
|
}
|
|
else
|
|
{
|
|
int nJ;
|
|
for ( nJ = 2; nJ < seName->GetLength(); ++nJ )
|
|
{
|
|
if ( seName->GetAt(nJ - 1) != '\\' && seName->GetAt(nJ) == '/' )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if ( nJ < seName->GetLength() )
|
|
{
|
|
seName->SetAt(0, '\\');
|
|
seName->Insert(0, '\\');
|
|
nCurIndex = 2;
|
|
}
|
|
}
|
|
}
|
|
for (; nCurIndex < seName->GetLength(); ++nCurIndex)
|
|
{
|
|
if ( seName->GetAt(nCurIndex) == '/' )
|
|
{
|
|
seName->SetAt(nCurIndex, '\\');
|
|
}
|
|
else if ( seName->GetAt(nCurIndex) == '\\' && nCurIndex + 1 < seName->GetLength() && seName->GetAt(nCurIndex + 1) == '/' )
|
|
{
|
|
seName->Delete(nCurIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
return seName;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// LinkDest
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
LinkDestination::LinkDestination(Array *pArray)
|
|
{
|
|
m_dLeft = m_dBottom = m_dRight = m_dTop = m_dZoom = 0;
|
|
m_bValidate = FALSE;
|
|
|
|
if ( pArray->GetCount() < 2 )
|
|
{
|
|
// TO DO: Error "Annotation destination array is too short"
|
|
return;
|
|
}
|
|
|
|
Object oArrayItem;
|
|
pArray->GetCopy( 0, &oArrayItem );
|
|
|
|
if ( oArrayItem.IsInt() )
|
|
{
|
|
m_nPageNum = oArrayItem.GetInt() + 1;
|
|
m_bPageIsRef = FALSE;
|
|
}
|
|
else if ( oArrayItem.IsRef() )
|
|
{
|
|
m_oPageRef.nNum = oArrayItem.GetRefNum();
|
|
m_oPageRef.nGen = oArrayItem.GetRefGen();
|
|
m_bPageIsRef = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Bad annotation destination"
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
oArrayItem.Free();
|
|
|
|
// Destination type
|
|
pArray->Get( 1, &oArrayItem );
|
|
|
|
if ( oArrayItem.IsName("XYZ") )
|
|
{
|
|
m_eType = destXYZ;
|
|
Object oTemp;
|
|
if ( pArray->GetCount() < 3 )
|
|
{
|
|
m_bChangeLeft = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pArray->Get( 2, &oTemp );
|
|
if ( oTemp.IsNull() )
|
|
{
|
|
m_bChangeLeft = FALSE;
|
|
}
|
|
else if ( oTemp.IsNum() )
|
|
{
|
|
m_bChangeLeft = TRUE;
|
|
m_dLeft = oTemp.GetNum();
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
oTemp.Free();
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
oTemp.Free();
|
|
}
|
|
if ( pArray->GetCount() < 4 )
|
|
{
|
|
m_bChangeTop = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pArray->Get( 3, &oTemp );
|
|
if ( oTemp.IsNull() )
|
|
{
|
|
m_bChangeTop = FALSE;
|
|
}
|
|
else if ( oTemp.IsNum() )
|
|
{
|
|
m_bChangeTop = TRUE;
|
|
m_dTop = oTemp.GetNum();
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
oTemp.Free();
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
oTemp.Free();
|
|
}
|
|
if ( pArray->GetCount() < 5 )
|
|
{
|
|
m_bChangeZoom = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pArray->Get( 4, &oTemp );
|
|
if ( oTemp.IsNull() )
|
|
{
|
|
m_bChangeZoom = FALSE;
|
|
}
|
|
else if ( oTemp.IsNum() )
|
|
{
|
|
m_bChangeZoom = TRUE;
|
|
m_dZoom = oTemp.GetNum();
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
oTemp.Free();
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
oTemp.Free();
|
|
}
|
|
}
|
|
else if ( oArrayItem.IsName("Fit") )
|
|
{
|
|
if ( pArray->GetCount() < 2 )
|
|
{
|
|
// TO DO: Error "Annotation destination array is too short"
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
m_eType = destFit;
|
|
}
|
|
else if ( oArrayItem.IsName("FitH") )
|
|
{
|
|
if ( pArray->GetCount() < 3 )
|
|
{
|
|
// TO DO: Error "Annotation destination array is too short"
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
m_eType = destFitH;
|
|
|
|
Object oTemp;
|
|
if ( !pArray->Get(2, &oTemp)->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
m_eType = destFit;
|
|
}
|
|
m_dTop = oTemp.GetNum();
|
|
oTemp.Free();
|
|
}
|
|
else if ( oArrayItem.IsName("FitV") )
|
|
{
|
|
if ( pArray->GetCount() < 3 )
|
|
{
|
|
// TO DO: Error "Annotation destination array is too short"
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
m_eType = destFitV;
|
|
|
|
Object oTemp;
|
|
if ( !pArray->Get(2, &oTemp)->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
m_eType = destFit;
|
|
}
|
|
m_dLeft = oTemp.GetNum();
|
|
oTemp.Free();
|
|
}
|
|
else if ( oArrayItem.IsName("FitR") )
|
|
{
|
|
if ( pArray->GetCount() < 6 )
|
|
{
|
|
// TO DO: Error "Annotation destination array is too short"
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
m_eType = destFitR;
|
|
|
|
Object oTemp;
|
|
if ( !pArray->Get(2, &oTemp)->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
m_eType = destFit;
|
|
}
|
|
m_dLeft = oTemp.GetNum();
|
|
oTemp.Free();
|
|
|
|
if ( !pArray->Get(3, &oTemp)->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
m_eType = destFit;
|
|
}
|
|
m_dBottom = oTemp.GetNum();
|
|
oTemp.Free();
|
|
|
|
if ( !pArray->Get(4, &oTemp)->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
m_eType = destFit;
|
|
}
|
|
m_dRight = oTemp.GetNum();
|
|
oTemp.Free();
|
|
|
|
if ( !pArray->Get(5, &oTemp)->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
m_eType = destFit;
|
|
}
|
|
m_dTop = oTemp.GetNum();
|
|
oTemp.Free();
|
|
}
|
|
else if ( oArrayItem.IsName("FitB") )
|
|
{
|
|
if ( pArray->GetCount() < 2 )
|
|
{
|
|
// TO DO: Error "Annotation destination array is too short"
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
m_eType = destFitB;
|
|
}
|
|
else if ( oArrayItem.IsName("FitBH") )
|
|
{
|
|
if ( pArray->GetCount() < 3 )
|
|
{
|
|
// TO DO: Error "Annotation destination array is too short"
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
m_eType = destFitBH;
|
|
|
|
Object oTemp;
|
|
if ( !pArray->Get(2, &oTemp)->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
m_eType = destFit;
|
|
}
|
|
m_dTop = oTemp.GetNum();
|
|
oTemp.Free();
|
|
}
|
|
else if ( oArrayItem.IsName("FitBV") )
|
|
{
|
|
if ( pArray->GetCount() < 3 )
|
|
{
|
|
// TO DO: Error "Annotation destination array is too short"
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
m_eType = destFitBV;
|
|
|
|
Object oTemp;
|
|
if ( !pArray->Get(2, &oTemp)->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation destination position"
|
|
m_eType = destFit;
|
|
}
|
|
m_dLeft = oTemp.GetNum();
|
|
oTemp.Free();
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Unknown annotation destination type"
|
|
oArrayItem.Free();
|
|
return;
|
|
}
|
|
|
|
oArrayItem.Free();
|
|
m_bValidate = TRUE;
|
|
return;
|
|
}
|
|
|
|
LinkDestination::LinkDestination(LinkDestination *pDest)
|
|
{
|
|
m_eType = pDest->m_eType;
|
|
m_bPageIsRef = pDest->m_bPageIsRef;
|
|
|
|
if ( m_bPageIsRef )
|
|
m_oPageRef = pDest->m_oPageRef;
|
|
else
|
|
m_nPageNum = pDest->m_nPageNum;
|
|
|
|
m_dLeft = pDest->m_dLeft;
|
|
m_dBottom = pDest->m_dBottom;
|
|
m_dRight = pDest->m_dRight;
|
|
m_dTop = pDest->m_dTop;
|
|
m_dZoom = pDest->m_dZoom;
|
|
m_bChangeLeft = pDest->m_bChangeLeft;
|
|
m_bChangeTop = pDest->m_bChangeTop;
|
|
m_bChangeZoom = pDest->m_bChangeZoom;
|
|
m_bValidate = TRUE;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// LinkGoTo
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
LinkGoTo::LinkGoTo(Object *pDestObject)
|
|
{
|
|
m_pDestination = NULL;
|
|
m_pNamedDestination = NULL;
|
|
|
|
if ( pDestObject->IsName() )
|
|
{
|
|
m_pNamedDestination = new StringExt( pDestObject->GetName() );
|
|
}
|
|
else if ( pDestObject->IsString() )
|
|
{
|
|
m_pNamedDestination = pDestObject->GetString()->Copy();
|
|
}
|
|
else if ( pDestObject->IsArray() )
|
|
{
|
|
m_pDestination = new LinkDestination( pDestObject->GetArray() );
|
|
if ( !m_pDestination->CheckValidate() )
|
|
{
|
|
delete m_pDestination;
|
|
m_pDestination = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Illegal annotation destination"
|
|
}
|
|
}
|
|
|
|
LinkGoTo::~LinkGoTo()
|
|
{
|
|
if ( m_pDestination )
|
|
delete m_pDestination;
|
|
if ( m_pNamedDestination )
|
|
delete m_pNamedDestination;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// LinkGoToR
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
LinkGoToR::LinkGoToR(Object *pFileSpecObject, Object *pDestObject)
|
|
{
|
|
m_pDestination = NULL;
|
|
m_pNamedDestination = NULL;
|
|
|
|
m_seFileName = GetFileSpecName( pFileSpecObject );
|
|
|
|
if ( pDestObject->IsName() )
|
|
{
|
|
m_pNamedDestination = new StringExt( pDestObject->GetName() );
|
|
}
|
|
else if ( pDestObject->IsString() )
|
|
{
|
|
m_pNamedDestination = pDestObject->GetString()->Copy();
|
|
}
|
|
else if ( pDestObject->IsArray() )
|
|
{
|
|
m_pDestination = new LinkDestination( pDestObject->GetArray() );
|
|
if ( !m_pDestination->CheckValidate() )
|
|
{
|
|
delete m_pDestination;
|
|
m_pDestination = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Illegal annotation destination"
|
|
}
|
|
}
|
|
|
|
LinkGoToR::~LinkGoToR()
|
|
{
|
|
if ( m_seFileName )
|
|
delete m_seFileName;
|
|
if ( m_pDestination )
|
|
delete m_pDestination;
|
|
if ( m_pNamedDestination )
|
|
delete m_pNamedDestination;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// LinkLaunch
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
LinkLaunch::LinkLaunch(Object *pActionObject)
|
|
{
|
|
m_seFileName = NULL;
|
|
m_pParameters = NULL;
|
|
|
|
if ( pActionObject->IsDict() )
|
|
{
|
|
Object oSpecObject;
|
|
if ( !pActionObject->DictLookup("F", &oSpecObject)->IsNull() )
|
|
{
|
|
m_seFileName = GetFileSpecName(&oSpecObject);
|
|
}
|
|
else
|
|
{
|
|
oSpecObject.Free();
|
|
if ( pActionObject->DictLookup("Win", &oSpecObject)->IsDict() )
|
|
{
|
|
Object oTemp;
|
|
oSpecObject.DictLookup("F", &oTemp);
|
|
m_seFileName = GetFileSpecName(&oTemp);
|
|
oTemp.Free();
|
|
if ( oSpecObject.DictLookup("P", &oTemp)->IsString() )
|
|
{
|
|
m_pParameters = oTemp.GetString()->Copy();
|
|
}
|
|
oTemp.Free();
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Bad launch-type link action"
|
|
}
|
|
}
|
|
oSpecObject.Free();
|
|
}
|
|
}
|
|
|
|
LinkLaunch::~LinkLaunch()
|
|
{
|
|
if ( m_seFileName )
|
|
delete m_seFileName;
|
|
if ( m_pParameters )
|
|
delete m_pParameters;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// LinkURI
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
LinkURI::LinkURI(Object *pUriObject, StringExt *seBaseURI)
|
|
{
|
|
m_seURI = NULL;
|
|
if ( pUriObject->IsString() )
|
|
{
|
|
StringExt *seTempURI = pUriObject->GetString()->Copy();
|
|
if ( seBaseURI && seBaseURI->GetLength() > 0 )
|
|
{
|
|
int nCount = strcspn( seTempURI->GetBuffer(), "/:" );
|
|
if ( nCount == seTempURI->GetLength() || seTempURI->GetAt(nCount) == '/' )
|
|
{
|
|
m_seURI = seBaseURI->Copy();
|
|
int nChar = m_seURI->GetAt( m_seURI->GetLength() - 1);
|
|
if ( nChar == '/' || nChar == '?' )
|
|
{
|
|
if ( seTempURI->GetAt(0) == '/' )
|
|
{
|
|
seTempURI->Delete(0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( seTempURI->GetAt(0) != '/' )
|
|
{
|
|
m_seURI->Append('/');
|
|
}
|
|
}
|
|
m_seURI->Append( seTempURI );
|
|
delete seTempURI;
|
|
}
|
|
else
|
|
{
|
|
m_seURI = seTempURI;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_seURI = seTempURI;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Illegal URI-type link"
|
|
}
|
|
}
|
|
|
|
LinkURI::~LinkURI()
|
|
{
|
|
if ( m_seURI )
|
|
delete m_seURI;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// LinkNamed
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
LinkNamed::LinkNamed(Object *pNameObject)
|
|
{
|
|
m_seName = NULL;
|
|
if ( pNameObject->IsName() )
|
|
{
|
|
m_seName = new StringExt(pNameObject->GetName());
|
|
}
|
|
}
|
|
|
|
LinkNamed::~LinkNamed()
|
|
{
|
|
if ( m_seName )
|
|
{
|
|
delete m_seName;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// LinkMovie
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
LinkMovie::LinkMovie(Object *pAnnotObject, Object *pTitleObject)
|
|
{
|
|
m_oAnnotRef.nNum = -1;
|
|
m_seTitle = NULL;
|
|
if ( pAnnotObject->IsRef() )
|
|
{
|
|
m_oAnnotRef = pAnnotObject->GetRef();
|
|
}
|
|
else if ( pTitleObject->IsString() )
|
|
{
|
|
m_seTitle = pTitleObject->GetString()->Copy();
|
|
}
|
|
else
|
|
{
|
|
// TO DO: Error "Movie action is missing both the Annot and T keys"
|
|
}
|
|
}
|
|
|
|
LinkMovie::~LinkMovie()
|
|
{
|
|
if ( m_seTitle )
|
|
{
|
|
delete m_seTitle;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// LinkUnknown
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
LinkUnknown::LinkUnknown(char *sAction)
|
|
{
|
|
m_seAction = new StringExt( sAction );
|
|
}
|
|
|
|
LinkUnknown::~LinkUnknown()
|
|
{
|
|
if ( m_seAction )
|
|
delete m_seAction;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// Link
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
Link::Link(Dict *pDict, StringExt *seBaseURI)
|
|
{
|
|
m_pAction = NULL;
|
|
m_bValid = FALSE;
|
|
|
|
// Rect
|
|
Object oDictItem;
|
|
if ( !pDict->Search("Rect", &oDictItem)->IsArray() )
|
|
{
|
|
// TO DO: Error "Annotation rectangle is wrong type"
|
|
oDictItem.Free();
|
|
return;
|
|
}
|
|
|
|
Object oTemp;
|
|
if ( !oDictItem.ArrayGet( 0, &oTemp )->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation rectangle"
|
|
oTemp.Free();
|
|
oDictItem.Free();
|
|
return;
|
|
}
|
|
m_dLeft = oTemp.GetNum();
|
|
oTemp.Free();
|
|
|
|
if ( !oDictItem.ArrayGet( 1, &oTemp )->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation rectangle"
|
|
oTemp.Free();
|
|
oDictItem.Free();
|
|
return;
|
|
}
|
|
m_dBottom = oTemp.GetNum();
|
|
oTemp.Free();
|
|
|
|
if ( !oDictItem.ArrayGet( 2, &oTemp )->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation rectangle"
|
|
oTemp.Free();
|
|
oDictItem.Free();
|
|
return;
|
|
}
|
|
m_dRight = oTemp.GetNum();
|
|
oTemp.Free();
|
|
|
|
if ( !oDictItem.ArrayGet( 3, &oTemp )->IsNum() )
|
|
{
|
|
// TO DO: Error "Bad annotation rectangle"
|
|
oTemp.Free();
|
|
oDictItem.Free();
|
|
return;
|
|
}
|
|
m_dTop = oTemp.GetNum();
|
|
oTemp.Free();
|
|
oDictItem.Free();
|
|
|
|
if ( m_dLeft > m_dRight )
|
|
{
|
|
double dTemp = m_dLeft;
|
|
m_dLeft = m_dRight;
|
|
m_dRight = dTemp;
|
|
}
|
|
if ( m_dBottom > m_dTop )
|
|
{
|
|
double dTemp = m_dBottom;
|
|
m_dBottom = m_dTop;
|
|
m_dTop = dTemp;
|
|
}
|
|
|
|
// Dest
|
|
if ( !pDict->Search("Dest", &oDictItem)->IsNull() )
|
|
{
|
|
m_pAction = LinkAction::ParseDestination(&oDictItem);
|
|
}
|
|
else // A (Action)
|
|
{
|
|
oDictItem.Free();
|
|
if ( pDict->Search("A", &oDictItem)->IsDict() )
|
|
{
|
|
m_pAction = LinkAction::ParseAction(&oDictItem, seBaseURI);
|
|
}
|
|
}
|
|
oDictItem.Free();
|
|
|
|
if ( m_pAction )
|
|
{
|
|
m_bValid = TRUE;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
Link::~Link()
|
|
{
|
|
if ( m_pAction )
|
|
{
|
|
delete m_pAction;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
// Links
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
Links::Links(Object *pAnnots, StringExt *seBaseURI)
|
|
{
|
|
m_ppLinks = NULL;
|
|
m_nLinksCount = 0;
|
|
|
|
int nSize = 0;
|
|
|
|
if ( pAnnots->IsArray() )
|
|
{
|
|
for ( int nIndex = 0; nIndex < pAnnots->ArrayGetLength(); ++nIndex )
|
|
{
|
|
Object oArrayItem;
|
|
if ( pAnnots->ArrayGet( nIndex, &oArrayItem )->IsDict() )
|
|
{
|
|
Object oTemp;
|
|
if ( oArrayItem.DictLookup("Subtype", &oTemp)->IsName("Link") )
|
|
{
|
|
Link *pLink = new Link( oArrayItem.GetDict(), seBaseURI );
|
|
if ( pLink->CheckValidate() )
|
|
{
|
|
if ( m_nLinksCount >= nSize )
|
|
{
|
|
nSize += 16;
|
|
m_ppLinks = (Link **)MemUtilsReallocArray( m_ppLinks, nSize, sizeof(Link *));
|
|
}
|
|
m_ppLinks[m_nLinksCount++] = pLink;
|
|
}
|
|
else
|
|
{
|
|
if ( pLink )
|
|
delete pLink;
|
|
}
|
|
}
|
|
oTemp.Free();
|
|
}
|
|
oArrayItem.Free();
|
|
}
|
|
}
|
|
}
|
|
|
|
Links::~Links()
|
|
{
|
|
for ( int nIndex = 0; nIndex < m_nLinksCount; ++nIndex )
|
|
{
|
|
if ( m_ppLinks[nIndex] )
|
|
delete m_ppLinks[nIndex];
|
|
}
|
|
MemUtilsFree(m_ppLinks);
|
|
}
|
|
|
|
LinkAction *Links::Find(double dX, double dY)
|
|
{
|
|
for ( int nIndex = m_nLinksCount - 1; nIndex >= 0; --nIndex )
|
|
{
|
|
if ( m_ppLinks[nIndex]->InRect(dX, dY) )
|
|
{
|
|
return m_ppLinks[nIndex]->GetAction();
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
BOOL Links::OnLink(double dX, double dY)
|
|
{
|
|
for ( int nIndex = 0; nIndex < m_nLinksCount; ++nIndex )
|
|
{
|
|
if ( m_ppLinks[nIndex]->InRect(dX, dY) )
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|