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