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

Generated by: LCOV version 1.10