LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/ui/xmlsource - xmlsourcedlg.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 330 0.3 %
Date: 2013-07-09 Functions: 2 45 4.4 %
Legend: Lines: hit not hit

          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             : 
      10             : #include "xmlsourcedlg.hxx"
      11             : #include "xmlsourcedlg.hrc"
      12             : 
      13             : #include "scresid.hxx"
      14             : #include "document.hxx"
      15             : #include "orcusfilters.hxx"
      16             : #include "filter.hxx"
      17             : #include "reffact.hxx"
      18             : #include "tabvwsh.hxx"
      19             : 
      20             : #include "unotools/pathoptions.hxx"
      21             : #include "tools/urlobj.hxx"
      22             : #include "svtools/svlbitm.hxx"
      23             : #include "svtools/treelistentry.hxx"
      24             : #include "svtools/viewdataentry.hxx"
      25             : #include "sfx2/objsh.hxx"
      26             : 
      27             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      28             : #include <com/sun/star/ui/dialogs/FilePicker.hpp>
      29             : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
      30             : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
      31             : 
      32             : using namespace com::sun::star;
      33             : 
      34             : namespace {
      35             : 
      36           0 : bool isAttribute(const SvTreeListEntry& rEntry)
      37             : {
      38           0 :     const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rEntry);
      39           0 :     if (!pUserData)
      40           0 :         return false;
      41             : 
      42           0 :     return pUserData->meType == ScOrcusXMLTreeParam::Attribute;
      43             : }
      44             : 
      45           0 : OUString getXPath(
      46             :     const SvTreeListBox& rTree, const SvTreeListEntry& rEntry, std::vector<size_t>& rNamespaces)
      47             : {
      48           0 :     OUStringBuffer aBuf;
      49           0 :     for (const SvTreeListEntry* p = &rEntry; p; p = rTree.GetParent(p))
      50             :     {
      51           0 :         const SvLBoxItem* pItem = p->GetFirstItem(SV_ITEM_ID_LBOXSTRING);
      52           0 :         if (!pItem)
      53           0 :             continue;
      54             : 
      55             :         // Collect used namespace.
      56           0 :         const ScOrcusXMLTreeParam::EntryData* pData = ScOrcusXMLTreeParam::getUserData(*p);
      57           0 :         if (pData)
      58           0 :             rNamespaces.push_back(pData->mnNamespaceID);
      59             : 
      60           0 :         const SvLBoxString* pStr = static_cast<const SvLBoxString*>(pItem);
      61           0 :         aBuf.insert(0, pStr->GetText());
      62           0 :         aBuf.insert(0, isAttribute(*p) ? '@' : '/');
      63             :     }
      64             : 
      65           0 :     return aBuf.makeStringAndClear();
      66             : }
      67             : 
      68             : }
      69             : 
      70           0 : ScXMLSourceTree::ScXMLSourceTree(Window* pParent, const ResId& rResId) :
      71           0 :     SvTreeListBox(pParent, rResId) {}
      72             : 
      73           0 : ScXMLSourceDlg::ScXMLSourceDlg(
      74             :     SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, ScDocument* pDoc) :
      75             :     ScAnyRefDlg(pB, pCW, pParent, RID_SCDLG_XML_SOURCE),
      76             :     maFlSourceFile(this, ScResId(FL_SOURCE_FILE)),
      77             :     maBtnSelectSource(this, ScResId(BTN_SELECT_SOURCE_FILE)),
      78             :     maFtSourceFile(this, ScResId(FT_SOURCE_FILE)),
      79             :     maFtMapXmlDoc(this, ScResId(FL_MAP_XML_TO_DOCUMENT)),
      80             :     maFtMappedCellTitle(this, ScResId(FT_MAPPED_CELL_TITLE)),
      81             :     maLbTree(this, ScResId(LB_SOURCE_TREE)),
      82             :     maRefEdit(this, this, NULL, ScResId(ED_MAPPED_CELL)),
      83             :     maRefBtn(this, ScResId(BTN_MAPPED_CELL), &maRefEdit, this),
      84             :     maBtnOk(this, ScResId(BTN_OK)),
      85             :     maBtnCancel(this, ScResId(BTN_CANCEL)),
      86             :     maImgFileOpen(ScResId(IMG_FILE_OPEN)),
      87             :     mpCurRefEntry(NULL),
      88             :     mpDoc(pDoc),
      89             :     mpActiveEdit(&maRefEdit),
      90           0 :     mbDlgLostFocus(false)
      91             : {
      92           0 :     maXMLParam.maImgElementDefault = Image(ScResId(IMG_ELEMENT_DEFAULT));
      93           0 :     maXMLParam.maImgElementRepeat = Image(ScResId(IMG_ELEMENT_REPEAT));
      94           0 :     maXMLParam.maImgAttribute = Image(ScResId(IMG_ELEMENT_ATTRIBUTE));
      95             : 
      96           0 :     maBtnSelectSource.SetModeImage(maImgFileOpen);
      97           0 :     FreeResource();
      98             : 
      99           0 :     Link aBtnHdl = LINK(this, ScXMLSourceDlg, BtnPressedHdl);
     100           0 :     maBtnSelectSource.SetClickHdl(aBtnHdl);
     101           0 :     maBtnOk.SetClickHdl(aBtnHdl);
     102           0 :     maBtnCancel.SetClickHdl(aBtnHdl);
     103             : 
     104           0 :     Link aLink = LINK(this, ScXMLSourceDlg, GetFocusHdl);
     105           0 :     maRefEdit.SetGetFocusHdl(aLink);
     106           0 :     maRefBtn.SetGetFocusHdl(aLink);
     107           0 :     aLink = LINK(this, ScXMLSourceDlg, LoseFocusHdl);
     108           0 :     maRefEdit.SetLoseFocusHdl(aLink);
     109           0 :     maRefBtn.SetLoseFocusHdl(aLink);
     110             : 
     111           0 :     aLink = LINK(this, ScXMLSourceDlg, TreeItemSelectHdl);
     112           0 :     maLbTree.SetSelectHdl(aLink);
     113             : 
     114           0 :     aLink = LINK(this, ScXMLSourceDlg, RefModifiedHdl);
     115           0 :     maRefEdit.SetModifyHdl(aLink);
     116             : 
     117           0 :     maBtnOk.Disable();
     118             : 
     119           0 :     SetNonLinkable();
     120           0 :     maBtnSelectSource.GrabFocus(); // Initial focus is on the select source button.
     121           0 : }
     122             : 
     123           0 : ScXMLSourceDlg::~ScXMLSourceDlg()
     124             : {
     125           0 : }
     126             : 
     127           0 : sal_Bool ScXMLSourceDlg::IsRefInputMode() const
     128             : {
     129           0 :     return mpActiveEdit != NULL && mpActiveEdit->IsEnabled();
     130             : }
     131             : 
     132           0 : void ScXMLSourceDlg::SetReference(const ScRange& rRange, ScDocument* pDoc)
     133             : {
     134           0 :     if (!mpActiveEdit)
     135           0 :         return;
     136             : 
     137           0 :     if (rRange.aStart != rRange.aEnd)
     138           0 :         RefInputStart(mpActiveEdit);
     139             : 
     140           0 :     OUString aStr;
     141           0 :     rRange.aStart.Format(aStr, SCA_ABS_3D, pDoc, pDoc->GetAddressConvention());
     142           0 :     mpActiveEdit->SetRefString(aStr);
     143             : 
     144           0 :     RefEditModified();
     145             : }
     146             : 
     147           0 : void ScXMLSourceDlg::Deactivate()
     148             : {
     149           0 :     mbDlgLostFocus = true;
     150           0 : }
     151             : 
     152           0 : void ScXMLSourceDlg::SetActive()
     153             : {
     154           0 :     if (mbDlgLostFocus)
     155             :     {
     156           0 :         mbDlgLostFocus = false;
     157           0 :         if (mpActiveEdit)
     158             :         {
     159           0 :             mpActiveEdit->GrabFocus();
     160             :         }
     161             :     }
     162             :     else
     163             :     {
     164           0 :         GrabFocus();
     165             :     }
     166             : 
     167           0 :     RefInputDone();
     168           0 : }
     169             : 
     170           0 : sal_Bool ScXMLSourceDlg::Close()
     171             : {
     172           0 :     return DoClose(ScXMLSourceDlgWrapper::GetChildWindowId());
     173             : }
     174             : 
     175           0 : void ScXMLSourceDlg::SelectSourceFile()
     176             : {
     177           0 :     uno::Reference<ui::dialogs::XFilePicker3> xFilePicker = ui::dialogs::FilePicker::createWithMode( comphelper::getProcessComponentContext(), ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE );
     178             : 
     179           0 :     if (maSrcPath.isEmpty())
     180             :         // Use default path.
     181           0 :         xFilePicker->setDisplayDirectory(SvtPathOptions().GetWorkPath());
     182             :     else
     183             :     {
     184             :         // Use the directory of current source file.
     185           0 :         INetURLObject aURL(maSrcPath);
     186           0 :         aURL.removeSegment();
     187           0 :         aURL.removeFinalSlash();
     188           0 :         OUString aPath = aURL.GetMainURL(INetURLObject::NO_DECODE);
     189           0 :         xFilePicker->setDisplayDirectory(aPath);
     190             :     }
     191             : 
     192           0 :     if (xFilePicker->execute() != ui::dialogs::ExecutableDialogResults::OK)
     193             :         // File picker dialog cancelled.
     194           0 :         return;
     195             : 
     196           0 :     uno::Sequence<OUString> aFiles = xFilePicker->getFiles();
     197           0 :     if (!aFiles.getLength())
     198           0 :         return;
     199             : 
     200             :     // There should only be one file returned from the file picker.
     201           0 :     maSrcPath = aFiles[0];
     202           0 :     maFtSourceFile.SetText(maSrcPath);
     203           0 :     maHighlightedEntries.clear();
     204           0 :     LoadSourceFileStructure(maSrcPath);
     205             : }
     206             : 
     207           0 : void ScXMLSourceDlg::LoadSourceFileStructure(const OUString& rPath)
     208             : {
     209           0 :     ScOrcusFilters* pOrcus = ScFormatFilter::Get().GetOrcusFilters();
     210           0 :     if (!pOrcus)
     211           0 :         return;
     212             : 
     213           0 :     mpXMLContext.reset(pOrcus->createXMLContext(*mpDoc, rPath));
     214           0 :     if (!mpXMLContext)
     215           0 :         return;
     216             : 
     217           0 :     mpXMLContext->loadXMLStructure(maLbTree, maXMLParam);
     218             : }
     219             : 
     220           0 : void ScXMLSourceDlg::HandleGetFocus(Control* pCtrl)
     221             : {
     222           0 :     mpActiveEdit = NULL;
     223           0 :     if (pCtrl == &maRefEdit || pCtrl == &maRefBtn)
     224           0 :         mpActiveEdit = &maRefEdit;
     225             : 
     226           0 :     if (mpActiveEdit)
     227           0 :         mpActiveEdit->SetSelection(Selection(0, SELECTION_MAX));
     228           0 : }
     229             : 
     230           0 : void ScXMLSourceDlg::HandleLoseFocus(Control* /*pCtrl*/)
     231             : {
     232           0 : }
     233             : 
     234             : namespace {
     235             : 
     236             : class UnhighlightEntry : std::unary_function<SvTreeListEntry*, void>
     237             : {
     238             :     SvTreeListBox& mrTree;
     239             : public:
     240           0 :     UnhighlightEntry(SvTreeListBox& rTree) : mrTree(rTree) {}
     241             : 
     242           0 :     void operator() (SvTreeListEntry* p)
     243             :     {
     244           0 :         SvViewDataEntry* pView = mrTree.GetViewDataEntry(p);
     245           0 :         if (!pView)
     246           0 :             return;
     247             : 
     248           0 :         pView->SetHighlighted(false);
     249           0 :         mrTree.PaintEntry(p);
     250             :     }
     251             : };
     252             : 
     253             : /**
     254             :  * When the current entry is a direct or indirect child of a mappable
     255             :  * repeat element entry, that entry becomes the reference entry.
     256             :  * Otherwise the reference entry equals the current entry.  A reference
     257             :  * entry is the entry that stores mapped cell position.
     258             :  */
     259           0 : SvTreeListEntry* getReferenceEntry(SvTreeListBox& rTree, SvTreeListEntry* pCurEntry)
     260             : {
     261           0 :     SvTreeListEntry* pParent = rTree.GetParent(pCurEntry);
     262           0 :     SvTreeListEntry* pRefEntry = NULL;
     263           0 :     while (pParent)
     264             :     {
     265           0 :         ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(*pParent);
     266             :         OSL_ASSERT(pUserData);
     267           0 :         if (pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat)
     268             :         {
     269             :             // This is a repeat element.
     270           0 :             if (pRefEntry)
     271             :             {
     272             :                 // Second repeat element encountered. Not good.
     273           0 :                 return pCurEntry;
     274             :             }
     275             : 
     276           0 :             pRefEntry = pParent;
     277             :         }
     278           0 :         pParent = rTree.GetParent(pParent);
     279             :     }
     280             : 
     281           0 :     return pRefEntry ? pRefEntry : pCurEntry;
     282             : }
     283             : 
     284             : }
     285             : 
     286           0 : void ScXMLSourceDlg::TreeItemSelected()
     287             : {
     288           0 :     SvTreeListEntry* pEntry = maLbTree.GetCurEntry();
     289           0 :     if (!pEntry)
     290           0 :         return;
     291             : 
     292           0 :     if (!maHighlightedEntries.empty())
     293             :     {
     294             :         // Remove highlights from all previously highlighted entries (if any).
     295           0 :         std::for_each(maHighlightedEntries.begin(), maHighlightedEntries.end(), UnhighlightEntry(maLbTree));
     296           0 :         maHighlightedEntries.clear();
     297             :     }
     298             : 
     299           0 :     mpCurRefEntry = getReferenceEntry(maLbTree, pEntry);
     300             : 
     301           0 :     ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(*mpCurRefEntry);
     302             :     OSL_ASSERT(pUserData);
     303             : 
     304           0 :     const ScAddress& rPos = pUserData->maLinkedPos;
     305           0 :     if (rPos.IsValid())
     306             :     {
     307           0 :         OUString aStr;
     308           0 :         rPos.Format(aStr, SCA_ABS_3D, mpDoc, mpDoc->GetAddressConvention());
     309           0 :         maRefEdit.SetRefString(aStr);
     310             :     }
     311             :     else
     312           0 :         maRefEdit.SetRefString(OUString());
     313             : 
     314           0 :     switch (pUserData->meType)
     315             :     {
     316             :         case ScOrcusXMLTreeParam::Attribute:
     317           0 :             AttributeSelected(*mpCurRefEntry);
     318           0 :         break;
     319             :         case ScOrcusXMLTreeParam::ElementDefault:
     320           0 :             DefaultElementSelected(*mpCurRefEntry);
     321           0 :         break;
     322             :         case ScOrcusXMLTreeParam::ElementRepeat:
     323           0 :             RepeatElementSelected(*mpCurRefEntry);
     324           0 :         break;
     325             :         default:
     326             :             ;
     327             :     }
     328             : }
     329             : 
     330           0 : void ScXMLSourceDlg::DefaultElementSelected(SvTreeListEntry& rEntry)
     331             : {
     332             : 
     333           0 :     if (maLbTree.GetChildCount(&rEntry) > 0)
     334             :     {
     335             :         // Only an element with no child elements (leaf element) can be linked.
     336           0 :         bool bHasChild = false;
     337           0 :         ScOrcusXMLTreeParam::EntryData* pUserData = NULL;
     338           0 :         for (SvTreeListEntry* pChild = maLbTree.FirstChild(&rEntry); pChild; pChild = maLbTree.NextSibling(pChild))
     339             :         {
     340           0 :             pUserData = ScOrcusXMLTreeParam::getUserData(*pChild);
     341             :             OSL_ASSERT(pUserData);
     342           0 :             if (pUserData->meType != ScOrcusXMLTreeParam::Attribute)
     343             :             {
     344             :                 // This child is not an attribute. Bail out.
     345           0 :                 bHasChild = true;
     346           0 :                 break;
     347             :             }
     348             :         }
     349             : 
     350           0 :         if (bHasChild)
     351             :         {
     352           0 :             SetNonLinkable();
     353           0 :             return;
     354             :         }
     355             :     }
     356             : 
     357             :     // Check all its parents and make sure non of them are range-linked nor
     358             :     // repeat elements.
     359           0 :     if (IsParentDirty(&rEntry))
     360             :     {
     361           0 :         SetNonLinkable();
     362           0 :         return;
     363             :     }
     364             : 
     365           0 :     SetSingleLinkable();
     366             : }
     367             : 
     368           0 : void ScXMLSourceDlg::RepeatElementSelected(SvTreeListEntry& rEntry)
     369             : {
     370             :     // Check all its parents first.
     371             : 
     372           0 :     if (IsParentDirty(&rEntry))
     373             :     {
     374           0 :         SetNonLinkable();
     375           0 :         return;
     376             :     }
     377             : 
     378             :     // Check all its child elements / attributes and make sure non of them are
     379             :     // linked or repeat elements.  In the future we will support range linking
     380             :     // of repeat element who has another repeat elements. But first I need to
     381             :     // support that scenario in orcus.
     382             : 
     383           0 :     if (IsChildrenDirty(&rEntry))
     384             :     {
     385           0 :         SetNonLinkable();
     386           0 :         return;
     387             :     }
     388             : 
     389           0 :     SvViewDataEntry* p = maLbTree.GetViewDataEntry(&rEntry);
     390           0 :     if (!p->IsHighlighted())
     391             :     {
     392             :         // Highlight the entry if not highlighted already.  This can happen
     393             :         // when the current entry is a child entry of a repeat element entry.
     394           0 :         p->SetHighlighted(true);
     395           0 :         maLbTree.PaintEntry(&rEntry);
     396           0 :         maHighlightedEntries.push_back(&rEntry);
     397             :     }
     398             : 
     399           0 :     SelectAllChildEntries(rEntry);
     400           0 :     SetRangeLinkable();
     401             : }
     402             : 
     403           0 : void ScXMLSourceDlg::AttributeSelected(SvTreeListEntry& rEntry)
     404             : {
     405             :     // Check all its parent elements and make sure non of them are linked nor
     406             :     // repeat elements.  In attribute's case, it's okay to have the immediate
     407             :     // parent element linked (but not range-linked).
     408             : 
     409           0 :     SvTreeListEntry* pParent = maLbTree.GetParent(&rEntry);
     410             :     OSL_ASSERT(pParent); // attribute should have a parent element.
     411             : 
     412           0 :     ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(*pParent);
     413             :     OSL_ASSERT(pUserData);
     414           0 :     if (pUserData->maLinkedPos.IsValid() && pUserData->mbRangeParent)
     415             :     {
     416             :         // Parent element is range-linked.  Bail out.
     417           0 :         SetNonLinkable();
     418           0 :         return;
     419             :     }
     420             : 
     421           0 :     if (IsParentDirty(&rEntry))
     422             :     {
     423           0 :         SetNonLinkable();
     424           0 :         return;
     425             :     }
     426             : 
     427           0 :     SetSingleLinkable();
     428             : }
     429             : 
     430           0 : void ScXMLSourceDlg::SetNonLinkable()
     431             : {
     432           0 :     maFtMappedCellTitle.Disable();
     433           0 :     maRefEdit.Disable();
     434           0 :     maRefBtn.Disable();
     435           0 : }
     436             : 
     437           0 : void ScXMLSourceDlg::SetSingleLinkable()
     438             : {
     439           0 :     maFtMappedCellTitle.Enable();
     440           0 :     maRefEdit.Enable();
     441           0 :     maRefBtn.Enable();
     442           0 : }
     443             : 
     444           0 : void ScXMLSourceDlg::SetRangeLinkable()
     445             : {
     446           0 :     maFtMappedCellTitle.Enable();
     447           0 :     maRefEdit.Enable();
     448           0 :     maRefBtn.Enable();
     449           0 : }
     450             : 
     451           0 : void ScXMLSourceDlg::SelectAllChildEntries(SvTreeListEntry& rEntry)
     452             : {
     453           0 :     SvTreeListEntries& rChildren = rEntry.GetChildEntries();
     454           0 :     SvTreeListEntries::iterator it = rChildren.begin(), itEnd = rChildren.end();
     455           0 :     for (; it != itEnd; ++it)
     456             :     {
     457           0 :         SvTreeListEntry& r = *it;
     458           0 :         SelectAllChildEntries(r); // select recursively.
     459           0 :         SvViewDataEntry* p = maLbTree.GetViewDataEntry(&r);
     460           0 :         p->SetHighlighted(true);
     461           0 :         maLbTree.PaintEntry(&r);
     462           0 :         maHighlightedEntries.push_back(&r);
     463             :     }
     464           0 : }
     465             : 
     466           0 : bool ScXMLSourceDlg::IsParentDirty(SvTreeListEntry* pEntry) const
     467             : {
     468           0 :     ScOrcusXMLTreeParam::EntryData* pUserData = NULL;
     469           0 :     SvTreeListEntry* pParent = maLbTree.GetParent(pEntry);
     470           0 :     while (pParent)
     471             :     {
     472           0 :         pUserData = ScOrcusXMLTreeParam::getUserData(*pParent);
     473             :         OSL_ASSERT(pUserData);
     474           0 :         if (pUserData->maLinkedPos.IsValid())
     475             :         {
     476             :             // This parent is already linked.
     477           0 :             return true;
     478             :         }
     479           0 :         if (pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat)
     480             :         {
     481             :             // This is a repeat element.
     482           0 :             return true;
     483             :         }
     484           0 :         pParent = maLbTree.GetParent(pParent);
     485             :     }
     486           0 :     return false;
     487             : }
     488             : 
     489           0 : bool ScXMLSourceDlg::IsChildrenDirty(SvTreeListEntry* pEntry) const
     490             : {
     491           0 :     ScOrcusXMLTreeParam::EntryData* pUserData = NULL;
     492           0 :     for (SvTreeListEntry* pChild = maLbTree.FirstChild(pEntry); pChild; pChild = maLbTree.NextSibling(pChild))
     493             :     {
     494           0 :         pUserData = ScOrcusXMLTreeParam::getUserData(*pChild);
     495             :         OSL_ASSERT(pUserData);
     496           0 :         if (pUserData->maLinkedPos.IsValid())
     497             :             // Already linked.
     498           0 :             return true;
     499             : 
     500           0 :         if (pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat)
     501             :             // We don't support linking of nested repeat elements (yet).
     502           0 :             return true;
     503             : 
     504           0 :         if (pUserData->meType == ScOrcusXMLTreeParam::ElementDefault)
     505             :         {
     506             :             // Check recursively.
     507           0 :             if (IsChildrenDirty(pChild))
     508           0 :                 return true;
     509             :         }
     510             :     }
     511             : 
     512           0 :     return false;
     513             : }
     514             : 
     515             : namespace {
     516             : 
     517             : /**
     518             :  * Pick only the leaf elements.
     519             :  */
     520           0 : void getFieldLinks(
     521             :     ScOrcusImportXMLParam::RangeLink& rRangeLink, std::vector<size_t>& rNamespaces,
     522             :     const SvTreeListBox& rTree, const SvTreeListEntry& rEntry)
     523             : {
     524           0 :     const SvTreeListEntries& rChildren = rEntry.GetChildEntries();
     525           0 :     if (rChildren.empty())
     526             :         // No more children.  We're done.
     527           0 :         return;
     528             : 
     529           0 :     SvTreeListEntries::const_iterator it = rChildren.begin(), itEnd = rChildren.end();
     530           0 :     for (; it != itEnd; ++it)
     531             :     {
     532           0 :         const SvTreeListEntry& rChild = *it;
     533           0 :         OUString aPath = getXPath(rTree, rChild, rNamespaces);
     534           0 :         const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rChild);
     535             : 
     536           0 :         if (pUserData && pUserData->mbLeafNode)
     537             :         {
     538           0 :             if (!aPath.isEmpty())
     539             :                 // XPath should never be empty anyway, but it won't hurt to check...
     540           0 :                 rRangeLink.maFieldPaths.push_back(OUStringToOString(aPath, RTL_TEXTENCODING_UTF8));
     541             :         }
     542             : 
     543             :         // Walk recursively.
     544           0 :         getFieldLinks(rRangeLink, rNamespaces, rTree, rChild);
     545           0 :     }
     546             : }
     547             : 
     548           0 : void removeDuplicates(std::vector<size_t>& rArray)
     549             : {
     550           0 :     std::sort(rArray.begin(), rArray.end());
     551           0 :     std::vector<size_t>::iterator it = std::unique(rArray.begin(), rArray.end());
     552           0 :     rArray.erase(it, rArray.end());
     553           0 : }
     554             : 
     555             : }
     556             : 
     557           0 : void ScXMLSourceDlg::OkPressed()
     558             : {
     559           0 :     if (!mpXMLContext)
     560           0 :         return;
     561             : 
     562             :     // Begin import.
     563             : 
     564           0 :     ScOrcusImportXMLParam aParam;
     565             : 
     566             :     // Convert single cell links.
     567             :     {
     568           0 :         std::set<const SvTreeListEntry*>::const_iterator it = maCellLinks.begin(), itEnd = maCellLinks.end();
     569           0 :         for (; it != itEnd; ++it)
     570             :         {
     571           0 :             const SvTreeListEntry& rEntry = **it;
     572           0 :             OUString aPath = getXPath(maLbTree, rEntry, aParam.maNamespaces);
     573           0 :             const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rEntry);
     574             : 
     575             :             aParam.maCellLinks.push_back(
     576             :                 ScOrcusImportXMLParam::CellLink(
     577           0 :                     pUserData->maLinkedPos, OUStringToOString(aPath, RTL_TEXTENCODING_UTF8)));
     578           0 :         }
     579             :     }
     580             : 
     581             :     // Convert range links. For now, an element with range link takes all its
     582             :     // child elements as its fields.
     583             :     {
     584           0 :         std::set<const SvTreeListEntry*>::const_iterator it = maRangeLinks.begin(), itEnd = maRangeLinks.end();
     585           0 :         for (; it != itEnd; ++it)
     586             :         {
     587           0 :             const SvTreeListEntry& rEntry = **it;
     588           0 :             const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rEntry);
     589             : 
     590           0 :             ScOrcusImportXMLParam::RangeLink aRangeLink;
     591           0 :             aRangeLink.maPos = pUserData->maLinkedPos;
     592             : 
     593             :             // Go through all its child elements.
     594           0 :             getFieldLinks(aRangeLink, aParam.maNamespaces, maLbTree, rEntry);
     595             : 
     596           0 :             aParam.maRangeLinks.push_back(aRangeLink);
     597           0 :         }
     598             :     }
     599             : 
     600             :     // Remove duplicate namespace IDs.
     601           0 :     removeDuplicates(aParam.maNamespaces);
     602             : 
     603             :     // Now do the import.
     604           0 :     mpXMLContext->importXML(aParam);
     605             : 
     606             :     // Don't forget to broadcast the change.
     607           0 :     SfxObjectShell* pShell = mpDoc->GetDocumentShell();
     608           0 :     pShell->Broadcast(SfxSimpleHint(FID_DATACHANGED));
     609             : 
     610             :     // Repaint the grid to force repaint the cell values.
     611           0 :     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
     612           0 :     if (pViewShell)
     613           0 :         pViewShell->PaintGrid();
     614             : 
     615           0 :     Close();
     616             : }
     617             : 
     618           0 : void ScXMLSourceDlg::CancelPressed()
     619             : {
     620           0 :     Close();
     621           0 : }
     622             : 
     623           0 : void ScXMLSourceDlg::RefEditModified()
     624             : {
     625           0 :     OUString aRefStr = maRefEdit.GetText();
     626             : 
     627             :     // Check if the address is valid.
     628           0 :     ScAddress aLinkedPos;
     629           0 :     sal_uInt16 nRes = aLinkedPos.Parse(aRefStr, mpDoc, mpDoc->GetAddressConvention());
     630           0 :     bool bValid = (nRes & SCA_VALID) == SCA_VALID;
     631             : 
     632             :     // TODO: For some unknown reason, setting the ref invalid will hide the text altogether.
     633             :     // Find out how to make this work.
     634             : //  maRefEdit.SetRefValid(bValid);
     635             : 
     636           0 :     if (!bValid)
     637           0 :         aLinkedPos.SetInvalid();
     638             : 
     639             :     // Set this address to the current reference entry.
     640           0 :     if (!mpCurRefEntry)
     641             :         // This should never happen.
     642           0 :         return;
     643             : 
     644           0 :     ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(*mpCurRefEntry);
     645           0 :     if (!pUserData)
     646             :         // This should never happen either.
     647           0 :         return;
     648             : 
     649           0 :     bool bRepeatElem = pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat;
     650           0 :     pUserData->maLinkedPos = aLinkedPos;
     651           0 :     pUserData->mbRangeParent = aLinkedPos.IsValid() && bRepeatElem;
     652             : 
     653           0 :     if (bRepeatElem)
     654             :     {
     655           0 :         if (bValid)
     656           0 :             maRangeLinks.insert(mpCurRefEntry);
     657             :         else
     658           0 :             maRangeLinks.erase(mpCurRefEntry);
     659             :     }
     660             :     else
     661             :     {
     662           0 :         if (bValid)
     663           0 :             maCellLinks.insert(mpCurRefEntry);
     664             :         else
     665           0 :             maCellLinks.erase(mpCurRefEntry);
     666             :     }
     667             : 
     668             :     // Enable the import button only when at least one link exists.
     669           0 :     bool bHasLink = !maCellLinks.empty() || !maRangeLinks.empty();
     670           0 :     maBtnOk.Enable(bHasLink);
     671             : }
     672             : 
     673           0 : IMPL_LINK(ScXMLSourceDlg, GetFocusHdl, Control*, pCtrl)
     674             : {
     675           0 :     HandleGetFocus(pCtrl);
     676           0 :     return 0;
     677             : }
     678             : 
     679           0 : IMPL_LINK(ScXMLSourceDlg, LoseFocusHdl, Control*, pCtrl)
     680             : {
     681           0 :     HandleLoseFocus(pCtrl);
     682           0 :     return 0;
     683             : }
     684             : 
     685           0 : IMPL_LINK(ScXMLSourceDlg, BtnPressedHdl, Button*, pBtn)
     686             : {
     687           0 :     if (pBtn == &maBtnSelectSource)
     688           0 :         SelectSourceFile();
     689           0 :     else if (pBtn == &maBtnOk)
     690           0 :         OkPressed();
     691           0 :     else if (pBtn == &maBtnCancel)
     692           0 :         CancelPressed();
     693           0 :     return 0;
     694             : }
     695             : 
     696           0 : IMPL_LINK_NOARG(ScXMLSourceDlg, TreeItemSelectHdl)
     697             : {
     698           0 :     TreeItemSelected();
     699           0 :     return 0;
     700             : }
     701             : 
     702           0 : IMPL_LINK_NOARG(ScXMLSourceDlg, RefModifiedHdl)
     703             : {
     704           0 :     RefEditModified();
     705           0 :     return 0;
     706          93 : }
     707             : 
     708             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10