xref: /aoo41x/main/svx/source/svdraw/svdotxln.cxx (revision cdf0e10c)
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