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

Generated by: LCOV version 1.10