Files
libreoffice/sw/source/core/fields/ddefld.cxx

451 lines
14 KiB
C++
Raw Normal View History

2000-09-18 23:08:29 +00:00
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2000-09-18 23:08:29 +00:00
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
2000-09-18 23:08:29 +00:00
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 23:08:29 +00:00
*
* This file is part of OpenOffice.org.
2000-09-18 23:08:29 +00:00
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
2000-09-18 23:08:29 +00:00
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
2000-09-18 23:08:29 +00:00
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
2000-09-18 23:08:29 +00:00
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
2000-09-18 23:08:29 +00:00
2010-01-13 22:25:07 +01:00
#include <sfx2/linkmgr.hxx>
2000-09-18 23:08:29 +00:00
#include <doc.hxx>
#include <editsh.hxx>
#include <errhdl.hxx>
#include <ndtxt.hxx>
#include <fmtfld.hxx>
#include <txtfld.hxx>
#include <ddefld.hxx>
#include <swtable.hxx>
#include <swbaslnk.hxx>
#include <swddetbl.hxx>
#ifndef _UNOFLDMID_H
#include <unofldmid.h>
2000-09-18 23:08:29 +00:00
#endif
#include <hints.hxx>
2000-09-18 23:08:29 +00:00
using rtl::OUString;
using namespace ::com::sun::star;
CWS-TOOLING: integrate CWS calc47 2008-12-10 20:38:34 +0100 oc r265231 : #i97115# 2008-12-09 14:19:59 +0100 oc r265084 : #i96939# 2008-12-09 11:55:29 +0100 oc r265073 : #i97061# 2008-12-09 11:37:05 +0100 oc r265067 : #i97061# 2008-12-09 11:31:49 +0100 oc r265066 : #i97061# 2008-12-09 11:30:30 +0100 oc r265065 : #i97061# 2008-12-04 17:13:43 +0100 er r264859 : DBG_ERROR needs semicolon 2008-12-04 02:34:13 +0100 er r264811 : unxsols4 needs to be compiled with exceptions when using STL 2008-12-04 02:24:30 +0100 er r264810 : WaE unxsols4: ScZoomSliderWnd::Update hides the function Window::Update() 2008-12-04 01:40:22 +0100 er r264809 : DBG_ASSERT needs semicolon 2008-12-03 11:00:55 +0100 er r264753 : CWS-TOOLING: rebase CWS calc47 to trunk@264325 (milestone: DEV300:m36) 2008-10-31 12:30:09 +0100 nn r262863 : #i90362# call CheckNeedsRepaint in UpdateFormulas 2008-10-29 14:49:48 +0100 nn r262802 : #i88521# initialization order (gcc warning) 2008-10-29 12:31:38 +0100 nn r262782 : #i88521# toolbar entry for scaling factor in page preview (patch from maoyg) 2008-10-29 12:31:00 +0100 nn r262781 : #i88521# toolbar entry for scaling factor in page preview (patch from maoyg) 2008-10-29 12:28:45 +0100 nn r262780 : #i88521# toolbar entry for scaling factor in page preview (patch from maoyg) 2008-10-28 17:01:37 +0100 nn r262756 : resolve gcc warnings 2008-10-28 13:46:07 +0100 nn r262742 : #i9709# always use system encoding for DDE (patch from rail) 2008-10-28 13:45:44 +0100 nn r262741 : #i9709# always use system encoding for DDE (patch from rail) 2008-10-27 20:55:51 +0100 nn r262689 : #i44349# refresh auto filter flags in ScUndoDragDrop::Redo (patch from gaozm) 2008-10-27 20:40:06 +0100 nn r262688 : #i4517# rename sheet with double click (patch from kohei) 2008-10-27 20:28:55 +0100 nn r262687 : #i20491# ensure stable sorting (patch from maoyg) 2008-10-27 20:13:19 +0100 nn r262686 : #i22758# direct sort (toolbar buttons): detect headers (patch from maoyg) 2008-10-27 19:42:51 +0100 nn r262685 : #i7277# default for sorting is cursor column (patch from maoyg) 2008-10-27 19:18:57 +0100 nn r262684 : #i7088# insert/delete columns/rows across selected sheets (patch from maoyg) 2008-10-27 18:59:43 +0100 nn r262683 : #i86856# show formula syntax in tip help (patch from maoyg) 2008-10-27 18:30:45 +0100 nn r262682 : #i89145# scroll wheel handling in page preview (patch from maoyg) 2008-10-27 18:03:10 +0100 nn r262681 : #i85226# take care of subtotal formulas in ScUndoQuery::Undo (patch from gaozm) 2008-10-27 17:41:16 +0100 nn r262680 : #i88437# add zoom slider in status bar also for Calc (patch from maoyg) 2008-10-27 15:53:52 +0100 nn r262678 : #i88467# undo for page margins/column widths in page preview (patch from maoyg)
2008-12-11 08:36:38 +00:00
#define DDE_TXT_ENCODING gsl_getSystemTextEncoding()
2000-09-18 23:08:29 +00:00
/*--------------------------------------------------------------------
Beschreibung: Globale Variablen
--------------------------------------------------------------------*/
class SwIntrnlRefLink : public SwBaseLink
{
SwDDEFieldType& rFldType;
public:
SwIntrnlRefLink( SwDDEFieldType& rType, USHORT nUpdateType, USHORT nFmt )
: SwBaseLink( nUpdateType, nFmt ),
rFldType( rType )
{}
virtual void Closed();
virtual void DataChanged( const String& rMimeType,
const uno::Any & rValue );
2000-09-18 23:08:29 +00:00
virtual const SwNode* GetAnchor() const;
virtual BOOL IsInRange( ULONG nSttNd, ULONG nEndNd, xub_StrLen nStt = 0,
xub_StrLen nEnd = STRING_NOTFOUND ) const;
};
void SwIntrnlRefLink::DataChanged( const String& rMimeType,
const uno::Any & rValue )
2000-09-18 23:08:29 +00:00
{
switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
2000-09-18 23:08:29 +00:00
{
case FORMAT_STRING:
if( !IsNoDataFlag() )
{
uno::Sequence< sal_Int8 > aSeq;
rValue >>= aSeq;
String sStr( (sal_Char*)aSeq.getConstArray(), static_cast<xub_StrLen>(aSeq.getLength()),
DDE_TXT_ENCODING );
2000-09-18 23:08:29 +00:00
// CR-LF am Ende entfernen, ist ueberfluessig!
xub_StrLen n = sStr.Len();
2001-04-12 16:50:46 +00:00
while( n && 0 == sStr.GetChar( n-1 ) )
--n;
2000-09-18 23:08:29 +00:00
if( n && 0x0a == sStr.GetChar( n-1 ) )
--n;
if( n && 0x0d == sStr.GetChar( n-1 ) )
--n;
BOOL bDel = n != sStr.Len();
if( bDel )
sStr.Erase( n );
rFldType.SetExpansion( sStr );
// erst Expansion setzen! (sonst wird das Flag geloescht!)
rFldType.SetCRLFDelFlag( bDel );
}
break;
// weitere Formate ...
default:
return;
}
ASSERT( rFldType.GetDoc(), "Kein pDoc" );
// keine Abhaengigen mehr?
if( rFldType.GetDepends() && !rFldType.IsModifyLocked() && !ChkNoDataFlag() )
{
ViewShell* pSh;
SwEditShell* pESh = rFldType.GetDoc()->GetEditShell( &pSh );
// dann suchen wir uns mal alle Felder. Wird kein gueltiges
// gefunden, dann Disconnecten wir uns!
SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
int bCallModify = FALSE;
rFldType.LockModify();
SwClientIter aIter( rFldType );
SwClient * pLast = aIter.GoStart();
if( pLast ) // konnte zum Anfang gesprungen werden ??
do {
// eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
if( !pLast->IsA( TYPE( SwFmtFld ) ) ||
((SwFmtFld*)pLast)->GetTxtFld() )
{
if( !bCallModify )
{
if( pESh )
pESh->StartAllAction();
else if( pSh )
pSh->StartAction();
}
pLast->Modify( 0, &aUpdateDDE );
bCallModify = TRUE;
}
} while( 0 != ( pLast = aIter++ ));
rFldType.UnlockModify();
if( bCallModify )
{
if( pESh )
pESh->EndAllAction();
else if( pSh )
pSh->EndAction();
if( pSh )
pSh->GetDoc()->SetModified();
}
}
}
void SwIntrnlRefLink::Closed()
{
if( rFldType.GetDoc() && !rFldType.GetDoc()->IsInDtor() )
{
// Advise verabschiedet sich, alle Felder in Text umwandeln ?
ViewShell* pSh;
SwEditShell* pESh = rFldType.GetDoc()->GetEditShell( &pSh );
if( pESh )
{
pESh->StartAllAction();
pESh->FieldToText( &rFldType );
pESh->EndAllAction();
}
else
{
pSh->StartAction();
// am Doc aufrufen ??
pSh->EndAction();
}
}
SvBaseLink::Closed();
}
const SwNode* SwIntrnlRefLink::GetAnchor() const
{
// hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen
const SwNode* pNd = 0;
SwClientIter aIter( rFldType );
SwClient * pLast = aIter.GoStart();
if( pLast ) // konnte zum Anfang gesprungen werden ??
do {
// eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
if( !pLast->IsA( TYPE( SwFmtFld ) ))
{
SwDepend* pDep = (SwDepend*)pLast;
SwDDETable* pDDETbl = (SwDDETable*)pDep->GetToTell();
pNd = pDDETbl->GetTabSortBoxes()[0]->GetSttNd();
}
else if( ((SwFmtFld*)pLast)->GetTxtFld() )
pNd = ((SwFmtFld*)pLast)->GetTxtFld()->GetpTxtNode();
if( pNd && &rFldType.GetDoc()->GetNodes() == &pNd->GetNodes() )
break;
pNd = 0;
} while( 0 != ( pLast = aIter++ ));
return pNd;
}
BOOL SwIntrnlRefLink::IsInRange( ULONG nSttNd, ULONG nEndNd,
xub_StrLen nStt, xub_StrLen nEnd ) const
{
// hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen
SwNodes* pNds = &rFldType.GetDoc()->GetNodes();
SwClientIter aIter( rFldType );
SwClient * pLast = aIter.GoStart();
if( pLast ) // konnte zum Anfang gesprungen werden ??
do {
// eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
if( !pLast->IsA( TYPE( SwFmtFld ) ))
{
SwDepend* pDep = (SwDepend*)pLast;
SwDDETable* pDDETbl = (SwDDETable*)pDep->GetToTell();
const SwTableNode* pTblNd = pDDETbl->GetTabSortBoxes()[0]->
GetSttNd()->FindTableNode();
if( pTblNd->GetNodes().IsDocNodes() &&
nSttNd < pTblNd->EndOfSectionIndex() &&
nEndNd > pTblNd->GetIndex() )
return TRUE;
}
else if( ((SwFmtFld*)pLast)->GetTxtFld() )
{
const SwTxtFld* pTFld = ((SwFmtFld*)pLast)->GetTxtFld();
const SwTxtNode* pNd = pTFld->GetpTxtNode();
if( pNd && pNds == &pNd->GetNodes() )
{
ULONG nNdPos = pNd->GetIndex();
if( nSttNd <= nNdPos && nNdPos <= nEndNd &&
( nNdPos != nSttNd || *pTFld->GetStart() >= nStt ) &&
( nNdPos != nEndNd || *pTFld->GetStart() < nEnd ))
return TRUE;
}
}
} while( 0 != ( pLast = aIter++ ));
return FALSE;
}
SwDDEFieldType::SwDDEFieldType(const String& rName,
const String& rCmd, USHORT nUpdateType )
: SwFieldType( RES_DDEFLD ),
aName( rName ), pDoc( 0 ), nRefCnt( 0 )
{
bCRLFFlag = bDeleted = FALSE;
refLink = new SwIntrnlRefLink( *this, nUpdateType, FORMAT_STRING );
SetCmd( rCmd );
}
SwDDEFieldType::~SwDDEFieldType()
{
if( pDoc && !pDoc->IsInDtor() )
pDoc->GetLinkManager().Remove( refLink );
2000-09-18 23:08:29 +00:00
refLink->Disconnect();
}
SwFieldType* SwDDEFieldType::Copy() const
{
SwDDEFieldType* pType = new SwDDEFieldType( aName, GetCmd(), GetType() );
pType->aExpansion = aExpansion;
pType->bCRLFFlag = bCRLFFlag;
pType->bDeleted = bDeleted;
pType->SetDoc( pDoc );
return pType;
}
const String& SwDDEFieldType::GetName() const
{
return aName;
}
void SwDDEFieldType::SetCmd( const String& rStr )
{
String sCmd( rStr );
xub_StrLen nPos;
while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( " " )) )
sCmd.Erase( nPos, 1 );
refLink->SetLinkSourceName( sCmd );
2000-09-18 23:08:29 +00:00
}
String SwDDEFieldType::GetCmd() const
{
return refLink->GetLinkSourceName();
2000-09-18 23:08:29 +00:00
}
void SwDDEFieldType::SetDoc( SwDoc* pNewDoc )
{
if( pNewDoc == pDoc )
return;
if( pDoc && refLink.Is() )
{
ASSERT( !nRefCnt, "wie kommen die Referenzen rueber?" );
pDoc->GetLinkManager().Remove( refLink );
2000-09-18 23:08:29 +00:00
}
pDoc = pNewDoc;
if( pDoc && nRefCnt )
{
refLink->SetVisible( pDoc->IsVisibleLinks() );
pDoc->GetLinkManager().InsertDDELink( refLink );
2000-09-18 23:08:29 +00:00
}
}
void SwDDEFieldType::_RefCntChgd()
{
if( nRefCnt )
{
refLink->SetVisible( pDoc->IsVisibleLinks() );
pDoc->GetLinkManager().InsertDDELink( refLink );
if( pDoc->GetCurrentViewShell() ) //swmod 071108//swmod 071225
2000-09-18 23:08:29 +00:00
UpdateNow();
}
else
{
Disconnect();
pDoc->GetLinkManager().Remove( refLink );
2000-09-18 23:08:29 +00:00
}
}
/* -----------------------------28.08.00 16:23--------------------------------
---------------------------------------------------------------------------*/
BOOL SwDDEFieldType::QueryValue( uno::Any& rVal, USHORT nWhichId ) const
2000-09-18 23:08:29 +00:00
{
BYTE nPart = 0;
switch( nWhichId )
2000-09-18 23:08:29 +00:00
{
case FIELD_PROP_PAR2: nPart = 3; break;
case FIELD_PROP_PAR4: nPart = 2; break;
case FIELD_PROP_SUBTYPE: nPart = 1; break;
case FIELD_PROP_BOOL1:
{
sal_Bool bSet = GetType() == sfx2::LINKUPDATE_ALWAYS ? TRUE : FALSE;
rVal.setValue(&bSet, ::getBooleanCppuType());
}
break;
case FIELD_PROP_PAR5:
rVal <<= ::rtl::OUString(aExpansion);
break;
default:
2001-10-26 10:10:02 +00:00
DBG_ERROR("illegal property");
2000-09-18 23:08:29 +00:00
}
if( nPart )
rVal <<= OUString(GetCmd().GetToken(nPart-1, sfx2::cTokenSeperator));
2000-09-18 23:08:29 +00:00
return TRUE;
}
/* -----------------------------28.08.00 16:23--------------------------------
---------------------------------------------------------------------------*/
BOOL SwDDEFieldType::PutValue( const uno::Any& rVal, USHORT nWhichId )
2000-09-18 23:08:29 +00:00
{
BYTE nPart = 0;
switch( nWhichId )
2000-09-18 23:08:29 +00:00
{
case FIELD_PROP_PAR2: nPart = 3; break;
case FIELD_PROP_PAR4: nPart = 2; break;
case FIELD_PROP_SUBTYPE: nPart = 1; break;
case FIELD_PROP_BOOL1:
SetType( static_cast<USHORT>(*(sal_Bool*)rVal.getValue() ?
sfx2::LINKUPDATE_ALWAYS :
sfx2::LINKUPDATE_ONCALL ) );
break;
case FIELD_PROP_PAR5:
{
::rtl::OUString sTemp;
rVal >>= sTemp;
aExpansion = sTemp;
}
break;
default:
2001-10-26 10:10:02 +00:00
DBG_ERROR("illegal property");
}
if( nPart )
{
String sTmp, sCmd( GetCmd() );
while(3 > sCmd.GetTokenCount(sfx2::cTokenSeperator))
sCmd += sfx2::cTokenSeperator;
sCmd.SetToken( nPart-1, sfx2::cTokenSeperator, ::GetString( rVal, sTmp ) );
2000-09-18 23:08:29 +00:00
SetCmd( sCmd );
}
return TRUE;
}
/* ---------------------------------------------------------------------------
---------------------------------------------------------------------------*/
SwDDEField::SwDDEField( SwDDEFieldType* pInitType )
: SwField(pInitType)
2000-09-18 23:08:29 +00:00
{
}
SwDDEField::~SwDDEField()
{
if( GetTyp()->IsLastDepend() ) // der Letzte mach das
((SwDDEFieldType*)GetTyp())->Disconnect(); // Licht aus
}
String SwDDEField::Expand() const
{
xub_StrLen nPos;
String aStr( ((SwDDEFieldType*)GetTyp())->GetExpansion() );
aStr.EraseAllChars( '\r' );
while( (nPos = aStr.Search( '\t' )) != STRING_NOTFOUND )
aStr.SetChar( nPos, ' ' );
2000-09-18 23:08:29 +00:00
while( (nPos = aStr.Search( '\n' )) != STRING_NOTFOUND )
aStr.SetChar( nPos, '|' );
2000-09-18 23:08:29 +00:00
if( aStr.Len() && ( aStr.GetChar( aStr.Len()-1 ) == '|') )
aStr.Erase( aStr.Len()-1, 1 );
return aStr;
}
SwField* SwDDEField::Copy() const
{
return new SwDDEField((SwDDEFieldType*)GetTyp());
}
/*--------------------------------------------------------------------
Beschreibung: Parameter des Typen erfragen
Name
--------------------------------------------------------------------*/
const String& SwDDEField::GetPar1() const
{
return ((SwDDEFieldType*)GetTyp())->GetName();
}
/*--------------------------------------------------------------------
Beschreibung: Parameter des Typen erfragen
Commando
--------------------------------------------------------------------*/
String SwDDEField::GetPar2() const
{
return ((SwDDEFieldType*)GetTyp())->GetCmd();
}
void SwDDEField::SetPar2(const String& rStr)
{
((SwDDEFieldType*)GetTyp())->SetCmd(rStr);
}