Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "sal/config.h"
21 :
22 : #include <comphelper/processfactory.hxx>
23 : #include <unotools/ucbstreamhelper.hxx>
24 : #include <unotools/localfilehelper.hxx>
25 : #include <ucbhelper/content.hxx>
26 : #include <unotools/datetime.hxx>
27 : #include <svx/svdotext.hxx>
28 : #include <svx/svdmodel.hxx>
29 : #include <editeng/editdata.hxx>
30 : #include <sfx2/lnkbase.hxx>
31 : #include <sfx2/linkmgr.hxx>
32 : #include <tools/urlobj.hxx>
33 : #include <svl/urihelper.hxx>
34 : #include <tools/tenccvt.hxx>
35 :
36 :
37 : class ImpSdrObjTextLink: public ::sfx2::SvBaseLink
38 : {
39 : SdrTextObj* pSdrObj;
40 :
41 : public:
42 0 : ImpSdrObjTextLink( SdrTextObj* pObj1 )
43 : : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, FORMAT_FILE ),
44 0 : pSdrObj( pObj1 )
45 0 : {}
46 : virtual ~ImpSdrObjTextLink();
47 :
48 : virtual void Closed();
49 : virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
50 : const String& rMimeType, const ::com::sun::star::uno::Any & rValue );
51 :
52 0 : bool Connect() { return 0 != SvBaseLink::GetRealObject(); }
53 : };
54 :
55 0 : ImpSdrObjTextLink::~ImpSdrObjTextLink()
56 : {
57 0 : }
58 :
59 0 : void ImpSdrObjTextLink::Closed()
60 : {
61 0 : if (pSdrObj )
62 : {
63 : // set pLink of the object to NULL, because we are destroying the link instance now
64 0 : ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
65 0 : if (pData!=NULL) pData->pLink=NULL;
66 0 : pSdrObj->ReleaseTextLink();
67 : }
68 0 : SvBaseLink::Closed();
69 0 : }
70 :
71 :
72 0 : ::sfx2::SvBaseLink::UpdateResult ImpSdrObjTextLink::DataChanged(
73 : const String& /*rMimeType*/, const ::com::sun::star::uno::Any & /*rValue */)
74 : {
75 0 : bool bForceReload = false;
76 0 : SdrModel* pModel = pSdrObj ? pSdrObj->GetModel() : 0;
77 0 : sfx2::LinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0;
78 0 : if( pLinkManager )
79 : {
80 0 : ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
81 0 : if( pData )
82 : {
83 0 : String aFile;
84 0 : String aFilter;
85 0 : pLinkManager->GetDisplayNames( this, 0,&aFile, 0, &aFilter );
86 :
87 0 : if( !pData->aFileName.Equals( aFile ) ||
88 0 : !pData->aFilterName.Equals( aFilter ))
89 : {
90 0 : pData->aFileName = aFile;
91 0 : pData->aFilterName = aFilter;
92 0 : pSdrObj->SetChanged();
93 0 : bForceReload = true;
94 0 : }
95 : }
96 : }
97 0 : if (pSdrObj )
98 0 : pSdrObj->ReloadLinkedText( bForceReload );
99 :
100 0 : return SUCCESS;
101 : }
102 :
103 :
104 0 : TYPEINIT1(ImpSdrObjTextLinkUserData,SdrObjUserData);
105 :
106 0 : ImpSdrObjTextLinkUserData::ImpSdrObjTextLinkUserData(SdrTextObj* pObj1):
107 : SdrObjUserData(SdrInventor,SDRUSERDATA_OBJTEXTLINK,0),
108 : pObj(pObj1),
109 : aFileDate0( DateTime::EMPTY ),
110 : pLink(NULL),
111 0 : eCharSet(RTL_TEXTENCODING_DONTKNOW)
112 : {
113 0 : }
114 :
115 0 : ImpSdrObjTextLinkUserData::~ImpSdrObjTextLinkUserData()
116 : {
117 0 : delete pLink;
118 0 : }
119 :
120 0 : SdrObjUserData* ImpSdrObjTextLinkUserData::Clone(SdrObject* pObj1) const
121 : {
122 0 : ImpSdrObjTextLinkUserData* pData=new ImpSdrObjTextLinkUserData((SdrTextObj*)pObj1);
123 0 : pData->aFileName =aFileName;
124 0 : pData->aFilterName=aFilterName;
125 0 : pData->aFileDate0 =aFileDate0;
126 0 : pData->eCharSet =eCharSet;
127 0 : pData->pLink=NULL;
128 0 : return pData;
129 : }
130 :
131 :
132 0 : void SdrTextObj::SetTextLink(const String& rFileName, const String& rFilterName, rtl_TextEncoding eCharSet)
133 : {
134 0 : if(eCharSet == RTL_TEXTENCODING_DONTKNOW)
135 0 : eCharSet = osl_getThreadTextEncoding();
136 :
137 0 : ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
138 0 : if (pData!=NULL) {
139 0 : ReleaseTextLink();
140 : }
141 0 : pData=new ImpSdrObjTextLinkUserData(this);
142 0 : pData->aFileName=rFileName;
143 0 : pData->aFilterName=rFilterName;
144 0 : pData->eCharSet=eCharSet;
145 0 : AppendUserData(pData);
146 0 : ImpLinkAnmeldung();
147 0 : }
148 :
149 0 : void SdrTextObj::ReleaseTextLink()
150 : {
151 0 : ImpLinkAbmeldung();
152 0 : sal_uInt16 nAnz=GetUserDataCount();
153 0 : for (sal_uInt16 nNum=nAnz; nNum>0;) {
154 0 : nNum--;
155 0 : SdrObjUserData* pData=GetUserData(nNum);
156 0 : if (pData->GetInventor()==SdrInventor && pData->GetId()==SDRUSERDATA_OBJTEXTLINK) {
157 0 : DeleteUserData(nNum);
158 : }
159 : }
160 0 : }
161 :
162 0 : bool SdrTextObj::ReloadLinkedText( bool bForceLoad)
163 : {
164 0 : ImpSdrObjTextLinkUserData* pData = GetLinkUserData();
165 0 : bool bRet = true;
166 :
167 0 : if( pData )
168 : {
169 0 : DateTime aFileDT( DateTime::EMPTY );
170 0 : bool bExists = true, bLoad = false;
171 :
172 : try
173 : {
174 0 : INetURLObject aURL( pData->aFileName );
175 : DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
176 :
177 0 : ::ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
178 0 : ::com::sun::star::uno::Any aAny( aCnt.getPropertyValue("DateModified") );
179 0 : ::com::sun::star::util::DateTime aDateTime;
180 :
181 0 : aAny >>= aDateTime;
182 0 : ::utl::typeConvert( aDateTime, aFileDT );
183 : }
184 0 : catch( ... )
185 : {
186 0 : bExists = false;
187 : }
188 :
189 0 : if( bExists )
190 : {
191 0 : if( bForceLoad )
192 0 : bLoad = true;
193 : else
194 0 : bLoad = ( aFileDT > pData->aFileDate0 );
195 :
196 0 : if( bLoad )
197 : {
198 0 : bRet = LoadText( pData->aFileName, pData->aFilterName, pData->eCharSet );
199 : }
200 :
201 0 : pData->aFileDate0 = aFileDT;
202 : }
203 : }
204 :
205 0 : return bRet;
206 : }
207 :
208 0 : bool SdrTextObj::LoadText(const String& rFileName, const String& /*rFilterName*/, rtl_TextEncoding eCharSet)
209 : {
210 0 : INetURLObject aFileURL( rFileName );
211 0 : bool bRet = false;
212 :
213 0 : if( aFileURL.GetProtocol() == INET_PROT_NOT_VALID )
214 : {
215 0 : OUString aFileURLStr;
216 :
217 0 : if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFileName, aFileURLStr ) )
218 0 : aFileURL = INetURLObject( aFileURLStr );
219 : else
220 0 : aFileURL.SetSmartURL( rFileName );
221 : }
222 :
223 : DBG_ASSERT( aFileURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
224 :
225 0 : SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );
226 :
227 0 : if( pIStm )
228 : {
229 0 : pIStm->SetStreamCharSet(GetSOLoadTextEncoding(eCharSet));
230 :
231 : char cRTF[5];
232 0 : cRTF[4] = 0;
233 0 : pIStm->Read(cRTF, 5);
234 :
235 0 : bool bRTF = cRTF[0] == '{' && cRTF[1] == '\\' && cRTF[2] == 'r' && cRTF[3] == 't' && cRTF[4] == 'f';
236 :
237 0 : pIStm->Seek(0);
238 :
239 0 : if( !pIStm->GetError() )
240 : {
241 0 : SetText( *pIStm, aFileURL.GetMainURL( INetURLObject::NO_DECODE ), sal::static_int_cast< sal_uInt16 >( bRTF ? EE_FORMAT_RTF : EE_FORMAT_TEXT ) );
242 0 : bRet = true;
243 : }
244 :
245 0 : delete pIStm;
246 : }
247 :
248 0 : return bRet;
249 : }
250 :
251 40911 : ImpSdrObjTextLinkUserData* SdrTextObj::GetLinkUserData() const
252 : {
253 40911 : ImpSdrObjTextLinkUserData* pData=NULL;
254 40911 : sal_uInt16 nAnz=GetUserDataCount();
255 83707 : for (sal_uInt16 nNum=nAnz; nNum>0 && pData==NULL;) {
256 1885 : nNum--;
257 1885 : pData=(ImpSdrObjTextLinkUserData*)GetUserData(nNum);
258 1885 : if (pData->GetInventor()!=SdrInventor || pData->GetId()!=SDRUSERDATA_OBJTEXTLINK) {
259 1885 : pData=NULL;
260 : }
261 : }
262 40911 : return pData;
263 : }
264 :
265 0 : void SdrTextObj::ImpLinkAnmeldung()
266 : {
267 0 : ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
268 0 : sfx2::LinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
269 0 : if (pLinkManager!=NULL && pData!=NULL && pData->pLink==NULL) { // don't register twice
270 0 : pData->pLink=new ImpSdrObjTextLink(this);
271 : #ifdef __GNUC__
272 : pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
273 0 : pData->aFilterName.Len() ?
274 : &pData->aFilterName : (const String *)NULL,
275 0 : (const String *)NULL);
276 : #else
277 : pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
278 : pData->aFilterName.Len() ? &pData->aFilterName : NULL,NULL);
279 : #endif
280 0 : pData->pLink->Connect();
281 : }
282 0 : }
283 :
284 30840 : void SdrTextObj::ImpLinkAbmeldung()
285 : {
286 30840 : ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
287 30840 : sfx2::LinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
288 30840 : if (pLinkManager!=NULL && pData!=NULL && pData->pLink!=NULL) { // don't register twice
289 : // when doing Remove, *pLink is deleted implicitly
290 0 : pLinkManager->Remove( pData->pLink );
291 0 : pData->pLink=NULL;
292 : }
293 31098 : }
294 :
295 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|