LibreOffice Module svx (master)  1
svdotxln.cxx
Go to the documentation of this file.
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 
23 #include <osl/file.hxx>
24 #include <osl/thread.h>
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/debug.hxx>
36 #include <tools/tenccvt.hxx>
37 #include <memory>
38 
40 {
42 
43 public:
44  explicit ImpSdrObjTextLink( SdrTextObj* pObj1 )
46  pSdrObj( pObj1 )
47  {}
48 
49  virtual void Closed() override;
50  virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
51  const OUString& rMimeType, const css::uno::Any & rValue ) override;
52 };
53 
55 {
56  if (pSdrObj )
57  {
58  // set pLink of the object to NULL, because we are destroying the link instance now
60  if (pData!=nullptr) pData->pLink=nullptr;
62  }
63  SvBaseLink::Closed();
64 }
65 
66 
68  const OUString& /*rMimeType*/, const css::uno::Any & /*rValue */)
69 {
70  bool bForceReload = false;
71  SdrModel* pModel(pSdrObj ? &pSdrObj->getSdrModelFromSdrObject() : nullptr);
72  sfx2::LinkManager* pLinkManager(pModel ? pModel->GetLinkManager() : nullptr);
73 
74  if( pLinkManager )
75  {
77  if( pData )
78  {
79  OUString aFile;
80  OUString aFilter;
81  sfx2::LinkManager::GetDisplayNames( this, nullptr,&aFile, nullptr, &aFilter );
82 
83  if( pData->aFileName != aFile ||
84  pData->aFilterName != aFilter )
85  {
86  pData->aFileName = aFile;
87  pData->aFilterName = aFilter;
89  bForceReload = true;
90  }
91  }
92  }
93  if (pSdrObj )
94  pSdrObj->ReloadLinkedText( bForceReload );
95 
96  return SUCCESS;
97 }
98 
99 
102  aFileDate0( DateTime::EMPTY ),
103  eCharSet(RTL_TEXTENCODING_DONTKNOW)
104 {
105 }
106 
108 {
109 }
110 
111 std::unique_ptr<SdrObjUserData> ImpSdrObjTextLinkUserData::Clone(SdrObject* ) const
112 {
114  pData->aFileName =aFileName;
115  pData->aFilterName=aFilterName;
116  pData->aFileDate0 =aFileDate0;
117  pData->eCharSet =eCharSet;
118  pData->pLink=nullptr;
119  return std::unique_ptr<SdrObjUserData>(pData);
120 }
121 
122 
123 void SdrTextObj::SetTextLink(const OUString& rFileName, const OUString& rFilterName)
124 {
125  rtl_TextEncoding eCharSet = osl_getThreadTextEncoding();
126 
128  if (pData!=nullptr) {
129  ReleaseTextLink();
130  }
131  pData=new ImpSdrObjTextLinkUserData;
132  pData->aFileName=rFileName;
133  pData->aFilterName=rFilterName;
134  pData->eCharSet=eCharSet;
135  AppendUserData(std::unique_ptr<SdrObjUserData>(pData));
136  ImpRegisterLink();
137 }
138 
140 {
142  sal_uInt16 nCount=GetUserDataCount();
143  for (sal_uInt16 nNum=nCount; nNum>0;) {
144  nNum--;
146  if (pData->GetInventor()==SdrInventor::Default && pData->GetId()==SDRUSERDATA_OBJTEXTLINK) {
147  DeleteUserData(nNum);
148  }
149  }
150 }
151 
152 bool SdrTextObj::ReloadLinkedText( bool bForceLoad)
153 {
155  bool bRet = true;
156 
157  if( pData )
158  {
159  DateTime aFileDT( DateTime::EMPTY );
160  bool bExists = true;
161 
162  try
163  {
164  INetURLObject aURL( pData->aFileName );
165  DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
166 
167  ::ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), css::uno::Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
168  css::uno::Any aAny( aCnt.getPropertyValue("DateModified") );
169  css::util::DateTime aDateTime;
170 
171  aAny >>= aDateTime;
172  ::utl::typeConvert( aDateTime, aFileDT );
173  }
174  catch( ... )
175  {
176  bExists = false;
177  }
178 
179  if( bExists )
180  {
181  bool bLoad = false;
182  if( bForceLoad )
183  bLoad = true;
184  else
185  bLoad = ( aFileDT > pData->aFileDate0 );
186 
187  if( bLoad )
188  {
189  bRet = LoadText( pData->aFileName, pData->eCharSet );
190  }
191 
192  pData->aFileDate0 = aFileDT;
193  }
194  }
195 
196  return bRet;
197 }
198 
199 bool SdrTextObj::LoadText(const OUString& rFileName, rtl_TextEncoding eCharSet)
200 {
201  INetURLObject aFileURL( rFileName );
202  bool bRet = false;
203 
204  if( aFileURL.GetProtocol() == INetProtocol::NotValid )
205  {
206  OUString aFileURLStr;
207 
208  if( osl::FileBase::getFileURLFromSystemPath( rFileName, aFileURLStr ) == osl::FileBase::E_None )
209  aFileURL = INetURLObject( aFileURLStr );
210  else
211  aFileURL.SetSmartURL( rFileName );
212  }
213 
214  DBG_ASSERT( aFileURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
215 
216  std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
217 
218  if( pIStm )
219  {
220  pIStm->SetStreamCharSet(GetSOLoadTextEncoding(eCharSet));
221 
222  char cRTF[5];
223  cRTF[4] = 0;
224  pIStm->ReadBytes(cRTF, 5);
225 
226  bool bRTF = cRTF[0] == '{' && cRTF[1] == '\\' && cRTF[2] == 'r' && cRTF[3] == 't' && cRTF[4] == 'f';
227 
228  pIStm->Seek(0);
229 
230  if( !pIStm->GetError() )
231  {
232  SetText( *pIStm, aFileURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), bRTF ? EETextFormat::Rtf : EETextFormat::Text );
233  bRet = true;
234  }
235  }
236 
237  return bRet;
238 }
239 
241 {
242  sal_uInt16 nCount=GetUserDataCount();
243  for (sal_uInt16 nNum=nCount; nNum>0;) {
244  nNum--;
246  if (pData->GetInventor() == SdrInventor::Default
247  && pData->GetId() == SDRUSERDATA_OBJTEXTLINK)
248  {
249  return static_cast<ImpSdrObjTextLinkUserData *>(pData);
250  }
251  }
252  return nullptr;
253 }
254 
256 {
258  sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
259  if (pLinkManager!=nullptr && pData!=nullptr && pData->pLink==nullptr) { // don't register twice
260  pData->pLink = new ImpSdrObjTextLink(this);
261  pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
262  !pData->aFilterName.isEmpty() ?
263  &pData->aFilterName : nullptr);
264  }
265 }
266 
268 {
270  sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
271  if (pLinkManager!=nullptr && pData!=nullptr && pData->pLink!=nullptr) { // don't register twice
272  // when doing Remove, *pLink is deleted implicitly
273  pLinkManager->Remove( pData->pLink.get() );
274  pData->pLink=nullptr;
275  }
276 }
277 
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
User data of a drawing object, e.g.
Definition: svdobj.hxx:204
URL aURL
bool LoadText(const OUString &rFileName, rtl_TextEncoding eCharSet)
Definition: svdotxln.cxx:199
#define OBJECT_CLIENT_FILE
std::shared_ptr< ContentProperties > const pData
void ReleaseTextLink()
Definition: svdotxln.cxx:139
SdrInventor
Definition: svdobj.hxx:152
SVX_DLLPRIVATE void ImpDeregisterLink()
Definition: svdotxln.cxx:267
#define SDRUSERDATA_OBJTEXTLINK
Definition: svdotext.hxx:88
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
void SetTextLink(const OUString &rFileName, const OUString &rFilterName)
Definition: svdotxln.cxx:123
int nCount
SotClipboardFormatId
SVX_DLLPRIVATE ImpSdrObjTextLinkUserData * GetLinkUserData() const
Definition: svdotxln.cxx:240
T * get() const
#define DBG_ASSERT(sCon, aError)
void Remove(SvBaseLink const *pLink)
void InsertFileLink(sfx2::SvBaseLink &, sal_uInt16 nFileType, const OUString &rFileNm, const OUString *pFilterNm=nullptr, const OUString *pRange=nullptr)
friend class ImpSdrObjTextLinkUserData
Definition: svdotext.hxx:168
void SetText(const OUString &rStr)
Definition: svdotext.cxx:221
void DeleteUserData(sal_uInt16 nNum)
Definition: svdobj.cxx:2657
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:299
tools::SvRef< ImpSdrObjTextLink > pLink
Definition: svdotext.hxx:114
rtl_TextEncoding GetSOLoadTextEncoding(rtl_TextEncoding eEncoding)
Abstract DrawObject.
Definition: svdobj.hxx:312
SVX_DLLPRIVATE void ImpRegisterLink()
Definition: svdotxln.cxx:255
void AppendUserData(std::unique_ptr< SdrObjUserData > pData)
Definition: svdobj.cxx:2642
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
static bool GetDisplayNames(const SvBaseLink *, OUString *pType, OUString *pFile=nullptr, OUString *pLink=nullptr, OUString *pFilter=nullptr)
rtl_TextEncoding eCharSet
Definition: svdotext.hxx:115
bool ReloadLinkedText(bool bForceLoad)
Definition: svdotxln.cxx:152
sal_uInt16 GetId() const
Definition: svdobj.hxx:220
INetProtocol GetProtocol() const
SdrObjUserData * GetUserData(sal_uInt16 nNum) const
Definition: svdobj.cxx:2636
virtual ~ImpSdrObjTextLinkUserData() override
Definition: svdotxln.cxx:107
friend class ImpSdrObjTextLink
Definition: svdotext.hxx:167
Reference< XComponentContext > getProcessComponentContext()
sal_uInt16 GetUserDataCount() const
Definition: svdobj.cxx:2630
virtual std::unique_ptr< SdrObjUserData > Clone(SdrObject *pObj1) const override
Definition: svdotxln.cxx:111
virtual void SetChanged()
Definition: svdobj.cxx:956
SdrInventor GetInventor() const
Definition: svdobj.hxx:219
SfxLinkUpdateMode
bool SetSmartURL(OUString const &rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)