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

Generated by: LCOV version 1.10