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

Generated by: LCOV version 1.11