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 <osl/thread.h>
24 : #include <unotools/ucbstreamhelper.hxx>
25 : #include <unotools/localfilehelper.hxx>
26 : #include <ucbhelper/content.hxx>
27 : #include <unotools/datetime.hxx>
28 : #include <svx/svdotext.hxx>
29 : #include <svx/svdmodel.hxx>
30 : #include <editeng/editdata.hxx>
31 : #include <sfx2/lnkbase.hxx>
32 : #include <sfx2/linkmgr.hxx>
33 : #include <tools/urlobj.hxx>
34 : #include <svl/urihelper.hxx>
35 : #include <tools/tenccvt.hxx>
36 :
37 :
38 : class ImpSdrObjTextLink: public ::sfx2::SvBaseLink
39 : {
40 : SdrTextObj* pSdrObj;
41 :
42 : public:
43 0 : ImpSdrObjTextLink( SdrTextObj* pObj1 )
44 : : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, FORMAT_FILE ),
45 0 : pSdrObj( pObj1 )
46 0 : {}
47 : virtual ~ImpSdrObjTextLink();
48 :
49 : virtual void Closed() SAL_OVERRIDE;
50 : virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
51 : const OUString& rMimeType, const ::com::sun::star::uno::Any & rValue ) SAL_OVERRIDE;
52 : };
53 :
54 0 : ImpSdrObjTextLink::~ImpSdrObjTextLink()
55 : {
56 0 : }
57 :
58 0 : void ImpSdrObjTextLink::Closed()
59 : {
60 0 : if (pSdrObj )
61 : {
62 : // set pLink of the object to NULL, because we are destroying the link instance now
63 0 : ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
64 0 : if (pData!=NULL) pData->pLink=NULL;
65 0 : pSdrObj->ReleaseTextLink();
66 : }
67 0 : SvBaseLink::Closed();
68 0 : }
69 :
70 :
71 0 : ::sfx2::SvBaseLink::UpdateResult ImpSdrObjTextLink::DataChanged(
72 : const OUString& /*rMimeType*/, const ::com::sun::star::uno::Any & /*rValue */)
73 : {
74 0 : bool bForceReload = false;
75 0 : SdrModel* pModel = pSdrObj ? pSdrObj->GetModel() : 0;
76 0 : sfx2::LinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0;
77 0 : if( pLinkManager )
78 : {
79 0 : ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
80 0 : if( pData )
81 : {
82 0 : OUString aFile;
83 0 : OUString aFilter;
84 0 : pLinkManager->GetDisplayNames( this, 0,&aFile, 0, &aFilter );
85 :
86 0 : if( pData->aFileName != aFile ||
87 0 : pData->aFilterName != aFilter )
88 : {
89 0 : pData->aFileName = aFile;
90 0 : pData->aFilterName = aFilter;
91 0 : pSdrObj->SetChanged();
92 0 : bForceReload = true;
93 0 : }
94 : }
95 : }
96 0 : if (pSdrObj )
97 0 : pSdrObj->ReloadLinkedText( bForceReload );
98 :
99 0 : return SUCCESS;
100 : }
101 :
102 :
103 0 : TYPEINIT1(ImpSdrObjTextLinkUserData,SdrObjUserData);
104 :
105 0 : ImpSdrObjTextLinkUserData::ImpSdrObjTextLinkUserData(SdrTextObj* pObj1):
106 : SdrObjUserData(SdrInventor,SDRUSERDATA_OBJTEXTLINK,0),
107 : pObj(pObj1),
108 : aFileDate0( DateTime::EMPTY ),
109 : pLink(NULL),
110 0 : eCharSet(RTL_TEXTENCODING_DONTKNOW)
111 : {
112 0 : }
113 :
114 0 : ImpSdrObjTextLinkUserData::~ImpSdrObjTextLinkUserData()
115 : {
116 0 : delete pLink;
117 0 : }
118 :
119 0 : SdrObjUserData* ImpSdrObjTextLinkUserData::Clone(SdrObject* pObj1) const
120 : {
121 0 : ImpSdrObjTextLinkUserData* pData=new ImpSdrObjTextLinkUserData((SdrTextObj*)pObj1);
122 0 : pData->aFileName =aFileName;
123 0 : pData->aFilterName=aFilterName;
124 0 : pData->aFileDate0 =aFileDate0;
125 0 : pData->eCharSet =eCharSet;
126 0 : pData->pLink=NULL;
127 0 : return pData;
128 : }
129 :
130 :
131 0 : void SdrTextObj::SetTextLink(const OUString& rFileName, const OUString& rFilterName, rtl_TextEncoding eCharSet)
132 : {
133 0 : if(eCharSet == RTL_TEXTENCODING_DONTKNOW)
134 0 : eCharSet = osl_getThreadTextEncoding();
135 :
136 0 : ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
137 0 : if (pData!=NULL) {
138 0 : ReleaseTextLink();
139 : }
140 0 : pData=new ImpSdrObjTextLinkUserData(this);
141 0 : pData->aFileName=rFileName;
142 0 : pData->aFilterName=rFilterName;
143 0 : pData->eCharSet=eCharSet;
144 0 : AppendUserData(pData);
145 0 : ImpLinkAnmeldung();
146 0 : }
147 :
148 0 : void SdrTextObj::ReleaseTextLink()
149 : {
150 0 : ImpLinkAbmeldung();
151 0 : sal_uInt16 nAnz=GetUserDataCount();
152 0 : for (sal_uInt16 nNum=nAnz; nNum>0;) {
153 0 : nNum--;
154 0 : SdrObjUserData* pData=GetUserData(nNum);
155 0 : if (pData->GetInventor()==SdrInventor && pData->GetId()==SDRUSERDATA_OBJTEXTLINK) {
156 0 : DeleteUserData(nNum);
157 : }
158 : }
159 0 : }
160 :
161 0 : bool SdrTextObj::ReloadLinkedText( bool bForceLoad)
162 : {
163 0 : ImpSdrObjTextLinkUserData* pData = GetLinkUserData();
164 0 : bool bRet = true;
165 :
166 0 : if( pData )
167 : {
168 0 : DateTime aFileDT( DateTime::EMPTY );
169 0 : bool bExists = true, bLoad = false;
170 :
171 : try
172 : {
173 0 : INetURLObject aURL( pData->aFileName );
174 : DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
175 :
176 0 : ::ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
177 0 : ::com::sun::star::uno::Any aAny( aCnt.getPropertyValue("DateModified") );
178 0 : ::com::sun::star::util::DateTime aDateTime;
179 :
180 0 : aAny >>= aDateTime;
181 0 : ::utl::typeConvert( aDateTime, aFileDT );
182 : }
183 0 : catch( ... )
184 : {
185 0 : bExists = false;
186 : }
187 :
188 0 : if( bExists )
189 : {
190 0 : if( bForceLoad )
191 0 : bLoad = true;
192 : else
193 0 : bLoad = ( aFileDT > pData->aFileDate0 );
194 :
195 0 : if( bLoad )
196 : {
197 0 : bRet = LoadText( pData->aFileName, pData->aFilterName, pData->eCharSet );
198 : }
199 :
200 0 : pData->aFileDate0 = aFileDT;
201 : }
202 : }
203 :
204 0 : return bRet;
205 : }
206 :
207 0 : bool SdrTextObj::LoadText(const OUString& rFileName, const OUString& /*rFilterName*/, rtl_TextEncoding eCharSet)
208 : {
209 0 : INetURLObject aFileURL( rFileName );
210 0 : bool bRet = false;
211 :
212 0 : if( aFileURL.GetProtocol() == INET_PROT_NOT_VALID )
213 : {
214 0 : OUString aFileURLStr;
215 :
216 0 : if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFileName, aFileURLStr ) )
217 0 : aFileURL = INetURLObject( aFileURLStr );
218 : else
219 0 : aFileURL.SetSmartURL( rFileName );
220 : }
221 :
222 : DBG_ASSERT( aFileURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
223 :
224 0 : SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );
225 :
226 0 : if( pIStm )
227 : {
228 0 : pIStm->SetStreamCharSet(GetSOLoadTextEncoding(eCharSet));
229 :
230 : char cRTF[5];
231 0 : cRTF[4] = 0;
232 0 : pIStm->Read(cRTF, 5);
233 :
234 0 : bool bRTF = cRTF[0] == '{' && cRTF[1] == '\\' && cRTF[2] == 'r' && cRTF[3] == 't' && cRTF[4] == 'f';
235 :
236 0 : pIStm->Seek(0);
237 :
238 0 : if( !pIStm->GetError() )
239 : {
240 0 : SetText( *pIStm, aFileURL.GetMainURL( INetURLObject::NO_DECODE ), sal::static_int_cast< sal_uInt16 >( bRTF ? EE_FORMAT_RTF : EE_FORMAT_TEXT ) );
241 0 : bRet = true;
242 : }
243 :
244 0 : delete pIStm;
245 : }
246 :
247 0 : return bRet;
248 : }
249 :
250 0 : ImpSdrObjTextLinkUserData* SdrTextObj::GetLinkUserData() const
251 : {
252 0 : ImpSdrObjTextLinkUserData* pData=NULL;
253 0 : sal_uInt16 nAnz=GetUserDataCount();
254 0 : for (sal_uInt16 nNum=nAnz; nNum>0 && pData==NULL;) {
255 0 : nNum--;
256 0 : pData=(ImpSdrObjTextLinkUserData*)GetUserData(nNum);
257 0 : if (pData->GetInventor()!=SdrInventor || pData->GetId()!=SDRUSERDATA_OBJTEXTLINK) {
258 0 : pData=NULL;
259 : }
260 : }
261 0 : return pData;
262 : }
263 :
264 0 : void SdrTextObj::ImpLinkAnmeldung()
265 : {
266 0 : ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
267 0 : sfx2::LinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
268 0 : if (pLinkManager!=NULL && pData!=NULL && pData->pLink==NULL) { // don't register twice
269 0 : pData->pLink = new ImpSdrObjTextLink(this);
270 : pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
271 0 : !pData->aFilterName.isEmpty() ?
272 : &pData->aFilterName : NULL,
273 0 : NULL);
274 : }
275 0 : }
276 :
277 0 : void SdrTextObj::ImpLinkAbmeldung()
278 : {
279 0 : ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
280 0 : sfx2::LinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
281 0 : if (pLinkManager!=NULL && pData!=NULL && pData->pLink!=NULL) { // don't register twice
282 : // when doing Remove, *pLink is deleted implicitly
283 0 : pLinkManager->Remove( pData->pLink );
284 0 : pData->pLink=NULL;
285 : }
286 0 : }
287 :
288 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|