LibreOffice Module sc (master)  1
linkarea.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 #undef SC_DLLIMPLEMENTATION
21 
22 #include <sfx2/docfile.hxx>
23 #include <sfx2/docfilt.hxx>
24 #include <sfx2/docinsert.hxx>
25 #include <sfx2/fcontnr.hxx>
26 #include <sfx2/filedlghelper.hxx>
27 #include <svtools/ehdl.hxx>
28 #include <svtools/inettbc.hxx>
29 #include <svtools/sfxecode.hxx>
30 
31 #include <linkarea.hxx>
32 #include <rangeutl.hxx>
33 #include <docsh.hxx>
34 #include <tablink.hxx>
35 #include <scresid.hxx>
36 #include <strings.hrc>
37 
39  : GenericDialogController(pParent, "modules/scalc/ui/externaldata.ui", "ExternalDataDialog")
40  , m_pSourceShell(nullptr)
41  , m_xCbUrl(new SvtURLBox(m_xBuilder->weld_combo_box("url")))
42  , m_xBtnBrowse(m_xBuilder->weld_button("browse"))
43  , m_xLbRanges(m_xBuilder->weld_tree_view("ranges"))
44  , m_xBtnReload(m_xBuilder->weld_check_button("reload"))
45  , m_xNfDelay(m_xBuilder->weld_spin_button("delay"))
46  , m_xFtSeconds(m_xBuilder->weld_label("secondsft"))
47  , m_xBtnOk(m_xBuilder->weld_button("ok"))
48 {
49  m_xLbRanges->set_selection_mode(SelectionMode::Multiple);
50 
51  m_xCbUrl->connect_entry_activate(LINK(this, ScLinkedAreaDlg, FileHdl));
52  m_xBtnBrowse->connect_clicked(LINK( this, ScLinkedAreaDlg, BrowseHdl));
53  m_xLbRanges->connect_changed(LINK( this, ScLinkedAreaDlg, RangeHdl));
54  m_xLbRanges->set_size_request(m_xLbRanges->get_approximate_digit_width() * 54,
55  m_xLbRanges->get_height_rows(5));
56  m_xBtnReload->connect_toggled(LINK( this, ScLinkedAreaDlg, ReloadHdl));
57  UpdateEnable();
58 }
59 
61 {
62 }
63 
64 constexpr OUStringLiteral FILTERNAME_HTML = u"HTML (StarCalc)";
65 constexpr OUStringLiteral FILTERNAME_QUERY = u"calc_HTML_WebQuery";
66 
68 {
69  m_xDocInserter.reset( new sfx2::DocumentInserter(m_xDialog.get(), ScDocShell::Factory().GetFactoryName()) );
70  m_xDocInserter->StartExecuteModal( LINK( this, ScLinkedAreaDlg, DialogClosedHdl ) );
71 }
72 
74 {
75  OUString aEntered = m_xCbUrl->GetURL();
76  if (m_pSourceShell)
77  {
78  SfxMedium* pMed = m_pSourceShell->GetMedium();
79  if ( aEntered == pMed->GetName() )
80  {
81  // already loaded - nothing to do
82  return true;
83  }
84  }
85 
86  OUString aFilter;
87  OUString aOptions;
88  // get filter name by looking at the file content (bWithContent = true)
89  // Break operation if any error occurred inside.
90  if (!ScDocumentLoader::GetFilterName( aEntered, aFilter, aOptions, true, false ))
91  return true;
92 
93  // #i53241# replace HTML filter with DataQuery filter
94  if (aFilter == FILTERNAME_HTML)
95  aFilter = FILTERNAME_QUERY;
96 
97  LoadDocument( aEntered, aFilter, aOptions );
98 
99  UpdateSourceRanges();
100  UpdateEnable();
101 
102  return true;
103 }
104 
105 void ScLinkedAreaDlg::LoadDocument( const OUString& rFile, const OUString& rFilter, const OUString& rOptions )
106 {
107  if (m_pSourceShell)
108  {
109  // unload old document
111  m_pSourceShell = nullptr;
112  aSourceRef.clear();
113  }
114 
115  if ( rFile.isEmpty() )
116  return;
117 
118  weld::WaitObject aWait(m_xDialog.get());
119 
120  OUString aNewFilter = rFilter;
121  OUString aNewOptions = rOptions;
122 
123  SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, rFile );
124 
125  ScDocumentLoader aLoader( rFile, aNewFilter, aNewOptions, 0, m_xDialog.get() ); // with interaction
126  m_pSourceShell = aLoader.GetDocShell();
127  if (m_pSourceShell)
128  {
129  ErrCode nErr = m_pSourceShell->GetErrorCode();
130  if (nErr)
131  ErrorHandler::HandleError( nErr ); // including warnings
132 
134  aLoader.ReleaseDocRef(); // don't call DoClose in DocLoader dtor
135  }
136 }
137 
138 void ScLinkedAreaDlg::InitFromOldLink( const OUString& rFile, const OUString& rFilter,
139  const OUString& rOptions, const OUString& rSource,
140  sal_uLong nRefresh )
141 {
142  LoadDocument( rFile, rFilter, rOptions );
143  if (m_pSourceShell)
144  {
146  m_xCbUrl->set_entry_text(pMed->GetName());
147  }
148  else
149  m_xCbUrl->set_entry_text(EMPTY_OUSTRING);
150 
152 
153  if (!rSource.isEmpty())
154  {
155  sal_Int32 nIdx {0};
156  do
157  {
158  m_xLbRanges->select_text(rSource.getToken(0, ';', nIdx));
159  }
160  while (nIdx>0);
161  }
162 
163  bool bDoRefresh = (nRefresh != 0);
164  m_xBtnReload->set_active(bDoRefresh);
165  if (bDoRefresh)
166  m_xNfDelay->set_value(nRefresh);
167 
168  UpdateEnable();
169 }
170 
172 {
173  UpdateEnable();
174 }
175 
177 {
178  UpdateEnable();
179 }
180 
181 IMPL_LINK( ScLinkedAreaDlg, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void )
182 {
183  if ( _pFileDlg->GetError() != ERRCODE_NONE )
184  return;
185 
186  std::unique_ptr<SfxMedium> pMed = m_xDocInserter->CreateMedium();
187  if ( pMed )
188  {
189  weld::WaitObject aWait(m_xDialog.get());
190 
191  // replace HTML filter with DataQuery filter
192  std::shared_ptr<const SfxFilter> pFilter = pMed->GetFilter();
193  if (pFilter && FILTERNAME_HTML == pFilter->GetFilterName())
194  {
195  std::shared_ptr<const SfxFilter> pNewFilter =
196  ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( FILTERNAME_QUERY );
197  if( pNewFilter )
198  pMed->SetFilter( pNewFilter );
199  }
200 
201  // ERRCTX_SFX_OPENDOC -> "Error loading document"
202  SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );
203 
204  if (m_pSourceShell)
205  m_pSourceShell->DoClose(); // deleted when assigning aSourceRef
206 
207  pMed->UseInteractionHandler( true ); // to enable the filter options dialog
208 
209  m_pSourceShell = new ScDocShell;
210  aSourceRef = m_pSourceShell;
211  m_pSourceShell->DoLoad( pMed.get() );
212 
213  ErrCode nErr = m_pSourceShell->GetErrorCode();
214  if (nErr)
215  ErrorHandler::HandleError( nErr ); // including warnings
216 
217  if (!m_pSourceShell->GetError()) // only errors
218  {
219  m_xCbUrl->set_entry_text(pMed->GetName());
220  }
221  else
222  {
223  m_pSourceShell->DoClose();
224  m_pSourceShell = nullptr;
225  aSourceRef.clear();
226 
227  m_xCbUrl->set_entry_text(EMPTY_OUSTRING);
228  }
229  pMed.release(); // DoLoad takes ownership
230  }
231 
232  UpdateSourceRanges();
233  UpdateEnable();
234 }
235 
236 #undef FILTERNAME_HTML
237 #undef FILTERNAME_QUERY
238 
240 {
241  m_xLbRanges->freeze();
242 
243  m_xLbRanges->clear();
244  if ( m_pSourceShell )
245  {
246  std::shared_ptr<const SfxFilter> pFilter = m_pSourceShell->GetMedium()->GetFilter();
247  if (pFilter && pFilter->GetFilterName() == SC_TEXT_CSV_FILTER_NAME)
248  {
249  // Insert dummy All range to have something selectable.
250  m_xLbRanges->append_text("CSV_all");
251  }
252 
253  // tdf#142600 - list tables in order of their appearance in the document's source
254  const ScRangeName* pRangeName = m_pSourceShell->GetDocument().GetRangeName();
255  for (size_t i = 1; i <= pRangeName->index_size(); i++)
256  {
257  if (const ScRangeData* pRangeData = pRangeName->findByIndex(i))
258  {
259  m_xLbRanges->append_text(pRangeData->GetName());
260  }
261  }
262  }
263 
264  m_xLbRanges->thaw();
265 
266  if (m_xLbRanges->n_children() >= 1)
267  m_xLbRanges->select(0);
268  else
269  {
270  m_xLbRanges->append_text(ScResId(STR_NO_NAMED_RANGES_AVAILABLE));
271  m_xLbRanges->set_sensitive(false);
272  }
273 }
274 
276 {
277  bool bEnable = ( m_pSourceShell && m_xLbRanges->count_selected_rows() );
278  m_xBtnOk->set_sensitive(bEnable);
279 
280  bool bReload = m_xBtnReload->get_active();
281  m_xNfDelay->set_sensitive(bReload);
282  m_xFtSeconds->set_sensitive(bReload);
283 }
284 
285 OUString ScLinkedAreaDlg::GetURL() const
286 {
287  if (m_pSourceShell)
288  {
290  return pMed->GetName();
291  }
292  return EMPTY_OUSTRING;
293 }
294 
296 {
297  if (m_pSourceShell)
298  {
300  return pMed->GetFilter()->GetFilterName();
301  }
302  return OUString();
303 }
304 
306 {
307  if (m_pSourceShell)
308  {
310  return ScDocumentLoader::GetOptions( *pMed );
311  }
312  return OUString();
313 }
314 
316 {
317  OUStringBuffer aBuf;
318  std::vector<OUString> aSelection = m_xLbRanges->get_selected_rows_text();
319  for (size_t i = 0; i < aSelection.size(); ++i)
320  {
321  if (i > 0)
322  aBuf.append(';');
323  aBuf.append(aSelection[i]);
324  }
325  return aBuf.makeStringAndClear();
326 }
327 
329 {
330  if (m_xBtnReload->get_active())
331  return sal::static_int_cast<sal_uLong>(m_xNfDelay->get_value());
332  else
333  return 0; // disabled
334 }
335 
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::shared_ptr< weld::Dialog > m_xDialog
OUString GetFilter() const
Definition: linkarea.cxx:295
sal_uLong GetRefresh() const
Definition: linkarea.cxx:328
#define EMPTY_OUSTRING
Definition: global.hxx:213
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:89
IMPL_LINK(ScLinkedAreaDlg, DialogClosedHdl, sfx2::FileDialogHelper *, _pFileDlg, void)
Definition: linkarea.cxx:181
virtual ~ScLinkedAreaDlg() override
Definition: linkarea.cxx:60
std::unique_ptr< weld::TreeView > m_xLbRanges
Definition: linkarea.hxx:41
const OUString & GetName() const
sal_uIntPtr sal_uLong
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:168
aBuf
std::unique_ptr< weld::SpinButton > m_xNfDelay
Definition: linkarea.hxx:43
constexpr OUStringLiteral FILTERNAME_HTML
Definition: linkarea.cxx:64
std::unique_ptr< weld::Button > m_xBtnBrowse
Definition: linkarea.hxx:40
static OUString GetOptions(const SfxMedium &rMedium)
Definition: tablink.cxx:422
void UpdateSourceRanges()
Definition: linkarea.cxx:239
std::unique_ptr< weld::Label > m_xFtSeconds
Definition: linkarea.hxx:44
constexpr OUStringLiteral FILTERNAME_QUERY
Definition: linkarea.cxx:65
void LoadDocument(const OUString &rFile, const OUString &rFilter, const OUString &rOptions)
Definition: linkarea.cxx:105
void InitFromOldLink(const OUString &rFile, const OUString &rFilter, const OUString &rOptions, const OUString &rSource, sal_uLong nRefresh)
Definition: linkarea.cxx:138
#define ERRCTX_SFX_OPENDOC
ScDocShell * m_pSourceShell
Definition: linkarea.hxx:35
int i
static DialogMask HandleError(ErrCode nId, weld::Window *pParent=nullptr, DialogMask nMask=DialogMask::MAX)
ScLinkedAreaDlg(weld::Widget *pParent)
Definition: linkarea.cxx:38
float u
OUString GetOptions() const
Definition: linkarea.cxx:305
std::unique_ptr< weld::Button > m_xBtnOk
Definition: linkarea.hxx:45
SC_DLLPUBLIC ScRangeData * findByIndex(sal_uInt16 i) const
Definition: rangenam.cxx:693
const std::shared_ptr< const SfxFilter > & GetFilter() const
IMPL_LINK_NOARG(ScLinkedAreaDlg, BrowseHdl, weld::Button &, void)
Definition: linkarea.cxx:67
SfxObjectShellRef aSourceRef
Definition: linkarea.hxx:37
SC_DLLPUBLIC size_t index_size() const
Definition: rangenam.cxx:804
#define ERRCODE_NONE
#define SC_TEXT_CSV_FILTER_NAME
Definition: global.hxx:60
Reference< XExecutableDialog > m_xDialog
const ScDocument & GetDocument() const
Definition: docsh.hxx:216
OUString GetSource() const
Definition: linkarea.cxx:315
static bool GetFilterName(const OUString &rFileName, OUString &rFilter, OUString &rOptions, bool bWithContent, bool bWithInteraction)
Returns the filter name and options from a file name.
Definition: tablink.cxx:432
std::unique_ptr< weld::CheckButton > m_xBtnReload
Definition: linkarea.hxx:42
OUString GetURL() const
Definition: linkarea.cxx:285
bool DoLoad(SfxMedium *pMedium)
void UpdateEnable()
Definition: linkarea.cxx:275
std::unique_ptr< SvtURLBox > m_xCbUrl
Definition: linkarea.hxx:39
SfxMedium * GetMedium() const