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 <linkarea.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));
58}
59
61{
62}
63
64constexpr OUStringLiteral FILTERNAME_HTML = u"HTML (StarCalc)";
65constexpr 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
105void 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;
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
124
125 ScDocumentLoader aLoader( rFile, aNewFilter, aNewOptions, 0, m_xDialog.get() ); // with interaction
126 m_pSourceShell = aLoader.GetDocShell();
127 if (m_pSourceShell)
128 {
130 if (nErr)
131 ErrorHandler::HandleError( nErr ); // including warnings
132
134 aLoader.ReleaseDocRef(); // don't call DoClose in DocLoader dtor
135 }
136}
137
138void ScLinkedAreaDlg::InitFromOldLink( const OUString& rFile, const OUString& rFilter,
139 const OUString& rOptions, std::u16string_view rSource,
140 sal_Int32 nRefreshDelaySeconds )
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(OUString());
150
152
153 if (!rSource.empty())
154 {
155 sal_Int32 nIdx {0};
156 do
157 {
158 m_xLbRanges->select_text(OUString(o3tl::getToken(rSource, 0, ';', nIdx)));
159 }
160 while (nIdx>0);
161 }
162
163 bool bDoRefresh = (nRefreshDelaySeconds != 0);
164 m_xBtnReload->set_active(bDoRefresh);
165 if (bDoRefresh)
166 m_xNfDelay->set_value(nRefreshDelaySeconds);
167
168 UpdateEnable();
169}
170
172{
173 UpdateEnable();
174}
175
177{
178 UpdateEnable();
179}
180
181IMPL_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(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
286{
287 if (m_pSourceShell)
288 {
290 return pMed->GetName();
291 }
292 return 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 m_xNfDelay->get_value();
332 else
333 return 0; // disabled
334}
335
336/* 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:220
void ReleaseDocRef()
Definition: tablink.cxx:561
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:433
ScDocShell * GetDocShell()
Definition: tablink.hxx:90
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:174
OUString GetURL() const
Definition: linkarea.cxx:285
sal_Int32 GetRefreshDelaySeconds() const
Definition: linkarea.cxx:328
ScLinkedAreaDlg(weld::Widget *pParent)
Definition: linkarea.cxx:38
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:105
std::unique_ptr< SvtURLBox > m_xCbUrl
Definition: linkarea.hxx:38
void UpdateEnable()
Definition: linkarea.cxx:275
std::unique_ptr< weld::CheckButton > m_xBtnReload
Definition: linkarea.hxx:41
OUString GetSource() const
Definition: linkarea.cxx:315
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:239
void InitFromOldLink(const OUString &rFile, const OUString &rFilter, const OUString &rOptions, std::u16string_view rSource, sal_Int32 nRefreshDelaySeconds)
Definition: linkarea.cxx:138
virtual ~ScLinkedAreaDlg() override
Definition: linkarea.cxx:60
OUString GetFilter() const
Definition: linkarea.cxx:295
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:305
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:181
constexpr OUStringLiteral FILTERNAME_QUERY
Definition: linkarea.cxx:65
constexpr OUStringLiteral FILTERNAME_HTML
Definition: linkarea.cxx:64
IMPL_LINK_NOARG(ScLinkedAreaDlg, BrowseHdl, weld::Button &, void)
Definition: linkarea.cxx:67
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