xref: /trunk/main/svx/source/svdraw/svdotxln.cxx (revision f6e50924)
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:
ImpSdrObjTextLink(SdrTextObj * pObj1)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 
Connect()77 	sal_Bool Connect() { return 0 != SvBaseLink::GetRealObject(); }
78 };
79 
~ImpSdrObjTextLink()80 ImpSdrObjTextLink::~ImpSdrObjTextLink()
81 {
82 }
83 
Closed()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 
DataChanged(const String &,const::com::sun::star::uno::Any &)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 
ImpSdrObjTextLinkUserData(SdrTextObj * pObj1)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 
~ImpSdrObjTextLinkUserData()147 ImpSdrObjTextLinkUserData::~ImpSdrObjTextLinkUserData()
148 {
149 #ifndef SVX_LIGHT
150 	delete pLink;
151 #endif
152 }
153 
Clone(SdrObject * pObj1) const154 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 
SetTextLink(const String & rFileName,const String & rFilterName,rtl_TextEncoding eCharSet)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 
ReleaseTextLink()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 
ReloadLinkedText(FASTBOOL bForceLoad)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 
LoadText(const String & rFileName,const String &,rtl_TextEncoding eCharSet)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 
GetLinkUserData() const303 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 
ImpLinkAnmeldung()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 
ImpLinkAbmeldung()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