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