LCOV - code coverage report
Current view: top level - cui/source/options - personalization.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 463 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 46 0.0 %
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 <config_folders.h>
      11             : 
      12             : #include "personalization.hxx"
      13             : #include "personasdochandler.hxx"
      14             : 
      15             : #include <comphelper/processfactory.hxx>
      16             : #include <officecfg/Office/Common.hxx>
      17             : #include <com/sun/star/container/XNameAccess.hpp>
      18             : #include <com/sun/star/beans/XPropertySet.hpp>
      19             : #include <osl/file.hxx>
      20             : #include <rtl/bootstrap.hxx>
      21             : #include <rtl/strbuf.hxx>
      22             : #include <tools/urlobj.hxx>
      23             : #include <vcl/edit.hxx>
      24             : #include <vcl/msgbox.hxx>
      25             : #include <vcl/lstbox.hxx>
      26             : #include <vcl/svapp.hxx>
      27             : #include <vcl/settings.hxx>
      28             : #include <vcl/graphicfilter.hxx>
      29             : #include <dialmgr.hxx>
      30             : #include "cuires.hrc"
      31             : 
      32             : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
      33             : #include <com/sun/star/xml/sax/XParser.hpp>
      34             : #include <com/sun/star/xml/sax/Parser.hpp>
      35             : #include "ucbhelper/content.hxx"
      36             : 
      37             : using namespace com::sun::star;
      38             : using namespace ::com::sun::star::uno;
      39             : using namespace ::com::sun::star::ucb;
      40             : using namespace ::com::sun::star::beans;
      41             : 
      42           0 : SelectPersonaDialog::SelectPersonaDialog( vcl::Window *pParent )
      43           0 :     : ModalDialog( pParent, "SelectPersonaDialog", "cui/ui/select_persona_dialog.ui" )
      44             : {
      45           0 :     get( m_pSearchButton, "search_personas" );
      46           0 :     m_pSearchButton->SetClickHdl( LINK( this, SelectPersonaDialog, SearchPersonas ) );
      47             : 
      48           0 :     get( m_vSearchSuggestions[0], "suggestion1" );
      49           0 :     m_vSearchSuggestions[0]->SetText( "LibreOffice" );
      50           0 :     m_vSearchSuggestions[0]->SetClickHdl( LINK( this, SelectPersonaDialog, SearchPersonas ) );
      51             : 
      52           0 :     get( m_vSearchSuggestions[1], "suggestion2" );
      53           0 :     m_vSearchSuggestions[1]->SetText( CUI_RES ( RID_SVXSTR_PERSONA_ABSTRACT ) );
      54           0 :     m_vSearchSuggestions[1]->SetClickHdl( LINK( this, SelectPersonaDialog, SearchPersonas ) );
      55             : 
      56           0 :     get( m_vSearchSuggestions[2], "suggestion3" );
      57           0 :     m_vSearchSuggestions[2]->SetText( CUI_RES ( RID_SVXSTR_PERSONA_COLOR ) );
      58           0 :     m_vSearchSuggestions[2]->SetClickHdl( LINK( this, SelectPersonaDialog, SearchPersonas ) );
      59             : 
      60           0 :     get( m_vSearchSuggestions[3], "suggestion4" );
      61           0 :     m_vSearchSuggestions[3]->SetText( CUI_RES( RID_SVXSTR_PERSONA_MUSIC ) );
      62           0 :     m_vSearchSuggestions[3]->SetClickHdl( LINK( this, SelectPersonaDialog, SearchPersonas ) );
      63             : 
      64           0 :     get( m_vSearchSuggestions[4], "suggestion5" );
      65           0 :     m_vSearchSuggestions[4]->SetText( CUI_RES( RID_SVXSTR_PERSONA_NATURE ) );
      66           0 :     m_vSearchSuggestions[4]->SetClickHdl( LINK( this, SelectPersonaDialog, SearchPersonas ) );
      67             : 
      68           0 :     get( m_pEdit, "search_term" );
      69           0 :     m_pEdit->SetPlaceholderText( CUI_RES( RID_SVXSTR_SEARCHTERM ) );
      70             : 
      71           0 :     get( m_pProgressLabel, "progress_label" );
      72             : 
      73           0 :     get( m_pOkButton, "ok" );
      74           0 :     m_pOkButton->SetClickHdl( LINK( this, SelectPersonaDialog, ActionOK ) );
      75             : 
      76           0 :     get( m_pCancelButton, "cancel" );
      77           0 :     m_pCancelButton->SetClickHdl( LINK( this, SelectPersonaDialog, ActionCancel ) );
      78           0 :     get( m_vResultList[0], "result1" );
      79           0 :     get( m_vResultList[1], "result2" );
      80           0 :     get( m_vResultList[2], "result3" );
      81           0 :     get( m_vResultList[3], "result4" );
      82           0 :     get( m_vResultList[4], "result5" );
      83           0 :     get( m_vResultList[5], "result6" );
      84           0 :     get( m_vResultList[6], "result7" );
      85           0 :     get( m_vResultList[7], "result8" );
      86           0 :     get( m_vResultList[8], "result9" );
      87             : 
      88           0 :     for (sal_Int32 nIndex = 0; nIndex < 9; ++nIndex)
      89             :     {
      90           0 :         m_vResultList[nIndex]->SetClickHdl( LINK( this, SelectPersonaDialog, SelectPersona ) );
      91           0 :         m_vResultList[nIndex]->Disable();
      92             :     }
      93           0 : }
      94             : 
      95           0 : SelectPersonaDialog::~SelectPersonaDialog()
      96             : {
      97           0 :     disposeOnce();
      98           0 : }
      99             : 
     100           0 : void SelectPersonaDialog::dispose()
     101             : {
     102           0 :     m_pEdit.clear();
     103           0 :     m_pSearchButton.clear();
     104           0 :     m_pProgressLabel.clear();
     105           0 :     for (VclPtr<PushButton> vp : m_vResultList)
     106           0 :         vp.clear();
     107           0 :     for (VclPtr<PushButton> vp : m_vSearchSuggestions)
     108           0 :         vp.clear();
     109           0 :     m_pOkButton.clear();
     110           0 :     m_pCancelButton.clear();
     111           0 :     ModalDialog::dispose();
     112           0 : }
     113             : 
     114           0 : OUString SelectPersonaDialog::GetSelectedPersona() const
     115             : {
     116           0 :     if( !m_aSelectedPersona.isEmpty( ) )
     117           0 :         return m_aSelectedPersona;
     118             : 
     119           0 :     return OUString();
     120             : }
     121             : 
     122           0 : IMPL_LINK( SelectPersonaDialog, SearchPersonas, PushButton*, pButton )
     123             : {
     124           0 :     OUString searchTerm;
     125           0 :     if( m_rSearchThread.is() )
     126           0 :         m_rSearchThread->StopExecution();
     127             : 
     128           0 :     if( pButton ==  m_pSearchButton )
     129           0 :         searchTerm = m_pEdit->GetText();
     130             :     else
     131             :     {
     132           0 :         for( sal_Int32 nIndex = 0; nIndex < 5; nIndex++ )
     133             :         {
     134           0 :             if( pButton == m_vSearchSuggestions[nIndex] )
     135             :             {
     136           0 :                 searchTerm = m_vSearchSuggestions[nIndex]->GetDisplayText();
     137           0 :                 break;
     138             :             }
     139             :         }
     140             :     }
     141             : 
     142           0 :     if( searchTerm.isEmpty( ) )
     143           0 :         return 0;
     144             : 
     145             :     // TODO FIXME!
     146             :     // Before the release, the allizom.org url shoud be changed to:
     147             :     // OUString rSearchURL = "https://services.addons.mozilla.org/en-US/firefox/api/1.5/search/" + searchTerm + "/9/9";
     148             :     // The problem why it cannot be done just now is that the SSL negotiation
     149             :     // with services.addons.mozilla.org fails very early - during an early
     150             :     // propfind, SSL returns X509_V_ERR_CERT_UNTRUSTED to neon, causing the
     151             :     // NE_SSL_UNTRUSTED being set in verify_callback in neon/src/ne_openssl.c
     152             :     //
     153             :     // This is not cleared anywhere during the init, and so later, even though
     154             :     // we have found the certificate, this triggers
     155             :     // NeonSession_CertificationNotify callback, that
     156             :     // causes that NE_SSL_UNTRUSTED is igored in cases when the condition
     157             :     //   if ( pSession->isDomainMatch(
     158             :     //      GetHostnamePart( xEECert.get()->getSubjectName() ) ) )
     159             :     // is true; but that is only when getSubjectName() actually returns a
     160             :     // wildcard, or the exact name.
     161             :     //
     162             :     // In the case of services.addons.mozilla.com, the certificate is for
     163             :     // versioncheck.addons.mozilla.com, but it also has
     164             :     //   X509v3 Subject Alternative Name:
     165             :     //       DNS:services.addons.mozilla.org, DNS:versioncheck-bg.addons.mozilla.org, DNS:pyrepo.addons.mozilla.org, DNS:versioncheck.addons.mozilla.org
     166             :     // So it is all valid; but the early X509_V_ERR_CERT_UNTRUSTED failure
     167             :     // described above just makes this being ignored.
     168             :     //
     169             :     // My suspicion is that this never actually worked, and the
     170             :     //   if ( pSession->isDomainMatch(
     171             :     //      GetHostnamePart( xEECert.get()->getSubjectName() ) ) )
     172             :     // works around the root cause that is there for years, and which makes it
     173             :     // work in most cases.  I guess that we initialize something wrongly or
     174             :     // too late; but I have already spent few hours debugging, and
     175             :     // give up for the moment - need to return to this at some stage.
     176           0 :     OUString rSearchURL = "https://addons.allizom.org/en-US/firefox/api/1.5/search/" + searchTerm + "/9/9";
     177           0 :     m_rSearchThread = new SearchAndParseThread( this, rSearchURL );
     178           0 :     m_rSearchThread->launch();
     179           0 :     return 0;
     180             : }
     181             : 
     182           0 : IMPL_LINK( SelectPersonaDialog, ActionOK, PushButton*, /* pButton */ )
     183             : {
     184           0 :     OUString aSelectedPersona = GetSelectedPersona();
     185             : 
     186           0 :     if( !aSelectedPersona.isEmpty() )
     187             :     {
     188           0 :         m_rSearchThread = new SearchAndParseThread( this, aSelectedPersona );
     189           0 :         m_rSearchThread->launch();
     190             :     }
     191             : 
     192             :     else
     193             :     {
     194           0 :         if( m_rSearchThread.is() )
     195           0 :             m_rSearchThread->StopExecution();
     196           0 :         EndDialog( RET_OK );
     197             :     }
     198           0 :     return 0;
     199             : }
     200             : 
     201           0 : IMPL_LINK( SelectPersonaDialog, ActionCancel, PushButton*, /* pButton */ )
     202             : {
     203           0 :     if( m_rSearchThread.is() )
     204           0 :         m_rSearchThread->StopExecution();
     205             : 
     206           0 :     EndDialog( RET_CANCEL );
     207           0 :     return 0;
     208             : }
     209             : 
     210           0 : IMPL_LINK( SelectPersonaDialog, SelectPersona, PushButton*, pButton )
     211             : {
     212           0 :     if( m_rSearchThread.is() )
     213           0 :         m_rSearchThread->StopExecution();
     214             : 
     215           0 :     for( sal_Int32 index = 0; index < 9; index++ )
     216             :     {
     217           0 :         if( pButton == m_vResultList[index] )
     218             :         {
     219           0 :             if( !m_vPersonaSettings[index].isEmpty() )
     220             :             {
     221           0 :                 m_aSelectedPersona = m_vPersonaSettings[index];
     222             :                 // get the persona name from the setting variable to show in the progress.
     223           0 :                 sal_Int32 nNameIndex = m_aSelectedPersona.indexOf( ';' );
     224           0 :                 OUString aName = m_aSelectedPersona.copy( 0, nNameIndex );
     225           0 :                 OUString aProgress( CUI_RES( RID_SVXSTR_SELECTEDPERSONA ) );
     226           0 :                 aProgress += aName;
     227           0 :                 SetProgress( aProgress );
     228             :             }
     229           0 :             break;
     230             :         }
     231             :     }
     232           0 :     return 0;
     233             : }
     234             : 
     235           0 : void SelectPersonaDialog::SetAppliedPersonaSetting( OUString& rPersonaSetting )
     236             : {
     237           0 :     m_aAppliedPersona = rPersonaSetting;
     238           0 : }
     239             : 
     240           0 : OUString SelectPersonaDialog::GetAppliedPersonaSetting() const
     241             : {
     242           0 :     return m_aAppliedPersona;
     243             : }
     244             : 
     245           0 : void SelectPersonaDialog::SetProgress( OUString& rProgress )
     246             : {
     247           0 :     if(rProgress.isEmpty())
     248           0 :         m_pProgressLabel->Hide();
     249             :     else
     250             :     {
     251           0 :         SolarMutexGuard aGuard;
     252           0 :         m_pProgressLabel->Show();
     253           0 :         m_pProgressLabel->SetText( rProgress );
     254           0 :         setOptimalLayoutSize();
     255             :     }
     256           0 : }
     257             : 
     258           0 : void SelectPersonaDialog::SetImages( Image aImage, sal_Int32 nIndex )
     259             : {
     260           0 :     m_vResultList[nIndex]->Enable();
     261           0 :     m_vResultList[nIndex]->SetModeImage( aImage );
     262           0 : }
     263             : 
     264           0 : void SelectPersonaDialog::AddPersonaSetting( OUString& rPersonaSetting )
     265             : {
     266           0 :     m_vPersonaSettings.push_back( rPersonaSetting );
     267           0 : }
     268             : 
     269           0 : void SelectPersonaDialog::ClearSearchResults()
     270             : {
     271           0 :     m_vPersonaSettings.clear();
     272           0 :     m_aSelectedPersona.clear();
     273           0 :     for( sal_Int32 nIndex = 0; nIndex < 9; nIndex++ )
     274             :     {
     275           0 :         m_vResultList[nIndex]->Disable();
     276           0 :         m_vResultList[nIndex]->SetModeImage(Image());
     277             :     }
     278           0 : }
     279             : 
     280           0 : SvxPersonalizationTabPage::SvxPersonalizationTabPage( vcl::Window *pParent, const SfxItemSet &rSet )
     281           0 :     : SfxTabPage( pParent, "PersonalizationTabPage", "cui/ui/personalization_tab.ui", &rSet )
     282             : {
     283             :     // persona
     284           0 :     get( m_pNoPersona, "no_persona" );
     285           0 :     get( m_pDefaultPersona, "default_persona" );
     286             : 
     287           0 :     get( m_pOwnPersona, "own_persona" );
     288           0 :     m_pOwnPersona->SetClickHdl( LINK( this, SvxPersonalizationTabPage, ForceSelect ) );
     289             : 
     290           0 :     get( m_pSelectPersona, "select_persona" );
     291           0 :     m_pSelectPersona->SetClickHdl( LINK( this, SvxPersonalizationTabPage, SelectPersona ) );
     292             : 
     293           0 :     get( m_vDefaultPersonaImages[0], "default1" );
     294           0 :     m_vDefaultPersonaImages[0]->SetClickHdl( LINK( this, SvxPersonalizationTabPage, DefaultPersona ) );
     295             : 
     296           0 :     get( m_vDefaultPersonaImages[1], "default2" );
     297           0 :     m_vDefaultPersonaImages[1]->SetClickHdl( LINK( this, SvxPersonalizationTabPage, DefaultPersona ) );
     298             : 
     299           0 :     get( m_vDefaultPersonaImages[2], "default3" );
     300           0 :     m_vDefaultPersonaImages[2]->SetClickHdl( LINK( this, SvxPersonalizationTabPage, DefaultPersona ) );
     301             : 
     302           0 :     get( m_pPersonaList, "installed_personas" );
     303           0 :     m_pPersonaList->SetSelectHdl( LINK( this, SvxPersonalizationTabPage, SelectInstalledPersona ) );
     304             : 
     305           0 :     get( m_pExtensionPersonaPreview, "persona_preview" );
     306             : 
     307           0 :     get ( m_pExtensionLabel, "extensions_label" );
     308             : 
     309           0 :     LoadDefaultImages();
     310           0 :     LoadExtensionThemes();
     311           0 : }
     312             : 
     313           0 : SvxPersonalizationTabPage::~SvxPersonalizationTabPage()
     314             : {
     315           0 :     disposeOnce();
     316           0 : }
     317             : 
     318           0 : void SvxPersonalizationTabPage::dispose()
     319             : {
     320           0 :     m_pNoPersona.clear();
     321           0 :     m_pDefaultPersona.clear();
     322           0 :     m_pOwnPersona.clear();
     323           0 :     m_pSelectPersona.clear();
     324           0 :     for (int i=0; i<3; ++i)
     325           0 :         m_vDefaultPersonaImages[i].clear();
     326           0 :     m_pExtensionPersonaPreview.clear();
     327           0 :     m_pPersonaList.clear();
     328           0 :     m_pExtensionLabel.clear();
     329           0 :     SfxTabPage::dispose();
     330           0 : }
     331             : 
     332             : 
     333           0 : VclPtr<SfxTabPage> SvxPersonalizationTabPage::Create( vcl::Window *pParent, const SfxItemSet *rSet )
     334             : {
     335           0 :     return VclPtr<SvxPersonalizationTabPage>::Create( pParent, *rSet );
     336             : }
     337             : 
     338           0 : bool SvxPersonalizationTabPage::FillItemSet( SfxItemSet * )
     339             : {
     340             :     // persona
     341           0 :     OUString aPersona( "default" );
     342           0 :     if ( m_pNoPersona->IsChecked() )
     343           0 :         aPersona = "no";
     344           0 :     else if ( m_pOwnPersona->IsChecked() )
     345           0 :         aPersona = "own";
     346             : 
     347           0 :     bool bModified = false;
     348           0 :     uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
     349           0 :     if ( xContext.is() &&
     350           0 :             ( aPersona != officecfg::Office::Common::Misc::Persona::get( xContext ) ||
     351           0 :               m_aPersonaSettings != officecfg::Office::Common::Misc::PersonaSettings::get( xContext ) ) )
     352             :     {
     353           0 :         bModified = true;
     354             :     }
     355             : 
     356             :     // write
     357           0 :     std::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create() );
     358           0 :     if( aPersona == "no" )
     359           0 :         m_aPersonaSettings.clear();
     360           0 :     officecfg::Office::Common::Misc::Persona::set( aPersona, batch );
     361           0 :     officecfg::Office::Common::Misc::PersonaSettings::set( m_aPersonaSettings, batch );
     362           0 :     batch->commit();
     363             : 
     364           0 :     if ( bModified )
     365             :     {
     366             :         // broadcast the change
     367           0 :         DataChangedEvent aDataChanged( DataChangedEventType::SETTINGS, NULL, AllSettingsFlags::STYLE );
     368           0 :         Application::NotifyAllWindows( aDataChanged );
     369             :     }
     370             : 
     371           0 :     return bModified;
     372             : }
     373             : 
     374           0 : void SvxPersonalizationTabPage::Reset( const SfxItemSet * )
     375             : {
     376           0 :     uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
     377             : 
     378             :     // persona
     379           0 :     OUString aPersona( "default" );
     380           0 :     if ( xContext.is() )
     381             :     {
     382           0 :         aPersona = officecfg::Office::Common::Misc::Persona::get( xContext );
     383           0 :         m_aPersonaSettings = officecfg::Office::Common::Misc::PersonaSettings::get( xContext );
     384             :     }
     385             : 
     386           0 :     if ( aPersona == "no" )
     387           0 :         m_pNoPersona->Check();
     388           0 :     else if ( aPersona == "own" )
     389           0 :         m_pOwnPersona->Check();
     390             :     else
     391           0 :         m_pDefaultPersona->Check();
     392           0 : }
     393             : 
     394           0 : void SvxPersonalizationTabPage::SetPersonaSettings( const OUString& aPersonaSettings )
     395             : {
     396           0 :     m_aPersonaSettings = aPersonaSettings;
     397           0 :     m_pOwnPersona->Check();
     398           0 : }
     399             : 
     400           0 : void SvxPersonalizationTabPage::LoadDefaultImages()
     401             : {
     402             :     // Load the pre saved personas
     403             : 
     404           0 :     OUString gallery( "" );
     405           0 :     gallery = "$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER;
     406           0 :     gallery += "/gallery/personas/";
     407           0 :     rtl::Bootstrap::expandMacros( gallery );
     408           0 :     OUString aPersonasList = gallery + "personas_list.txt";
     409           0 :     SvFileStream aStream( aPersonasList, StreamMode::READ );
     410           0 :     GraphicFilter aFilter;
     411           0 :     Graphic aGraphic;
     412           0 :     sal_Int32 nIndex = 0;
     413             : 
     414           0 :     while( aStream.IsOpen() && !aStream.IsEof() )
     415             :     {
     416           0 :         OString aLine;
     417           0 :         aStream.ReadLine( aLine );
     418           0 :         OUString aPersonaSetting( OStringToOUString( aLine, RTL_TEXTENCODING_UTF8 ) );
     419           0 :         OUString aPreviewFile;
     420           0 :         sal_Int32 nNewIndex = aPersonaSetting.indexOf( ';', 0 );
     421           0 :         if( nNewIndex < 0 )
     422           0 :             break;
     423           0 :         aPreviewFile = aPersonaSetting.copy( 0, nNewIndex );
     424           0 :         aPersonaSetting = aPersonaSetting.copy( nNewIndex + 1 );
     425           0 :         m_vDefaultPersonaSettings.push_back( aPersonaSetting );
     426             : 
     427           0 :         INetURLObject aURLObj( gallery + aPreviewFile );
     428           0 :         aFilter.ImportGraphic( aGraphic, aURLObj );
     429           0 :         Bitmap aBmp = aGraphic.GetBitmap();
     430           0 :         m_vDefaultPersonaImages[nIndex]->Show();
     431           0 :         m_vDefaultPersonaImages[nIndex++]->SetModeImage( Image( aBmp ) );
     432           0 :     }
     433           0 : }
     434             : 
     435           0 : void SvxPersonalizationTabPage::LoadExtensionThemes()
     436             : {
     437             :     // See if any extensions are used to install personas. If yes, load them.
     438             : 
     439           0 :     css::uno::Sequence<OUString> installedPersonas( officecfg::Office::Common::Misc::PersonasList::get()->getElementNames() );
     440           0 :     sal_Int32 nLength = installedPersonas.getLength();
     441             : 
     442           0 :     if( nLength == 0 )
     443           0 :         return;
     444             : 
     445           0 :     m_pPersonaList->Show();
     446           0 :     m_pExtensionLabel->Show();
     447             : 
     448           0 :     for( sal_Int32 nIndex = 0; nIndex < nLength; nIndex++ )
     449             :     {
     450           0 :         Reference< XPropertySet > xPropertySet( officecfg::Office::Common::Misc::PersonasList::get()->getByName( installedPersonas[nIndex] ), UNO_QUERY_THROW );
     451           0 :         OUString aPersonaName, aPreviewFile, aHeaderFile, aFooterFile, aTextColor, aAccentColor, aPersonaSettings;
     452           0 :         Any aValue = xPropertySet->getPropertyValue( "Name" );
     453           0 :         aValue >>= aPersonaName;
     454           0 :         m_pPersonaList->InsertEntry( aPersonaName );
     455             : 
     456           0 :         aValue = xPropertySet->getPropertyValue( "Preview" );
     457           0 :         aValue >>= aPreviewFile;
     458             : 
     459           0 :         aValue = xPropertySet->getPropertyValue( "Header" );
     460           0 :         aValue >>= aHeaderFile;
     461             : 
     462           0 :         aValue = xPropertySet->getPropertyValue( "Footer" );
     463           0 :         aValue >>= aFooterFile;
     464             : 
     465           0 :         aValue = xPropertySet->getPropertyValue( "TextColor" );
     466           0 :         aValue >>= aTextColor;
     467             : 
     468           0 :         aValue = xPropertySet->getPropertyValue( "AccentColor" );
     469           0 :         aValue >>= aAccentColor;
     470             : 
     471           0 :         aPersonaSettings = aPreviewFile + ";" + aHeaderFile + ";" + aFooterFile + ";" + aTextColor + ";" + aAccentColor;
     472           0 :         rtl::Bootstrap::expandMacros( aPersonaSettings );
     473           0 :         m_vExtensionPersonaSettings.push_back( aPersonaSettings );
     474           0 :     }
     475             : }
     476             : 
     477           0 : IMPL_LINK( SvxPersonalizationTabPage, SelectPersona, PushButton*, /*pButton*/ )
     478             : {
     479           0 :     ScopedVclPtrInstance< SelectPersonaDialog > aDialog(nullptr);
     480             : 
     481           0 :     if ( aDialog->Execute() == RET_OK )
     482             :     {
     483           0 :         OUString aPersonaSetting( aDialog->GetAppliedPersonaSetting() );
     484           0 :         if ( !aPersonaSetting.isEmpty() )
     485             :         {
     486           0 :             SetPersonaSettings( aPersonaSetting );
     487           0 :         }
     488             :     }
     489             : 
     490           0 :     return 0;
     491             : }
     492             : 
     493           0 : IMPL_LINK( SvxPersonalizationTabPage, ForceSelect, RadioButton*, pButton )
     494             : {
     495           0 :     if ( pButton == m_pOwnPersona && m_aPersonaSettings.isEmpty() )
     496           0 :         SelectPersona( m_pSelectPersona );
     497             : 
     498           0 :     return 0;
     499             : }
     500             : 
     501           0 : IMPL_LINK( SvxPersonalizationTabPage, DefaultPersona, PushButton*, pButton )
     502             : {
     503           0 :     m_pDefaultPersona->Check();
     504           0 :     for( sal_Int32 nIndex = 0; nIndex < 3; nIndex++ )
     505             :     {
     506           0 :         if( pButton == m_vDefaultPersonaImages[nIndex] )
     507           0 :             m_aPersonaSettings = m_vDefaultPersonaSettings[nIndex];
     508             :     }
     509             : 
     510           0 :     return 0;
     511             : }
     512             : 
     513           0 : IMPL_LINK( SvxPersonalizationTabPage, SelectInstalledPersona, ListBox*, )
     514             : {
     515           0 :     m_pOwnPersona->Check();
     516             : 
     517             :     // Get the details of the selected theme.
     518           0 :     m_pExtensionPersonaPreview->Show();
     519           0 :     sal_Int32 nSelectedPos = m_pPersonaList->GetSelectEntryPos();
     520           0 :     OUString aSettings = m_vExtensionPersonaSettings[nSelectedPos];
     521           0 :     sal_Int32 nIndex = aSettings.indexOf( ';', 0 );
     522           0 :     OUString aPreviewFile = aSettings.copy( 0, nIndex );
     523           0 :     m_aPersonaSettings = aSettings.copy( nIndex + 1 );
     524             : 
     525             :     // Show the preview file in the button.
     526           0 :     GraphicFilter aFilter;
     527           0 :     Graphic aGraphic;
     528           0 :     INetURLObject aURLObj( aPreviewFile );
     529           0 :     aFilter.ImportGraphic( aGraphic, aURLObj );
     530           0 :     Bitmap aBmp = aGraphic.GetBitmap();
     531           0 :     m_pExtensionPersonaPreview->SetModeImage( Image( aBmp ) );
     532             : 
     533           0 :     return 0;
     534             : }
     535             : 
     536             : /// Find the value on the Persona page, and convert it to a usable form.
     537           0 : static OUString searchValue( const OString &rBuffer, sal_Int32 from, const OString &rIdentifier )
     538             : {
     539           0 :     sal_Int32 where = rBuffer.indexOf( rIdentifier, from );
     540           0 :     if ( where < 0 )
     541           0 :         return OUString();
     542             : 
     543           0 :     where += rIdentifier.getLength();
     544             : 
     545           0 :     sal_Int32 end = rBuffer.indexOf( "&#34;", where );
     546           0 :     if ( end < 0 )
     547           0 :         return OUString();
     548             : 
     549           0 :     OString aOString( rBuffer.copy( where, end - where ) );
     550           0 :     OUString aString( aOString.getStr(),  aOString.getLength(), RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS );
     551             : 
     552           0 :     return aString.replaceAll( "\\/", "/" );
     553             : }
     554             : 
     555             : /// Parse the Persona web page, and find where to get the bitmaps + the color values.
     556           0 : static bool parsePersonaInfo( const OString &rBuffer, OUString *pHeaderURL, OUString *pFooterURL,
     557             :                               OUString *pTextColor, OUString *pAccentColor, OUString *pPreviewURL,
     558             :                               OUString *pName )
     559             : {
     560             :     // it is the first attribute that contains "persona="
     561           0 :     sal_Int32 persona = rBuffer.indexOf( "data-browsertheme=\"{" );
     562           0 :     if ( persona < 0 )
     563           0 :         return false;
     564             : 
     565             :     // now search inside
     566           0 :     *pHeaderURL = searchValue( rBuffer, persona, "&#34;headerURL&#34;:&#34;" );
     567           0 :     if ( pHeaderURL->isEmpty() )
     568           0 :         return false;
     569             : 
     570           0 :     *pFooterURL = searchValue( rBuffer, persona, "&#34;footerURL&#34;:&#34;" );
     571           0 :     if ( pFooterURL->isEmpty() )
     572           0 :         return false;
     573             : 
     574           0 :     *pTextColor = searchValue( rBuffer, persona, "&#34;textcolor&#34;:&#34;" );
     575           0 :     if ( pTextColor->isEmpty() )
     576           0 :         return false;
     577             : 
     578           0 :     *pAccentColor = searchValue( rBuffer, persona, "&#34;accentcolor&#34;:&#34;" );
     579           0 :     if ( pAccentColor->isEmpty() )
     580           0 :         return false;
     581             : 
     582           0 :     *pPreviewURL = searchValue( rBuffer, persona, "&#34;previewURL&#34;:&#34;" );
     583           0 :     if ( pPreviewURL->isEmpty() )
     584           0 :         return false;
     585             : 
     586           0 :     *pName = searchValue( rBuffer, persona, "&#34;name&#34;:&#34;" );
     587           0 :     if ( pName->isEmpty() )
     588           0 :         return false;
     589             : 
     590           0 :     return true;
     591             : }
     592             : 
     593           0 : SearchAndParseThread::SearchAndParseThread( SelectPersonaDialog* pDialog,
     594             :                           const OUString& rURL ) :
     595             :             Thread( "cuiPersonasSearchThread" ),
     596             :             m_pPersonaDialog( pDialog ),
     597             :             m_aURL( rURL ),
     598           0 :             m_bExecute( true )
     599             : {
     600           0 : }
     601             : 
     602           0 : SearchAndParseThread::~SearchAndParseThread()
     603             : {
     604           0 : }
     605             : 
     606           0 : void SearchAndParseThread::execute()
     607             : {
     608           0 :     if( m_aURL.startsWith( "https://" ) )
     609             :     {
     610           0 :         m_pPersonaDialog->ClearSearchResults();
     611           0 :         OUString sProgress( CUI_RES( RID_SVXSTR_SEARCHING ) );
     612           0 :         m_pPersonaDialog->SetProgress( sProgress );
     613           0 :         Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
     614           0 :         Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(xContext);
     615           0 :         PersonasDocHandler* pHandler = new PersonasDocHandler();
     616           0 :         Reference< xml::sax::XDocumentHandler > xDocHandler = pHandler;
     617           0 :         uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY );
     618           0 :         uno::Reference< io::XInputStream > xStream;
     619           0 :         xParser->setDocumentHandler( xDocHandler );
     620             : 
     621           0 :         if ( !xFileAccess.is() )
     622           0 :             return;
     623             : 
     624             :         try {
     625           0 :             xStream = xFileAccess->openFileRead( m_aURL );
     626             :         }
     627           0 :         catch (...)
     628             :         {
     629           0 :             sProgress = CUI_RES(RID_SVXSTR_SEARCHERROR);
     630           0 :             sProgress = sProgress.replaceAll("%1", m_aURL);
     631           0 :             m_pPersonaDialog->SetProgress(sProgress);
     632           0 :             return;
     633             :         }
     634             : 
     635           0 :         xml::sax::InputSource aParserInput;
     636           0 :         aParserInput.aInputStream = xStream;
     637           0 :         xParser->parseStream( aParserInput );
     638             : 
     639           0 :         if( !pHandler->hasResults() )
     640             :         {
     641           0 :             sProgress = CUI_RES( RID_SVXSTR_NORESULTS );
     642           0 :             m_pPersonaDialog->SetProgress( sProgress );
     643           0 :             return;
     644             :         }
     645             : 
     646           0 :         std::vector<OUString> vLearnmoreURLs = pHandler->getLearnmoreURLs();
     647           0 :         std::vector<OUString>::iterator it;
     648           0 :         sal_Int32 nIndex = 0;
     649           0 :         GraphicFilter aFilter;
     650           0 :         Graphic aGraphic;
     651             : 
     652           0 :         for( it = vLearnmoreURLs.begin(); it!=vLearnmoreURLs.end(); ++it )
     653             :         {
     654           0 :             OUString sPreviewFile, aPersonaSetting;
     655           0 :             getPreviewFile( *it, &sPreviewFile, &aPersonaSetting );
     656           0 :             INetURLObject aURLObj( sPreviewFile );
     657           0 :             aFilter.ImportGraphic( aGraphic, aURLObj );
     658           0 :             Bitmap aBmp = aGraphic.GetBitmap();
     659             : 
     660           0 :             if( !m_bExecute )
     661           0 :                 return;
     662             : 
     663             :             // for VCL to be able to do visual changes in the thread
     664           0 :             SolarMutexGuard aGuard;
     665           0 :             m_pPersonaDialog->SetImages( Image( aBmp ), nIndex++ );
     666           0 :             m_pPersonaDialog->setOptimalLayoutSize();
     667           0 :             m_pPersonaDialog->AddPersonaSetting( aPersonaSetting );
     668           0 :         }
     669             : 
     670           0 :         if( !m_bExecute )
     671           0 :             return;
     672             : 
     673           0 :         SolarMutexGuard aGuard;
     674           0 :         sProgress.clear();
     675           0 :         m_pPersonaDialog->SetProgress( sProgress );
     676           0 :         m_pPersonaDialog->setOptimalLayoutSize();
     677             :     }
     678             : 
     679             :     else
     680             :     {
     681           0 :         OUString sProgress( CUI_RES( RID_SVXSTR_APPLYPERSONA ) );
     682           0 :         m_pPersonaDialog->SetProgress( sProgress );
     683             : 
     684           0 :         uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY );
     685           0 :         if ( !xFileAccess.is() )
     686           0 :             return;
     687             : 
     688           0 :         OUString aName, aHeaderURL, aFooterURL, aTextColor, aAccentColor;
     689           0 :         OUString aPersonaSetting;
     690             : 
     691             :         // get the required fields from m_aURL
     692           0 :         sal_Int32 nOldIndex = 0;
     693           0 :         sal_Int32 nNewIndex = m_aURL.indexOf( ';', nOldIndex );
     694           0 :         aName = m_aURL.copy( nOldIndex, ( nNewIndex - nOldIndex ) );
     695             : 
     696           0 :         nOldIndex = nNewIndex + 1;
     697           0 :         nNewIndex = m_aURL.indexOf( ';', nOldIndex );
     698           0 :         aHeaderURL = m_aURL.copy(nOldIndex , ( nNewIndex - nOldIndex ) );
     699             : 
     700           0 :         nOldIndex = nNewIndex + 1;
     701           0 :         nNewIndex = m_aURL.indexOf( ';', nOldIndex );
     702           0 :         aFooterURL = m_aURL.copy( nOldIndex,  ( nNewIndex - nOldIndex ) );
     703             : 
     704           0 :         nOldIndex = nNewIndex + 1;
     705           0 :         nNewIndex = m_aURL.indexOf( ';', nOldIndex );
     706           0 :         aTextColor = m_aURL.copy( nOldIndex, ( nNewIndex - nOldIndex ) );
     707             : 
     708           0 :         nOldIndex = nNewIndex + 1;
     709           0 :         nNewIndex = m_aURL.getLength();
     710           0 :         aAccentColor = m_aURL.copy( nOldIndex, ( nNewIndex - nOldIndex ) );
     711             : 
     712             :         // copy the images to the user's gallery
     713           0 :         OUString gallery = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}";
     714           0 :         rtl::Bootstrap::expandMacros( gallery );
     715           0 :         gallery += "/user/gallery/personas/";
     716           0 :         osl::Directory::createPath( gallery );
     717             : 
     718           0 :         OUString aHeaderFile( INetURLObject( aHeaderURL ).getName() );
     719           0 :         OUString aFooterFile( INetURLObject( aFooterURL ).getName() );
     720             : 
     721           0 :         aHeaderFile = aName + "/" + aHeaderFile;
     722           0 :         aFooterFile = aName + "/" + aFooterFile;
     723             : 
     724             :         try {
     725           0 :             xFileAccess->copy( aHeaderURL, gallery + aHeaderFile );
     726           0 :             xFileAccess->copy( aFooterURL, gallery + aFooterFile );
     727             :         }
     728           0 :         catch ( const uno::Exception & )
     729             :         {
     730           0 :             sProgress = CUI_RES( RID_SVXSTR_SEARCHERROR );
     731           0 :             sProgress = sProgress.replaceAll("%1", m_aURL);
     732           0 :             m_pPersonaDialog->SetProgress( sProgress );
     733           0 :             return;
     734             :         }
     735             : 
     736           0 :         if( !m_bExecute )
     737           0 :             return;
     738             : 
     739           0 :         SolarMutexGuard aGuard;
     740             : 
     741           0 :         aPersonaSetting = aHeaderFile + ";" + aFooterFile + ";" + aTextColor + ";" + aAccentColor;
     742           0 :         m_pPersonaDialog->SetAppliedPersonaSetting( aPersonaSetting );
     743           0 :         m_pPersonaDialog->EndDialog( RET_OK );
     744             :     }
     745             : }
     746             : 
     747           0 : void SearchAndParseThread::getPreviewFile( const OUString& rURL, OUString *pPreviewFile, OUString *pPersonaSetting )
     748             : {
     749           0 :     uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY );
     750           0 :     if ( !xFileAccess.is() )
     751           0 :         return;
     752             : 
     753           0 :     uno::Reference< io::XInputStream > xStream;
     754             :     try {
     755           0 :         xStream = xFileAccess->openFileRead( rURL );
     756             :     }
     757           0 :     catch (...)
     758             :     {
     759           0 :         OUString sProgress( CUI_RES( RID_SVXSTR_SEARCHERROR ) );
     760           0 :         sProgress = sProgress.replaceAll("%1", m_aURL);
     761           0 :         m_pPersonaDialog->SetProgress( sProgress );
     762           0 :         return;
     763             :     }
     764           0 :     if ( !xStream.is() )
     765           0 :         return;
     766             : 
     767             :     // read the persona specification
     768             :     // NOTE: Parsing for real is an overkill here; and worse - I tried, and
     769             :     // the HTML the site provides is not 100% valid ;-)
     770           0 :     const sal_Int32 BUF_LEN = 8000;
     771           0 :     uno::Sequence< sal_Int8 > buffer( BUF_LEN );
     772           0 :     OStringBuffer aBuffer( 64000 );
     773             : 
     774           0 :     sal_Int32 nRead = 0;
     775           0 :     while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN )
     776           0 :         aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
     777             : 
     778           0 :     if ( nRead > 0 )
     779           0 :         aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
     780             : 
     781           0 :     xStream->closeInput();
     782             : 
     783             :     // get the important bits of info
     784           0 :     OUString aHeaderURL, aFooterURL, aTextColor, aAccentColor, aPreviewURL, aName;
     785             : 
     786           0 :     if ( !parsePersonaInfo( aBuffer.makeStringAndClear(), &aHeaderURL, &aFooterURL, &aTextColor, &aAccentColor, &aPreviewURL, &aName ) )
     787           0 :         return;
     788             : 
     789             :     // copy the images to the user's gallery
     790           0 :     OUString gallery = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}";
     791           0 :     rtl::Bootstrap::expandMacros( gallery );
     792           0 :     gallery += "/user/gallery/personas/";
     793           0 :     gallery += aName + "/";
     794           0 :     osl::Directory::createPath( gallery );
     795             : 
     796           0 :     OUString aPreviewFile( INetURLObject( aPreviewURL ).getName() );
     797             : 
     798             :     try {
     799           0 :         xFileAccess->copy( aPreviewURL, gallery + aPreviewFile );
     800             :     }
     801           0 :     catch ( const uno::Exception & )
     802             :     {
     803           0 :         return;
     804             :     }
     805           0 :     *pPreviewFile = gallery + aPreviewFile;
     806           0 :     *pPersonaSetting = aName + ";" + aHeaderURL + ";" + aFooterURL + ";" + aTextColor + ";" + aAccentColor;
     807           0 : }
     808             : 
     809             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11