LibreOffice Module sc (master)  1
xmlsourcedlg.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 
10 #include <xmlsourcedlg.hxx>
11 #include <bitmaps.hlst>
12 #include <document.hxx>
13 #include <orcusfilters.hxx>
14 #include <filter.hxx>
15 #include <reffact.hxx>
16 #include <tabvwsh.hxx>
17 
18 #include <unotools/pathoptions.hxx>
19 #include <tools/urlobj.hxx>
20 #include <sfx2/filedlghelper.hxx>
21 #include <sfx2/objsh.hxx>
22 
23 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
24 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
25 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
26 
27 using namespace com::sun::star;
28 
29 namespace {
30 
31 bool isAttribute(const weld::TreeView& rControl, const weld::TreeIter& rEntry)
32 {
33  const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rControl, rEntry);
34  if (!pUserData)
35  return false;
36 
37  return pUserData->meType == ScOrcusXMLTreeParam::Attribute;
38 }
39 
40 OUString getXPath(
41  const weld::TreeView& rTree, const weld::TreeIter& rEntry, std::vector<size_t>& rNamespaces)
42 {
43  OUStringBuffer aBuf;
44  std::unique_ptr<weld::TreeIter> xEntry(rTree.make_iterator(&rEntry));
45  do
46  {
47  // Collect used namespace.
49  if (pData)
50  rNamespaces.push_back(pData->mnNamespaceID);
51 
52  // element separator is '/' whereas attribute separator is '/@' in xpath.
53  aBuf.insert(0, rTree.get_text(*xEntry, 0));
54  if (isAttribute(rTree, *xEntry))
55  aBuf.insert(0, "/@");
56  else
57  aBuf.insert(0, '/');
58  }
59  while (rTree.iter_parent(*xEntry));
60 
61  return aBuf.makeStringAndClear();
62 }
63 
64 }
65 
67  SfxBindings* pB, SfxChildWindow* pCW, weld::Window* pParent, ScDocument* pDoc)
68  : ScAnyRefDlgController(pB, pCW, pParent, "modules/scalc/ui/xmlsourcedialog.ui", "XMLSourceDialog")
69  , mpDoc(pDoc)
70  , mbDlgLostFocus(false)
71  , mxBtnSelectSource(m_xBuilder->weld_button("selectsource"))
72  , mxFtSourceFile(m_xBuilder->weld_label("sourcefile"))
73  , mxMapGrid(m_xBuilder->weld_container("mapgrid"))
74  , mxLbTree(m_xBuilder->weld_tree_view("tree"))
75  , mxRefEdit(new formula::RefEdit(m_xBuilder->weld_entry("edit")))
76  , mxRefBtn(new formula::RefButton(m_xBuilder->weld_button("ref")))
77  , mxBtnOk(m_xBuilder->weld_button("ok"))
78  , mxBtnCancel(m_xBuilder->weld_button("cancel"))
79  , maCustomCompare(*mxLbTree)
80  , maCellLinks(maCustomCompare)
81  , maRangeLinks(maCustomCompare)
82 {
83  mxLbTree->set_size_request(mxLbTree->get_approximate_digit_width() * 40,
84  mxLbTree->get_height_rows(15));
85  mxLbTree->set_selection_mode(SelectionMode::Multiple);
86  mxRefEdit->SetReferences(this, nullptr);
87  mxRefBtn->SetReferences(this, mxRefEdit.get());
88 
89  mpActiveEdit = mxRefEdit.get();
90 
91  maXMLParam.maImgElementDefault = RID_BMP_ELEMENT_DEFAULT;
92  maXMLParam.maImgElementRepeat = RID_BMP_ELEMENT_REPEAT;
93  maXMLParam.maImgAttribute = RID_BMP_ELEMENT_ATTRIBUTE;
94 
95  Link<weld::Button&,void> aBtnHdl = LINK(this, ScXMLSourceDlg, BtnPressedHdl);
96  mxBtnSelectSource->connect_clicked(aBtnHdl);
97  mxBtnOk->connect_clicked(aBtnHdl);
98  mxBtnCancel->connect_clicked(aBtnHdl);
99 
100  mxLbTree->connect_changed(LINK(this, ScXMLSourceDlg, TreeItemSelectHdl));
101 
102  Link<formula::RefEdit&,void> aLink = LINK(this, ScXMLSourceDlg, RefModifiedHdl);
103  mxRefEdit->SetModifyHdl(aLink);
104 
105  mxBtnOk->set_sensitive(false);
106 
107  SetNonLinkable();
108  mxBtnSelectSource->grab_focus(); // Initial focus is on the select source button.
109 }
110 
112 {
113 }
114 
116 {
117  return mpActiveEdit != nullptr && mpActiveEdit->GetWidget()->get_sensitive();
118 }
119 
121 {
122  if (!mpActiveEdit)
123  return;
124 
125  if (rRange.aStart != rRange.aEnd)
127 
128  OUString aStr(rRange.aStart.Format(ScRefFlags::ADDR_ABS_3D, &rDoc, rDoc.GetAddressConvention()));
129  mpActiveEdit->SetRefString(aStr);
130 
131  RefEditModified();
132 }
133 
135 {
136  mbDlgLostFocus = true;
137 }
138 
140 {
141  if (mbDlgLostFocus)
142  {
143  mbDlgLostFocus = false;
144  if (mpActiveEdit)
145  {
147  }
148  }
149  else
150  {
151  m_xDialog->grab_focus();
152  }
153 
154  RefInputDone();
155 }
156 
158 {
159  DoClose(ScXMLSourceDlgWrapper::GetChildWindowId());
160 }
161 
163 {
164  sfx2::FileDialogHelper aDlgHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
165  FileDialogFlags::NONE, m_xDialog.get());
167 
168  uno::Reference<ui::dialogs::XFilePicker3> xFilePicker = aDlgHelper.GetFilePicker();
169 
170  // Use the directory of current source file.
172  aURL.removeSegment();
173  aURL.removeFinalSlash();
174  OUString aPath = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
175  xFilePicker->setDisplayDirectory(aPath);
176 
177  if (xFilePicker->execute() != ui::dialogs::ExecutableDialogResults::OK)
178  // File picker dialog cancelled.
179  return;
180 
181  uno::Sequence<OUString> aFiles = xFilePicker->getSelectedFiles();
182  if (!aFiles.hasElements())
183  return;
184 
185  // There should only be one file returned from the file picker.
186  maSrcPath = aFiles[0];
187  mxFtSourceFile->set_label(maSrcPath);
189 }
190 
191 void ScXMLSourceDlg::LoadSourceFileStructure(const OUString& rPath)
192 {
194  if (!pOrcus)
195  return;
196 
197  mpXMLContext = pOrcus->createXMLContext(*mpDoc, rPath);
198  if (!mpXMLContext)
199  return;
200 
201  mpXMLContext->loadXMLStructure(*mxLbTree, maXMLParam);
202 }
203 
204 namespace {
205 
212 std::unique_ptr<weld::TreeIter> getReferenceEntry(const weld::TreeView& rTree, const weld::TreeIter& rCurEntry)
213 {
214  std::unique_ptr<weld::TreeIter> xParent(rTree.make_iterator(&rCurEntry));
215  bool bParent = rTree.iter_parent(*xParent);
216  std::unique_ptr<weld::TreeIter> xRefEntry;
217  while (bParent)
218  {
220  OSL_ASSERT(pUserData);
221  if (pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat)
222  {
223  // This is a repeat element - a potential reference entry.
224  xRefEntry = rTree.make_iterator(xParent.get());
225  }
226  bParent = rTree.iter_parent(*xParent);
227  }
228 
229  if (xRefEntry)
230  return xRefEntry;
231 
232  std::unique_ptr<weld::TreeIter> xCurEntry(rTree.make_iterator(&rCurEntry));
233  return xCurEntry;
234 }
235 
236 }
237 
239 {
240  std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
241  if (!mxLbTree->get_cursor(xEntry.get()))
242  return;
243 
244  mxLbTree->unselect_all();
245  mxLbTree->select(*xEntry);
246 
247  mxCurRefEntry = getReferenceEntry(*mxLbTree, *xEntry);
248 
250  OSL_ASSERT(pUserData);
251 
252  const ScAddress& rPos = pUserData->maLinkedPos;
253  if (rPos.IsValid())
254  {
256  mxRefEdit->SetRefString(aStr);
257  }
258  else
259  mxRefEdit->SetRefString(OUString());
260 
261  switch (pUserData->meType)
262  {
265  break;
268  break;
271  break;
272  default:
273  ;
274  }
275 }
276 
278 {
279  if (mxLbTree->iter_has_child(rEntry))
280  {
281  // Only an element with no child elements (leaf element) can be linked.
282  bool bHasChild = false;
283  std::unique_ptr<weld::TreeIter> xChild(mxLbTree->make_iterator(&rEntry));
284  (void)mxLbTree->iter_children(*xChild);
285  do
286  {
288  OSL_ASSERT(pUserData);
289  if (pUserData->meType != ScOrcusXMLTreeParam::Attribute)
290  {
291  // This child is not an attribute. Bail out.
292  bHasChild = true;
293  break;
294  }
295  }
296  while (mxLbTree->iter_next_sibling(*xChild));
297 
298  if (bHasChild)
299  {
300  SetNonLinkable();
301  return;
302  }
303  }
304 
305  // Check all its parents and make sure non of them are range-linked nor
306  // repeat elements.
307  if (IsParentDirty(&rEntry))
308  {
309  SetNonLinkable();
310  return;
311  }
312 
314 }
315 
317 {
318  // Check all its parents first.
319 
320  if (IsParentDirty(&rEntry))
321  {
322  SetNonLinkable();
323  return;
324  }
325 
326  // Check all its child elements / attributes and make sure non of them are
327  // linked.
328 
329  if (IsChildrenDirty(&rEntry))
330  {
331  SetNonLinkable();
332  return;
333  }
334 
335  if (!mxLbTree->is_selected(rEntry))
336  {
337  // Highlight the entry if not highlighted already. This can happen
338  // when the current entry is a child entry of a repeat element entry.
339  mxLbTree->select(rEntry);
340  }
341 
342  SelectAllChildEntries(rEntry);
344 }
345 
347 {
348  // Check all its parent elements and make sure non of them are linked nor
349  // repeat elements. In attribute's case, it's okay to have the immediate
350  // parent element linked (but not range-linked).
351  std::unique_ptr<weld::TreeIter> xParent(mxLbTree->make_iterator(&rEntry));
352  mxLbTree->iter_parent(*xParent);
353 
355  OSL_ASSERT(pUserData);
356  if (pUserData->maLinkedPos.IsValid() && pUserData->mbRangeParent)
357  {
358  // Parent element is range-linked. Bail out.
359  SetNonLinkable();
360  return;
361  }
362 
363  if (IsParentDirty(&rEntry))
364  {
365  SetNonLinkable();
366  return;
367  }
368 
370 }
371 
373 {
374  mxMapGrid->set_sensitive(false);
375 }
376 
378 {
379  mxMapGrid->set_sensitive(true);
380 }
381 
383 {
384  mxMapGrid->set_sensitive(true);
385 }
386 
388 {
389  std::unique_ptr<weld::TreeIter> xChild(mxLbTree->make_iterator(&rEntry));
390  if (!mxLbTree->iter_children(*xChild))
391  return;
392  do
393  {
394  SelectAllChildEntries(*xChild); // select recursively.
395  mxLbTree->select(*xChild);
396  } while (mxLbTree->iter_next_sibling(*xChild));
397 }
398 
400 {
401  std::unique_ptr<weld::TreeIter> xParent(mxLbTree->make_iterator(pEntry));
402  if (!mxLbTree->iter_parent(*xParent))
403  return false;
404  do
405  {
407  assert(pUserData);
408  if (pUserData->maLinkedPos.IsValid())
409  {
410  // This parent is already linked.
411  return true;
412  }
413  }
414  while (mxLbTree->iter_parent(*xParent));
415  return false;
416 }
417 
419 {
420  std::unique_ptr<weld::TreeIter> xChild(mxLbTree->make_iterator(pEntry));
421  if (!mxLbTree->iter_children(*xChild))
422  return false;
423 
424  do
425  {
427  OSL_ASSERT(pUserData);
428  if (pUserData->maLinkedPos.IsValid())
429  // Already linked.
430  return true;
431 
433  {
434  // Check recursively.
435  if (IsChildrenDirty(xChild.get()))
436  return true;
437  }
438  } while (mxLbTree->iter_next_sibling(*xChild));
439 
440  return false;
441 }
442 
443 namespace {
444 
448 void getFieldLinks(
449  ScOrcusImportXMLParam::RangeLink& rRangeLink, std::vector<size_t>& rNamespaces,
450  const weld::TreeView& rTree, const weld::TreeIter& rEntry)
451 {
452  std::unique_ptr<weld::TreeIter> xChild(rTree.make_iterator(&rEntry));
453  if (!rTree.iter_children(*xChild))
454  // No more children. We're done.
455  return;
456 
457  do
458  {
459  OUString aPath = getXPath(rTree, *xChild, rNamespaces);
460  const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rTree, *xChild);
461 
462  if (pUserData)
463  {
464  if (pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat)
465  // nested repeat element automatically becomes a row-group node.
466  rRangeLink.maRowGroups.push_back(
467  OUStringToOString(aPath, RTL_TEXTENCODING_UTF8));
468 
469  if (pUserData->mbLeafNode && !aPath.isEmpty())
470  // XPath should never be empty anyway, but it won't hurt to check...
471  rRangeLink.maFieldPaths.push_back(OUStringToOString(aPath, RTL_TEXTENCODING_UTF8));
472  }
473 
474  // Walk recursively.
475  getFieldLinks(rRangeLink, rNamespaces, rTree, *xChild);
476  } while (rTree.iter_next_sibling(*xChild));
477 }
478 
479 void removeDuplicates(std::vector<size_t>& rArray)
480 {
481  std::sort(rArray.begin(), rArray.end());
482  std::vector<size_t>::iterator it = std::unique(rArray.begin(), rArray.end());
483  rArray.erase(it, rArray.end());
484 }
485 
486 }
487 
489 {
490  if (!mpXMLContext)
491  return;
492 
493  // Begin import.
494 
495  ScOrcusImportXMLParam aParam;
496 
497  // Convert single cell links.
498  for (const auto& rEntry : maCellLinks)
499  {
500  OUString aPath = getXPath(*mxLbTree, *rEntry, aParam.maNamespaces);
502 
503  aParam.maCellLinks.emplace_back(
504  pUserData->maLinkedPos, OUStringToOString(aPath, RTL_TEXTENCODING_UTF8));
505  }
506 
507  // Convert range links. For now, an element with range link takes all its
508  // child elements as its fields.
509  for (const auto& rEntry: maRangeLinks)
510  {
512 
514  aRangeLink.maPos = pUserData->maLinkedPos;
515 
516  // Go through all its child elements.
517  getFieldLinks(aRangeLink, aParam.maNamespaces, *mxLbTree, *rEntry);
518 
519  // Add the reference entry as a row-group node, which will be used
520  // as a row position increment point.
521  OUString aThisEntry = getXPath(*mxLbTree, *rEntry, aParam.maNamespaces);
522  aRangeLink.maRowGroups.push_back(
523  OUStringToOString(aThisEntry, RTL_TEXTENCODING_UTF8));
524 
525  aParam.maRangeLinks.push_back(aRangeLink);
526  }
527 
528  // Remove duplicate namespace IDs.
529  removeDuplicates(aParam.maNamespaces);
530 
531  // Now do the import.
532  mpXMLContext->importXML(aParam);
533 
534  // Don't forget to broadcast the change.
536  pShell->Broadcast(SfxHint(SfxHintId::ScDataChanged));
537 
538  // Repaint the grid to force repaint the cell values.
540  if (pViewShell)
541  pViewShell->PaintGrid();
542 
543  m_xDialog->response(RET_OK);
544 }
545 
547 {
548  m_xDialog->response(RET_CANCEL);
549 }
550 
552 {
553  OUString aRefStr = mxRefEdit->GetText();
554 
555  // Check if the address is valid.
556  ScAddress aLinkedPos;
557  ScRefFlags nRes = aLinkedPos.Parse(aRefStr, *mpDoc, mpDoc->GetAddressConvention());
558  bool bValid = ( (nRes & ScRefFlags::VALID) == ScRefFlags::VALID );
559 
560  // TODO: For some unknown reason, setting the ref invalid will hide the text altogether.
561  // Find out how to make this work.
562 // mxRefEdit->SetRefValid(bValid);
563 
564  if (!bValid)
565  aLinkedPos.SetInvalid();
566 
567  // Set this address to the current reference entry.
568  if (!mxCurRefEntry)
569  // This should never happen.
570  return;
571 
573  if (!pUserData)
574  // This should never happen either.
575  return;
576 
577  bool bRepeatElem = pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat;
578  pUserData->maLinkedPos = aLinkedPos;
579  pUserData->mbRangeParent = aLinkedPos.IsValid() && bRepeatElem;
580 
581  if (bRepeatElem)
582  {
583  if (bValid)
584  maRangeLinks.insert(mxLbTree->make_iterator(mxCurRefEntry.get()));
585  else
587  }
588  else
589  {
590  if (bValid)
591  maCellLinks.insert(mxLbTree->make_iterator(mxCurRefEntry.get()));
592  else
593  maCellLinks.erase(mxCurRefEntry);
594  }
595 
596  // Enable the import button only when at least one link exists.
597  bool bHasLink = !maCellLinks.empty() || !maRangeLinks.empty();
598  mxBtnOk->set_sensitive(bHasLink);
599 }
600 
601 IMPL_LINK(ScXMLSourceDlg, BtnPressedHdl, weld::Button&, rBtn, void)
602 {
603  if (&rBtn == mxBtnSelectSource.get())
604  SelectSourceFile();
605  else if (&rBtn == mxBtnOk.get())
606  OkPressed();
607  else if (&rBtn == mxBtnCancel.get())
608  CancelPressed();
609 }
610 
611 IMPL_LINK_NOARG(ScXMLSourceDlg, TreeItemSelectHdl, weld::TreeView&, void)
612 {
613  TreeItemSelected();
614 }
615 
617 {
618  RefEditModified();
619 }
620 
621 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< weld::TreeIter > mxCurRefEntry
EntryType meType
numerical ID for xml namespace
Definition: orcusxml.hxx:34
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2117
OUString maImgElementRepeat
Definition: orcusxml.hxx:45
URL aURL
ScAddress aStart
Definition: address.hxx:499
Collection of orcus filter wrappers.
virtual bool iter_parent(TreeIter &rIter) const =0
std::unique_ptr< ContentProperties > pData
void RefEditModified()
std::unique_ptr< weld::Label > mxFtSourceFile
OUString maImgAttribute
Definition: orcusxml.hxx:46
void RepeatElementSelected(const weld::TreeIter &rEntry)
ScOrcusXMLTreeParam maXMLParam
void LoadSourceFileStructure(const OUString &rPath)
aBuf
static EntryData * getUserData(const weld::TreeView &rControl, const weld::TreeIter &rEntry)
Definition: orcusxml.cxx:22
static SC_DLLPUBLIC ScFormatFilterPlugin & Get()
Definition: impex.cxx:2584
void DefaultElementSelected(const weld::TreeIter &rEntry)
void PaintGrid()
Definition: tabview3.cxx:2628
ScAddress aEnd
Definition: address.hxx:500
ScDocument * mpDoc
OUString maSrcPath
RET_CANCEL
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:494
IMPL_LINK(ScXMLSourceDlg, BtnPressedHdl, weld::Button &, rBtn, void)
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const =0
virtual ScOrcusFilters * GetOrcusFilters()=0
virtual void Close() override
std::unique_ptr< ScOrcusXMLContext > mpXMLContext
std::unique_ptr< formula::RefButton > mxRefBtn
void SetSingleLinkable()
std::unique_ptr< formula::RefEdit > mxRefEdit
void TreeItemSelected()
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::vector< RangeLink > maRangeLinks
Definition: orcusxml.hxx:76
IMPL_LINK_NOARG(ScXMLSourceDlg, TreeItemSelectHdl, weld::TreeView &, void)
void SetContext(Context _eNewContext)
virtual void SetActive() override
bool IsValid() const
Definition: address.hxx:292
virtual void Deactivate() override
formula::RefEdit * mpActiveEdit
virtual std::unique_ptr< ScOrcusXMLContext > createXMLContext(ScDocument &rDoc, const OUString &rPath) const =0
Create a context for XML file.
void SetRefString(const OUString &rStr)
std::set< std::unique_ptr< weld::TreeIter >, CustomCompare > maRangeLinks
virtual bool IsRefInputMode() const override
bool mbRangeParent
linked cell position (invalid if unlinked)
Definition: orcusxml.hxx:36
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:756
virtual OUString get_text(int row, int col=-1) const =0
bool removeFinalSlash()
weld::Entry * GetWidget() const
bool IsChildrenDirty(const weld::TreeIter *pEntry) const
void AttributeSelected(const weld::TreeIter &rEntry)
bool IsParentDirty(const weld::TreeIter *pEntry) const
Check if any of its parents is linked or repeated.
virtual bool iter_children(TreeIter &rIter) const =0
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
virtual bool get_sensitive() const =0
std::vector< size_t > maNamespaces
Definition: orcusxml.hxx:74
OUString maImgElementDefault
Definition: orcusxml.hxx:44
static ScTabViewShell * GetActiveViewShell()
Definition: tabvwsh4.cxx:1038
std::vector< CellLink > maCellLinks
Definition: orcusxml.hxx:75
std::unique_ptr< weld::Button > mxBtnCancel
std::unique_ptr< weld::Button > mxBtnSelectSource
std::unique_ptr< weld::TreeView > mxLbTree
RET_OK
std::unique_ptr< weld::Container > mxMapGrid
Reference< XExecutableDialog > m_xDialog
void SetInvalid()
Definition: address.hxx:286
std::set< std::unique_ptr< weld::TreeIter >, CustomCompare > maCellLinks
void SelectAllChildEntries(const weld::TreeIter &rEntry)
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1057
virtual bool iter_next_sibling(TreeIter &rIter) const =0
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const Details &rDetails=detailsOOOa1, ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, sal_Int32 *pSheetEndPos=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1549
void SetRangeLinkable()
virtual ~ScXMLSourceDlg() override
ScRefFlags
Definition: address.hxx:144
virtual void SetReference(const ScRange &rRange, ScDocument &rDoc) override
ScXMLSourceDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScDocument *pDoc)
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:695
Custom data stored with each tree item.
Definition: orcusxml.hxx:31
aStr
void SelectSourceFile()
std::unique_ptr< weld::Button > mxBtnOk
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:726
bool removeSegment(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true)
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo