LCOV - code coverage report
Current view: top level - vcl/source/window - builder.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 847 1885 44.9 %
Date: 2014-11-03 Functions: 57 105 54.3 %
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 <com/sun/star/frame/ModuleManager.hpp>
      11             : #include <com/sun/star/frame/XModuleManager2.hpp>
      12             : #include <com/sun/star/frame/theUICommandDescription.hpp>
      13             : #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
      14             : #include <com/sun/star/ui/ImageType.hpp>
      15             : #include <com/sun/star/ui/XImageManager.hpp>
      16             : #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
      17             : #include <com/sun/star/ui/XUIConfigurationManager.hpp>
      18             : #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
      19             : #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
      20             : 
      21             : #include <comphelper/processfactory.hxx>
      22             : #include <osl/module.hxx>
      23             : #include <sal/log.hxx>
      24             : #include <unotools/configmgr.hxx>
      25             : #include <vcl/builder.hxx>
      26             : #include <vcl/button.hxx>
      27             : #include <vcl/dialog.hxx>
      28             : #include <vcl/edit.hxx>
      29             : #include <vcl/field.hxx>
      30             : #include <vcl/fixed.hxx>
      31             : #include <vcl/fixedhyper.hxx>
      32             : #include <vcl/layout.hxx>
      33             : #include <vcl/lstbox.hxx>
      34             : #include <vcl/menubtn.hxx>
      35             : #include <vcl/mnemonic.hxx>
      36             : #include <vcl/prgsbar.hxx>
      37             : #include <vcl/scrbar.hxx>
      38             : #include <vcl/svapp.hxx>
      39             : #include <vcl/tabctrl.hxx>
      40             : #include <vcl/tabpage.hxx>
      41             : #include <vcl/throbber.hxx>
      42             : #include <vcl/toolbox.hxx>
      43             : #include <vcl/vclmedit.hxx>
      44             : #include <vcl/settings.hxx>
      45             : #include <svdata.hxx>
      46             : #include <svids.hrc>
      47             : #include <window.h>
      48             : #include <xmlreader/xmlreader.hxx>
      49             : 
      50             : using namespace com::sun::star;
      51             : 
      52             : #ifdef DISABLE_DYNLOADING
      53             : #include <dlfcn.h>
      54             : #endif
      55             : 
      56             : namespace
      57             : {
      58           0 :     sal_uInt16 mapStockToImageResource(const OString& sType)
      59             :     {
      60           0 :         sal_uInt16 nRet = 0;
      61           0 :         if (sType == "gtk-index")
      62           0 :             nRet = SV_RESID_BITMAP_INDEX;
      63           0 :         else if (sType == "gtk-refresh")
      64           0 :             nRet = SV_RESID_BITMAP_REFRESH;
      65           0 :         return nRet;
      66             :     }
      67             : 
      68           0 :     SymbolType mapStockToSymbol(const OString& sType)
      69             :     {
      70           0 :         SymbolType eRet = SymbolType::DONTKNOW;
      71           0 :         if (sType == "gtk-media-next")
      72           0 :             eRet = SymbolType::NEXT;
      73           0 :         else if (sType == "gtk-media-previous")
      74           0 :             eRet = SymbolType::PREV;
      75           0 :         else if (sType == "gtk-media-play")
      76           0 :             eRet = SymbolType::PLAY;
      77           0 :         else if (sType == "gtk-goto-first")
      78           0 :             eRet = SymbolType::FIRST;
      79           0 :         else if (sType == "gtk-goto-last")
      80           0 :             eRet = SymbolType::LAST;
      81           0 :         else if (sType == "gtk-go-back")
      82           0 :             eRet = SymbolType::ARROW_LEFT;
      83           0 :         else if (sType == "gtk-go-forward")
      84           0 :             eRet = SymbolType::ARROW_RIGHT;
      85           0 :         else if (sType == "gtk-go-up")
      86           0 :             eRet = SymbolType::ARROW_UP;
      87           0 :         else if (sType == "gtk-go-down")
      88           0 :             eRet = SymbolType::ARROW_DOWN;
      89           0 :         else if (sType == "gtk-missing-image")
      90           0 :             eRet = SymbolType::IMAGE;
      91           0 :         else if (sType == "gtk-help")
      92           0 :             eRet = SymbolType::HELP;
      93           0 :         else if (sType == "gtk-close")
      94           0 :             eRet = SymbolType::CLOSE;
      95           0 :         else if (mapStockToImageResource(sType))
      96           0 :             eRet = SymbolType::IMAGE;
      97           0 :         return eRet;
      98             :     }
      99             : }
     100             : 
     101           0 : void VclBuilder::loadTranslations(const LanguageTag &rLanguageTag, const OUString& rUri)
     102             : {
     103             :     /* FIXME-BCP47: support language tags with
     104             :      * LanguageTag::getFallbackStrings() ? */
     105           0 :     for (int i = rLanguageTag.getCountry().isEmpty() ? 1 : 0; i < 2; ++i)
     106             :     {
     107           0 :         OUStringBuffer aTransBuf;
     108           0 :         sal_Int32 nLastSlash = rUri.lastIndexOf('/');
     109           0 :         if (nLastSlash != -1)
     110           0 :             aTransBuf.append(rUri.copy(0, nLastSlash));
     111             :         else
     112             :         {
     113           0 :             aTransBuf.append('.');
     114           0 :             nLastSlash = 0;
     115             :         }
     116           0 :         aTransBuf.append("/res/");
     117           0 :         OUString sLang(rLanguageTag.getLanguage());
     118           0 :         switch (i)
     119             :         {
     120             :             case 0:
     121           0 :                 sLang = sLang + "-" + rLanguageTag.getCountry();
     122           0 :                 break;
     123             :             default:
     124           0 :                 break;
     125             :         }
     126           0 :         aTransBuf.append(sLang);
     127           0 :         aTransBuf.append(".zip");
     128           0 :         sal_Int32 nEndName = rUri.lastIndexOf('.');
     129           0 :         if (nEndName == -1)
     130           0 :             nEndName = rUri.getLength();
     131           0 :         OUString sZippedFile(rUri.copy(nLastSlash + 1, nEndName - nLastSlash - 1) + "/" + sLang + ".ui");
     132             :         try
     133             :         {
     134             :             uno::Reference<packages::zip::XZipFileAccess2> xNameAccess =
     135             :                 packages::zip::ZipFileAccess::createWithURL(
     136           0 :                         comphelper::getProcessComponentContext(), aTransBuf.makeStringAndClear());
     137           0 :             if (!xNameAccess.is())
     138           0 :                 continue;
     139           0 :             uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName(sZippedFile), uno::UNO_QUERY);
     140           0 :             if (!xInputStream.is())
     141           0 :                 continue;
     142           0 :             OStringBuffer sStr;
     143             :             for (;;)
     144             :             {
     145           0 :                 sal_Int32 const size = 2048;
     146           0 :                 css::uno::Sequence< sal_Int8 > data(size);
     147           0 :                 sal_Int32 n = xInputStream->readBytes(data, size);
     148           0 :                 sStr.append(reinterpret_cast<const sal_Char *>(data.getConstArray()), n);
     149           0 :                 if (n < size)
     150           0 :                     break;
     151           0 :             }
     152             : 
     153           0 :             xmlreader::XmlReader reader(const_cast<char *>(sStr.getStr()), sStr.getLength());
     154           0 :             handleTranslations(reader);
     155           0 :             break;
     156             :         }
     157           0 :         catch (const uno::Exception &)
     158             :         {
     159             :         }
     160           0 :     }
     161           0 : }
     162             : 
     163             : #if defined SAL_LOG_WARN
     164             : namespace
     165             : {
     166             :     bool isButtonType(WindowType nType)
     167             :     {
     168             :         return nType == WINDOW_PUSHBUTTON ||
     169             :                nType == WINDOW_OKBUTTON ||
     170             :                nType == WINDOW_CANCELBUTTON ||
     171             :                nType == WINDOW_HELPBUTTON ||
     172             :                nType == WINDOW_IMAGEBUTTON ||
     173             :                nType == WINDOW_MENUBUTTON ||
     174             :                nType == WINDOW_MOREBUTTON ||
     175             :                nType == WINDOW_SPINBUTTON;
     176             :     }
     177             : }
     178             : #endif
     179             : 
     180        2254 : VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUString& sUIFile, const OString& sID, const uno::Reference<frame::XFrame>& rFrame)
     181             :     : m_sID(sID)
     182             :     , m_sHelpRoot(OUStringToOString(sUIFile, RTL_TEXTENCODING_UTF8))
     183        2254 :     , m_pStringReplace(ResMgr::GetReadStringHook())
     184             :     , m_pParent(pParent)
     185             :     , m_bToplevelParentFound(false)
     186        2254 :     , m_pParserState(new ParserState)
     187        6762 :     , m_xFrame(rFrame)
     188             : {
     189        2254 :     m_bToplevelHasDeferredInit = pParent && pParent->IsSystemWindow() && static_cast<SystemWindow*>(pParent)->isDeferredInit();
     190        2254 :     m_bToplevelHasDeferredProperties = m_bToplevelHasDeferredInit;
     191             : 
     192        2254 :     sal_Int32 nIdx = m_sHelpRoot.lastIndexOf('.');
     193        2254 :     if (nIdx != -1)
     194        2254 :         m_sHelpRoot = m_sHelpRoot.copy(0, nIdx);
     195        2254 :     m_sHelpRoot = m_sHelpRoot + OString('/');
     196             : 
     197        2254 :     OUString sUri = sUIDir + sUIFile;
     198             : 
     199        2254 :     const LanguageTag& rLanguageTag = Application::GetSettings().GetUILanguageTag();
     200        2254 :     bool bEN_US = (rLanguageTag.getBcp47() == "en-US");
     201        2254 :     if (!bEN_US)
     202           0 :         loadTranslations(rLanguageTag, sUri);
     203             : 
     204             :     try
     205             :     {
     206        2254 :         xmlreader::XmlReader reader(sUri);
     207             : 
     208        2254 :         handleChild(pParent, reader);
     209             :     }
     210           0 :     catch (const uno::Exception &rExcept)
     211             :     {
     212             :         SAL_WARN("vcl.layout", "Unable to read .ui file: " << rExcept.Message);
     213           0 :         throw;
     214             :     }
     215             : 
     216             :     //Set Mnemonic widgets when everything has been imported
     217        5984 :     for (std::vector<MnemonicWidgetMap>::iterator aI = m_pParserState->m_aMnemonicWidgetMaps.begin(),
     218        2254 :         aEnd = m_pParserState->m_aMnemonicWidgetMaps.end(); aI != aEnd; ++aI)
     219             :     {
     220        1476 :         FixedText *pOne = get<FixedText>(aI->m_sID);
     221        1476 :         vcl::Window *pOther = get<vcl::Window>(aI->m_sValue);
     222             :         SAL_WARN_IF(!pOne || !pOther, "vcl", "missing either source " << aI->m_sID << " or target " << aI->m_sValue << " member of Mnemonic Widget Mapping");
     223        1476 :         if (pOne && pOther)
     224        1476 :             pOne->set_mnemonic_widget(pOther);
     225             :     }
     226             : 
     227             :     //Set a11y relations when everything has been imported
     228       42410 :     for (AtkMap::iterator aI = m_pParserState->m_aAtkInfo.begin(),
     229        2254 :          aEnd = m_pParserState->m_aAtkInfo.end(); aI != aEnd; ++aI)
     230             :     {
     231       37902 :         vcl::Window *pSource = aI->first;
     232       37902 :         const stringmap &rMap = aI->second;
     233             : 
     234       75804 :         for (stringmap::const_iterator aP = rMap.begin(),
     235       37902 :             aEndP = rMap.end(); aP != aEndP; ++aP)
     236             :         {
     237           0 :             const OString &rTarget = aP->second;
     238           0 :             vcl::Window *pTarget = get<vcl::Window>(rTarget);
     239             :             SAL_WARN_IF(!pTarget, "vcl", "missing member of a11y relation: "
     240             :                 << rTarget.getStr());
     241           0 :             if (!pTarget)
     242           0 :                 continue;
     243           0 :             const OString &rType = aP->first;
     244           0 :             if (rType == "labelled-by")
     245           0 :                 pSource->SetAccessibleRelationLabeledBy(pTarget);
     246           0 :             else if (rType == "label-for")
     247           0 :                 pSource->SetAccessibleRelationLabelFor(pTarget);
     248           0 :             else if (rType == "member-of")
     249           0 :                 pSource->SetAccessibleRelationMemberOf(pTarget);
     250             :             else
     251             :             {
     252             :                 SAL_INFO("vcl.layout", "unhandled a11y relation :" << rType.getStr());
     253             :             }
     254             :         }
     255             :     }
     256             : 
     257             :     //Set radiobutton groups when everything has been imported
     258        4508 :     for (std::vector<RadioButtonGroupMap>::iterator aI = m_pParserState->m_aGroupMaps.begin(),
     259        2254 :          aEnd = m_pParserState->m_aGroupMaps.end(); aI != aEnd; ++aI)
     260             :     {
     261           0 :         RadioButton *pOne = get<RadioButton>(aI->m_sID);
     262           0 :         RadioButton *pOther = get<RadioButton>(aI->m_sValue);
     263             :         SAL_WARN_IF(!pOne || !pOther, "vcl", "missing member of radiobutton group");
     264           0 :         if (pOne && pOther)
     265           0 :             pOne->group(*pOther);
     266             :     }
     267             : 
     268             :     //Set ComboBox models when everything has been imported
     269        4508 :     for (std::vector<ComboBoxModelMap>::iterator aI = m_pParserState->m_aModelMaps.begin(),
     270        2254 :          aEnd = m_pParserState->m_aModelMaps.end(); aI != aEnd; ++aI)
     271             :     {
     272           0 :         ListBox *pTarget = get<ListBox>(aI->m_sID);
     273           0 :         const ListStore *pStore = get_model_by_name(aI->m_sValue);
     274             :         SAL_WARN_IF(!pTarget || !pStore, "vcl", "missing elements of combobox/liststore");
     275           0 :         if (pTarget && pStore)
     276           0 :             mungeModel(*pTarget, *pStore, aI->m_nActiveId);
     277             :     }
     278             : 
     279             :     //Set TextView buffers when everything has been imported
     280        4508 :     for (std::vector<TextBufferMap>::iterator aI = m_pParserState->m_aTextBufferMaps.begin(),
     281        2254 :          aEnd = m_pParserState->m_aTextBufferMaps.end(); aI != aEnd; ++aI)
     282             :     {
     283           0 :         VclMultiLineEdit *pTarget = get<VclMultiLineEdit>(aI->m_sID);
     284           0 :         const TextBuffer *pBuffer = get_buffer_by_name(aI->m_sValue);
     285             :         SAL_WARN_IF(!pTarget || !pBuffer, "vcl", "missing elements of textview/textbuffer");
     286           0 :         if (pTarget && pBuffer)
     287           0 :             mungeTextBuffer(*pTarget, *pBuffer);
     288             :     }
     289             : 
     290             :     //Set SpinButton adjustments when everything has been imported
     291        4508 :     for (std::vector<WidgetAdjustmentMap>::iterator aI = m_pParserState->m_aNumericFormatterAdjustmentMaps.begin(),
     292        2254 :          aEnd = m_pParserState->m_aNumericFormatterAdjustmentMaps.end(); aI != aEnd; ++aI)
     293             :     {
     294           0 :         NumericFormatter *pTarget = dynamic_cast<NumericFormatter*>(get<vcl::Window>(aI->m_sID));
     295           0 :         const Adjustment *pAdjustment = get_adjustment_by_name(aI->m_sValue);
     296             :         SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of spinbutton/adjustment");
     297           0 :         if (pTarget && pAdjustment)
     298           0 :             mungeAdjustment(*pTarget, *pAdjustment);
     299             :     }
     300             : 
     301        4508 :     for (std::vector<WidgetAdjustmentMap>::iterator aI = m_pParserState->m_aTimeFormatterAdjustmentMaps.begin(),
     302        2254 :          aEnd = m_pParserState->m_aTimeFormatterAdjustmentMaps.end(); aI != aEnd; ++aI)
     303             :     {
     304           0 :         TimeField *pTarget = dynamic_cast<TimeField*>(get<vcl::Window>(aI->m_sID));
     305           0 :         const Adjustment *pAdjustment = get_adjustment_by_name(aI->m_sValue);
     306             :         SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of spinbutton/adjustment");
     307           0 :         if (pTarget && pAdjustment)
     308           0 :             mungeAdjustment(*pTarget, *pAdjustment);
     309             :     }
     310             : 
     311        4508 :     for (std::vector<WidgetAdjustmentMap>::iterator aI = m_pParserState->m_aDateFormatterAdjustmentMaps.begin(),
     312        2254 :          aEnd = m_pParserState->m_aDateFormatterAdjustmentMaps.end(); aI != aEnd; ++aI)
     313             :     {
     314           0 :         DateField *pTarget = dynamic_cast<DateField*>(get<vcl::Window>(aI->m_sID));
     315           0 :         const Adjustment *pAdjustment = get_adjustment_by_name(aI->m_sValue);
     316             :         SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of spinbutton/adjustment");
     317           0 :         if (pTarget && pAdjustment)
     318           0 :             mungeAdjustment(*pTarget, *pAdjustment);
     319             :     }
     320             : 
     321             :     //Set ScrollBar adjustments when everything has been imported
     322        4508 :     for (std::vector<WidgetAdjustmentMap>::iterator aI = m_pParserState->m_aScrollAdjustmentMaps.begin(),
     323        2254 :          aEnd = m_pParserState->m_aScrollAdjustmentMaps.end(); aI != aEnd; ++aI)
     324             :     {
     325           0 :         ScrollBar *pTarget = get<ScrollBar>(aI->m_sID);
     326           0 :         const Adjustment *pAdjustment = get_adjustment_by_name(aI->m_sValue);
     327             :         SAL_WARN_IF(!pTarget || !pAdjustment, "vcl", "missing elements of scrollbar/adjustment");
     328           0 :         if (pTarget && pAdjustment)
     329           0 :             mungeAdjustment(*pTarget, *pAdjustment);
     330             :     }
     331             : 
     332             :     //Set size-groups when all widgets have been imported
     333        5246 :     for (std::vector<SizeGroup>::iterator aI = m_pParserState->m_aSizeGroups.begin(),
     334        2254 :         aEnd = m_pParserState->m_aSizeGroups.end(); aI != aEnd; ++aI)
     335             :     {
     336         738 :         boost::shared_ptr< VclSizeGroup > xGroup(new VclSizeGroup);
     337             : 
     338        2214 :         for (stringmap::iterator aP = aI->m_aProperties.begin(),
     339         738 :             aEndP = aI->m_aProperties.end(); aP != aEndP; ++aP)
     340             :         {
     341         738 :             const OString &rKey = aP->first;
     342         738 :             const OString &rValue = aP->second;
     343         738 :             xGroup->set_property(rKey, rValue);
     344             :         }
     345             : 
     346        5904 :         for (std::vector<OString>::iterator aW = aI->m_aWidgets.begin(),
     347         738 :             aEndW = aI->m_aWidgets.end(); aW != aEndW; ++aW)
     348             :         {
     349        4428 :             vcl::Window* pWindow = get<vcl::Window>(aW->getStr());
     350        4428 :             pWindow->add_to_size_group(xGroup);
     351             :         }
     352         738 :     }
     353             : 
     354             :     //Set button images when everything has been imported
     355        4508 :     std::set<OString> aImagesToBeRemoved;
     356        4526 :     for (std::vector<ButtonImageWidgetMap>::iterator aI = m_pParserState->m_aButtonImageWidgetMaps.begin(),
     357        2254 :          aEnd = m_pParserState->m_aButtonImageWidgetMaps.end(); aI != aEnd; ++aI)
     358             :     {
     359          18 :         PushButton *pTargetButton = NULL;
     360          18 :         RadioButton *pTargetRadio = NULL;
     361          18 :         Button *pTarget = NULL;
     362             : 
     363          18 :         if (!aI->m_bRadio)
     364             :         {
     365          18 :             pTargetButton = get<PushButton>(aI->m_sID);
     366          18 :             pTarget = pTargetButton;
     367             :         }
     368             :         else
     369             :         {
     370           0 :             pTargetRadio = get<RadioButton>(aI->m_sID);
     371           0 :             pTarget = pTargetRadio;
     372             :         }
     373             : 
     374          18 :         FixedImage *pImage = get<FixedImage>(aI->m_sValue);
     375             :         SAL_WARN_IF(!pTarget || !pImage,
     376             :             "vcl", "missing elements of button/image/stock");
     377          18 :         if (!pTarget || !pImage)
     378           0 :             continue;
     379          18 :         aImagesToBeRemoved.insert(aI->m_sValue);
     380             : 
     381          18 :         VclBuilder::StockMap::iterator aFind = m_pParserState->m_aStockMap.find(aI->m_sValue);
     382          18 :         if (aFind == m_pParserState->m_aStockMap.end())
     383             :         {
     384          18 :             if (!aI->m_bRadio)
     385          18 :                 pTargetButton->SetModeImage(pImage->GetImage());
     386             :             else
     387           0 :                 pTargetRadio->SetModeRadioImage(pImage->GetImage());
     388             :         }
     389             :         else
     390             :         {
     391           0 :             const stockinfo &rImageInfo = aFind->second;
     392           0 :             SymbolType eType = mapStockToSymbol(rImageInfo.m_sStock);
     393             :             SAL_WARN_IF(eType == SymbolType::DONTKNOW, "vcl", "missing stock image element for button");
     394           0 :             if (eType == SymbolType::DONTKNOW)
     395           0 :                 continue;
     396           0 :             if (!aI->m_bRadio)
     397             :             {
     398           0 :                 pTargetButton->SetSymbol(eType);
     399             :                 //fdo#76457 keep symbol images small e.g. tools->customize->menu
     400             :                 //but images the right size. Really the PushButton::CalcMinimumSize
     401             :                 //and PushButton::ImplDrawPushButton are the better place to handle
     402             :                 //this, but its such a train-wreck
     403           0 :                 if (eType != SymbolType::IMAGE)
     404           0 :                     pTargetButton->SetStyle(pTargetButton->GetStyle() | WB_SMALLSTYLE);
     405             :             }
     406             :             else
     407             :                 SAL_WARN_IF(eType != SymbolType::IMAGE, "vcl.layout", "inimplemented symbol type for radiobuttons");
     408           0 :             if (eType == SymbolType::IMAGE)
     409             :             {
     410           0 :                 Bitmap aBitmap(VclResId(mapStockToImageResource(rImageInfo.m_sStock)));
     411           0 :                 Image const aImage(aBitmap);
     412           0 :                 if (!aI->m_bRadio)
     413           0 :                     pTargetButton->SetModeImage(aImage);
     414             :                 else
     415           0 :                     pTargetRadio->SetModeRadioImage(aImage);
     416             :             }
     417           0 :             switch (rImageInfo.m_nSize)
     418             :             {
     419             :                 case 1:
     420           0 :                     pTarget->SetSmallSymbol();
     421           0 :                     break;
     422             :                 case 4:
     423           0 :                     break;
     424             :                 default:
     425             :                     SAL_WARN("vcl.layout", "unsupported image size " << rImageInfo.m_nSize);
     426           0 :                     break;
     427             :             }
     428             :         }
     429             :     }
     430             : 
     431             :     //There may be duplicate use of an Image, so we used a set to collect and
     432             :     //now we can remove them from the tree after their final munge
     433        4526 :     for (std::set<OString>::iterator aI = aImagesToBeRemoved.begin(),
     434        2254 :         aEnd = aImagesToBeRemoved.end(); aI != aEnd; ++aI)
     435             :     {
     436          18 :         delete_by_name(*aI);
     437             :     }
     438             : 
     439             :     //Set button menus when everything has been imported
     440        4510 :     for (std::vector<ButtonMenuMap>::iterator aI = m_pParserState->m_aButtonMenuMaps.begin(),
     441        2254 :          aEnd = m_pParserState->m_aButtonMenuMaps.end(); aI != aEnd; ++aI)
     442             :     {
     443           2 :         MenuButton *pTarget = get<MenuButton>(aI->m_sID);
     444           2 :         PopupMenu *pMenu = get_menu(aI->m_sValue);
     445             :         SAL_WARN_IF(!pTarget || !pMenu,
     446             :             "vcl", "missing elements of button/menu");
     447           2 :         if (!pTarget || !pMenu)
     448           0 :             continue;
     449           2 :         pTarget->SetPopupMenu(pMenu);
     450             :     }
     451             : 
     452             :     //Remove ScrollWindow parent widgets whose children in vcl implement scrolling
     453             :     //internally.
     454        4508 :     for (std::map<vcl::Window*, vcl::Window*>::iterator aI = m_pParserState->m_aRedundantParentWidgets.begin(),
     455        2254 :         aEnd = m_pParserState->m_aRedundantParentWidgets.end(); aI != aEnd; ++aI)
     456             :     {
     457           0 :         delete_by_window(aI->first);
     458             :     }
     459             : 
     460             :     //fdo#67378 merge the label into the disclosure button
     461        4508 :     for (std::vector<VclExpander*>::iterator aI = m_pParserState->m_aExpanderWidgets.begin(),
     462        2254 :         aEnd = m_pParserState->m_aExpanderWidgets.end(); aI != aEnd; ++aI)
     463             :     {
     464           0 :         VclExpander *pOne = *aI;
     465             : 
     466           0 :         vcl::Window *pChild = pOne->get_child();
     467           0 :         vcl::Window* pLabel = pOne->GetWindow(WINDOW_LASTCHILD);
     468           0 :         if (pLabel && pLabel != pChild && pLabel->GetType() == WINDOW_FIXEDTEXT)
     469             :         {
     470           0 :             FixedText *pLabelWidget = static_cast<FixedText*>(pLabel);
     471           0 :             pOne->set_label(pLabelWidget->GetText());
     472           0 :             delete_by_window(pLabel);
     473             :         }
     474             :     }
     475             : 
     476             :     //drop maps, etc. that we don't need again
     477        2254 :     delete m_pParserState;
     478             : 
     479             :     SAL_WARN_IF(!m_sID.isEmpty() && (!m_bToplevelParentFound && !get_by_name(m_sID)), "vcl.layout",
     480             :         "Requested top level widget \"" << m_sID.getStr() <<
     481        2254 :         "\" not found in " << sUIFile);
     482             : 
     483             : #if defined SAL_LOG_WARN
     484             :     if (m_bToplevelParentFound && m_pParent->IsDialog())
     485             :     {
     486             :         int nButtons = 0;
     487             :         bool bHasDefButton = false;
     488             :         for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
     489             :              aEnd = m_aChildren.end(); aI != aEnd; ++aI)
     490             :         {
     491             :             if (isButtonType(aI->m_pWindow->GetType()))
     492             :             {
     493             :                 ++nButtons;
     494             :                 if (aI->m_pWindow->GetStyle() & WB_DEFBUTTON)
     495             :                 {
     496             :                     bHasDefButton = true;
     497             :                     break;
     498             :                 }
     499             :             }
     500             :         }
     501             :         SAL_WARN_IF(nButtons && !bHasDefButton, "vcl.layout", "No default button defined in " << sUIFile);
     502             :     }
     503             : #endif
     504        2254 : }
     505             : 
     506        4508 : VclBuilder::~VclBuilder()
     507             : {
     508       40138 :     for (std::vector<WinAndId>::reverse_iterator aI = m_aChildren.rbegin(),
     509        2254 :          aEnd = m_aChildren.rend(); aI != aEnd; ++aI)
     510             :     {
     511       35630 :         delete aI->m_pWindow;
     512             :     }
     513             : 
     514        4510 :     for (std::vector<MenuAndId>::reverse_iterator aI = m_aMenus.rbegin(),
     515        2254 :          aEnd = m_aMenus.rend(); aI != aEnd; ++aI)
     516             :     {
     517           2 :         delete aI->m_pMenu;
     518             :     }
     519        2254 : }
     520             : 
     521           0 : void VclBuilder::handleTranslations(xmlreader::XmlReader &reader)
     522             : {
     523           0 :     xmlreader::Span name;
     524             :     int nsId;
     525             : 
     526           0 :     OString sID, sProperty;
     527             : 
     528             :     while(true)
     529             :     {
     530             :         xmlreader::XmlReader::Result res = reader.nextItem(
     531           0 :             xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
     532             : 
     533           0 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
     534             :         {
     535           0 :             if (name.equals("e"))
     536             :             {
     537           0 :                 while (reader.nextAttribute(&nsId, &name))
     538             :                 {
     539           0 :                     if (name.equals("g"))
     540             :                     {
     541           0 :                         name = reader.getAttributeValue(false);
     542           0 :                         sID = OString(name.begin, name.length);
     543           0 :                         sal_Int32 nDelim = sID.indexOf(':');
     544           0 :                         if (nDelim != -1)
     545           0 :                             sID = sID.copy(nDelim);
     546             :                     }
     547           0 :                     else if (name.equals("i"))
     548             :                     {
     549           0 :                         name = reader.getAttributeValue(false);
     550           0 :                         sProperty = OString(name.begin, name.length);
     551             :                     }
     552             :                 }
     553             :             }
     554             :         }
     555             : 
     556           0 :         if (res == xmlreader::XmlReader::RESULT_TEXT && !sID.isEmpty())
     557             :         {
     558           0 :             OString sTranslation(name.begin, name.length);
     559           0 :             m_pParserState->m_aTranslations[sID][sProperty] = sTranslation;
     560             :         }
     561             : 
     562           0 :         if (res == xmlreader::XmlReader::RESULT_END)
     563           0 :             sID = OString();
     564             : 
     565           0 :         if (res == xmlreader::XmlReader::RESULT_DONE)
     566           0 :             break;
     567           0 :     }
     568           0 : }
     569             : 
     570        5224 : OString VclBuilder::extractCustomProperty(VclBuilder::stringmap &rMap)
     571             : {
     572        5224 :     OString sCustomProperty;
     573        5224 :     VclBuilder::stringmap::iterator aFind = rMap.find(OString("customproperty"));
     574        5224 :     if (aFind != rMap.end())
     575             :     {
     576           2 :         sCustomProperty = aFind->second;
     577           2 :         rMap.erase(aFind);
     578             :     }
     579        5224 :     return sCustomProperty;
     580             : }
     581             : 
     582             : namespace
     583             : {
     584          34 :     OString extractTypeHint(VclBuilder::stringmap &rMap)
     585             :     {
     586          34 :         OString sRet("normal");
     587          34 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("type-hint"));
     588          34 :         if (aFind != rMap.end())
     589             :         {
     590          34 :             sRet = aFind->second;
     591          34 :             rMap.erase(aFind);
     592             :         }
     593          34 :         return sRet;
     594             :     }
     595             : 
     596          34 :     bool extractResizable(VclBuilder::stringmap &rMap)
     597             :     {
     598          34 :         bool bResizable = true;
     599          34 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("resizable"));
     600          34 :         if (aFind != rMap.end())
     601             :         {
     602          34 :             bResizable = toBool(aFind->second);
     603          34 :             rMap.erase(aFind);
     604             :         }
     605          34 :         return bResizable;
     606             :     }
     607             : 
     608          34 :     bool extractDecorated(VclBuilder::stringmap &rMap)
     609             :     {
     610          34 :         bool bDecorated = true;
     611          34 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("decorated"));
     612          34 :         if (aFind != rMap.end())
     613             :         {
     614           0 :             bDecorated = toBool(aFind->second);
     615           0 :             rMap.erase(aFind);
     616             :         }
     617          34 :         return bDecorated;
     618             :     }
     619             : 
     620          34 :     bool extractCloseable(VclBuilder::stringmap &rMap)
     621             :     {
     622          34 :         bool bCloseable = true;
     623          34 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("deletable"));
     624          34 :         if (aFind != rMap.end())
     625             :         {
     626           0 :             bCloseable = toBool(aFind->second);
     627           0 :             rMap.erase(aFind);
     628             :         }
     629          34 :         return bCloseable;
     630             :     }
     631             : 
     632           0 :     bool extractEntry(VclBuilder::stringmap &rMap)
     633             :     {
     634           0 :         bool bHasEntry = false;
     635           0 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("has-entry"));
     636           0 :         if (aFind != rMap.end())
     637             :         {
     638           0 :             bHasEntry = toBool(aFind->second);
     639           0 :             rMap.erase(aFind);
     640             :         }
     641           0 :         return bHasEntry;
     642             :     }
     643             : 
     644        9682 :     bool extractOrientation(VclBuilder::stringmap &rMap)
     645             :     {
     646        9682 :         bool bVertical = false;
     647        9682 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("orientation"));
     648        9682 :         if (aFind != rMap.end())
     649             :         {
     650        2262 :             bVertical = aFind->second.equalsIgnoreAsciiCase("vertical");
     651        2262 :             rMap.erase(aFind);
     652             :         }
     653        9682 :         return bVertical;
     654             :     }
     655             : 
     656           0 :     bool extractInconsistent(VclBuilder::stringmap &rMap)
     657             :     {
     658           0 :         bool bInconsistent = false;
     659           0 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("inconsistent"));
     660           0 :         if (aFind != rMap.end())
     661             :         {
     662           0 :             bInconsistent = toBool(aFind->second);
     663           0 :             rMap.erase(aFind);
     664             :         }
     665           0 :         return bInconsistent;
     666             :     }
     667             : 
     668       29842 :     OString extractIconName(VclBuilder::stringmap &rMap)
     669             :     {
     670       29842 :         OString sIconName;
     671       29842 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("icon-name"));
     672       29842 :         if (aFind != rMap.end())
     673             :         {
     674         306 :             sIconName = aFind->second;
     675         306 :             rMap.erase(aFind);
     676             :         }
     677       29842 :         return sIconName;
     678             :     }
     679             : 
     680           0 :     OUString getStockText(const OString &rType)
     681             :     {
     682           0 :         if (rType == "gtk-ok")
     683           0 :             return (VclResId(SV_BUTTONTEXT_OK).toString());
     684           0 :         else if (rType == "gtk-cancel")
     685           0 :             return (VclResId(SV_BUTTONTEXT_CANCEL).toString());
     686           0 :         else if (rType == "gtk-help")
     687           0 :             return (VclResId(SV_BUTTONTEXT_HELP).toString());
     688           0 :         else if (rType == "gtk-close")
     689           0 :             return (VclResId(SV_BUTTONTEXT_CLOSE).toString());
     690           0 :         else if (rType == "gtk-revert-to-saved")
     691           0 :             return (VclResId(SV_BUTTONTEXT_RESET).toString());
     692           0 :         else if (rType == "gtk-add")
     693           0 :             return (VclResId(SV_BUTTONTEXT_ADD).toString());
     694           0 :         else if (rType == "gtk-delete")
     695           0 :             return (VclResId(SV_BUTTONTEXT_DELETE).toString());
     696           0 :         else if (rType == "gtk-remove")
     697           0 :             return (VclResId(SV_BUTTONTEXT_REMOVE).toString());
     698           0 :         else if (rType == "gtk-new")
     699           0 :             return (VclResId(SV_BUTTONTEXT_NEW).toString());
     700           0 :         else if (rType == "gtk-edit")
     701           0 :             return (VclResId(SV_BUTTONTEXT_EDIT).toString());
     702           0 :         else if (rType == "gtk-apply")
     703           0 :             return (VclResId(SV_BUTTONTEXT_APPLY).toString());
     704           0 :         else if (rType == "gtk-save")
     705           0 :             return (VclResId(SV_BUTTONTEXT_SAVE).toString());
     706           0 :         else if (rType == "gtk-open")
     707           0 :             return (VclResId(SV_BUTTONTEXT_OPEN).toString());
     708           0 :         else if (rType == "gtk-undo")
     709           0 :             return (VclResId(SV_BUTTONTEXT_UNDO).toString());
     710           0 :         else if (rType == "gtk-paste")
     711           0 :             return (VclResId(SV_BUTTONTEXT_PASTE).toString());
     712           0 :         else if (rType == "gtk-media-next")
     713           0 :             return (VclResId(SV_BUTTONTEXT_NEXT).toString());
     714           0 :         else if (rType == "gtk-go-up")
     715           0 :             return (VclResId(SV_BUTTONTEXT_GO_UP).toString());
     716           0 :         else if (rType == "gtk-go-down")
     717           0 :             return (VclResId(SV_BUTTONTEXT_GO_DOWN).toString());
     718           0 :         else if (rType == "gtk-clear")
     719           0 :             return (VclResId(SV_BUTTONTEXT_CLEAR).toString());
     720           0 :         else if (rType == "gtk-media-play")
     721           0 :             return (VclResId(SV_BUTTONTEXT_PLAY).toString());
     722           0 :         else if (rType == "gtk-find")
     723           0 :             return (VclResId(SV_BUTTONTEXT_FIND).toString());
     724           0 :         else if (rType == "gtk-stop")
     725           0 :             return (VclResId(SV_BUTTONTEXT_STOP).toString());
     726           0 :         else if (rType == "gtk-connect")
     727           0 :             return (VclResId(SV_BUTTONTEXT_CONNECT).toString());
     728           0 :         else if (rType == "gtk-yes")
     729           0 :             return (VclResId(SV_BUTTONTEXT_YES).toString());
     730           0 :         else if (rType == "gtk-no")
     731           0 :             return (VclResId(SV_BUTTONTEXT_NO).toString());
     732             :         SAL_WARN("vcl.layout", "unknown stock type: " << rType.getStr());
     733           0 :         return OUString();
     734             :     }
     735             : 
     736          22 :     bool extractStock(VclBuilder::stringmap &rMap)
     737             :     {
     738          22 :         bool bIsStock = false;
     739          22 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("use-stock"));
     740          22 :         if (aFind != rMap.end())
     741             :         {
     742           0 :             bIsStock = toBool(aFind->second);
     743           0 :             rMap.erase(aFind);
     744             :         }
     745          22 :         return bIsStock;
     746             :     }
     747             : 
     748          22 :     WinBits extractRelief(VclBuilder::stringmap &rMap)
     749             :     {
     750          22 :         WinBits nBits = WB_3DLOOK;
     751          22 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("relief"));
     752          22 :         if (aFind != rMap.end())
     753             :         {
     754          22 :             if (aFind->second == "half")
     755           0 :                 nBits = WB_FLATBUTTON | WB_BEVELBUTTON;
     756          22 :             else if (aFind->second == "none")
     757          22 :                 nBits = WB_FLATBUTTON;
     758          22 :             rMap.erase(aFind);
     759             :         }
     760          22 :         return nBits;
     761             :     }
     762             : 
     763         316 :     OString extractLabel(VclBuilder::stringmap &rMap)
     764             :     {
     765         316 :         OString sType;
     766         316 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("label"));
     767         316 :         if (aFind != rMap.end())
     768             :         {
     769         316 :             sType = aFind->second;
     770         316 :             rMap.erase(aFind);
     771             :         }
     772         316 :         return sType;
     773             :     }
     774             : 
     775       29842 :     OString extractActionName(VclBuilder::stringmap &rMap)
     776             :     {
     777       29842 :         OString sActionName;
     778       29842 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("action-name"));
     779       29842 :         if (aFind != rMap.end())
     780             :         {
     781       29842 :             sActionName = aFind->second;
     782       29842 :             rMap.erase(aFind);
     783             :         }
     784       29842 :         return sActionName;
     785             :     }
     786             : 
     787       29842 :     bool extractVisible(VclBuilder::stringmap &rMap)
     788             :     {
     789       29842 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("visible"));
     790       29842 :         if (aFind != rMap.end())
     791             :         {
     792       29842 :             return toBool(aFind->second);
     793             :         }
     794           0 :         return false;
     795             :     }
     796             : 
     797       29536 :     Size extractSizeRequest(VclBuilder::stringmap &rMap)
     798             :     {
     799       29536 :         OString sWidthRequest("0");
     800       59072 :         OString sHeightRequest("0");
     801       29536 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("width-request"));
     802       29536 :         if (aFind != rMap.end())
     803             :         {
     804        2952 :             sWidthRequest = aFind->second;
     805        2952 :             rMap.erase(aFind);
     806             :         }
     807       29536 :         aFind = rMap.find(OString("height-request"));
     808       29536 :         if (aFind != rMap.end())
     809             :         {
     810        2214 :             sHeightRequest = aFind->second;
     811        2214 :             rMap.erase(aFind);
     812             :         }
     813       59072 :         return Size(sWidthRequest.toInt32(), sHeightRequest.toInt32());
     814             :     }
     815             : 
     816       29842 :     OString extractTooltipText(VclBuilder::stringmap &rMap)
     817             :     {
     818       29842 :         OString sTooltipText;
     819       29842 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("tooltip-text"));
     820       29842 :         if (aFind == rMap.end())
     821       18756 :             aFind = rMap.find(OString("tooltip-markup"));
     822       29842 :         if (aFind != rMap.end())
     823             :         {
     824       11086 :             sTooltipText = aFind->second;
     825       11086 :             rMap.erase(aFind);
     826             :         }
     827       29842 :         return sTooltipText;
     828             :     }
     829             : 
     830          22 :     void setupFromActionName(Button *pButton, VclBuilder::stringmap &rMap, const uno::Reference<frame::XFrame>& rFrame)
     831             :     {
     832          22 :         if (!rFrame.is())
     833          44 :             return;
     834             : 
     835           0 :         OUString aCommand(OStringToOUString(extractActionName(rMap), RTL_TEXTENCODING_UTF8));
     836           0 :         if (aCommand.isEmpty())
     837           0 :             return;
     838             : 
     839           0 :         uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
     840           0 :         uno::Reference<frame::XModuleManager2> xModuleManager(frame::ModuleManager::create(xContext));
     841           0 :         OUString aModuleId(xModuleManager->identify(rFrame));
     842             : 
     843           0 :         OUString aLabel(VclBuilder::getCommandLabel(aCommand, xContext, aModuleId));
     844           0 :         if (!aLabel.isEmpty())
     845           0 :             pButton->SetText(aLabel);
     846             : 
     847           0 :         Image aImage(VclBuilder::getCommandImage(aCommand, /* bLarge = */ false, xContext, rFrame, aModuleId));
     848           0 :         pButton->SetModeImage(aImage);
     849             : 
     850           0 :         pButton->SetCommandHandler(aCommand);
     851             :     }
     852             : 
     853          20 :     Button* extractStockAndBuildPushButton(vcl::Window *pParent, VclBuilder::stringmap &rMap)
     854             :     {
     855          20 :         WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER;
     856             : 
     857          20 :         nBits |= extractRelief(rMap);
     858             : 
     859          20 :         bool bIsStock = extractStock(rMap);
     860             : 
     861          20 :         Button *pWindow = NULL;
     862             : 
     863          20 :         if (bIsStock)
     864             :         {
     865           0 :             OString sType = extractLabel(rMap);
     866           0 :             if (sType == "gtk-ok")
     867           0 :                 pWindow = new OKButton(pParent, nBits);
     868           0 :             else if (sType == "gtk-cancel")
     869           0 :                 pWindow = new CancelButton(pParent, nBits);
     870           0 :             else if (sType == "gtk-close")
     871           0 :                 pWindow = new CloseButton(pParent, nBits);
     872           0 :             else if (sType == "gtk-help")
     873           0 :                 pWindow = new HelpButton(pParent, nBits);
     874             :             else
     875             :             {
     876           0 :                 pWindow = new PushButton(pParent, nBits);
     877           0 :                 pWindow->SetText(getStockText(sType));
     878           0 :             }
     879             :         }
     880             : 
     881          20 :         if (!pWindow)
     882          20 :             pWindow = new PushButton(pParent, nBits);
     883          20 :         return pWindow;
     884             :     }
     885             : 
     886           2 :     Button * extractStockAndBuildMenuButton(vcl::Window *pParent, VclBuilder::stringmap &rMap)
     887             :     {
     888           2 :         WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER|WB_3DLOOK;
     889             : 
     890           2 :         nBits |= extractRelief(rMap);
     891             : 
     892           2 :         Button *pWindow = new MenuButton(pParent, nBits);
     893             : 
     894           2 :         if (extractStock(rMap))
     895             :         {
     896           0 :             pWindow->SetText(getStockText(extractLabel(rMap)));
     897             :         }
     898             : 
     899           2 :         return pWindow;
     900             :     }
     901             : 
     902        3690 :     OString extractUnit(const OString& sPattern)
     903             :     {
     904        3690 :         OString sUnit(sPattern);
     905        3690 :         for (sal_Int32 i = 0; i < sPattern.getLength(); ++i)
     906             :         {
     907           0 :             if (sPattern[i] != '.' && sPattern[i] != ',' && sPattern[i] != '0')
     908             :             {
     909           0 :                 sUnit = sPattern.copy(i);
     910           0 :                 break;
     911             :             }
     912             :         }
     913        3690 :         return sUnit;
     914             :     }
     915             : 
     916           0 :     int extractDecimalDigits(const OString& sPattern)
     917             :     {
     918           0 :         int nDigits = 0;
     919           0 :         bool bAfterPoint = false;
     920           0 :         for (sal_Int32 i = 0; i < sPattern.getLength(); ++i)
     921             :         {
     922           0 :             if (sPattern[i] == '.' || sPattern[i] == ',')
     923           0 :                 bAfterPoint = true;
     924           0 :             else if (sPattern[i] == '0')
     925             :             {
     926           0 :                 if (bAfterPoint)
     927           0 :                     ++nDigits;
     928             :             }
     929             :             else
     930           0 :                 break;
     931             :         }
     932           0 :         return nDigits;
     933             :     }
     934             : 
     935        3690 :     FieldUnit detectMetricUnit(const OString& sUnit)
     936             :     {
     937        3690 :         FieldUnit eUnit = FUNIT_NONE;
     938             : 
     939        3690 :         if (sUnit == "mm")
     940           0 :             eUnit = FUNIT_MM;
     941        3690 :         else if (sUnit == "cm")
     942           0 :             eUnit = FUNIT_CM;
     943        3690 :         else if (sUnit == "m")
     944           0 :             eUnit = FUNIT_M;
     945        3690 :         else if (sUnit == "km")
     946           0 :             eUnit = FUNIT_KM;
     947        3690 :         else if ((sUnit == "twips") || (sUnit == "twip"))
     948           0 :             eUnit = FUNIT_TWIP;
     949        3690 :         else if (sUnit == "pt")
     950           0 :             eUnit = FUNIT_POINT;
     951        3690 :         else if (sUnit == "pc")
     952           0 :             eUnit = FUNIT_PICA;
     953        3690 :         else if (sUnit == "\"" || (sUnit == "in") || (sUnit == "inch"))
     954           0 :             eUnit = FUNIT_INCH;
     955        3690 :         else if ((sUnit == "'") || (sUnit == "ft") || (sUnit == "foot") || (sUnit == "feet"))
     956           0 :             eUnit = FUNIT_FOOT;
     957        3690 :         else if (sUnit == "mile" || (sUnit == "miles"))
     958           0 :             eUnit = FUNIT_MILE;
     959        3690 :         else if (sUnit == "ch")
     960           0 :             eUnit = FUNIT_CHAR;
     961        3690 :         else if (sUnit == "line")
     962           0 :             eUnit = FUNIT_LINE;
     963        3690 :         else if (sUnit == "%")
     964           0 :             eUnit = FUNIT_PERCENT;
     965        3690 :         else if ((sUnit == "pixels") || (sUnit == "pixel") || (sUnit == "px"))
     966           0 :             eUnit = FUNIT_PIXEL;
     967        3690 :         else if ((sUnit == "degrees") || (sUnit == "degree"))
     968           0 :             eUnit = FUNIT_DEGREE;
     969        3690 :         else if ((sUnit == "sec") || (sUnit == "seconds") || (sUnit == "second"))
     970           0 :             eUnit = FUNIT_SECOND;
     971        3690 :         else if ((sUnit == "ms") || (sUnit == "milliseconds") || (sUnit == "millisecond"))
     972           0 :             eUnit = FUNIT_MILLISECOND;
     973        3690 :         else if (sUnit != "0")
     974        3690 :             eUnit = FUNIT_CUSTOM;
     975             : 
     976        3690 :         return eUnit;
     977             :     }
     978             : 
     979          34 :     WinBits extractDeferredBits(VclBuilder::stringmap &rMap)
     980             :     {
     981          34 :         WinBits nBits = WB_3DLOOK|WB_HIDE;
     982          34 :         if (extractResizable(rMap))
     983           0 :             nBits |= WB_SIZEABLE;
     984          34 :         if (extractCloseable(rMap))
     985          34 :             nBits |= WB_CLOSEABLE;
     986          34 :         OString sBorder = VclBuilder::extractCustomProperty(rMap);
     987          34 :         if (!sBorder.isEmpty())
     988           0 :             nBits |= WB_BORDER;
     989          34 :         if (!extractDecorated(rMap))
     990           0 :             nBits |= WB_OWNERDRAWDECORATION;
     991          68 :         OString sType(extractTypeHint(rMap));
     992          34 :         if (sType == "utility")
     993          34 :             nBits |= WB_SYSTEMWINDOW | WB_DIALOGCONTROL | WB_MOVEABLE;
     994           0 :         else if (sType == "popup-menu")
     995           0 :             nBits |= WB_SYSTEMWINDOW | WB_DIALOGCONTROL | WB_POPUP;
     996             :         else
     997           0 :             nBits |= WB_MOVEABLE;
     998          68 :         return nBits;
     999             :     }
    1000             : }
    1001             : 
    1002        3690 : FieldUnit VclBuilder::detectUnit(OString const& rString)
    1003             : {
    1004        3690 :     OString const unit(extractUnit(rString));
    1005        3690 :     return detectMetricUnit(unit);
    1006             : }
    1007             : 
    1008           0 : void VclBuilder::ensureDefaultWidthChars(VclBuilder::stringmap &rMap)
    1009             : {
    1010           0 :     OString sWidthChars("width-chars");
    1011           0 :     VclBuilder::stringmap::iterator aFind = rMap.find(sWidthChars);
    1012           0 :     if (aFind == rMap.end())
    1013           0 :         rMap[sWidthChars] = "25";
    1014           0 : }
    1015             : 
    1016           0 : bool VclBuilder::extractGroup(const OString &id, stringmap &rMap)
    1017             : {
    1018           0 :     VclBuilder::stringmap::iterator aFind = rMap.find(OString("group"));
    1019           0 :     if (aFind != rMap.end())
    1020             :     {
    1021           0 :         OString sID = aFind->second;
    1022           0 :         sal_Int32 nDelim = sID.indexOf(':');
    1023           0 :         if (nDelim != -1)
    1024           0 :             sID = sID.copy(0, nDelim);
    1025           0 :         m_pParserState->m_aGroupMaps.push_back(RadioButtonGroupMap(id, sID));
    1026           0 :         rMap.erase(aFind);
    1027           0 :         return true;
    1028             :     }
    1029           0 :     return false;
    1030             : }
    1031             : 
    1032           0 : void VclBuilder::connectNumericFormatterAdjustment(const OString &id, const OString &rAdjustment)
    1033             : {
    1034           0 :     if (!rAdjustment.isEmpty())
    1035           0 :         m_pParserState->m_aNumericFormatterAdjustmentMaps.push_back(WidgetAdjustmentMap(id, rAdjustment));
    1036           0 : }
    1037             : 
    1038           0 : void VclBuilder::connectTimeFormatterAdjustment(const OString &id, const OString &rAdjustment)
    1039             : {
    1040           0 :     if (!rAdjustment.isEmpty())
    1041           0 :         m_pParserState->m_aTimeFormatterAdjustmentMaps.push_back(WidgetAdjustmentMap(id, rAdjustment));
    1042           0 : }
    1043             : 
    1044           0 : void VclBuilder::connectDateFormatterAdjustment(const OString &id, const OString &rAdjustment)
    1045             : {
    1046           0 :     if (!rAdjustment.isEmpty())
    1047           0 :         m_pParserState->m_aDateFormatterAdjustmentMaps.push_back(WidgetAdjustmentMap(id, rAdjustment));
    1048           0 : }
    1049             : 
    1050           0 : bool VclBuilder::extractScrollAdjustment(const OString &id, VclBuilder::stringmap &rMap)
    1051             : {
    1052           0 :     VclBuilder::stringmap::iterator aFind = rMap.find(OString("adjustment"));
    1053           0 :     if (aFind != rMap.end())
    1054             :     {
    1055           0 :         m_pParserState->m_aScrollAdjustmentMaps.push_back(WidgetAdjustmentMap(id, aFind->second));
    1056           0 :         rMap.erase(aFind);
    1057           0 :         return true;
    1058             :     }
    1059           0 :     return false;
    1060             : }
    1061             : 
    1062             : namespace
    1063             : {
    1064           0 :     sal_Int32 extractActive(VclBuilder::stringmap &rMap)
    1065             :     {
    1066           0 :         sal_Int32 nActiveId = 0;
    1067           0 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("active"));
    1068           0 :         if (aFind != rMap.end())
    1069             :         {
    1070           0 :             nActiveId = aFind->second.toInt32();
    1071           0 :             rMap.erase(aFind);
    1072             :         }
    1073           0 :         return nActiveId;
    1074             :     }
    1075             : 
    1076        1478 :     bool extractSelectable(VclBuilder::stringmap &rMap)
    1077             :     {
    1078        1478 :         bool bSelectable = false;
    1079        1478 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("selectable"));
    1080        1478 :         if (aFind != rMap.end())
    1081             :         {
    1082           0 :             bSelectable = toBool(aFind->second);
    1083           0 :             rMap.erase(aFind);
    1084             :         }
    1085        1478 :         return bSelectable;
    1086             :     }
    1087             : 
    1088           0 :     OString extractAdjustment(VclBuilder::stringmap &rMap)
    1089             :     {
    1090           0 :         OString sAdjustment;
    1091           0 :         VclBuilder::stringmap::iterator aFind = rMap.find(OString("adjustment"));
    1092           0 :         if (aFind != rMap.end())
    1093             :         {
    1094           0 :             sAdjustment= aFind->second;
    1095           0 :             rMap.erase(aFind);
    1096           0 :             return sAdjustment;
    1097             :         }
    1098           0 :         return sAdjustment;
    1099             :     }
    1100             : }
    1101             : 
    1102           0 : bool VclBuilder::extractModel(const OString &id, stringmap &rMap)
    1103             : {
    1104           0 :     VclBuilder::stringmap::iterator aFind = rMap.find(OString("model"));
    1105           0 :     if (aFind != rMap.end())
    1106             :     {
    1107           0 :         m_pParserState->m_aModelMaps.push_back(ComboBoxModelMap(id, aFind->second,
    1108           0 :             extractActive(rMap)));
    1109           0 :         rMap.erase(aFind);
    1110           0 :         return true;
    1111             :     }
    1112           0 :     return false;
    1113             : }
    1114             : 
    1115           0 : bool VclBuilder::extractDropdown(VclBuilder::stringmap &rMap)
    1116             : {
    1117           0 :     bool bDropdown = true;
    1118           0 :     VclBuilder::stringmap::iterator aFind = rMap.find(OString("dropdown"));
    1119           0 :     if (aFind != rMap.end())
    1120             :     {
    1121           0 :         bDropdown = toBool(aFind->second);
    1122           0 :         rMap.erase(aFind);
    1123             :     }
    1124           0 :     return bDropdown;
    1125             : }
    1126             : 
    1127           0 : bool VclBuilder::extractBuffer(const OString &id, stringmap &rMap)
    1128             : {
    1129           0 :     VclBuilder::stringmap::iterator aFind = rMap.find(OString("buffer"));
    1130           0 :     if (aFind != rMap.end())
    1131             :     {
    1132           0 :         m_pParserState->m_aTextBufferMaps.push_back(TextBufferMap(id, aFind->second));
    1133           0 :         rMap.erase(aFind);
    1134           0 :         return true;
    1135             :     }
    1136           0 :     return false;
    1137             : }
    1138             : 
    1139        3710 : bool VclBuilder::extractStock(const OString &id, stringmap &rMap)
    1140             : {
    1141        3710 :     VclBuilder::stringmap::iterator aFind = rMap.find(OString("stock"));
    1142        3710 :     if (aFind != rMap.end())
    1143             :     {
    1144           0 :         stockinfo aInfo;
    1145           0 :         aInfo.m_sStock = aFind->second;
    1146           0 :         rMap.erase(aFind);
    1147           0 :         aFind = rMap.find(OString("icon-size"));
    1148           0 :         if (aFind != rMap.end())
    1149             :         {
    1150           0 :             aInfo.m_nSize = aFind->second.toInt32();
    1151           0 :             rMap.erase(aFind);
    1152             :         }
    1153           0 :         m_pParserState->m_aStockMap[id] = aInfo;
    1154           0 :         return true;
    1155             :     }
    1156        3710 :     return false;
    1157             : }
    1158             : 
    1159       65490 : bool VclBuilder::extractButtonImage(const OString &id, stringmap &rMap, bool bRadio)
    1160             : {
    1161       65490 :     VclBuilder::stringmap::iterator aFind = rMap.find(OString("image"));
    1162       65490 :     if (aFind != rMap.end())
    1163             :     {
    1164          18 :         m_pParserState->m_aButtonImageWidgetMaps.push_back(ButtonImageWidgetMap(id, aFind->second, bRadio));
    1165          18 :         rMap.erase(aFind);
    1166          18 :         return true;
    1167             :     }
    1168       65472 :     return false;
    1169             : }
    1170             : 
    1171        1478 : void VclBuilder::extractMnemonicWidget(const OString &rLabelID, stringmap &rMap)
    1172             : {
    1173        1478 :     VclBuilder::stringmap::iterator aFind = rMap.find(OString("mnemonic-widget"));
    1174        1478 :     if (aFind != rMap.end())
    1175             :     {
    1176        1476 :         OString sID = aFind->second;
    1177        1476 :         sal_Int32 nDelim = sID.indexOf(':');
    1178        1476 :         if (nDelim != -1)
    1179           0 :             sID = sID.copy(0, nDelim);
    1180        1476 :         m_pParserState->m_aMnemonicWidgetMaps.push_back(MnemonicWidgetMap(rLabelID, sID));
    1181        1476 :         rMap.erase(aFind);
    1182             :     }
    1183        1478 : }
    1184             : 
    1185           0 : vcl::Window* VclBuilder::prepareWidgetOwnScrolling(vcl::Window *pParent, WinBits &rWinStyle)
    1186             : {
    1187             :     //For Widgets that manage their own scrolling, if one appears as a child of
    1188             :     //a scrolling window shoehorn that scrolling settings to this widget and
    1189             :     //return the real parent to use
    1190           0 :     if (pParent && pParent->GetType() == WINDOW_SCROLLWINDOW)
    1191             :     {
    1192           0 :         WinBits nScrollBits = pParent->GetStyle();
    1193           0 :         nScrollBits &= (WB_AUTOHSCROLL|WB_HSCROLL|WB_AUTOVSCROLL|WB_VSCROLL);
    1194           0 :         rWinStyle |= nScrollBits;
    1195           0 :         pParent = pParent->GetParent();
    1196             :     }
    1197             : 
    1198           0 :     return pParent;
    1199             : }
    1200             : 
    1201           0 : void VclBuilder::cleanupWidgetOwnScrolling(vcl::Window *pScrollParent, vcl::Window *pWindow, stringmap &rMap)
    1202             : {
    1203             :     //remove the redundant scrolling parent
    1204           0 :     sal_Int32 nWidthReq = pScrollParent->get_width_request();
    1205           0 :     rMap[OString("width-request")] = OString::number(nWidthReq);
    1206           0 :     sal_Int32 nHeightReq = pScrollParent->get_height_request();
    1207           0 :     rMap[OString("height-request")] = OString::number(nHeightReq);
    1208             : 
    1209           0 :     m_pParserState->m_aRedundantParentWidgets[pScrollParent] = pWindow;
    1210           0 : }
    1211             : 
    1212             : #ifndef DISABLE_DYNLOADING
    1213           0 : extern "C" { static void SAL_CALL thisModule() {} }
    1214             : #endif
    1215             : 
    1216       65524 : vcl::Window *VclBuilder::makeObject(vcl::Window *pParent, const OString &name, const OString &id,
    1217             :     stringmap &rMap, const std::vector<OString> &rItems)
    1218             : {
    1219       65524 :     bool bIsPlaceHolder = name.isEmpty();
    1220       65524 :     bool bVertical = false;
    1221             : 
    1222       65524 :     if (pParent && pParent->GetType() == WINDOW_TABCONTROL)
    1223             :     {
    1224             :         //We have to add a page
    1225             : 
    1226             :         //make default pageid == position
    1227           0 :         TabControl *pTabControl = static_cast<TabControl*>(pParent);
    1228           0 :         sal_uInt16 nNewPageCount = pTabControl->GetPageCount()+1;
    1229           0 :         sal_uInt16 nNewPageId = nNewPageCount;
    1230           0 :         pTabControl->InsertPage(nNewPageId, OUString());
    1231           0 :         pTabControl->SetCurPageId(nNewPageId);
    1232             : 
    1233           0 :         if (!bIsPlaceHolder)
    1234             :         {
    1235           0 :             TabPage* pPage = new TabPage(pTabControl);
    1236           0 :             pPage->Show();
    1237             : 
    1238             :             //Make up a name for it
    1239           0 :             OString sTabPageId = get_by_window(pParent) +
    1240           0 :                 OString("-page") +
    1241           0 :                 OString::number(nNewPageCount);
    1242           0 :             m_aChildren.push_back(WinAndId(sTabPageId, pPage, false));
    1243           0 :             pPage->SetHelpId(m_sHelpRoot + sTabPageId);
    1244             : 
    1245             :             //And give the page one container as a child to make it a layout enabled
    1246             :             //tab page
    1247           0 :             VclBin* pContainer = new VclBin(pPage);
    1248           0 :             pContainer->Show();
    1249           0 :             m_aChildren.push_back(WinAndId(OString(), pContainer, false));
    1250           0 :             pContainer->SetHelpId(m_sHelpRoot + sTabPageId + OString("-bin"));
    1251           0 :             pParent = pContainer;
    1252             : 
    1253           0 :             pTabControl->SetTabPage(nNewPageId, pPage);
    1254             :         }
    1255             :     }
    1256             : 
    1257       65524 :     if (bIsPlaceHolder || name == "GtkTreeSelection")
    1258          34 :         return NULL;
    1259             : 
    1260       65490 :     extractButtonImage(id, rMap, name == "GtkRadioButton");
    1261             : 
    1262       65490 :     vcl::Window *pWindow = NULL;
    1263       65490 :     if (name == "GtkDialog")
    1264             :     {
    1265           0 :         WinBits nBits = WB_CLIPCHILDREN|WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
    1266           0 :         if (extractResizable(rMap))
    1267           0 :             nBits |= WB_SIZEABLE;
    1268           0 :         pWindow = new Dialog(pParent, nBits);
    1269             :     }
    1270       65490 :     else if (name == "GtkMessageDialog")
    1271             :     {
    1272           0 :         WinBits nBits = WB_CLIPCHILDREN|WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
    1273           0 :         if (extractResizable(rMap))
    1274           0 :             nBits |= WB_SIZEABLE;
    1275           0 :         pWindow = new MessageDialog(pParent, nBits);
    1276             :     }
    1277       65490 :     else if (name == "GtkBox")
    1278             :     {
    1279        9646 :         bVertical = extractOrientation(rMap);
    1280        9646 :         if (bVertical)
    1281        2262 :             pWindow = new VclVBox(pParent);
    1282             :         else
    1283        7384 :             pWindow = new VclHBox(pParent);
    1284             :     }
    1285       55844 :     else if (name == "GtkHBox")
    1286           0 :         pWindow = new VclHBox(pParent);
    1287       55844 :     else if (name == "GtkVBox")
    1288           0 :         pWindow = new VclVBox(pParent);
    1289       55844 :     else if (name == "GtkButtonBox")
    1290             :     {
    1291           0 :         bVertical = extractOrientation(rMap);
    1292           0 :         if (bVertical)
    1293           0 :             pWindow = new VclVButtonBox(pParent);
    1294             :         else
    1295           0 :             pWindow = new VclHButtonBox(pParent);
    1296             :     }
    1297       55844 :     else if (name == "GtkHButtonBox")
    1298           0 :         pWindow = new VclHButtonBox(pParent);
    1299       55844 :     else if (name == "GtkVButtonBox")
    1300           0 :         pWindow = new VclVButtonBox(pParent);
    1301       55844 :     else if (name == "GtkGrid")
    1302        1514 :         pWindow = new VclGrid(pParent);
    1303       54330 :     else if (name == "GtkFrame")
    1304           0 :         pWindow = new VclFrame(pParent);
    1305       54330 :     else if (name == "GtkExpander")
    1306             :     {
    1307           0 :         VclExpander *pExpander = new VclExpander(pParent);
    1308           0 :         m_pParserState->m_aExpanderWidgets.push_back(pExpander);
    1309           0 :         pWindow = pExpander;
    1310             :     }
    1311       54330 :     else if (name == "GtkAlignment")
    1312           0 :         pWindow = new VclAlignment(pParent);
    1313       54330 :     else if (name == "GtkButton")
    1314             :     {
    1315             :         Button *pButton;
    1316          22 :         OString sMenu = extractCustomProperty(rMap);
    1317          22 :         if (sMenu.isEmpty())
    1318          20 :             pButton = extractStockAndBuildPushButton(pParent, rMap);
    1319             :         else
    1320             :         {
    1321           2 :             pButton = extractStockAndBuildMenuButton(pParent, rMap);
    1322           2 :             m_pParserState->m_aButtonMenuMaps.push_back(ButtonMenuMap(id, sMenu));
    1323             :         }
    1324          22 :         pButton->SetImageAlign(IMAGEALIGN_LEFT); //default to left
    1325          22 :         setupFromActionName(pButton, rMap, m_xFrame);
    1326          22 :         pWindow = pButton;
    1327             :     }
    1328       54308 :     else if (name == "GtkRadioButton")
    1329             :     {
    1330           0 :         extractGroup(id, rMap);
    1331           0 :         WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER|WB_3DLOOK;
    1332           0 :         OString sWrap = extractCustomProperty(rMap);
    1333           0 :         if (!sWrap.isEmpty())
    1334           0 :             nBits |= WB_WORDBREAK;
    1335           0 :         RadioButton *pButton = new RadioButton(pParent, nBits);
    1336           0 :         pButton->SetImageAlign(IMAGEALIGN_LEFT); //default to left
    1337           0 :         pWindow = pButton;
    1338             :     }
    1339       54308 :     else if (name == "GtkCheckButton")
    1340             :     {
    1341           0 :         WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER|WB_3DLOOK;
    1342           0 :         OString sWrap = extractCustomProperty(rMap);
    1343           0 :         if (!sWrap.isEmpty())
    1344           0 :             nBits |= WB_WORDBREAK;
    1345             :         //maybe always import as TriStateBox and enable/disable tristate
    1346           0 :         bool bIsTriState = extractInconsistent(rMap);
    1347             :         CheckBox *pCheckBox = bIsTriState ?
    1348           0 :             new TriStateBox(pParent, nBits) :
    1349           0 :             new CheckBox(pParent, nBits);
    1350           0 :         if (bIsTriState)
    1351           0 :             pCheckBox->SetState(TRISTATE_INDET);
    1352           0 :         pCheckBox->SetImageAlign(IMAGEALIGN_LEFT); //default to left
    1353           0 :         pWindow = pCheckBox;
    1354             :     }
    1355       54308 :     else if (name == "GtkSpinButton")
    1356             :     {
    1357           0 :         OString sAdjustment = extractAdjustment(rMap);
    1358           0 :         OString sPattern = extractCustomProperty(rMap);
    1359           0 :         OString sUnit = extractUnit(sPattern);
    1360             : 
    1361           0 :         WinBits nBits = WB_CLIPCHILDREN|WB_LEFT|WB_BORDER|WB_3DLOOK;
    1362           0 :         if (!id.endsWith("-nospin"))
    1363           0 :             nBits |= WB_SPIN | WB_REPEAT;
    1364             : 
    1365           0 :         if (sPattern.isEmpty())
    1366             :         {
    1367           0 :             connectNumericFormatterAdjustment(id, sAdjustment);
    1368             :             SAL_INFO("vcl.layout", "making numeric field for " << name.getStr() << " " << sUnit.getStr());
    1369           0 :             pWindow = new NumericField(pParent, nBits);
    1370             :         }
    1371             :         else
    1372             :         {
    1373           0 :             if (sPattern == "hh:mm")
    1374             :             {
    1375           0 :                 connectTimeFormatterAdjustment(id, sAdjustment);
    1376             :                 SAL_INFO("vcl.layout", "making time field for " << name.getStr() << " " << sUnit.getStr());
    1377           0 :                 TimeField *pField = new TimeField(pParent, nBits);
    1378           0 :                 pWindow = pField;
    1379             :             }
    1380           0 :             else if (sPattern == "yy:mm:dd")
    1381             :             {
    1382           0 :                 connectDateFormatterAdjustment(id, sAdjustment);
    1383             :                 SAL_INFO("vcl.layout", "making date field for " << name.getStr() << " " << sUnit.getStr());
    1384           0 :                 DateField *pField = new DateField(pParent, nBits);
    1385           0 :                 pWindow = pField;
    1386             :             }
    1387             :             else
    1388             :             {
    1389           0 :                 connectNumericFormatterAdjustment(id, sAdjustment);
    1390           0 :                 FieldUnit eUnit = detectMetricUnit(sUnit);
    1391             :                 SAL_INFO("vcl.layout", "making metric field for " << name.getStr() << " " << sUnit.getStr());
    1392           0 :                 MetricField *pField = new MetricField(pParent, nBits);
    1393           0 :                 pField->SetUnit(eUnit);
    1394           0 :                 if (eUnit == FUNIT_CUSTOM)
    1395           0 :                     pField->SetCustomUnitText(OStringToOUString(sUnit, RTL_TEXTENCODING_UTF8));
    1396           0 :                 pWindow = pField;
    1397             :             }
    1398           0 :         }
    1399             :     }
    1400       54308 :     else if (name == "GtkLinkButton")
    1401           0 :         pWindow = new FixedHyperlink(pParent, WB_CENTER|WB_VCENTER|WB_3DLOOK|WB_NOLABEL);
    1402       54308 :     else if ((name == "GtkComboBox") || (name == "GtkComboBoxText") || (name == "VclComboBoxText"))
    1403             :     {
    1404           0 :         OString sPattern = extractCustomProperty(rMap);
    1405           0 :         extractModel(id, rMap);
    1406             : 
    1407           0 :         WinBits nBits = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK;
    1408             : 
    1409           0 :         bool bDropdown = VclBuilder::extractDropdown(rMap);
    1410             : 
    1411           0 :         if (bDropdown)
    1412           0 :             nBits |= WB_DROPDOWN;
    1413             : 
    1414           0 :         if (!sPattern.isEmpty())
    1415             :         {
    1416           0 :             OString sAdjustment = extractAdjustment(rMap);
    1417           0 :             connectNumericFormatterAdjustment(id, sAdjustment);
    1418           0 :             OString sUnit = extractUnit(sPattern);
    1419           0 :             FieldUnit eUnit = detectMetricUnit(sUnit);
    1420             :             SAL_WARN("vcl.layout", "making metric box for type: " << name.getStr()
    1421             :                 << " unit: " << sUnit.getStr()
    1422             :                 << " name: " << id.getStr()
    1423             :                 << " use a VclComboBoxNumeric instead");
    1424           0 :             MetricBox *pBox = new MetricBox(pParent, nBits);
    1425           0 :             pBox->EnableAutoSize(true);
    1426           0 :             pBox->SetUnit(eUnit);
    1427           0 :             pBox->SetDecimalDigits(extractDecimalDigits(sPattern));
    1428           0 :             if (eUnit == FUNIT_CUSTOM)
    1429           0 :                 pBox->SetCustomUnitText(OStringToOUString(sUnit, RTL_TEXTENCODING_UTF8));
    1430           0 :             pWindow = pBox;
    1431             :         }
    1432           0 :         else if (extractEntry(rMap))
    1433             :         {
    1434           0 :             ComboBox* pComboBox = new ComboBox(pParent, nBits);
    1435           0 :             pComboBox->EnableAutoSize(true);
    1436           0 :             if (!rItems.empty())
    1437             :             {
    1438           0 :                 sal_uInt16 nActiveId = extractActive(rMap);
    1439           0 :                 for (std::vector<OString>::const_iterator aI = rItems.begin(), aEnd = rItems.end(); aI != aEnd; ++aI)
    1440           0 :                     pComboBox->InsertEntry(OStringToOUString(*aI, RTL_TEXTENCODING_UTF8));
    1441           0 :                 if (nActiveId < rItems.size())
    1442           0 :                     pComboBox->SelectEntryPos(nActiveId);
    1443             :             }
    1444           0 :             pWindow = pComboBox;
    1445             :         }
    1446             :         else
    1447             :         {
    1448           0 :             ListBox *pListBox = new ListBox(pParent, nBits|WB_SIMPLEMODE);
    1449           0 :             pListBox->EnableAutoSize(true);
    1450           0 :             if (!rItems.empty())
    1451             :             {
    1452           0 :                 sal_uInt16 nActiveId = extractActive(rMap);
    1453           0 :                 for (std::vector<OString>::const_iterator aI = rItems.begin(), aEnd = rItems.end(); aI != aEnd; ++aI)
    1454           0 :                     pListBox->InsertEntry(OStringToOUString(*aI, RTL_TEXTENCODING_UTF8));
    1455           0 :                 if (nActiveId < rItems.size())
    1456           0 :                     pListBox->SelectEntryPos(nActiveId);
    1457             :             }
    1458           0 :             pWindow = pListBox;
    1459           0 :         }
    1460             :     }
    1461       54308 :     else if (name == "VclComboBoxNumeric")
    1462             :     {
    1463           0 :         OString sPattern = extractCustomProperty(rMap);
    1464           0 :         OString sAdjustment = extractAdjustment(rMap);
    1465           0 :         extractModel(id, rMap);
    1466             : 
    1467           0 :         WinBits nBits = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK;
    1468             : 
    1469           0 :         bool bDropdown = VclBuilder::extractDropdown(rMap);
    1470             : 
    1471           0 :         if (bDropdown)
    1472           0 :             nBits |= WB_DROPDOWN;
    1473             : 
    1474           0 :         if (!sPattern.isEmpty())
    1475             :         {
    1476           0 :             connectNumericFormatterAdjustment(id, sAdjustment);
    1477           0 :             OString sUnit = extractUnit(sPattern);
    1478           0 :             FieldUnit eUnit = detectMetricUnit(sUnit);
    1479             :             SAL_INFO("vcl.layout", "making metric box for " << name.getStr() << " " << sUnit.getStr());
    1480           0 :             MetricBox *pBox = new MetricBox(pParent, nBits);
    1481           0 :             pBox->EnableAutoSize(true);
    1482           0 :             pBox->SetUnit(eUnit);
    1483           0 :             pBox->SetDecimalDigits(extractDecimalDigits(sPattern));
    1484           0 :             if (eUnit == FUNIT_CUSTOM)
    1485           0 :                 pBox->SetCustomUnitText(OStringToOUString(sUnit, RTL_TEXTENCODING_UTF8));
    1486           0 :             pWindow = pBox;
    1487             :         }
    1488             :         else
    1489             :         {
    1490             :             SAL_INFO("vcl.layout", "making numeric box for " << name.getStr());
    1491           0 :             connectNumericFormatterAdjustment(id, sAdjustment);
    1492           0 :             NumericBox* pBox = new NumericBox(pParent, nBits);
    1493           0 :             if (bDropdown)
    1494           0 :                 pBox->EnableAutoSize(true);
    1495           0 :             pWindow = pBox;
    1496           0 :         }
    1497             :     }
    1498       54308 :     else if (name == "GtkTreeView")
    1499             :     {
    1500             :         //To-Do
    1501             :         //a) move svtools SvTreeViewBox into vcl
    1502             :         //b) make that the default target for GtkTreeView
    1503             :         //c) remove the non-drop down mode of ListBox and convert
    1504             :         //   everything over to SvTreeViewBox
    1505             :         //d) remove the users of makeSvTreeViewBox
    1506           0 :         extractModel(id, rMap);
    1507           0 :         WinBits nWinStyle = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_SIMPLEMODE;
    1508           0 :         OString sBorder = extractCustomProperty(rMap);
    1509           0 :         if (!sBorder.isEmpty())
    1510           0 :             nWinStyle |= WB_BORDER;
    1511             :         //ListBox manages its own scrolling,
    1512           0 :         vcl::Window *pRealParent = prepareWidgetOwnScrolling(pParent, nWinStyle);
    1513           0 :         pWindow = new ListBox(pRealParent, nWinStyle);
    1514           0 :         if (pRealParent != pParent)
    1515           0 :             cleanupWidgetOwnScrolling(pParent, pWindow, rMap);
    1516             :     }
    1517       54308 :     else if (name == "GtkLabel")
    1518             :     {
    1519        1478 :         WinBits nWinStyle = WB_CENTER|WB_VCENTER|WB_3DLOOK;
    1520        1478 :         OString sBorder = extractCustomProperty(rMap);
    1521        1478 :         if (!sBorder.isEmpty())
    1522           0 :             nWinStyle |= WB_BORDER;
    1523        1478 :         extractMnemonicWidget(id, rMap);
    1524        1478 :         if (extractSelectable(rMap))
    1525           0 :             pWindow = new SelectableFixedText(pParent, nWinStyle);
    1526             :         else
    1527        1478 :             pWindow = new FixedText(pParent, nWinStyle);
    1528             :     }
    1529       52830 :     else if (name == "GtkImage")
    1530             :     {
    1531        3710 :         extractStock(id, rMap);
    1532        3710 :         pWindow = new FixedImage(pParent, WB_CENTER|WB_VCENTER|WB_3DLOOK|WB_SCALE);
    1533             :         //such parentless GtkImages are temps used to set icons on buttons
    1534             :         //default them to hidden to stop e.g. insert->index entry flicking temp
    1535             :         //full screen windows
    1536        3710 :         if (!pParent)
    1537             :         {
    1538           0 :             rMap["visible"] = "false";
    1539             :         }
    1540             : 
    1541             :     }
    1542       49120 :     else if (name == "GtkSeparator")
    1543             :     {
    1544          36 :         bVertical = extractOrientation(rMap);
    1545          36 :         if (bVertical)
    1546           0 :             pWindow = new FixedLine(pParent, WB_VERT);
    1547             :         else
    1548          36 :             pWindow = new FixedLine(pParent, WB_HORZ);
    1549             :     }
    1550       49084 :     else if (name == "GtkScrollbar")
    1551             :     {
    1552           0 :         extractScrollAdjustment(id, rMap);
    1553           0 :         bVertical = extractOrientation(rMap);
    1554           0 :         if (bVertical)
    1555           0 :             pWindow = new ScrollBar(pParent, WB_VERT);
    1556             :         else
    1557           0 :             pWindow = new ScrollBar(pParent, WB_HORZ);
    1558             :     }
    1559       49084 :     else if (name == "GtkProgressBar")
    1560             :     {
    1561           0 :         extractScrollAdjustment(id, rMap);
    1562           0 :         bVertical = extractOrientation(rMap);
    1563           0 :         if (bVertical)
    1564           0 :             pWindow = new ProgressBar(pParent, WB_VERT);
    1565             :         else
    1566           0 :             pWindow = new ProgressBar(pParent, WB_HORZ);
    1567             :     }
    1568       49084 :     else if (name == "GtkScrolledWindow")
    1569             :     {
    1570           0 :         pWindow = new VclScrolledWindow(pParent);
    1571             :     }
    1572       49084 :     else if (name == "GtkViewport")
    1573             :     {
    1574           0 :         pWindow = new VclViewport(pParent);
    1575             :     }
    1576       49084 :     else if (name == "GtkEventBox")
    1577             :     {
    1578           0 :         pWindow = new VclEventBox(pParent);
    1579             :     }
    1580       49084 :     else if (name == "GtkEntry")
    1581             :     {
    1582           0 :         pWindow = new Edit(pParent, WB_LEFT|WB_VCENTER|WB_BORDER|WB_3DLOOK);
    1583           0 :         ensureDefaultWidthChars(rMap);
    1584             :     }
    1585       49084 :     else if (name == "GtkNotebook")
    1586           0 :         pWindow = new TabControl(pParent, WB_STDTABCONTROL|WB_3DLOOK);
    1587       49084 :     else if (name == "GtkDrawingArea")
    1588             :     {
    1589           0 :         OString sBorder = extractCustomProperty(rMap);
    1590           0 :         pWindow = new vcl::Window(pParent, sBorder.isEmpty() ? 0 : WB_BORDER);
    1591             :     }
    1592       49084 :     else if (name == "GtkTextView")
    1593             :     {
    1594           0 :         extractBuffer(id, rMap);
    1595             : 
    1596           0 :         WinBits nWinStyle = WB_CLIPCHILDREN|WB_LEFT;
    1597           0 :         OString sBorder = extractCustomProperty(rMap);
    1598           0 :         if (!sBorder.isEmpty())
    1599           0 :             nWinStyle |= WB_BORDER;
    1600             :         //VclMultiLineEdit manages its own scrolling,
    1601           0 :         vcl::Window *pRealParent = prepareWidgetOwnScrolling(pParent, nWinStyle);
    1602           0 :         pWindow = new VclMultiLineEdit(pRealParent, nWinStyle);
    1603           0 :         if (pRealParent != pParent)
    1604           0 :             cleanupWidgetOwnScrolling(pParent, pWindow, rMap);
    1605             :     }
    1606       49084 :     else if (name == "GtkSpinner")
    1607             :     {
    1608           0 :         pWindow = new Throbber(pParent, WB_3DLOOK);
    1609             :     }
    1610       49084 :     else if (name == "GtkToolbar")
    1611             :     {
    1612        6692 :         pWindow = new ToolBox(pParent, WB_3DLOOK | WB_TABSTOP);
    1613             :     }
    1614       42392 :     else if (name == "GtkToolButton" || name == "GtkMenuToolButton")
    1615             :     {
    1616       29842 :         ToolBox *pToolBox = dynamic_cast<ToolBox*>(pParent);
    1617       29842 :         if (pToolBox)
    1618             :         {
    1619       29842 :             OUString aCommand(OStringToOUString(extractActionName(rMap), RTL_TEXTENCODING_UTF8));
    1620             : 
    1621       29842 :             sal_uInt16 nItemId = 0;
    1622       29842 :             ToolBoxItemBits nBits = ToolBoxItemBits::NONE;
    1623       29842 :             if (name == "GtkMenuToolButton")
    1624        8872 :                 nBits |= ToolBoxItemBits::DROPDOWN;
    1625             : 
    1626       29842 :             if (!aCommand.isEmpty() && m_xFrame.is())
    1627             :             {
    1628       29536 :                 pToolBox->InsertItem(aCommand, m_xFrame, nBits, extractSizeRequest(rMap));
    1629       29536 :                 nItemId = pToolBox->GetItemId(aCommand);
    1630             :             }
    1631             :             else
    1632             :             {
    1633         306 :                 const sal_uInt16 COMMAND_ITEMID_START = 30000;
    1634         306 :                 nItemId = COMMAND_ITEMID_START + pToolBox->GetItemCount();
    1635             :                 pToolBox->InsertItem(nItemId,
    1636         306 :                     OStringToOUString(extractLabel(rMap), RTL_TEXTENCODING_UTF8), nBits);
    1637         306 :                 pToolBox->SetItemCommand(nItemId, aCommand);
    1638         306 :                 pToolBox->SetHelpId(nItemId, m_sHelpRoot + id);
    1639             :             }
    1640             : 
    1641       59684 :             OString sTooltip(extractTooltipText(rMap));
    1642       29842 :             if (!sTooltip.isEmpty())
    1643       11086 :                 pToolBox->SetQuickHelpText(nItemId, OStringToOUString(sTooltip, RTL_TEXTENCODING_UTF8));
    1644             : 
    1645       59684 :             OString sIconName(extractIconName(rMap));
    1646       29842 :             if (!sIconName.isEmpty())
    1647         306 :                 pToolBox->SetItemImage(nItemId, FixedImage::loadThemeImage(sIconName));
    1648             : 
    1649       29842 :             if (!extractVisible(rMap))
    1650           0 :                 pToolBox->HideItem(nItemId);
    1651             : 
    1652       29842 :             m_pParserState->m_nLastToolbarId = nItemId;
    1653             : 
    1654       59684 :             return NULL; // no widget to be created
    1655             :         }
    1656             :     }
    1657       12550 :     else if (name == "GtkSeparatorToolItem")
    1658             :     {
    1659           0 :         ToolBox *pToolBox = dynamic_cast<ToolBox*>(pParent);
    1660           0 :         if (pToolBox)
    1661             :         {
    1662           0 :             pToolBox->InsertSeparator();
    1663           0 :             return NULL; // no widget to be created
    1664             :         }
    1665             :     }
    1666       12550 :     else if (name == "GtkWindow")
    1667             :     {
    1668           0 :         WinBits nBits = extractDeferredBits(rMap);
    1669           0 :         pWindow = new FloatingWindow(pParent, nBits|WB_MOVEABLE);
    1670             :     }
    1671             :     else
    1672             :     {
    1673       12550 :         sal_Int32 nDelim = name.indexOf('-');
    1674       12550 :         if (nDelim != -1)
    1675             :         {
    1676             : #ifndef DISABLE_DYNLOADING
    1677       12550 :             OUStringBuffer sModuleBuf;
    1678             : #ifdef SAL_DLLPREFIX
    1679       12550 :             sModuleBuf.append(SAL_DLLPREFIX);
    1680             : #endif
    1681       12550 :             sModuleBuf.append(OStringToOUString(name.copy(0, nDelim), RTL_TEXTENCODING_UTF8));
    1682       12550 :             sModuleBuf.append(SAL_DLLEXTENSION);
    1683             : #endif
    1684       25100 :             OUString sFunction(OStringToOUString(OString("make") + name.copy(nDelim+1), RTL_TEXTENCODING_UTF8));
    1685             : #ifndef DISABLE_DYNLOADING
    1686       25100 :             OUString sModule = sModuleBuf.makeStringAndClear();
    1687       12550 :             ModuleMap::iterator aI = m_aModuleMap.find(sModule);
    1688       12550 :             osl::Module* pModule = NULL;
    1689       12550 :             if (aI == m_aModuleMap.end())
    1690             :             {
    1691        2216 :                 pModule = new osl::Module;
    1692        2216 :                 pModule->loadRelative(&thisModule, sModule);
    1693        2216 :                 aI = m_aModuleMap.insert(sModule, pModule).first;
    1694             :             }
    1695       12550 :             customMakeWidget pFunction = (customMakeWidget)aI->second->getFunctionSymbol(sFunction);
    1696             : #else
    1697             :             customMakeWidget pFunction = (customMakeWidget)osl_getFunctionSymbol((oslModule) RTLD_DEFAULT, sFunction.pData);
    1698             : #endif
    1699       12550 :             if (pFunction)
    1700       25100 :                 pWindow = (*pFunction)(pParent, rMap);
    1701             :         }
    1702             :     }
    1703             :     SAL_WARN_IF(!pWindow, "vcl.layout", "probably need to implement " << name.getStr() << " or add a make" << name.getStr() << " function");
    1704       35648 :     if (pWindow)
    1705             :     {
    1706       35648 :         pWindow->SetHelpId(m_sHelpRoot + id);
    1707             :         SAL_INFO("vcl.layout", "for " << name.getStr() <<
    1708             :             ", created " << pWindow << " child of " <<
    1709             :             pParent << "(" << pWindow->mpWindowImpl->mpParent << "/" <<
    1710             :             pWindow->mpWindowImpl->mpRealParent << "/" <<
    1711             :             pWindow->mpWindowImpl->mpBorderWindow << ") with helpid " <<
    1712             :             pWindow->GetHelpId().getStr());
    1713       35648 :         m_aChildren.push_back(WinAndId(id, pWindow, bVertical));
    1714             :     }
    1715       35648 :     return pWindow;
    1716             : }
    1717             : 
    1718             : namespace
    1719             : {
    1720             :     //return true for window types which exist in vcl but are not themselves
    1721             :     //represented in the .ui format, i.e. only their children exist.
    1722       67778 :     bool isConsideredGtkPseudo(vcl::Window *pWindow)
    1723             :     {
    1724       67778 :         return pWindow->GetType() == WINDOW_TABPAGE;
    1725             :     }
    1726             : }
    1727             : 
    1728             : //Any properties from .ui load we couldn't set because of potential virtual methods
    1729             : //during ctor are applied here
    1730         102 : void VclBuilder::setDeferredProperties()
    1731             : {
    1732         102 :     if (!m_bToplevelHasDeferredProperties)
    1733         170 :         return;
    1734          34 :     stringmap aDeferredProperties;
    1735          34 :     aDeferredProperties.swap(m_aDeferredProperties);
    1736          34 :     m_bToplevelHasDeferredProperties = false;
    1737          34 :     set_properties(m_pParent, aDeferredProperties);
    1738             : }
    1739             : 
    1740       37902 : void VclBuilder::set_properties(vcl::Window *pWindow, const stringmap &rProps)
    1741             : {
    1742      197774 :     for (stringmap::const_iterator aI = rProps.begin(), aEnd = rProps.end(); aI != aEnd; ++aI)
    1743             :     {
    1744      159872 :         const OString &rKey = aI->first;
    1745      159872 :         const OString &rValue = aI->second;
    1746      159872 :         pWindow->set_property(rKey, rValue);
    1747             :     }
    1748       37902 : }
    1749             : 
    1750       67778 : vcl::Window *VclBuilder::insertObject(vcl::Window *pParent, const OString &rClass,
    1751             :     const OString &rID, stringmap &rProps, stringmap &rPango,
    1752             :     stringmap &rAtk,
    1753             :     std::vector<OString> &rItems)
    1754             : {
    1755       67778 :     vcl::Window *pCurrentChild = NULL;
    1756             : 
    1757       67778 :     if (m_pParent && !isConsideredGtkPseudo(m_pParent) && !m_sID.isEmpty() && rID.equals(m_sID))
    1758             :     {
    1759        2254 :         pCurrentChild = m_pParent;
    1760             : 
    1761             :         //toplevels default to resizable and apparently you can't change them
    1762             :         //afterwards, so we need to wait until now before we can truly
    1763             :         //initialize the dialog.
    1764        2254 :         if (pParent && pParent->IsSystemWindow())
    1765             :         {
    1766          34 :             SystemWindow *pSysWin = static_cast<SystemWindow*>(pCurrentChild);
    1767          34 :             pSysWin->doDeferredInit(extractDeferredBits(rProps));
    1768          34 :             m_bToplevelHasDeferredInit = false;
    1769             :         }
    1770             : 
    1771        2254 :         if (pCurrentChild->GetHelpId().isEmpty())
    1772             :         {
    1773        2254 :             pCurrentChild->SetHelpId(m_sHelpRoot + m_sID);
    1774             :             SAL_INFO("vcl.layout", "for toplevel dialog " << this << " " <<
    1775             :                 rID.getStr() << ", set helpid " <<
    1776             :                 pCurrentChild->GetHelpId().getStr());
    1777             :         }
    1778        2254 :         m_bToplevelParentFound = true;
    1779             :     }
    1780             :     else
    1781             :     {
    1782             :         //if we're being inserting under a toplevel dialog whose init is
    1783             :         //deferred due to waiting to encounter it in this .ui, and it hasn't
    1784             :         //been seen yet, then make unattached widgets parent-less toplevels
    1785       65524 :         if (pParent == m_pParent && m_bToplevelHasDeferredInit)
    1786           0 :             pParent = NULL;
    1787       65524 :         pCurrentChild = makeObject(pParent, rClass, rID, rProps, rItems);
    1788             :     }
    1789             : 
    1790       67778 :     if (pCurrentChild)
    1791             :     {
    1792       37902 :         if (pCurrentChild == m_pParent && m_bToplevelHasDeferredProperties)
    1793          34 :             m_aDeferredProperties = rProps;
    1794             :         else
    1795       37868 :             set_properties(pCurrentChild, rProps);
    1796             : 
    1797       37902 :         for (stringmap::iterator aI = rPango.begin(), aEnd = rPango.end(); aI != aEnd; ++aI)
    1798             :         {
    1799           0 :             const OString &rKey = aI->first;
    1800           0 :             const OString &rValue = aI->second;
    1801           0 :             pCurrentChild->set_font_attribute(rKey, rValue);
    1802             :         }
    1803             : 
    1804       37902 :         m_pParserState->m_aAtkInfo[pCurrentChild] = rAtk;
    1805             :     }
    1806             : 
    1807       67778 :     rProps.clear();
    1808       67778 :     rPango.clear();
    1809       67778 :     rAtk.clear();
    1810       67778 :     rItems.clear();
    1811             : 
    1812       67778 :     if (!pCurrentChild)
    1813       29876 :         pCurrentChild = m_aChildren.empty() ? pParent : m_aChildren.back().m_pWindow;
    1814       67778 :     return pCurrentChild;
    1815             : }
    1816             : 
    1817       38548 : void VclBuilder::reorderWithinParent(vcl::Window &rWindow, sal_uInt16 nNewPosition)
    1818             : {
    1819       38548 :     if (rWindow.mpWindowImpl->mpParent != rWindow.mpWindowImpl->mpRealParent)
    1820             :     {
    1821             :         assert(rWindow.mpWindowImpl->mpBorderWindow ==
    1822             :             rWindow.mpWindowImpl->mpParent);
    1823             :         assert(rWindow.mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent ==
    1824             :             rWindow.mpWindowImpl->mpRealParent);
    1825           0 :         reorderWithinParent(*rWindow.mpWindowImpl->mpBorderWindow, nNewPosition);
    1826       38548 :         return;
    1827             :     }
    1828       38548 :     rWindow.reorderWithinParent(nNewPosition);
    1829             : }
    1830             : 
    1831           0 : void VclBuilder::handleTabChild(vcl::Window *pParent, xmlreader::XmlReader &reader)
    1832             : {
    1833           0 :     OString sID;
    1834             : 
    1835           0 :     int nLevel = 1;
    1836           0 :     stringmap aProperties;
    1837             :     while(true)
    1838             :     {
    1839           0 :         xmlreader::Span name;
    1840             :         int nsId;
    1841             : 
    1842             :         xmlreader::XmlReader::Result res = reader.nextItem(
    1843           0 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    1844             : 
    1845           0 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    1846             :         {
    1847           0 :             ++nLevel;
    1848           0 :             if (name.equals("object"))
    1849             :             {
    1850           0 :                 while (reader.nextAttribute(&nsId, &name))
    1851             :                 {
    1852           0 :                     if (name.equals("id"))
    1853             :                     {
    1854           0 :                         name = reader.getAttributeValue(false);
    1855           0 :                         sID = OString(name.begin, name.length);
    1856           0 :                         sal_Int32 nDelim = sID.indexOf(':');
    1857           0 :                         if (nDelim != -1)
    1858             :                         {
    1859           0 :                             OString sPattern = sID.copy(nDelim+1);
    1860           0 :                             aProperties[OString("customproperty")] = sPattern;
    1861           0 :                             sID = sID.copy(0, nDelim);
    1862             :                         }
    1863             :                     }
    1864             :                 }
    1865             :             }
    1866           0 :             else if (name.equals("property"))
    1867           0 :                 collectProperty(reader, sID, aProperties);
    1868             :         }
    1869             : 
    1870           0 :         if (res == xmlreader::XmlReader::RESULT_END)
    1871           0 :             --nLevel;
    1872             : 
    1873           0 :         if (!nLevel)
    1874           0 :             break;
    1875             : 
    1876           0 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    1877           0 :             break;
    1878             :     }
    1879             : 
    1880           0 :     if (!pParent)
    1881           0 :         return;
    1882             : 
    1883           0 :     TabControl *pTabControl = static_cast<TabControl*>(pParent);
    1884           0 :     VclBuilder::stringmap::iterator aFind = aProperties.find(OString("label"));
    1885           0 :     if (aFind != aProperties.end())
    1886             :     {
    1887           0 :         sal_uInt16 nPageId = pTabControl->GetCurPageId();
    1888             :         pTabControl->SetPageText(nPageId,
    1889           0 :             OStringToOUString(aFind->second, RTL_TEXTENCODING_UTF8));
    1890           0 :         pTabControl->SetPageName(nPageId, sID);
    1891             :     }
    1892             :     else
    1893           0 :         pTabControl->RemovePage(pTabControl->GetCurPageId());
    1894             : }
    1895             : 
    1896             : //so that tabbing between controls goes in a visually sensible sequence
    1897             : //we sort these into a best-tab-order sequence
    1898       34094 : bool VclBuilder::sortIntoBestTabTraversalOrder::operator()(const vcl::Window *pA, const vcl::Window *pB) const
    1899             : {
    1900             :     //sort child order within parent list by grid position
    1901       34094 :     sal_Int32 nTopA = pA->get_grid_top_attach();
    1902       34094 :     sal_Int32 nTopB = pB->get_grid_top_attach();
    1903       34094 :     if (nTopA < nTopB)
    1904         772 :         return true;
    1905       33322 :     if (nTopA > nTopB)
    1906        1510 :         return false;
    1907       31812 :     sal_Int32 nLeftA = pA->get_grid_left_attach();
    1908       31812 :     sal_Int32 nLeftB = pB->get_grid_left_attach();
    1909       31812 :     if (nLeftA < nLeftB)
    1910        1484 :         return true;
    1911       30328 :     if (nLeftA > nLeftB)
    1912        4436 :         return false;
    1913             :     //sort into two groups of pack start and pack end
    1914       25892 :     VclPackType ePackA = pA->get_pack_type();
    1915       25892 :     VclPackType ePackB = pB->get_pack_type();
    1916       25892 :     if (ePackA < ePackB)
    1917           0 :         return true;
    1918       25892 :     if (ePackA > ePackB)
    1919        3690 :         return false;
    1920       22202 :     bool bVerticalContainer = m_pBuilder->get_window_packing_data(pA->GetParent()).m_bVerticalOrient;
    1921       22202 :     bool bPackA = pA->get_secondary();
    1922       22202 :     bool bPackB = pB->get_secondary();
    1923       22202 :     if (!bVerticalContainer)
    1924             :     {
    1925             :         //for horizontal boxes group secondaries before primaries
    1926        8124 :         if (bPackA > bPackB)
    1927           0 :             return true;
    1928        8124 :         if (bPackA < bPackB)
    1929           0 :             return false;
    1930             :     }
    1931             :     else
    1932             :     {
    1933             :         //for vertical boxes group secondaries after primaries
    1934       14078 :         if (bPackA < bPackB)
    1935           0 :             return true;
    1936       14078 :         if (bPackA > bPackB)
    1937           0 :             return false;
    1938             :     }
    1939             :     //honour relative box positions with pack group, (numerical order is reversed
    1940             :     //for VCL_PACK_END, they are packed from the end back, but here we need
    1941             :     //them in visual layout order so that tabbing works as expected)
    1942       22202 :     sal_Int32 nPackA = m_pBuilder->get_window_packing_data(pA).m_nPosition;
    1943       22202 :     sal_Int32 nPackB = m_pBuilder->get_window_packing_data(pB).m_nPosition;
    1944       22202 :     if (nPackA < nPackB)
    1945           0 :         return ePackA == VCL_PACK_START;
    1946       22202 :     if (nPackA > nPackB)
    1947       22200 :         return ePackA != VCL_PACK_START;
    1948             :     //sort labels of Frames before body
    1949           2 :     if (pA->GetParent() == pB->GetParent())
    1950             :     {
    1951           2 :         const VclFrame *pFrameParent = dynamic_cast<const VclFrame*>(pA->GetParent());
    1952           2 :         if (pFrameParent)
    1953             :         {
    1954           0 :             const vcl::Window *pLabel = pFrameParent->get_label_widget();
    1955           0 :             int nFramePosA = (pA == pLabel) ? 0 : 1;
    1956           0 :             int nFramePosB = (pB == pLabel) ? 0 : 1;
    1957           0 :             return nFramePosA < nFramePosB;
    1958             :         }
    1959             :     }
    1960           2 :     return false;
    1961             : }
    1962             : 
    1963       67760 : void VclBuilder::handleChild(vcl::Window *pParent, xmlreader::XmlReader &reader)
    1964             : {
    1965       67760 :     vcl::Window *pCurrentChild = NULL;
    1966             : 
    1967       67760 :     xmlreader::Span name;
    1968             :     int nsId;
    1969      135520 :     OString sType, sInternalChild;
    1970             : 
    1971      135520 :     while (reader.nextAttribute(&nsId, &name))
    1972             :     {
    1973           0 :         if (name.equals("type"))
    1974             :         {
    1975           0 :             name = reader.getAttributeValue(false);
    1976           0 :             sType = OString(name.begin, name.length);
    1977             :         }
    1978           0 :         else if (name.equals("internal-child"))
    1979             :         {
    1980           0 :             name = reader.getAttributeValue(false);
    1981           0 :             sInternalChild = OString(name.begin, name.length);
    1982             :         }
    1983             :     }
    1984             : 
    1985       67760 :     if (sType.equals("tab"))
    1986             :     {
    1987           0 :         handleTabChild(pParent, reader);
    1988       67760 :         return;
    1989             :     }
    1990             : 
    1991       67760 :     int nLevel = 1;
    1992             :     while(true)
    1993             :     {
    1994             :         xmlreader::XmlReader::Result res = reader.nextItem(
    1995      209986 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    1996             : 
    1997      209986 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    1998             :         {
    1999      138460 :             if (name.equals("object") || name.equals("placeholder"))
    2000             :             {
    2001       69256 :                 pCurrentChild = handleObject(pParent, reader);
    2002             : 
    2003       69256 :                 bool bObjectInserted = pCurrentChild && pParent != pCurrentChild;
    2004             : 
    2005       69256 :                 if (bObjectInserted)
    2006             :                 {
    2007             :                     //Internal-children default in glade to not having their visible bits set
    2008             :                     //even though they are visible (generally anyway)
    2009       35648 :                     if (!sInternalChild.isEmpty())
    2010           0 :                         pCurrentChild->Show();
    2011             : 
    2012             :                     //Select the first page if it's a notebook
    2013       35648 :                     if (pCurrentChild->GetType() == WINDOW_TABCONTROL)
    2014             :                     {
    2015           0 :                         TabControl *pTabControl = static_cast<TabControl*>(pCurrentChild);
    2016           0 :                         pTabControl->SetCurPageId(pTabControl->GetPageId(0));
    2017             : 
    2018             :                         //To-Do add reorder capability to the TabControl
    2019             :                     }
    2020             :                     else
    2021             :                     {
    2022             :                         // We want to sort labels before contents of frames
    2023             :                         // for key board traversal, especially if there
    2024             :                         // are multiple widgets using the same mnemonic
    2025       35648 :                         if (sType.equals("label"))
    2026             :                         {
    2027           0 :                             if (VclFrame *pFrameParent = dynamic_cast<VclFrame*>(pParent))
    2028           0 :                                 pFrameParent->designate_label(pCurrentChild);
    2029             :                         }
    2030       35648 :                         if (sInternalChild.startsWith("vbox") || sInternalChild.startsWith("messagedialog-vbox"))
    2031             :                         {
    2032           0 :                             if (Dialog *pBoxParent = dynamic_cast<Dialog*>(pParent))
    2033           0 :                                 pBoxParent->set_content_area(static_cast<VclBox*>(pCurrentChild));
    2034             :                         }
    2035       35648 :                         else if (sInternalChild.startsWith("action_area") || sInternalChild.startsWith("messagedialog-action_area"))
    2036             :                         {
    2037           0 :                             vcl::Window *pContentArea = pCurrentChild->GetParent();
    2038             :                             assert(pContentArea && pContentArea->GetType() == WINDOW_CONTAINER);
    2039           0 :                             if (Dialog *pBoxParent = dynamic_cast<Dialog*>(pContentArea ? pContentArea->GetParent() : NULL))
    2040             :                             {
    2041           0 :                                 pBoxParent->set_action_area(static_cast<VclButtonBox*>(pCurrentChild));
    2042             :                             }
    2043             :                         }
    2044             : 
    2045             :                         //To-Do make reorder a virtual in Window, move this foo
    2046             :                         //there and see above
    2047       35648 :                         std::vector<vcl::Window*> aChilds;
    2048       74196 :                         for (vcl::Window* pChild = pCurrentChild->GetWindow(WINDOW_FIRSTCHILD); pChild;
    2049       38548 :                             pChild = pChild->GetWindow(WINDOW_NEXT))
    2050             :                         {
    2051       38548 :                             aChilds.push_back(pChild);
    2052             :                         }
    2053             : 
    2054       35648 :                         bool bIsButtonBox = dynamic_cast<VclButtonBox*>(pCurrentChild) != NULL;
    2055             : 
    2056             :                         //sort child order within parent so that tabbing
    2057             :                         //between controls goes in a visually sensible sequence
    2058       35648 :                         std::stable_sort(aChilds.begin(), aChilds.end(), sortIntoBestTabTraversalOrder(this));
    2059       35648 :                         reorderWithinParent(aChilds, bIsButtonBox);
    2060             :                     }
    2061             :                 }
    2062             :             }
    2063       69204 :             else if (name.equals("packing"))
    2064             :             {
    2065       65438 :                 handlePacking(pCurrentChild, pParent, reader);
    2066             :             }
    2067             :             else
    2068        3766 :                 ++nLevel;
    2069             :         }
    2070             : 
    2071      209986 :         if (res == xmlreader::XmlReader::RESULT_END)
    2072       69272 :             --nLevel;
    2073             : 
    2074      209986 :         if (!nLevel)
    2075       65506 :             break;
    2076             : 
    2077      144480 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2078        2254 :             break;
    2079       67760 :     }
    2080             : }
    2081             : 
    2082       35648 : void VclBuilder::reorderWithinParent(std::vector<vcl::Window*>& rChilds, bool bIsButtonBox)
    2083             : {
    2084       74196 :     for (size_t i = 0; i < rChilds.size(); ++i)
    2085             :     {
    2086       38548 :         reorderWithinParent(*rChilds[i], i);
    2087             : 
    2088       38548 :         if (!bIsButtonBox)
    2089       38548 :             continue;
    2090             : 
    2091             :         //The first member of the group for legacy code needs WB_GROUP set and the
    2092             :         //others not
    2093           0 :         WinBits nBits = rChilds[i]->GetStyle();
    2094           0 :         nBits &= ~WB_GROUP;
    2095           0 :         if (i == 0)
    2096           0 :             nBits |= WB_GROUP;
    2097           0 :         rChilds[i]->SetStyle(nBits);
    2098             :     }
    2099       35648 : }
    2100             : 
    2101       29536 : OUString VclBuilder::getCommandLabel(const OUString& rCommand, const uno::Reference<uno::XComponentContext>& rContext, const OUString& rModuleId)
    2102             : {
    2103       29536 :     if (rCommand.isEmpty())
    2104           0 :         return OUString();
    2105             : 
    2106             :     try
    2107             :     {
    2108       29536 :         uno::Reference<container::XNameAccess> xUICommandLabels;
    2109       36928 :         uno::Reference<container::XNameAccess> xUICommandDescription(frame::theUICommandDescription::get(rContext));
    2110             : 
    2111       29536 :         if ((xUICommandDescription->getByName(rModuleId) >>= xUICommandLabels) && xUICommandLabels.is())
    2112             :         {
    2113       29536 :             uno::Sequence<beans::PropertyValue> aProperties;
    2114       29536 :             if (xUICommandLabels->getByName(rCommand) >>= aProperties)
    2115             :             {
    2116       22144 :                 for ( sal_Int32 i = 0; i < aProperties.getLength(); i++ )
    2117             :                 {
    2118       22144 :                     if (aProperties[i].Name == "Label")
    2119             :                     {
    2120       22144 :                         OUString aLabel;
    2121       22144 :                         if (aProperties[i].Value >>= aLabel)
    2122       22144 :                             return aLabel;
    2123             :                     }
    2124             :                 }
    2125        7392 :             }
    2126        7392 :         }
    2127             :     }
    2128        7392 :     catch (uno::Exception&)
    2129             :     {
    2130             :     }
    2131             : 
    2132        7392 :     return OUString();
    2133             : }
    2134             : 
    2135       29536 : Image VclBuilder::getCommandImage(const OUString& rCommand, bool bLarge,
    2136             :         const uno::Reference<uno::XComponentContext>& rContext, const uno::Reference<frame::XFrame>& rFrame,
    2137             :         const OUString& rModuleId)
    2138             : {
    2139       29536 :     if (rCommand.isEmpty())
    2140           0 :         return Image();
    2141             : 
    2142       29536 :     sal_Int16 nImageType(ui::ImageType::COLOR_NORMAL | ui::ImageType::SIZE_DEFAULT);
    2143       29536 :     if (bLarge)
    2144           0 :         nImageType |= ui::ImageType::SIZE_LARGE;
    2145             : 
    2146             :     try
    2147             :     {
    2148       29536 :         uno::Reference<frame::XController> xController(rFrame->getController());
    2149       59072 :         uno::Reference<frame::XModel> xModel(xController->getModel());
    2150             : 
    2151       59072 :         uno::Reference<ui::XUIConfigurationManagerSupplier> xSupplier(xModel, uno::UNO_QUERY);
    2152       29536 :         if (xSupplier.is())
    2153             :         {
    2154       29536 :             uno::Reference<ui::XUIConfigurationManager> xDocUICfgMgr(xSupplier->getUIConfigurationManager(), uno::UNO_QUERY);
    2155       59072 :             uno::Reference<ui::XImageManager> xDocImgMgr(xDocUICfgMgr->getImageManager(), uno::UNO_QUERY);
    2156             : 
    2157       59072 :             uno::Sequence< uno::Reference<graphic::XGraphic> > aGraphicSeq;
    2158       59072 :             uno::Sequence<OUString> aImageCmdSeq(1);
    2159       29536 :             aImageCmdSeq[0] = rCommand;
    2160             : 
    2161       29536 :             aGraphicSeq = xDocImgMgr->getImages( nImageType, aImageCmdSeq );
    2162       59072 :             uno::Reference<graphic::XGraphic> xGraphic = aGraphicSeq[0];
    2163       59072 :             Image aImage(xGraphic);
    2164             : 
    2165       29536 :             if (!!aImage)
    2166       29536 :                 return aImage;
    2167       29536 :         }
    2168             :     }
    2169           0 :     catch (uno::Exception&)
    2170             :     {
    2171             :     }
    2172             : 
    2173             :     try {
    2174       29536 :         uno::Reference<ui::XModuleUIConfigurationManagerSupplier> xModuleCfgMgrSupplier(ui::theModuleUIConfigurationManagerSupplier::get(rContext));
    2175       59072 :         uno::Reference<ui::XUIConfigurationManager> xUICfgMgr(xModuleCfgMgrSupplier->getUIConfigurationManager(rModuleId));
    2176             : 
    2177       59072 :         uno::Sequence< uno::Reference<graphic::XGraphic> > aGraphicSeq;
    2178       59072 :         uno::Reference<ui::XImageManager> xModuleImageManager(xUICfgMgr->getImageManager(), uno::UNO_QUERY);
    2179             : 
    2180       59072 :         uno::Sequence<OUString> aImageCmdSeq(1);
    2181       29536 :         aImageCmdSeq[0] = rCommand;
    2182             : 
    2183       29536 :         aGraphicSeq = xModuleImageManager->getImages(nImageType, aImageCmdSeq);
    2184             : 
    2185       59072 :         uno::Reference<graphic::XGraphic> xGraphic(aGraphicSeq[0]);
    2186             : 
    2187       59072 :         return Image(xGraphic);
    2188             :     }
    2189           0 :     catch (uno::Exception&)
    2190             :     {
    2191             :     }
    2192             : 
    2193           0 :     return Image();
    2194             : }
    2195             : 
    2196           0 : void VclBuilder::collectPangoAttribute(xmlreader::XmlReader &reader, stringmap &rMap)
    2197             : {
    2198           0 :     xmlreader::Span span;
    2199             :     int nsId;
    2200             : 
    2201           0 :     OString sProperty;
    2202           0 :     OString sValue;
    2203             : 
    2204           0 :     while (reader.nextAttribute(&nsId, &span))
    2205             :     {
    2206           0 :         if (span.equals("name"))
    2207             :         {
    2208           0 :             span = reader.getAttributeValue(false);
    2209           0 :             sProperty = OString(span.begin, span.length);
    2210             :         }
    2211           0 :         else if (span.equals("value"))
    2212             :         {
    2213           0 :             span = reader.getAttributeValue(false);
    2214           0 :             sValue = OString(span.begin, span.length);
    2215             :         }
    2216             :     }
    2217             : 
    2218           0 :     if (!sProperty.isEmpty())
    2219           0 :         rMap[sProperty] = sValue;
    2220           0 : }
    2221             : 
    2222           0 : void VclBuilder::collectAtkAttribute(xmlreader::XmlReader &reader, stringmap &rMap)
    2223             : {
    2224           0 :     xmlreader::Span span;
    2225             :     int nsId;
    2226             : 
    2227           0 :     OString sProperty;
    2228           0 :     OString sValue;
    2229             : 
    2230           0 :     while (reader.nextAttribute(&nsId, &span))
    2231             :     {
    2232           0 :         if (span.equals("type"))
    2233             :         {
    2234           0 :             span = reader.getAttributeValue(false);
    2235           0 :             sProperty = OString(span.begin, span.length);
    2236             :         }
    2237           0 :         else if (span.equals("target"))
    2238             :         {
    2239           0 :             span = reader.getAttributeValue(false);
    2240           0 :             sValue = OString(span.begin, span.length);
    2241           0 :             sal_Int32 nDelim = sValue.indexOf(':');
    2242           0 :             if (nDelim != -1)
    2243           0 :                 sValue = sValue.copy(0, nDelim);
    2244             :         }
    2245             :     }
    2246             : 
    2247           0 :     if (!sProperty.isEmpty())
    2248           0 :         rMap[sProperty] = sValue;
    2249           0 : }
    2250             : 
    2251         738 : void VclBuilder::handleAdjustment(const OString &rID, stringmap &rProperties)
    2252             : {
    2253         738 :     m_pParserState->m_aAdjustments[rID] = rProperties;
    2254         738 : }
    2255             : 
    2256           0 : void VclBuilder::handleTextBuffer(const OString &rID, stringmap &rProperties)
    2257             : {
    2258           0 :     m_pParserState->m_aTextBuffers[rID] = rProperties;
    2259           0 : }
    2260             : 
    2261           0 : void VclBuilder::handleRow(xmlreader::XmlReader &reader, const OString &rID, sal_Int32 nRowIndex)
    2262             : {
    2263           0 :     int nLevel = 1;
    2264             : 
    2265           0 :     ListStore::row aRow;
    2266             : 
    2267             :     while(true)
    2268             :     {
    2269           0 :         xmlreader::Span name;
    2270             :         int nsId;
    2271             : 
    2272             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2273           0 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2274             : 
    2275           0 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2276           0 :             break;
    2277             : 
    2278           0 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2279             :         {
    2280           0 :             ++nLevel;
    2281           0 :             if (name.equals("col"))
    2282             :             {
    2283           0 :                 bool bTranslated = false;
    2284           0 :                 OString sValue;
    2285           0 :                 sal_uInt32 nId = 0;
    2286             : 
    2287           0 :                 while (reader.nextAttribute(&nsId, &name))
    2288             :                 {
    2289           0 :                     if (name.equals("id"))
    2290             :                     {
    2291           0 :                         name = reader.getAttributeValue(false);
    2292           0 :                         nId = OString(name.begin, name.length).toInt32();
    2293             :                     }
    2294           0 :                     else if (nId == 0 && name.equals("translatable") && reader.getAttributeValue(false).equals("yes"))
    2295             :                     {
    2296           0 :                         sValue = getTranslation(rID, OString::number(nRowIndex));
    2297           0 :                         bTranslated = !sValue.isEmpty();
    2298             :                     }
    2299             :                 }
    2300             : 
    2301             :                 reader.nextItem(
    2302           0 :                     xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
    2303             : 
    2304           0 :                 if (!bTranslated)
    2305           0 :                     sValue = OString(name.begin, name.length);
    2306             : 
    2307           0 :                 if (aRow.size() < nId+1)
    2308           0 :                     aRow.resize(nId+1);
    2309           0 :                 aRow[nId] = sValue;
    2310             :             }
    2311             :         }
    2312             : 
    2313           0 :         if (res == xmlreader::XmlReader::RESULT_END)
    2314             :         {
    2315           0 :             --nLevel;
    2316             :         }
    2317             : 
    2318           0 :         if (!nLevel)
    2319           0 :             break;
    2320             :     }
    2321             : 
    2322           0 :     m_pParserState->m_aModels[rID].m_aEntries.push_back(aRow);
    2323           0 : }
    2324             : 
    2325           0 : void VclBuilder::handleListStore(xmlreader::XmlReader &reader, const OString &rID)
    2326             : {
    2327           0 :     int nLevel = 1;
    2328           0 :     sal_Int32 nRowIndex = 0;
    2329             : 
    2330             :     while(true)
    2331             :     {
    2332           0 :         xmlreader::Span name;
    2333             :         int nsId;
    2334             : 
    2335             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2336           0 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2337             : 
    2338           0 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2339           0 :             break;
    2340             : 
    2341           0 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2342             :         {
    2343           0 :             if (name.equals("row"))
    2344           0 :                 handleRow(reader, rID, nRowIndex++);
    2345             :             else
    2346           0 :                 ++nLevel;
    2347             :         }
    2348             : 
    2349           0 :         if (res == xmlreader::XmlReader::RESULT_END)
    2350             :         {
    2351           0 :             --nLevel;
    2352             :         }
    2353             : 
    2354           0 :         if (!nLevel)
    2355           0 :             break;
    2356           0 :     }
    2357           0 : }
    2358             : 
    2359           0 : void VclBuilder::handleAtkObject(xmlreader::XmlReader &reader, const OString &rID, vcl::Window *pWindow)
    2360             : {
    2361             :     assert(pWindow);
    2362             : 
    2363           0 :     int nLevel = 1;
    2364             : 
    2365           0 :     stringmap aProperties;
    2366             : 
    2367             :     while(true)
    2368             :     {
    2369           0 :         xmlreader::Span name;
    2370             :         int nsId;
    2371             : 
    2372             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2373           0 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2374             : 
    2375           0 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2376           0 :             break;
    2377             : 
    2378           0 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2379             :         {
    2380           0 :             ++nLevel;
    2381           0 :             if (name.equals("property"))
    2382           0 :                 collectProperty(reader, rID, aProperties);
    2383             :         }
    2384             : 
    2385           0 :         if (res == xmlreader::XmlReader::RESULT_END)
    2386             :         {
    2387           0 :             --nLevel;
    2388             :         }
    2389             : 
    2390           0 :         if (!nLevel)
    2391           0 :             break;
    2392             :     }
    2393             : 
    2394           0 :     for (stringmap::iterator aI = aProperties.begin(), aEnd = aProperties.end(); aI != aEnd; ++aI)
    2395             :     {
    2396           0 :         const OString &rKey = aI->first;
    2397           0 :         const OString &rValue = aI->second;
    2398             : 
    2399           0 :         if (rKey.match("AtkObject::"))
    2400           0 :             pWindow->set_property(rKey.copy(RTL_CONSTASCII_LENGTH("AtkObject::")), rValue);
    2401             :         else
    2402             :             SAL_WARN("vcl.layout", "unhandled atk prop: " << rKey.getStr());
    2403           0 :     }
    2404           0 : }
    2405             : 
    2406           0 : std::vector<OString> VclBuilder::handleItems(xmlreader::XmlReader &reader, const OString &rID)
    2407             : {
    2408           0 :     int nLevel = 1;
    2409             : 
    2410           0 :     std::vector<OString> aItems;
    2411           0 :     sal_Int32 nItemIndex = 0;
    2412             : 
    2413             :     while(true)
    2414             :     {
    2415           0 :         xmlreader::Span name;
    2416             :         int nsId;
    2417             : 
    2418             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2419           0 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2420             : 
    2421           0 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2422           0 :             break;
    2423             : 
    2424           0 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2425             :         {
    2426           0 :             ++nLevel;
    2427           0 :             if (name.equals("item"))
    2428             :             {
    2429           0 :                 bool bTranslated = false;
    2430           0 :                 OString sValue;
    2431             : 
    2432           0 :                 while (reader.nextAttribute(&nsId, &name))
    2433             :                 {
    2434           0 :                     if (name.equals("translatable") && reader.getAttributeValue(false).equals("yes"))
    2435             :                     {
    2436           0 :                         sValue = getTranslation(rID, OString::number(nItemIndex));
    2437           0 :                         bTranslated = !sValue.isEmpty();
    2438             :                     }
    2439             :                 }
    2440             : 
    2441             :                 reader.nextItem(
    2442           0 :                     xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
    2443             : 
    2444           0 :                 if (!bTranslated)
    2445           0 :                     sValue = OString(name.begin, name.length);
    2446             : 
    2447           0 :                 if (m_pStringReplace)
    2448             :                 {
    2449           0 :                     OUString sTmp = (*m_pStringReplace)(OStringToOUString(sValue, RTL_TEXTENCODING_UTF8));
    2450           0 :                     sValue = OUStringToOString(sTmp, RTL_TEXTENCODING_UTF8);
    2451             :                 }
    2452             : 
    2453           0 :                 aItems.push_back(sValue);
    2454           0 :                 ++nItemIndex;
    2455             :             }
    2456             :         }
    2457             : 
    2458           0 :         if (res == xmlreader::XmlReader::RESULT_END)
    2459             :         {
    2460           0 :             --nLevel;
    2461             :         }
    2462             : 
    2463           0 :         if (!nLevel)
    2464           0 :             break;
    2465             :     }
    2466             : 
    2467           0 :     return aItems;
    2468             : }
    2469             : 
    2470           2 : void VclBuilder::handleMenu(xmlreader::XmlReader &reader, const OString &rID)
    2471             : {
    2472           2 :     PopupMenu *pCurrentMenu = new PopupMenu;
    2473             : 
    2474           2 :     int nLevel = 1;
    2475             : 
    2476           2 :     stringmap aProperties;
    2477             : 
    2478             :     while(true)
    2479             :     {
    2480          22 :         xmlreader::Span name;
    2481             :         int nsId;
    2482             : 
    2483             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2484          22 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2485             : 
    2486          22 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2487           2 :             break;
    2488             : 
    2489          22 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2490             :         {
    2491          16 :             if (name.equals("child"))
    2492             :             {
    2493          12 :                 handleMenuChild(pCurrentMenu, reader);
    2494             :             }
    2495             :             else
    2496             :             {
    2497           4 :                 ++nLevel;
    2498           4 :                 if (name.equals("property"))
    2499           4 :                     collectProperty(reader, rID, aProperties);
    2500             :             }
    2501             :         }
    2502             : 
    2503          22 :         if (res == xmlreader::XmlReader::RESULT_END)
    2504             :         {
    2505           6 :             --nLevel;
    2506             :         }
    2507             : 
    2508          22 :         if (!nLevel)
    2509           2 :             break;
    2510             :     }
    2511             : 
    2512           2 :     m_aMenus.push_back(MenuAndId(rID, pCurrentMenu));
    2513           2 : }
    2514             : 
    2515          12 : void VclBuilder::handleMenuChild(PopupMenu *pParent, xmlreader::XmlReader &reader)
    2516             : {
    2517          12 :     xmlreader::Span name;
    2518             :     int nsId;
    2519             : 
    2520          12 :     int nLevel = 1;
    2521             :     while(true)
    2522             :     {
    2523             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2524          24 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2525             : 
    2526          24 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2527             :         {
    2528          12 :             if (name.equals("object") || name.equals("placeholder"))
    2529             :             {
    2530          12 :                 handleMenuObject(pParent, reader);
    2531             :             }
    2532             :             else
    2533           0 :                 ++nLevel;
    2534             :         }
    2535             : 
    2536          24 :         if (res == xmlreader::XmlReader::RESULT_END)
    2537          12 :             --nLevel;
    2538             : 
    2539          24 :         if (!nLevel)
    2540          12 :             break;
    2541             : 
    2542          12 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2543           0 :             break;
    2544          12 :     }
    2545          12 : }
    2546             : 
    2547          12 : void VclBuilder::handleMenuObject(PopupMenu *pParent, xmlreader::XmlReader &reader)
    2548             : {
    2549          12 :     OString sClass;
    2550          24 :     OString sID;
    2551          24 :     OString sCustomProperty;
    2552             : 
    2553          12 :     xmlreader::Span name;
    2554             :     int nsId;
    2555             : 
    2556          48 :     while (reader.nextAttribute(&nsId, &name))
    2557             :     {
    2558          24 :         if (name.equals("class"))
    2559             :         {
    2560          12 :             name = reader.getAttributeValue(false);
    2561          12 :             sClass = OString(name.begin, name.length);
    2562             :         }
    2563          12 :         else if (name.equals("id"))
    2564             :         {
    2565          12 :             name = reader.getAttributeValue(false);
    2566          12 :             sID = OString(name.begin, name.length);
    2567          12 :             sal_Int32 nDelim = sID.indexOf(':');
    2568          12 :             if (nDelim != -1)
    2569             :             {
    2570           0 :                 sCustomProperty = sID.copy(nDelim+1);
    2571           0 :                 sID = sID.copy(0, nDelim);
    2572             :             }
    2573             :         }
    2574             :     }
    2575             : 
    2576          12 :     int nLevel = 1;
    2577             : 
    2578          24 :     stringmap aProperties, aAccelerators;
    2579             : 
    2580          12 :     if (!sCustomProperty.isEmpty())
    2581           0 :         aProperties[OString("customproperty")] = sCustomProperty;
    2582             : 
    2583             :     while(true)
    2584             :     {
    2585             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2586          80 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2587             : 
    2588          80 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2589           0 :             break;
    2590             : 
    2591          80 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2592             :         {
    2593          34 :             ++nLevel;
    2594          34 :             if (name.equals("property"))
    2595          34 :                 collectProperty(reader, sID, aProperties);
    2596           0 :             else if (name.equals("accelerator"))
    2597           0 :                 collectAccelerator(reader, aAccelerators);
    2598             :         }
    2599             : 
    2600          80 :         if (res == xmlreader::XmlReader::RESULT_END)
    2601             :         {
    2602          46 :             --nLevel;
    2603             :         }
    2604             : 
    2605          80 :         if (!nLevel)
    2606          12 :             break;
    2607             :     }
    2608             : 
    2609          24 :     insertMenuObject(pParent, sClass, sID, aProperties, aAccelerators);
    2610          12 : }
    2611             : 
    2612         738 : void VclBuilder::handleSizeGroup(xmlreader::XmlReader &reader, const OString &rID)
    2613             : {
    2614         738 :     m_pParserState->m_aSizeGroups.push_back(SizeGroup(rID));
    2615         738 :     SizeGroup &rSizeGroup = m_pParserState->m_aSizeGroups.back();
    2616             : 
    2617         738 :     int nLevel = 1;
    2618             : 
    2619             :     while(true)
    2620             :     {
    2621       12546 :         xmlreader::Span name;
    2622             :         int nsId;
    2623             : 
    2624             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2625       12546 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2626             : 
    2627       12546 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2628         738 :             break;
    2629             : 
    2630       12546 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2631             :         {
    2632        5904 :             ++nLevel;
    2633        5904 :             if (name.equals("widget"))
    2634             :             {
    2635       13284 :                 while (reader.nextAttribute(&nsId, &name))
    2636             :                 {
    2637        4428 :                     if (name.equals("name"))
    2638             :                     {
    2639        4428 :                         name = reader.getAttributeValue(false);
    2640        4428 :                         OString sWidget = OString(name.begin, name.length);
    2641        4428 :                         sal_Int32 nDelim = sWidget.indexOf(':');
    2642        4428 :                         if (nDelim != -1)
    2643           0 :                             sWidget = sWidget.copy(0, nDelim);
    2644        4428 :                         rSizeGroup.m_aWidgets.push_back(sWidget);
    2645             :                     }
    2646             :                 }
    2647             :             }
    2648             :             else
    2649             :             {
    2650        1476 :                 if (name.equals("property"))
    2651         738 :                     collectProperty(reader, rID, rSizeGroup.m_aProperties);
    2652             :             }
    2653             :         }
    2654             : 
    2655       12546 :         if (res == xmlreader::XmlReader::RESULT_END)
    2656             :         {
    2657        6642 :             --nLevel;
    2658             :         }
    2659             : 
    2660       12546 :         if (!nLevel)
    2661         738 :             break;
    2662       11808 :     }
    2663         738 : }
    2664             : 
    2665        5234 : OString VclBuilder::convertMnemonicMarkup(const OString &rIn)
    2666             : {
    2667        5234 :     OStringBuffer aRet(rIn);
    2668       20694 :     for (sal_Int32 nI = 0; nI < aRet.getLength(); ++nI)
    2669             :     {
    2670       15460 :         if (aRet[nI] == '_' && nI+1 < aRet.getLength())
    2671             :         {
    2672        1498 :             if (aRet[nI+1] != '_')
    2673        1498 :                 aRet[nI] = MNEMONIC_CHAR;
    2674             :             else
    2675           0 :                 aRet.remove(nI, 1);
    2676        1498 :             ++nI;
    2677             :         }
    2678             :     }
    2679        5234 :     return aRet.makeStringAndClear();
    2680             : }
    2681             : 
    2682             : namespace
    2683             : {
    2684           0 :     vcl::KeyCode makeKeyCode(const OString &rKey)
    2685             :     {
    2686           0 :         if (rKey == "Insert")
    2687           0 :             return vcl::KeyCode(KEY_INSERT);
    2688           0 :         else if (rKey == "Delete")
    2689           0 :             return vcl::KeyCode(KEY_DELETE);
    2690             : 
    2691             :         assert (rKey.getLength() == 1);
    2692           0 :         sal_Char cChar = rKey.toChar();
    2693             : 
    2694           0 :         if (cChar >= 'a' && cChar <= 'z')
    2695           0 :             return vcl::KeyCode(KEY_A + (cChar - 'a'));
    2696           0 :         else if (cChar >= 'A' && cChar <= 'Z')
    2697           0 :             return vcl::KeyCode(KEY_A + (cChar - 'A'));
    2698           0 :         else if (cChar >= '0' && cChar <= '9')
    2699           0 :             return vcl::KeyCode(KEY_0 + (cChar - 'A'));
    2700             : 
    2701           0 :         return vcl::KeyCode(cChar);
    2702             :     }
    2703             : }
    2704             : 
    2705          12 : void VclBuilder::insertMenuObject(PopupMenu *pParent, const OString &rClass, const OString &rID,
    2706             :     stringmap &rProps, stringmap &rAccels)
    2707             : {
    2708          12 :     sal_uInt16 nOldCount = pParent->GetItemCount();
    2709          12 :     sal_uInt16 nNewId = nOldCount + 1;
    2710             : 
    2711          12 :     if (rClass == "GtkMenuItem")
    2712             :     {
    2713          10 :         OUString sLabel(OStringToOUString(convertMnemonicMarkup(extractLabel(rProps)), RTL_TEXTENCODING_UTF8));
    2714          10 :         pParent->InsertItem(nNewId, sLabel, MenuItemBits::TEXT, rID);
    2715             :     }
    2716           2 :     else if (rClass == "GtkSeparatorMenuItem")
    2717             :     {
    2718           2 :         pParent->InsertSeparator(rID);
    2719             :     }
    2720             : 
    2721             :     SAL_WARN_IF(nOldCount == pParent->GetItemCount(), "vcl.layout", "probably need to implement " << rClass.getStr());
    2722             : 
    2723          12 :     if (nOldCount != pParent->GetItemCount())
    2724             :     {
    2725          12 :         pParent->SetHelpId(nNewId, m_sHelpRoot + rID);
    2726             : 
    2727          36 :         for (stringmap::iterator aI = rProps.begin(), aEnd = rProps.end(); aI != aEnd; ++aI)
    2728             :         {
    2729          24 :             const OString &rKey = aI->first;
    2730          24 :             const OString &rValue = aI->second;
    2731             : 
    2732          24 :             if (rKey == "tooltip-markup")
    2733           0 :                 pParent->SetTipHelpText(nNewId, OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
    2734          24 :             else if (rKey == "tooltip-text")
    2735           0 :                 pParent->SetTipHelpText(nNewId, OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
    2736          24 :             else if (rKey == "visible")
    2737          12 :                 pParent->ShowItem(nNewId, toBool(rValue));
    2738          12 :             else if (rKey == "has-default" && toBool(rValue))
    2739           0 :                 pParent->SetSelectedEntry(nNewId);
    2740             :             else
    2741             :                 SAL_INFO("vcl.layout", "unhandled property: " << rKey.getStr());
    2742             :         }
    2743             : 
    2744          12 :         for (stringmap::iterator aI = rAccels.begin(), aEnd = rAccels.end(); aI != aEnd; ++aI)
    2745             :         {
    2746           0 :             const OString &rSignal = aI->first;
    2747           0 :             const OString &rValue = aI->second;
    2748             : 
    2749           0 :             if (rSignal == "activate")
    2750           0 :                 pParent->SetAccelKey(nNewId, makeKeyCode(rValue));
    2751             :             else
    2752             :                 SAL_INFO("vcl.layout", "unhandled accelerator for: " << rSignal.getStr());
    2753             :         }
    2754             :     }
    2755             : 
    2756          12 :     rProps.clear();
    2757          12 : }
    2758             : 
    2759       69256 : vcl::Window* VclBuilder::handleObject(vcl::Window *pParent, xmlreader::XmlReader &reader)
    2760             : {
    2761       69256 :     OString sClass;
    2762      138512 :     OString sID;
    2763      138512 :     OString sCustomProperty;
    2764             : 
    2765       69256 :     xmlreader::Span name;
    2766             :     int nsId;
    2767             : 
    2768      276956 :     while (reader.nextAttribute(&nsId, &name))
    2769             :     {
    2770      138444 :         if (name.equals("class"))
    2771             :         {
    2772       69222 :             name = reader.getAttributeValue(false);
    2773       69222 :             sClass = OString(name.begin, name.length);
    2774             :         }
    2775       69222 :         else if (name.equals("id"))
    2776             :         {
    2777       69222 :             name = reader.getAttributeValue(false);
    2778       69222 :             sID = OString(name.begin, name.length);
    2779       69222 :             sal_Int32 nDelim = sID.indexOf(':');
    2780       69222 :             if (nDelim != -1)
    2781             :             {
    2782           2 :                 sCustomProperty = sID.copy(nDelim+1);
    2783           2 :                 sID = sID.copy(0, nDelim);
    2784             :             }
    2785             :         }
    2786             :     }
    2787             : 
    2788       69256 :     if (sClass == "GtkListStore")
    2789             :     {
    2790           0 :         handleListStore(reader, sID);
    2791           0 :         return NULL;
    2792             :     }
    2793       69256 :     else if (sClass == "GtkMenu")
    2794             :     {
    2795           2 :         handleMenu(reader, sID);
    2796           2 :         return NULL;
    2797             :     }
    2798       69254 :     else if (sClass == "GtkSizeGroup")
    2799             :     {
    2800         738 :         handleSizeGroup(reader, sID);
    2801         738 :         return NULL;
    2802             :     }
    2803       68516 :     else if (sClass == "AtkObject")
    2804             :     {
    2805           0 :         handleAtkObject(reader, sID, pParent);
    2806           0 :         return NULL;
    2807             :     }
    2808             : 
    2809       68516 :     int nLevel = 1;
    2810             : 
    2811      137032 :     stringmap aProperties, aPangoAttributes, aAtkAttributes;
    2812      137032 :     std::vector<OString> aItems;
    2813             : 
    2814       68516 :     if (!sCustomProperty.isEmpty())
    2815           2 :         aProperties[OString("customproperty")] = sCustomProperty;
    2816             : 
    2817       68516 :     vcl::Window *pCurrentChild = NULL;
    2818             :     while(true)
    2819             :     {
    2820             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2821      819658 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2822             : 
    2823      819658 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2824           0 :             break;
    2825             : 
    2826      819658 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2827             :         {
    2828      408324 :             if (name.equals("child"))
    2829             :             {
    2830       65506 :                 if (!pCurrentChild)
    2831             :                 {
    2832             :                     pCurrentChild = insertObject(pParent, sClass, sID,
    2833       28962 :                         aProperties, aPangoAttributes, aAtkAttributes, aItems);
    2834             :                 }
    2835       65506 :                 handleChild(pCurrentChild, reader);
    2836             :             }
    2837      342818 :             else if (name.equals("items"))
    2838           0 :                 aItems = handleItems(reader, sID);
    2839             :             else
    2840             :             {
    2841      342818 :                 ++nLevel;
    2842      342818 :                 if (name.equals("property"))
    2843      342818 :                     collectProperty(reader, sID, aProperties);
    2844           0 :                 else if (name.equals("attribute"))
    2845           0 :                     collectPangoAttribute(reader, aPangoAttributes);
    2846           0 :                 else if (name.equals("relation"))
    2847           0 :                     collectAtkAttribute(reader, aAtkAttributes);
    2848           0 :                 else if (name.equals("action-widget"))
    2849           0 :                     handleActionWidget(reader);
    2850             :             }
    2851             :         }
    2852             : 
    2853      819658 :         if (res == xmlreader::XmlReader::RESULT_END)
    2854             :         {
    2855      411334 :             --nLevel;
    2856             :         }
    2857             : 
    2858      819658 :         if (!nLevel)
    2859       68516 :             break;
    2860             :     }
    2861             : 
    2862       68516 :     if (sClass == "GtkAdjustment")
    2863             :     {
    2864         738 :         handleAdjustment(sID, aProperties);
    2865         738 :         return NULL;
    2866             :     }
    2867       67778 :     else if (sClass == "GtkTextBuffer")
    2868             :     {
    2869           0 :         handleTextBuffer(sID, aProperties);
    2870           0 :         return NULL;
    2871             :     }
    2872             : 
    2873       67778 :     if (!pCurrentChild)
    2874             :     {
    2875             :         pCurrentChild = insertObject(pParent, sClass, sID, aProperties,
    2876       38816 :             aPangoAttributes, aAtkAttributes, aItems);
    2877             :     }
    2878             : 
    2879      137034 :     return pCurrentChild;
    2880             : }
    2881             : 
    2882       65438 : void VclBuilder::handlePacking(vcl::Window *pCurrent, vcl::Window *pParent, xmlreader::XmlReader &reader)
    2883             : {
    2884       65438 :     xmlreader::Span name;
    2885             :     int nsId;
    2886             : 
    2887       65438 :     int nLevel = 1;
    2888             : 
    2889             :     while(true)
    2890             :     {
    2891             :         xmlreader::XmlReader::Result res = reader.nextItem(
    2892      423718 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
    2893             : 
    2894      423718 :         if (res == xmlreader::XmlReader::RESULT_DONE)
    2895           0 :             break;
    2896             : 
    2897      423718 :         if (res == xmlreader::XmlReader::RESULT_BEGIN)
    2898             :         {
    2899      179140 :             ++nLevel;
    2900      179140 :             if (name.equals("property"))
    2901      179140 :                 applyPackingProperty(pCurrent, pParent, reader);
    2902             :         }
    2903             : 
    2904      423718 :         if (res == xmlreader::XmlReader::RESULT_END)
    2905             :         {
    2906      244578 :             --nLevel;
    2907             :         }
    2908             : 
    2909      423718 :         if (!nLevel)
    2910       65438 :             break;
    2911      358280 :     }
    2912       65438 : }
    2913             : 
    2914      179140 : void VclBuilder::applyPackingProperty(vcl::Window *pCurrent,
    2915             :     vcl::Window *pParent,
    2916             :     xmlreader::XmlReader &reader)
    2917             : {
    2918      179140 :     if (!pCurrent)
    2919      179140 :         return;
    2920             : 
    2921             :     //ToolBoxItems are not true widgets just elements
    2922             :     //of the ToolBox itself
    2923      179140 :     ToolBox *pToolBoxParent = NULL;
    2924      179140 :     if (pCurrent == pParent)
    2925       59684 :         pToolBoxParent = dynamic_cast<ToolBox*>(pParent);
    2926             : 
    2927      179140 :     xmlreader::Span name;
    2928             :     int nsId;
    2929             : 
    2930      179140 :     if (pCurrent->GetType() == WINDOW_SCROLLWINDOW)
    2931             :     {
    2932           0 :         std::map<vcl::Window*, vcl::Window*>::iterator aFind = m_pParserState->m_aRedundantParentWidgets.find(pCurrent);
    2933           0 :         if (aFind != m_pParserState->m_aRedundantParentWidgets.end())
    2934             :         {
    2935           0 :             pCurrent = aFind->second;
    2936             :             assert(pCurrent);
    2937             :         }
    2938             :     }
    2939             : 
    2940      537420 :     while (reader.nextAttribute(&nsId, &name))
    2941             :     {
    2942      179140 :         if (name.equals("name"))
    2943             :         {
    2944      179140 :             name = reader.getAttributeValue(false);
    2945      179140 :             OString sKey(name.begin, name.length);
    2946      179140 :             sKey = sKey.replace('_', '-');
    2947             :             reader.nextItem(
    2948      179140 :                 xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
    2949      271978 :             OString sValue(name.begin, name.length);
    2950             : 
    2951      179140 :             if (sKey == "expand")
    2952             :             {
    2953       56460 :                 bool bTrue = (!sValue.isEmpty() && (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1'));
    2954       56460 :                 if (pToolBoxParent)
    2955       29842 :                     pToolBoxParent->SetItemExpand(m_pParserState->m_nLastToolbarId, bTrue);
    2956             :                 else
    2957       26618 :                     pCurrent->set_expand(bTrue);
    2958       56460 :                 continue;
    2959             :             }
    2960             : 
    2961      122680 :             if (pToolBoxParent)
    2962       29842 :                 continue;
    2963             : 
    2964       92838 :             if (sKey == "fill")
    2965             :             {
    2966       26618 :                 bool bTrue = (!sValue.isEmpty() && (sValue[0] == 't' || sValue[0] == 'T' || sValue[0] == '1'));
    2967       26618 :                 pCurrent->set_fill(bTrue);
    2968             :             }
    2969       66220 :             else if (sKey == "pack-type")
    2970             :             {
    2971        3690 :                 VclPackType ePackType = (!sValue.isEmpty() && (sValue[0] == 'e' || sValue[0] == 'E')) ? VCL_PACK_END : VCL_PACK_START;
    2972        3690 :                 pCurrent->set_pack_type(ePackType);
    2973             :             }
    2974       62530 :             else if (sKey == "left-attach")
    2975             :             {
    2976        8978 :                 pCurrent->set_grid_left_attach(sValue.toInt32());
    2977             :             }
    2978       53552 :             else if (sKey == "top-attach")
    2979             :             {
    2980        8978 :                 pCurrent->set_grid_top_attach(sValue.toInt32());
    2981             :             }
    2982       44574 :             else if (sKey == "width")
    2983             :             {
    2984        8978 :                 pCurrent->set_grid_width(sValue.toInt32());
    2985             :             }
    2986       35596 :             else if (sKey == "height")
    2987             :             {
    2988        8978 :                 pCurrent->set_grid_height(sValue.toInt32());
    2989             :             }
    2990       26618 :             else if (sKey == "padding")
    2991             :             {
    2992           0 :                 pCurrent->set_padding(sValue.toInt32());
    2993             :             }
    2994       26618 :             else if (sKey == "position")
    2995             :             {
    2996       26618 :                 set_window_packing_position(pCurrent, sValue.toInt32());
    2997             :             }
    2998           0 :             else if (sKey == "secondary")
    2999             :             {
    3000           0 :                 pCurrent->set_secondary(toBool(sValue));
    3001             :             }
    3002           0 :             else if (sKey == "non-homogeneous")
    3003             :             {
    3004           0 :                 pCurrent->set_non_homogeneous(toBool(sValue));
    3005             :             }
    3006           0 :             else if (sKey == "homogeneous")
    3007             :             {
    3008           0 :                 pCurrent->set_non_homogeneous(!toBool(sValue));
    3009             :             }
    3010             :             else
    3011             :             {
    3012             :                 SAL_WARN("vcl.layout", "unknown packing: " << sKey.getStr());
    3013       92838 :             }
    3014             :         }
    3015             :     }
    3016             : }
    3017             : 
    3018       22530 : OString VclBuilder::getTranslation(const OString &rID, const OString &rProperty) const
    3019             : {
    3020       22530 :     Translations::const_iterator aWidgetFind = m_pParserState->m_aTranslations.find(rID);
    3021       22530 :     if (aWidgetFind != m_pParserState->m_aTranslations.end())
    3022             :     {
    3023           0 :         const WidgetTranslations &rWidgetTranslations = aWidgetFind->second;
    3024           0 :         WidgetTranslations::const_iterator aPropertyFind = rWidgetTranslations.find(rProperty);
    3025           0 :         if (aPropertyFind != rWidgetTranslations.end())
    3026           0 :             return aPropertyFind->second;
    3027             :     }
    3028       22530 :     return OString();
    3029             : }
    3030             : 
    3031      343594 : void VclBuilder::collectProperty(xmlreader::XmlReader &reader, const OString &rID, stringmap &rMap)
    3032             : {
    3033      343594 :     xmlreader::Span name;
    3034             :     int nsId;
    3035             : 
    3036      343594 :     OString sProperty;
    3037      687188 :     OString sValue;
    3038             : 
    3039      343594 :     bool bTranslated = false;
    3040             : 
    3041     1059970 :     while (reader.nextAttribute(&nsId, &name))
    3042             :     {
    3043      372782 :         if (name.equals("name"))
    3044             :         {
    3045      343594 :             name = reader.getAttributeValue(false);
    3046      343594 :             sProperty = OString(name.begin, name.length);
    3047             :         }
    3048       29188 :         else if (name.equals("translatable") && reader.getAttributeValue(false).equals("yes"))
    3049             :         {
    3050       22530 :             sValue = getTranslation(rID, sProperty);
    3051       22530 :             bTranslated = !sValue.isEmpty();
    3052             :         }
    3053             : 
    3054             :     }
    3055             : 
    3056      343594 :     reader.nextItem(xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
    3057      343594 :     if (!bTranslated)
    3058      343594 :         sValue = OString(name.begin, name.length);
    3059             : 
    3060      343594 :     if (!sProperty.isEmpty())
    3061             :     {
    3062      343594 :         sProperty = sProperty.replace('_', '-');
    3063      343594 :         if (m_pStringReplace)
    3064             :         {
    3065      343354 :             OUString sTmp = (*m_pStringReplace)(OStringToOUString(sValue, RTL_TEXTENCODING_UTF8));
    3066      343354 :             rMap[sProperty] = OUStringToOString(sTmp, RTL_TEXTENCODING_UTF8);
    3067             :         }
    3068             :         else
    3069             :         {
    3070         240 :             rMap[sProperty] = sValue;
    3071             :         }
    3072      343594 :     }
    3073      343594 : }
    3074             : 
    3075           0 : void VclBuilder::handleActionWidget(xmlreader::XmlReader &reader)
    3076             : {
    3077           0 :     xmlreader::Span name;
    3078             :     int nsId;
    3079             : 
    3080           0 :     OString sResponse;
    3081             : 
    3082           0 :     while (reader.nextAttribute(&nsId, &name))
    3083             :     {
    3084           0 :         if (name.equals("response"))
    3085             :         {
    3086           0 :             name = reader.getAttributeValue(false);
    3087           0 :             sResponse = OString(name.begin, name.length);
    3088             :         }
    3089             :     }
    3090             : 
    3091           0 :     reader.nextItem(xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
    3092           0 :     OString sID = OString(name.begin, name.length);
    3093           0 :     sal_Int32 nDelim = sID.indexOf(':');
    3094           0 :     if (nDelim != -1)
    3095           0 :         sID = sID.copy(0, nDelim);
    3096           0 :     set_response(sID, sResponse.toInt32());
    3097           0 : }
    3098             : 
    3099           0 : void VclBuilder::collectAccelerator(xmlreader::XmlReader &reader, stringmap &rMap)
    3100             : {
    3101           0 :     xmlreader::Span name;
    3102             :     int nsId;
    3103             : 
    3104           0 :     OString sProperty;
    3105           0 :     OString sValue;
    3106             : 
    3107           0 :     while (reader.nextAttribute(&nsId, &name))
    3108             :     {
    3109           0 :         if (name.equals("key"))
    3110             :         {
    3111           0 :             name = reader.getAttributeValue(false);
    3112           0 :             sValue = OString(name.begin, name.length);
    3113             :         }
    3114           0 :         else if (name.equals("signal"))
    3115             :         {
    3116           0 :             name = reader.getAttributeValue(false);
    3117           0 :             sProperty = OString(name.begin, name.length);
    3118             :         }
    3119             : 
    3120             :     }
    3121             : 
    3122           0 :     if (!sProperty.isEmpty() && !sValue.isEmpty())
    3123             :     {
    3124           0 :         rMap[sProperty] = sValue;
    3125           0 :     }
    3126           0 : }
    3127             : 
    3128           0 : vcl::Window *VclBuilder::get_widget_root()
    3129             : {
    3130           0 :     return m_aChildren.empty() ? NULL : m_aChildren[0].m_pWindow;
    3131             : }
    3132             : 
    3133       23316 : vcl::Window *VclBuilder::get_by_name(const OString& sID)
    3134             : {
    3135      343796 :     for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
    3136       23316 :          aEnd = m_aChildren.end(); aI != aEnd; ++aI)
    3137             :     {
    3138      320480 :         if (aI->m_sID.equals(sID))
    3139       23316 :             return aI->m_pWindow;
    3140             :     }
    3141             : 
    3142           0 :     return NULL;
    3143             : }
    3144             : 
    3145           2 : PopupMenu *VclBuilder::get_menu(const OString& sID)
    3146             : {
    3147           4 :     for (std::vector<MenuAndId>::iterator aI = m_aMenus.begin(),
    3148           2 :          aEnd = m_aMenus.end(); aI != aEnd; ++aI)
    3149             :     {
    3150           2 :         if (aI->m_sID.equals(sID))
    3151           2 :             return aI->m_pMenu;
    3152             :     }
    3153             : 
    3154           0 :     return NULL;
    3155             : }
    3156             : 
    3157           0 : short VclBuilder::get_response(const vcl::Window *pWindow) const
    3158             : {
    3159           0 :     for (std::vector<WinAndId>::const_iterator aI = m_aChildren.begin(),
    3160           0 :          aEnd = m_aChildren.end(); aI != aEnd; ++aI)
    3161             :     {
    3162           0 :         if (aI->m_pWindow == pWindow)
    3163             :         {
    3164           0 :             return aI->m_nResponseId;
    3165             :         }
    3166             :     }
    3167             : 
    3168             :     //how did we not find sID ?
    3169             :     assert(false);
    3170           0 :     return RET_CANCEL;
    3171             : }
    3172             : 
    3173           0 : void VclBuilder::set_response(const OString& sID, short nResponse)
    3174             : {
    3175           0 :     for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
    3176           0 :          aEnd = m_aChildren.end(); aI != aEnd; ++aI)
    3177             :     {
    3178           0 :         if (aI->m_sID.equals(sID))
    3179             :         {
    3180           0 :             aI->m_nResponseId = nResponse;
    3181           0 :             return;
    3182             :         }
    3183             :     }
    3184             : 
    3185             :     //how did we not find sID ?
    3186             :     assert(false);
    3187             : }
    3188             : 
    3189          18 : void VclBuilder::delete_by_name(const OString& sID)
    3190             : {
    3191          36 :     for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
    3192          18 :          aEnd = m_aChildren.end(); aI != aEnd; ++aI)
    3193             :     {
    3194          18 :         if (aI->m_sID.equals(sID))
    3195             :         {
    3196          18 :             delete aI->m_pWindow;
    3197          18 :             m_aChildren.erase(aI);
    3198          18 :             break;
    3199             :         }
    3200             :     }
    3201          18 : }
    3202             : 
    3203           0 : void VclBuilder::delete_by_window(const vcl::Window *pWindow)
    3204             : {
    3205           0 :     drop_ownership(pWindow);
    3206           0 :     delete pWindow;
    3207           0 : }
    3208             : 
    3209           0 : void VclBuilder::drop_ownership(const vcl::Window *pWindow)
    3210             : {
    3211           0 :     for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
    3212           0 :          aEnd = m_aChildren.end(); aI != aEnd; ++aI)
    3213             :     {
    3214           0 :         if (aI->m_pWindow == pWindow)
    3215             :         {
    3216           0 :             m_aChildren.erase(aI);
    3217           0 :             break;
    3218             :         }
    3219             :     }
    3220           0 : }
    3221             : 
    3222           0 : OString VclBuilder::get_by_window(const vcl::Window *pWindow) const
    3223             : {
    3224           0 :     for (std::vector<WinAndId>::const_iterator aI = m_aChildren.begin(),
    3225           0 :          aEnd = m_aChildren.end(); aI != aEnd; ++aI)
    3226             :     {
    3227           0 :         if (aI->m_pWindow == pWindow)
    3228           0 :             return aI->m_sID;
    3229             :     }
    3230             : 
    3231           0 :     return OString();
    3232             : }
    3233             : 
    3234       66606 : VclBuilder::PackingData VclBuilder::get_window_packing_data(const vcl::Window *pWindow) const
    3235             : {
    3236             :     //We've stored the return of new Control, some of these get
    3237             :     //border windows placed around them which are what you get
    3238             :     //from GetChild, so scoot up a level if necessary to get the
    3239             :     //window whose position value we have
    3240             :     const vcl::Window *pPropHolder = pWindow->mpWindowImpl->mpClientWindow ?
    3241       66606 :         pWindow->mpWindowImpl->mpClientWindow : pWindow;
    3242             : 
    3243     1035156 :     for (std::vector<WinAndId>::const_iterator aI = m_aChildren.begin(),
    3244       66606 :          aEnd = m_aChildren.end(); aI != aEnd; ++aI)
    3245             :     {
    3246      968546 :         if (aI->m_pWindow == pPropHolder)
    3247       66602 :             return aI->m_aPackingData;
    3248             :     }
    3249             : 
    3250           4 :     return PackingData();
    3251             : }
    3252             : 
    3253       26618 : void VclBuilder::set_window_packing_position(const vcl::Window *pWindow, sal_Int32 nPosition)
    3254             : {
    3255      465542 :     for (std::vector<WinAndId>::iterator aI = m_aChildren.begin(),
    3256       26618 :          aEnd = m_aChildren.end(); aI != aEnd; ++aI)
    3257             :     {
    3258      412306 :         if (aI->m_pWindow == pWindow)
    3259       26618 :             aI->m_aPackingData.m_nPosition = nPosition;
    3260             :     }
    3261       26618 : }
    3262             : 
    3263           0 : const VclBuilder::ListStore *VclBuilder::get_model_by_name(const OString& sID) const
    3264             : {
    3265           0 :     std::map<OString, ListStore>::const_iterator aI = m_pParserState->m_aModels.find(sID);
    3266           0 :     if (aI != m_pParserState->m_aModels.end())
    3267           0 :         return &(aI->second);
    3268           0 :     return NULL;
    3269             : }
    3270             : 
    3271           0 : const VclBuilder::TextBuffer *VclBuilder::get_buffer_by_name(const OString& sID) const
    3272             : {
    3273           0 :     std::map<OString, TextBuffer>::const_iterator aI = m_pParserState->m_aTextBuffers.find(sID);
    3274           0 :     if (aI != m_pParserState->m_aTextBuffers.end())
    3275           0 :         return &(aI->second);
    3276           0 :     return NULL;
    3277             : }
    3278             : 
    3279           0 : const VclBuilder::Adjustment *VclBuilder::get_adjustment_by_name(const OString& sID) const
    3280             : {
    3281           0 :     std::map<OString, Adjustment>::const_iterator aI = m_pParserState->m_aAdjustments.find(sID);
    3282           0 :     if (aI != m_pParserState->m_aAdjustments.end())
    3283           0 :         return &(aI->second);
    3284           0 :     return NULL;
    3285             : }
    3286             : 
    3287           0 : void VclBuilder::mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId)
    3288             : {
    3289           0 :     for (std::vector<ListStore::row>::const_iterator aI = rStore.m_aEntries.begin(), aEnd = rStore.m_aEntries.end();
    3290             :         aI != aEnd; ++aI)
    3291             :     {
    3292           0 :         const ListStore::row &rRow = *aI;
    3293           0 :         sal_uInt16 nEntry = rTarget.InsertEntry(OStringToOUString(rRow[0], RTL_TEXTENCODING_UTF8));
    3294           0 :         if (rRow.size() > 1)
    3295             :         {
    3296           0 :             sal_IntPtr nValue = rRow[1].toInt32();
    3297           0 :             rTarget.SetEntryData(nEntry, reinterpret_cast<void*>(nValue));
    3298             :         }
    3299             :     }
    3300           0 :     if (nActiveId < rStore.m_aEntries.size())
    3301           0 :         rTarget.SelectEntryPos(nActiveId);
    3302           0 : }
    3303             : 
    3304           0 : void VclBuilder::mungeAdjustment(NumericFormatter &rTarget, const Adjustment &rAdjustment)
    3305             : {
    3306           0 :     int nMul = rtl_math_pow10Exp(1, rTarget.GetDecimalDigits());
    3307             : 
    3308           0 :     for (stringmap::const_iterator aI = rAdjustment.begin(), aEnd = rAdjustment.end(); aI != aEnd; ++aI)
    3309             :     {
    3310           0 :         const OString &rKey = aI->first;
    3311           0 :         const OString &rValue = aI->second;
    3312             : 
    3313           0 :         if (rKey == "upper")
    3314             :         {
    3315           0 :             sal_Int64 nUpper = rValue.toDouble() * nMul;
    3316           0 :             rTarget.SetMax(nUpper);
    3317           0 :             rTarget.SetLast(nUpper);
    3318             :         }
    3319           0 :         else if (rKey == "lower")
    3320             :         {
    3321           0 :             sal_Int64 nLower = rValue.toDouble() * nMul;
    3322           0 :             rTarget.SetMin(nLower);
    3323           0 :             rTarget.SetFirst(nLower);
    3324             :         }
    3325           0 :         else if (rKey == "value")
    3326             :         {
    3327           0 :             sal_Int64 nValue = rValue.toDouble() * nMul;
    3328           0 :             rTarget.SetValue(nValue);
    3329             :         }
    3330           0 :         else if (rKey == "step-increment")
    3331             :         {
    3332           0 :             sal_Int64 nSpinSize = rValue.toDouble() * nMul;
    3333           0 :             rTarget.SetSpinSize(nSpinSize);
    3334             :         }
    3335             :         else
    3336             :         {
    3337             :             SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
    3338             :         }
    3339             :     }
    3340           0 : }
    3341             : 
    3342           0 : void VclBuilder::mungeAdjustment(TimeField &rTarget, const Adjustment &rAdjustment)
    3343             : {
    3344           0 :     for (stringmap::const_iterator aI = rAdjustment.begin(), aEnd = rAdjustment.end(); aI != aEnd; ++aI)
    3345             :     {
    3346           0 :         const OString &rKey = aI->first;
    3347           0 :         const OString &rValue = aI->second;
    3348             : 
    3349           0 :         if (rKey == "upper")
    3350             :         {
    3351           0 :             tools::Time aUpper(rValue.toInt32());
    3352           0 :             rTarget.SetMax(aUpper);
    3353           0 :             rTarget.SetLast(aUpper);
    3354             :         }
    3355           0 :         else if (rKey == "lower")
    3356             :         {
    3357           0 :             tools::Time aLower(rValue.toInt32());
    3358           0 :             rTarget.SetMin(aLower);
    3359           0 :             rTarget.SetFirst(aLower);
    3360             :         }
    3361           0 :         else if (rKey == "value")
    3362             :         {
    3363           0 :             tools::Time aValue(rValue.toInt32());
    3364           0 :             rTarget.SetTime(aValue);
    3365             :         }
    3366             :         else
    3367             :         {
    3368             :             SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
    3369             :         }
    3370             :     }
    3371           0 : }
    3372             : 
    3373           0 : void VclBuilder::mungeAdjustment(DateField &rTarget, const Adjustment &rAdjustment)
    3374             : {
    3375           0 :     for (stringmap::const_iterator aI = rAdjustment.begin(), aEnd = rAdjustment.end(); aI != aEnd; ++aI)
    3376             :     {
    3377           0 :         const OString &rKey = aI->first;
    3378           0 :         const OString &rValue = aI->second;
    3379             : 
    3380           0 :         if (rKey == "upper")
    3381             :         {
    3382           0 :             Date aUpper(rValue.toInt32());
    3383           0 :             rTarget.SetMax(aUpper);
    3384           0 :             rTarget.SetLast(aUpper);
    3385             :         }
    3386           0 :         else if (rKey == "lower")
    3387             :         {
    3388           0 :             Date aLower(rValue.toInt32());
    3389           0 :             rTarget.SetMin(aLower);
    3390           0 :             rTarget.SetFirst(aLower);
    3391             :         }
    3392           0 :         else if (rKey == "value")
    3393             :         {
    3394           0 :             Date aValue(rValue.toInt32());
    3395           0 :             rTarget.SetDate(aValue);
    3396             :         }
    3397             :         else
    3398             :         {
    3399             :             SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
    3400             :         }
    3401             :     }
    3402           0 : }
    3403             : 
    3404           0 : void VclBuilder::mungeAdjustment(ScrollBar &rTarget, const Adjustment &rAdjustment)
    3405             : {
    3406           0 :     for (stringmap::const_iterator aI = rAdjustment.begin(), aEnd = rAdjustment.end(); aI != aEnd; ++aI)
    3407             :     {
    3408           0 :         const OString &rKey = aI->first;
    3409           0 :         const OString &rValue = aI->second;
    3410             : 
    3411           0 :         if (rKey == "upper")
    3412           0 :             rTarget.SetRangeMax(rValue.toInt32());
    3413           0 :         else if (rKey == "lower")
    3414           0 :             rTarget.SetRangeMin(rValue.toInt32());
    3415           0 :         else if (rKey == "value")
    3416           0 :             rTarget.SetThumbPos(rValue.toInt32());
    3417           0 :         else if (rKey == "step-increment")
    3418           0 :             rTarget.SetLineSize(rValue.toInt32());
    3419           0 :         else if (rKey == "page-increment")
    3420           0 :             rTarget.SetPageSize(rValue.toInt32());
    3421             :         else
    3422             :         {
    3423             :             SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
    3424             :         }
    3425             :     }
    3426           0 : }
    3427             : 
    3428           0 : void VclBuilder::mungeTextBuffer(VclMultiLineEdit &rTarget, const TextBuffer &rTextBuffer)
    3429             : {
    3430           0 :     for (stringmap::const_iterator aI = rTextBuffer.begin(), aEnd = rTextBuffer.end(); aI != aEnd; ++aI)
    3431             :     {
    3432           0 :         const OString &rKey = aI->first;
    3433           0 :         const OString &rValue = aI->second;
    3434             : 
    3435           0 :         if (rKey == "text")
    3436           0 :             rTarget.SetText(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
    3437             :         else
    3438             :         {
    3439             :             SAL_INFO("vcl.layout", "unhandled property :" << rKey.getStr());
    3440             :         }
    3441             :     }
    3442        1233 : }
    3443             : 
    3444             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10