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