Line data Source code
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 <comphelper/string.hxx>
23 : #include <sfx2/app.hxx>
24 : #include <sfx2/docfile.hxx>
25 : #include <sfx2/docfilt.hxx>
26 : #include <sfx2/docinsert.hxx>
27 : #include <sfx2/fcontnr.hxx>
28 : #include <sfx2/filedlghelper.hxx>
29 : #include <svtools/ehdl.hxx>
30 : #include <svtools/sfxecode.hxx>
31 : #include <vcl/waitobj.hxx>
32 :
33 : #include "linkarea.hxx"
34 : #include "scresid.hxx"
35 : #include "sc.hrc"
36 : #include "rangeutl.hxx"
37 : #include "docsh.hxx"
38 : #include "tablink.hxx"
39 :
40 0 : ScLinkedAreaDlg::ScLinkedAreaDlg(vcl::Window* pParent)
41 : : ModalDialog(pParent, "ExternalDataDialog", "modules/scalc/ui/externaldata.ui")
42 : , pSourceShell(NULL)
43 0 : , pDocInserter(NULL)
44 :
45 : {
46 0 : get(m_pCbUrl, "url");
47 0 : get(m_pLbRanges, "ranges");
48 0 : m_pLbRanges->EnableMultiSelection(true);
49 0 : m_pLbRanges->SetDropDownLineCount(8);
50 0 : get(m_pBtnBrowse, "browse");
51 0 : get(m_pBtnReload, "reload");
52 0 : get(m_pNfDelay, "delay");
53 0 : get(m_pFtSeconds, "secondsft");
54 0 : get(m_pBtnOk, "ok");
55 :
56 0 : m_pCbUrl->SetSelectHdl( LINK( this, ScLinkedAreaDlg, FileHdl ) );
57 0 : m_pBtnBrowse->SetClickHdl( LINK( this, ScLinkedAreaDlg, BrowseHdl ) );
58 0 : m_pLbRanges->SetSelectHdl( LINK( this, ScLinkedAreaDlg, RangeHdl ) );
59 0 : m_pBtnReload->SetClickHdl( LINK( this, ScLinkedAreaDlg, ReloadHdl ) );
60 0 : UpdateEnable();
61 0 : }
62 :
63 0 : ScLinkedAreaDlg::~ScLinkedAreaDlg()
64 : {
65 0 : disposeOnce();
66 0 : }
67 :
68 0 : void ScLinkedAreaDlg::dispose()
69 : {
70 : // pSourceShell is deleted by aSourceRef
71 0 : m_pCbUrl.clear();
72 0 : m_pBtnBrowse.clear();
73 0 : m_pLbRanges.clear();
74 0 : m_pBtnReload.clear();
75 0 : m_pNfDelay.clear();
76 0 : m_pFtSeconds.clear();
77 0 : m_pBtnOk.clear();
78 0 : ModalDialog::dispose();
79 0 : }
80 :
81 0 : short ScLinkedAreaDlg::Execute()
82 : {
83 : // set parent for file dialog or filter options
84 :
85 0 : vcl::Window* pOldDefParent = Application::GetDefDialogParent();
86 0 : Application::SetDefDialogParent( this );
87 :
88 0 : short nRet = ModalDialog::Execute();
89 :
90 0 : Application::SetDefDialogParent( pOldDefParent );
91 :
92 0 : return nRet;
93 : }
94 :
95 : #define FILTERNAME_HTML "HTML (StarCalc)"
96 : #define FILTERNAME_QUERY "calc_HTML_WebQuery"
97 :
98 0 : IMPL_LINK_NOARG(ScLinkedAreaDlg, BrowseHdl)
99 : {
100 0 : if ( !pDocInserter )
101 : pDocInserter = new sfx2::DocumentInserter(
102 0 : OUString::createFromAscii( ScDocShell::Factory().GetShortName() ) );
103 0 : pDocInserter->StartExecuteModal( LINK( this, ScLinkedAreaDlg, DialogClosedHdl ) );
104 0 : return 0;
105 : }
106 :
107 0 : IMPL_LINK_NOARG(ScLinkedAreaDlg, FileHdl)
108 : {
109 0 : OUString aEntered = m_pCbUrl->GetURL();
110 0 : if (pSourceShell)
111 : {
112 0 : SfxMedium* pMed = pSourceShell->GetMedium();
113 0 : if ( aEntered.equals(pMed->GetName()) )
114 : {
115 : // already loaded - nothing to do
116 0 : return 0;
117 : }
118 : }
119 :
120 0 : OUString aFilter;
121 0 : OUString aOptions;
122 : // get filter name by looking at the file content (bWithContent = true)
123 : // Break operation if any error occurred inside.
124 0 : if (!ScDocumentLoader::GetFilterName( aEntered, aFilter, aOptions, true, true ))
125 0 : return 0;
126 :
127 : // #i53241# replace HTML filter with DataQuery filter
128 0 : if (aFilter == FILTERNAME_HTML)
129 0 : aFilter = FILTERNAME_QUERY;
130 :
131 0 : LoadDocument( aEntered, aFilter, aOptions );
132 :
133 0 : UpdateSourceRanges();
134 0 : UpdateEnable();
135 0 : return 0;
136 : }
137 :
138 0 : void ScLinkedAreaDlg::LoadDocument( const OUString& rFile, const OUString& rFilter, const OUString& rOptions )
139 : {
140 0 : if ( pSourceShell )
141 : {
142 : // unload old document
143 0 : pSourceShell->DoClose();
144 0 : pSourceShell = NULL;
145 0 : aSourceRef.Clear();
146 : }
147 :
148 0 : if ( !rFile.isEmpty() )
149 : {
150 0 : WaitObject aWait( this );
151 :
152 0 : OUString aNewFilter = rFilter;
153 0 : OUString aNewOptions = rOptions;
154 :
155 0 : SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, rFile );
156 :
157 0 : ScDocumentLoader aLoader( rFile, aNewFilter, aNewOptions, 0, true ); // with interaction
158 0 : pSourceShell = aLoader.GetDocShell();
159 0 : if ( pSourceShell )
160 : {
161 0 : sal_uLong nErr = pSourceShell->GetErrorCode();
162 0 : if (nErr)
163 0 : ErrorHandler::HandleError( nErr ); // including warnings
164 :
165 0 : aSourceRef = pSourceShell;
166 0 : aLoader.ReleaseDocRef(); // don't call DoClose in DocLoader dtor
167 0 : }
168 : }
169 0 : }
170 :
171 0 : void ScLinkedAreaDlg::InitFromOldLink( const OUString& rFile, const OUString& rFilter,
172 : const OUString& rOptions, const OUString& rSource,
173 : sal_uLong nRefresh )
174 : {
175 0 : LoadDocument( rFile, rFilter, rOptions );
176 0 : if (pSourceShell)
177 : {
178 0 : SfxMedium* pMed = pSourceShell->GetMedium();
179 0 : m_pCbUrl->SetText( pMed->GetName() );
180 : }
181 : else
182 0 : m_pCbUrl->SetText( EMPTY_OUSTRING );
183 :
184 0 : UpdateSourceRanges();
185 :
186 0 : sal_Int32 nRangeCount = comphelper::string::getTokenCount(rSource, ';');
187 0 : for ( sal_Int32 i=0; i<nRangeCount; i++ )
188 : {
189 0 : OUString aRange = rSource.getToken(i,';');
190 0 : m_pLbRanges->SelectEntry( aRange );
191 0 : }
192 :
193 0 : bool bDoRefresh = (nRefresh != 0);
194 0 : m_pBtnReload->Check( bDoRefresh );
195 0 : if (bDoRefresh)
196 0 : m_pNfDelay->SetValue( nRefresh );
197 :
198 0 : UpdateEnable();
199 0 : }
200 :
201 0 : IMPL_LINK_NOARG(ScLinkedAreaDlg, RangeHdl)
202 : {
203 0 : UpdateEnable();
204 0 : return 0;
205 : }
206 :
207 0 : IMPL_LINK_NOARG(ScLinkedAreaDlg, ReloadHdl)
208 : {
209 0 : UpdateEnable();
210 0 : return 0;
211 : }
212 :
213 0 : IMPL_LINK( ScLinkedAreaDlg, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg )
214 : {
215 0 : if ( _pFileDlg->GetError() != ERRCODE_NONE )
216 0 : return 0;
217 :
218 0 : SfxMedium* pMed = pDocInserter->CreateMedium();
219 0 : if ( pMed )
220 : {
221 0 : WaitObject aWait( this );
222 :
223 : // replace HTML filter with DataQuery filter
224 0 : const OUString aHTMLFilterName( FILTERNAME_HTML );
225 0 : const OUString aWebQFilterName( FILTERNAME_QUERY );
226 :
227 0 : const SfxFilter* pFilter = pMed->GetFilter();
228 0 : if (pFilter && aHTMLFilterName.equals(pFilter->GetFilterName()))
229 : {
230 : const SfxFilter* pNewFilter =
231 0 : ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( aWebQFilterName );
232 0 : if( pNewFilter )
233 0 : pMed->SetFilter( pNewFilter );
234 : }
235 :
236 : // ERRCTX_SFX_OPENDOC -> "Error loading document"
237 0 : SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );
238 :
239 0 : if (pSourceShell)
240 0 : pSourceShell->DoClose(); // deleted when assigning aSourceRef
241 :
242 0 : pMed->UseInteractionHandler( true ); // to enable the filter options dialog
243 :
244 0 : pSourceShell = new ScDocShell;
245 0 : aSourceRef = pSourceShell;
246 0 : pSourceShell->DoLoad( pMed );
247 :
248 0 : sal_uLong nErr = pSourceShell->GetErrorCode();
249 0 : if (nErr)
250 0 : ErrorHandler::HandleError( nErr ); // including warnings
251 :
252 0 : if ( !pSourceShell->GetError() ) // only errors
253 : {
254 0 : m_pCbUrl->SetText( pMed->GetName() );
255 : }
256 : else
257 : {
258 0 : pSourceShell->DoClose();
259 0 : pSourceShell = NULL;
260 0 : aSourceRef.Clear();
261 :
262 0 : m_pCbUrl->SetText( EMPTY_OUSTRING );
263 0 : }
264 : }
265 :
266 0 : UpdateSourceRanges();
267 0 : UpdateEnable();
268 0 : return 0;
269 : }
270 :
271 : #undef FILTERNAME_HTML
272 : #undef FILTERNAME_QUERY
273 :
274 0 : void ScLinkedAreaDlg::UpdateSourceRanges()
275 : {
276 0 : m_pLbRanges->SetUpdateMode(false);
277 :
278 0 : m_pLbRanges->Clear();
279 0 : if ( pSourceShell )
280 : {
281 0 : ScAreaNameIterator aIter( &pSourceShell->GetDocument() );
282 0 : ScRange aDummy;
283 0 : OUString aName;
284 0 : while ( aIter.Next( aName, aDummy ) )
285 0 : m_pLbRanges->InsertEntry( aName );
286 : }
287 :
288 0 : m_pLbRanges->SetUpdateMode(true);
289 :
290 0 : if ( m_pLbRanges->GetEntryCount() == 1 )
291 0 : m_pLbRanges->SelectEntryPos(0);
292 0 : }
293 :
294 0 : void ScLinkedAreaDlg::UpdateEnable()
295 : {
296 0 : bool bEnable = ( pSourceShell && m_pLbRanges->GetSelectEntryCount() );
297 0 : m_pBtnOk->Enable( bEnable );
298 :
299 0 : bool bReload = m_pBtnReload->IsChecked();
300 0 : m_pNfDelay->Enable( bReload );
301 0 : m_pFtSeconds->Enable( bReload );
302 0 : }
303 :
304 0 : OUString ScLinkedAreaDlg::GetURL()
305 : {
306 0 : if (pSourceShell)
307 : {
308 0 : SfxMedium* pMed = pSourceShell->GetMedium();
309 0 : return pMed->GetName();
310 : }
311 0 : return EMPTY_OUSTRING;
312 : }
313 :
314 0 : OUString ScLinkedAreaDlg::GetFilter()
315 : {
316 0 : if (pSourceShell)
317 : {
318 0 : SfxMedium* pMed = pSourceShell->GetMedium();
319 0 : return pMed->GetFilter()->GetFilterName();
320 : }
321 0 : return OUString();
322 : }
323 :
324 0 : OUString ScLinkedAreaDlg::GetOptions()
325 : {
326 0 : if (pSourceShell)
327 : {
328 0 : SfxMedium* pMed = pSourceShell->GetMedium();
329 0 : return ScDocumentLoader::GetOptions( *pMed );
330 : }
331 0 : return OUString();
332 : }
333 :
334 0 : OUString ScLinkedAreaDlg::GetSource()
335 : {
336 0 : OUStringBuffer aBuf;
337 0 : sal_uInt16 nCount = m_pLbRanges->GetSelectEntryCount();
338 0 : for (sal_uInt16 i=0; i<nCount; i++)
339 : {
340 0 : if (i > 0)
341 0 : aBuf.append(';');
342 0 : aBuf.append(m_pLbRanges->GetSelectEntry(i));
343 : }
344 0 : return aBuf.makeStringAndClear();
345 : }
346 :
347 0 : sal_uLong ScLinkedAreaDlg::GetRefresh()
348 : {
349 0 : if ( m_pBtnReload->IsChecked() )
350 0 : return sal::static_int_cast<sal_uLong>( m_pNfDelay->GetValue() );
351 : else
352 0 : return 0; // disabled
353 0 : }
354 :
355 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|