1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #include <unotools/ucbstreamhelper.hxx> 32 #include <unotools/localfilehelper.hxx> 33 #include <ucbhelper/content.hxx> 34 #include <ucbhelper/contentbroker.hxx> 35 #include <unotools/datetime.hxx> 36 #include <svx/svdotext.hxx> 37 #include "svx/svditext.hxx" 38 #include <svx/svdmodel.hxx> 39 #include <editeng/editdata.hxx> 40 #include <sfx2/lnkbase.hxx> 41 #include <sfx2/linkmgr.hxx> 42 #include <tools/urlobj.hxx> 43 #include <svl/urihelper.hxx> 44 45 // #90477# 46 #include <tools/tenccvt.hxx> 47 48 #ifndef SVX_LIGHT 49 //////////////////////////////////////////////////////////////////////////////////////////////////// 50 // 51 // @@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@ @@ @@@@@@ @@ @@ @@ @@ @@ @@ 52 // @@ @@ @@ @@ @@ @@ @@ @@@@ @@ @@ @@ @@@ @@ @@ @@ 53 // @@ @@ @@@@@ @@ @@ @@@@@ @@ @@ @@ @@ @@@@@@ @@@@ 54 // @@ @@ @@ @@ @@ @@ @@ @@ @@@@ @@ @@ @@ @@ @@@ @@ @@ 55 // @@@@ @@@@@ @@@@ @@ @@@@@@ @@ @@ @@ @@@@@ @@ @@ @@ @@ @@ 56 // 57 // ImpSdrObjTextLink zur Verbindung von SdrTextObj und LinkManager 58 // 59 // Einem solchen Link merke ich mir als SdrObjUserData am Objekt. Im Gegensatz 60 // zum Grafik-Link werden die ObjektDaten jedoch kopiert (fuer Paint, etc.). 61 // Die Information ob das Objekt ein Link ist besteht genau darin, dass dem 62 // Objekt ein entsprechender UserData-Record angehaengt ist oder nicht. 63 // 64 //////////////////////////////////////////////////////////////////////////////////////////////////// 65 66 class ImpSdrObjTextLink: public ::sfx2::SvBaseLink 67 { 68 SdrTextObj* pSdrObj; 69 70 public: 71 ImpSdrObjTextLink( SdrTextObj* pObj1 ) 72 : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, FORMAT_FILE ), 73 pSdrObj( pObj1 ) 74 {} 75 virtual ~ImpSdrObjTextLink(); 76 77 virtual void Closed(); 78 virtual void DataChanged( const String& rMimeType, 79 const ::com::sun::star::uno::Any & rValue ); 80 81 sal_Bool Connect() { return 0 != SvBaseLink::GetRealObject(); } 82 }; 83 84 ImpSdrObjTextLink::~ImpSdrObjTextLink() 85 { 86 } 87 88 void ImpSdrObjTextLink::Closed() 89 { 90 if (pSdrObj ) 91 { 92 // pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird. 93 ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData(); 94 if (pData!=NULL) pData->pLink=NULL; 95 pSdrObj->ReleaseTextLink(); 96 } 97 SvBaseLink::Closed(); 98 } 99 100 101 void ImpSdrObjTextLink::DataChanged( const String& /*rMimeType*/, 102 const ::com::sun::star::uno::Any & /*rValue */) 103 { 104 FASTBOOL bForceReload=sal_False; 105 SdrModel* pModel = pSdrObj ? pSdrObj->GetModel() : 0; 106 sfx2::LinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0; 107 if( pLinkManager ) 108 { 109 ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData(); 110 if( pData ) 111 { 112 String aFile; 113 String aFilter; 114 pLinkManager->GetDisplayNames( this, 0,&aFile, 0, &aFilter ); 115 116 if( !pData->aFileName.Equals( aFile ) || 117 !pData->aFilterName.Equals( aFilter )) 118 { 119 pData->aFileName = aFile; 120 pData->aFilterName = aFilter; 121 pSdrObj->SetChanged(); 122 bForceReload = sal_True; 123 } 124 } 125 } 126 if (pSdrObj ) 127 pSdrObj->ReloadLinkedText( bForceReload ); 128 } 129 #endif // SVX_LIGHT 130 131 //////////////////////////////////////////////////////////////////////////////////////////////////// 132 // 133 // @@ @@ @@ @@ @@ @@ @@ @@ @@@@@ @@@@@@ @@@@@ @@@@@ @@@@ @@@@@@ @@@@ 134 // @@ @@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ 135 // @@ @@ @@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@@@@ @@ @@ @@@@@@ @@ @@@@@@ 136 // @@ @@ @@ @@@ @@@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ 137 // @@@@@ @@ @@ @@ @@ @@ @@@@ @@@@@ @@@@@@ @@ @@ @@@@@ @@ @@ @@ @@ @@ 138 // 139 //////////////////////////////////////////////////////////////////////////////////////////////////// 140 141 TYPEINIT1(ImpSdrObjTextLinkUserData,SdrObjUserData); 142 143 ImpSdrObjTextLinkUserData::ImpSdrObjTextLinkUserData(SdrTextObj* pObj1): 144 SdrObjUserData(SdrInventor,SDRUSERDATA_OBJTEXTLINK,0), 145 pObj(pObj1), 146 pLink(NULL), 147 eCharSet(RTL_TEXTENCODING_DONTKNOW) 148 { 149 } 150 151 ImpSdrObjTextLinkUserData::~ImpSdrObjTextLinkUserData() 152 { 153 #ifndef SVX_LIGHT 154 delete pLink; 155 #endif 156 } 157 158 SdrObjUserData* ImpSdrObjTextLinkUserData::Clone(SdrObject* pObj1) const 159 { 160 ImpSdrObjTextLinkUserData* pData=new ImpSdrObjTextLinkUserData((SdrTextObj*)pObj1); 161 pData->aFileName =aFileName; 162 pData->aFilterName=aFilterName; 163 pData->aFileDate0 =aFileDate0; 164 pData->eCharSet =eCharSet; 165 pData->pLink=NULL; 166 return pData; 167 } 168 169 //////////////////////////////////////////////////////////////////////////////////////////////////// 170 // 171 // @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@ 172 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ 173 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@ 174 // @@ @@@@ @@@ @@ @@ @@ @@@@@ @@ 175 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@ 176 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ 177 // @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@ 178 // 179 //////////////////////////////////////////////////////////////////////////////////////////////////// 180 181 void SdrTextObj::SetTextLink(const String& rFileName, const String& rFilterName, rtl_TextEncoding eCharSet) 182 { 183 if(eCharSet == RTL_TEXTENCODING_DONTKNOW) 184 eCharSet = gsl_getSystemTextEncoding(); 185 186 ImpSdrObjTextLinkUserData* pData=GetLinkUserData(); 187 if (pData!=NULL) { 188 ReleaseTextLink(); 189 } 190 pData=new ImpSdrObjTextLinkUserData(this); 191 pData->aFileName=rFileName; 192 pData->aFilterName=rFilterName; 193 pData->eCharSet=eCharSet; 194 InsertUserData(pData); 195 ImpLinkAnmeldung(); 196 } 197 198 void SdrTextObj::ReleaseTextLink() 199 { 200 ImpLinkAbmeldung(); 201 sal_uInt16 nAnz=GetUserDataCount(); 202 for (sal_uInt16 nNum=nAnz; nNum>0;) { 203 nNum--; 204 SdrObjUserData* pData=GetUserData(nNum); 205 if (pData->GetInventor()==SdrInventor && pData->GetId()==SDRUSERDATA_OBJTEXTLINK) { 206 DeleteUserData(nNum); 207 } 208 } 209 } 210 211 FASTBOOL SdrTextObj::ReloadLinkedText( FASTBOOL bForceLoad) 212 { 213 ImpSdrObjTextLinkUserData* pData = GetLinkUserData(); 214 FASTBOOL bRet = sal_True; 215 216 if( pData ) 217 { 218 ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); 219 DateTime aFileDT; 220 sal_Bool bExists = sal_False, bLoad = sal_False; 221 222 if( pBroker ) 223 { 224 bExists = sal_True; 225 226 try 227 { 228 INetURLObject aURL( pData->aFileName ); 229 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); 230 231 ::ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); 232 ::com::sun::star::uno::Any aAny( aCnt.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ) ) ); 233 ::com::sun::star::util::DateTime aDateTime; 234 235 aAny >>= aDateTime; 236 ::utl::typeConvert( aDateTime, aFileDT ); 237 } 238 catch( ... ) 239 { 240 bExists = sal_False; 241 } 242 } 243 244 if( bExists ) 245 { 246 if( bForceLoad ) 247 bLoad = sal_True; 248 else 249 bLoad = ( aFileDT > pData->aFileDate0 ); 250 251 if( bLoad ) 252 { 253 bRet = LoadText( pData->aFileName, pData->aFilterName, pData->eCharSet ); 254 } 255 256 pData->aFileDate0 = aFileDT; 257 } 258 } 259 260 return bRet; 261 } 262 263 FASTBOOL SdrTextObj::LoadText(const String& rFileName, const String& /*rFilterName*/, rtl_TextEncoding eCharSet) 264 { 265 INetURLObject aFileURL( rFileName ); 266 sal_Bool bRet = sal_False; 267 268 if( aFileURL.GetProtocol() == INET_PROT_NOT_VALID ) 269 { 270 String aFileURLStr; 271 272 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFileName, aFileURLStr ) ) 273 aFileURL = INetURLObject( aFileURLStr ); 274 else 275 aFileURL.SetSmartURL( rFileName ); 276 } 277 278 DBG_ASSERT( aFileURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); 279 280 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ); 281 282 if( pIStm ) 283 { 284 // #90477# pIStm->SetStreamCharSet( eCharSet ); 285 pIStm->SetStreamCharSet(GetSOLoadTextEncoding(eCharSet, (sal_uInt16)pIStm->GetVersion())); 286 287 char cRTF[5]; 288 cRTF[4] = 0; 289 pIStm->Read(cRTF, 5); 290 291 sal_Bool bRTF = cRTF[0] == '{' && cRTF[1] == '\\' && cRTF[2] == 'r' && cRTF[3] == 't' && cRTF[4] == 'f'; 292 293 pIStm->Seek(0); 294 295 if( !pIStm->GetError() ) 296 { 297 SetText( *pIStm, aFileURL.GetMainURL( INetURLObject::NO_DECODE ), sal::static_int_cast< sal_uInt16 >( bRTF ? EE_FORMAT_RTF : EE_FORMAT_TEXT ) ); 298 bRet = sal_True; 299 } 300 301 delete pIStm; 302 } 303 304 return bRet; 305 } 306 307 ImpSdrObjTextLinkUserData* SdrTextObj::GetLinkUserData() const 308 { 309 ImpSdrObjTextLinkUserData* pData=NULL; 310 sal_uInt16 nAnz=GetUserDataCount(); 311 for (sal_uInt16 nNum=nAnz; nNum>0 && pData==NULL;) { 312 nNum--; 313 pData=(ImpSdrObjTextLinkUserData*)GetUserData(nNum); 314 if (pData->GetInventor()!=SdrInventor || pData->GetId()!=SDRUSERDATA_OBJTEXTLINK) { 315 pData=NULL; 316 } 317 } 318 return pData; 319 } 320 321 void SdrTextObj::ImpLinkAnmeldung() 322 { 323 ImpSdrObjTextLinkUserData* pData=GetLinkUserData(); 324 sfx2::LinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL; 325 if (pLinkManager!=NULL && pData!=NULL && pData->pLink==NULL) { // Nicht 2x Anmelden 326 pData->pLink=new ImpSdrObjTextLink(this); 327 #ifdef GCC 328 pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName, 329 pData->aFilterName.Len() ? 330 &pData->aFilterName : (const String *)NULL, 331 (const String *)NULL); 332 #else 333 pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName, 334 pData->aFilterName.Len() ? &pData->aFilterName : NULL,NULL); 335 #endif 336 pData->pLink->Connect(); 337 } 338 } 339 340 void SdrTextObj::ImpLinkAbmeldung() 341 { 342 ImpSdrObjTextLinkUserData* pData=GetLinkUserData(); 343 sfx2::LinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL; 344 if (pLinkManager!=NULL && pData!=NULL && pData->pLink!=NULL) { // Nicht 2x Abmelden 345 // Bei Remove wird *pLink implizit deleted 346 pLinkManager->Remove( pData->pLink ); 347 pData->pLink=NULL; 348 } 349 } 350 351