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_clicked(LINK( this, ScLinkedAreaDlg, ReloadHdl));
57  UpdateEnable();
58 }
59 
61 {
62 }
63 
64 #define FILTERNAME_HTML "HTML (StarCalc)"
65 #define FILTERNAME_QUERY "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 
254  ScRange aDummy;
255  OUString aName;
256  while ( aIter.Next( aName, aDummy ) )
257  m_xLbRanges->append_text(aName);
258  }
259 
260  m_xLbRanges->thaw();
261 
262  if (m_xLbRanges->n_children() >= 1)
263  m_xLbRanges->select(0);
264  else
265  {
266  m_xLbRanges->append_text(ScResId(STR_NO_NAMED_RANGES_AVAILABLE));
267  m_xLbRanges->set_sensitive(false);
268  }
269 }
270 
272 {
273  bool bEnable = ( m_pSourceShell && m_xLbRanges->count_selected_rows() );
274  m_xBtnOk->set_sensitive(bEnable);
275 
276  bool bReload = m_xBtnReload->get_active();
277  m_xNfDelay->set_sensitive(bReload);
278  m_xFtSeconds->set_sensitive(bReload);
279 }
280 
281 OUString ScLinkedAreaDlg::GetURL() const
282 {
283  if (m_pSourceShell)
284  {
286  return pMed->GetName();
287  }
288  return EMPTY_OUSTRING;
289 }
290 
292 {
293  if (m_pSourceShell)
294  {
296  return pMed->GetFilter()->GetFilterName();
297  }
298  return OUString();
299 }
300 
302 {
303  if (m_pSourceShell)
304  {
306  return ScDocumentLoader::GetOptions( *pMed );
307  }
308  return OUString();
309 }
310 
312 {
313  OUStringBuffer aBuf;
314  std::vector<OUString> aSelection = m_xLbRanges->get_selected_rows_text();
315  for (size_t i = 0; i < aSelection.size(); ++i)
316  {
317  if (i > 0)
318  aBuf.append(';');
319  aBuf.append(aSelection[i]);
320  }
321  return aBuf.makeStringAndClear();
322 }
323 
325 {
326  if (m_xBtnReload->get_active())
327  return sal::static_int_cast<sal_uLong>(m_xNfDelay->get_value());
328  else
329  return 0; // disabled
330 }
331 
332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::shared_ptr< weld::Dialog > m_xDialog
OUString GetFilter() const
Definition: linkarea.cxx:291
#define FILTERNAME_QUERY
Definition: linkarea.cxx:65
sal_uLong GetRefresh() const
Definition: linkarea.cxx:324
#define EMPTY_OUSTRING
Definition: global.hxx:215
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:42
const OUString & GetName() const
sal_uIntPtr sal_uLong
aBuf
std::unique_ptr< weld::SpinButton > m_xNfDelay
Definition: linkarea.hxx:44
std::unique_ptr< weld::Button > m_xBtnBrowse
Definition: linkarea.hxx:41
#define FILTERNAME_HTML
Definition: linkarea.cxx:64
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:45
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:36
int i
static DialogMask HandleError(ErrCode nId, weld::Window *pParent=nullptr, DialogMask nMask=DialogMask::MAX)
OUString ScResId(const char *pId)
Definition: scdll.cxx:95
OUString GetOptions() const
Definition: linkarea.cxx:301
std::unique_ptr< weld::Button > m_xBtnOk
Definition: linkarea.hxx:46
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:38
#define ERRCODE_NONE
ScLinkedAreaDlg(weld::Window *pParent)
Definition: linkarea.cxx:38
OUString aName
#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:311
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:43
OUString GetURL() const
Definition: linkarea.cxx:281
bool DoLoad(SfxMedium *pMedium)
void UpdateEnable()
Definition: linkarea.cxx:271
std::unique_ptr< SvtURLBox > m_xCbUrl
Definition: linkarea.hxx:40
SfxMedium * GetMedium() const