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