diff options
author | Muhammet Kara <muhammet.kara@collabora.com> | 2019-05-22 22:25:37 +0300 |
---|---|---|
committer | Muhammet Kara <muhammet.kara@collabora.com> | 2019-05-23 13:44:20 +0200 |
commit | e1e9e2aa16f08a8fd9e38db706d63e8eceeda8d1 (patch) | |
tree | 03bb85ac09cc6bd4131e524b0c6c828c1255f79a /cui | |
parent | dd5c9897c4930cb30bd8e5d6a0018b9515970111 (diff) |
Kill Mozilla personas
As per ESC & Design Team decisions.
It has become unusable anyway after major changes
on the Mozilla side.
Long live Libreoffice Themes! :)
Change-Id: I2893fbc5e4f5637ee9715fa426b92ca58534f126
Reviewed-on: https://gerrit.libreoffice.org/72811
Tested-by: Jenkins
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
Reviewed-by: Heiko Tietze <tietze.heiko@gmail.com>
Reviewed-by: Muhammet Kara <muhammet.kara@collabora.com>
Diffstat (limited to 'cui')
-rw-r--r-- | cui/UIConfig_cui.mk | 1 | ||||
-rw-r--r-- | cui/inc/strings.hrc | 1 | ||||
-rw-r--r-- | cui/qa/unit/data/cui-dialogs-test_4.txt | 1 | ||||
-rw-r--r-- | cui/source/options/personalization.cxx | 861 | ||||
-rw-r--r-- | cui/source/options/personalization.hxx | 112 | ||||
-rw-r--r-- | cui/uiconfig/ui/personalization_tab.ui | 113 | ||||
-rw-r--r-- | cui/uiconfig/ui/select_persona_dialog.ui | 339 |
7 files changed, 1 insertions, 1427 deletions
diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk index a20d96e6d4b0..64ead226721c 100644 --- a/cui/UIConfig_cui.mk +++ b/cui/UIConfig_cui.mk @@ -179,7 +179,6 @@ $(eval $(call gb_UIConfig_add_uifiles,cui,\ cui/uiconfig/ui/searchattrdialog \ cui/uiconfig/ui/searchformatdialog \ cui/uiconfig/ui/securityoptionsdialog \ - cui/uiconfig/ui/select_persona_dialog \ cui/uiconfig/ui/selectpathdialog \ cui/uiconfig/ui/shadowtabpage \ cui/uiconfig/ui/showcoldialog \ diff --git a/cui/inc/strings.hrc b/cui/inc/strings.hrc index 7c32af629907..6627ad93bc44 100644 --- a/cui/inc/strings.hrc +++ b/cui/inc/strings.hrc @@ -368,7 +368,6 @@ #define RID_SVXSTR_NORESULTS NC_("RID_SVXSTR_NORESULTS", "No results found.") #define RID_SVXSTR_APPLYPERSONA NC_("RID_SVXSTR_APPLYPERSONA", "Applying Theme...") #define RID_SVXSTR_INVALIDPERSONAURL NC_("RID_SVXSTR_INVALIDPERSONAURL", "Please enter a valid theme address or a search term.") -#define RID_SVXSTR_MOZAPIUNREACHABLE NC_("RID_SVXSTR_MOZAPIUNREACHABLE", "The Mozilla Themes API is currently unavailable.") #define RID_SVXSTR_TABLE_PRESET_NONE NC_("RID_SVXSTR_TABLE_PRESET_NONE", "Set No Borders") #define RID_SVXSTR_TABLE_PRESET_ONLYOUTER NC_("RID_SVXSTR_TABLE_PRESET_ONLYOUTER", "Set Outer Border Only") diff --git a/cui/qa/unit/data/cui-dialogs-test_4.txt b/cui/qa/unit/data/cui-dialogs-test_4.txt index eea768ef72b6..eaa3a6ce3dd8 100644 --- a/cui/qa/unit/data/cui-dialogs-test_4.txt +++ b/cui/qa/unit/data/cui-dialogs-test_4.txt @@ -47,7 +47,6 @@ cui/ui/scriptorganizer.ui cui/ui/searchattrdialog.ui cui/ui/searchformatdialog.ui cui/ui/securityoptionsdialog.ui -cui/ui/select_persona_dialog.ui cui/ui/selectpathdialog.ui cui/ui/shadowtabpage.ui cui/ui/showcoldialog.ui diff --git a/cui/source/options/personalization.cxx b/cui/source/options/personalization.cxx index b1f9d3f38e4e..0ab9a28fecc8 100644 --- a/cui/source/options/personalization.cxx +++ b/cui/source/options/personalization.cxx @@ -20,12 +20,7 @@ #include <rtl/strbuf.hxx> #include <tools/urlobj.hxx> #include <tools/stream.hxx> -#include <vcl/edit.hxx> #include <vcl/event.hxx> -#include <vcl/fixed.hxx> -#include <vcl/fixedhyper.hxx> -#include <vcl/weld.hxx> -#include <vcl/lstbox.hxx> #include <vcl/svapp.hxx> #include <vcl/settings.hxx> #include <vcl/graphicfilter.hxx> @@ -41,12 +36,6 @@ #include <ucbhelper/content.hxx> #include <comphelper/simplefileaccessinteraction.hxx> -#include <curl/curl.h> - -#include <orcus/json_document_tree.hpp> -#include <orcus/config.hpp> -#include <orcus/pstring.hpp> - #include <vector> using namespace com::sun::star; @@ -54,12 +43,6 @@ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::ucb; using namespace ::com::sun::star::beans; -#ifdef UNX -static const char kUserAgent[] = "LibreOffice PersonaDownloader/1.0 (Linux)"; -#else -static const char kUserAgent[] = "LibreOffice PersonaDownloader/1.0 (unknown platform)"; -#endif - struct PersonaInfo { OUString sSlug; @@ -70,343 +53,12 @@ struct PersonaInfo OUString sTextColor; }; -namespace { - -// Callback to get the response data from server. -size_t WriteCallback(void *ptr, size_t size, - size_t nmemb, void *userp) -{ - if (!userp) - return 0; - - std::string* response = static_cast<std::string *>(userp); - size_t real_size = size * nmemb; - response->append(static_cast<char *>(ptr), real_size); - return real_size; -} - -// Callback to get the response data from server to a file. -size_t WriteCallbackFile(void *ptr, size_t size, - size_t nmemb, void *userp) -{ - if (!userp) - return 0; - - SvStream* response = static_cast<SvStream *>(userp); - size_t real_size = size * nmemb; - response->WriteBytes(ptr, real_size); - return real_size; -} - -// Gets the content of the given URL and returns as a standard string -std::string curlGet(const OString& rURL) -{ - CURL* curl = curl_easy_init(); - - if (!curl) - return std::string(); - - curl_easy_setopt(curl, CURLOPT_URL, rURL.getStr()); - curl_easy_setopt(curl, CURLOPT_USERAGENT, kUserAgent); - - std::string response_body; - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, - static_cast<void *>(&response_body)); - - CURLcode cc = curl_easy_perform(curl); - long http_code = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - - if (http_code != 200) - { - SAL_WARN("cui.options", "Download failed. Error code: " << http_code); - } - - if (cc != CURLE_OK) - { - SAL_WARN("cui.options", "curl error: " << cc); - } - - return response_body; -} - -// Downloads and saves the file at the given rURL to a local path (sFileURL) -void curlDownload(const OString& rURL, const OUString& sFileURL) -{ - CURL* curl = curl_easy_init(); - SvFileStream aFile( sFileURL, StreamMode::WRITE ); - - if (!curl) - return; - - curl_easy_setopt(curl, CURLOPT_URL, rURL.getStr()); - curl_easy_setopt(curl, CURLOPT_USERAGENT, kUserAgent); - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallbackFile); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, - static_cast<void *>(&aFile)); - - CURLcode cc = curl_easy_perform(curl); - long http_code = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - - if (http_code != 200) - { - SAL_WARN("cui.options", "Download failed. Error code: " << http_code); - } - - if (cc != CURLE_OK) - { - SAL_WARN("cui.options", "curl error: " << cc); - } -} - -} //End of anonymous namespace -SelectPersonaDialog::SelectPersonaDialog(weld::Window *pParent) - : GenericDialogController(pParent, "cui/ui/select_persona_dialog.ui", "SelectPersonaDialog") - , m_xEdit(m_xBuilder->weld_entry("search_term")) - , m_xSearchButton(m_xBuilder->weld_button("search_personas")) - , m_xProgressLabel(m_xBuilder->weld_label("progress_label")) - , m_xCategories(m_xBuilder->weld_combo_box("categoriesCB")) - , m_xOkButton(m_xBuilder->weld_button("ok")) - , m_xCancelButton(m_xBuilder->weld_button("cancel")) - , m_vResultList{ m_xBuilder->weld_button("result1"), - m_xBuilder->weld_button("result2"), - m_xBuilder->weld_button("result3"), - m_xBuilder->weld_button("result4"), - m_xBuilder->weld_button("result5"), - m_xBuilder->weld_button("result6"), - m_xBuilder->weld_button("result7"), - m_xBuilder->weld_button("result8"), - m_xBuilder->weld_button("result9") } -{ - m_xSearchButton->connect_clicked( LINK( this, SelectPersonaDialog, SearchPersonas ) ); - m_xCategories->connect_changed( LINK( this, SelectPersonaDialog, SelectCategory ) ); - m_xOkButton->connect_clicked( LINK( this, SelectPersonaDialog, ActionOK ) ); - m_xCancelButton->connect_clicked( LINK( this, SelectPersonaDialog, ActionCancel ) ); - - for (auto & nIndex : m_vResultList) - { - nIndex->connect_clicked( LINK( this, SelectPersonaDialog, SelectPersona ) ); - nIndex->set_sensitive(false); - } - - m_xCategories->set_active_text("Featured"); - SelectCategory(*m_xCategories); -} - -SelectPersonaDialog::~SelectPersonaDialog() -{ - if (m_pSearchThread.is()) - { - // Release the solar mutex, so the thread is not affected by the race - // when it's after the m_bExecute check but before taking the solar - // mutex. - SolarMutexReleaser aReleaser; - m_pSearchThread->join(); - } -} - -OUString SelectPersonaDialog::GetSelectedPersona() const -{ - if( !m_aSelectedPersona.isEmpty( ) ) - return m_aSelectedPersona; - - return OUString(); -} - -IMPL_LINK_NOARG( SelectPersonaDialog, SearchPersonas, weld::Button&, void ) -{ - OUString searchTerm = m_xEdit->get_text(); - - if( searchTerm.isEmpty( ) ) - return; - - if( m_pSearchThread.is() ) - m_pSearchThread->StopExecution(); - - // Direct url of a persona given - if ( searchTerm.startsWith( "https://addons.mozilla.org/" ) ) - { - OUString sSlug = searchTerm.getToken( 6, '/' ); - - // Check if we got the slug - if ( sSlug.isEmpty() ) - { - SolarMutexGuard aGuard; - OUString sError = CuiResId( RID_SVXSTR_INVALIDPERSONAURL ); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr, - VclMessageType::Error, VclButtonsType::Ok, - sError)); - xBox->run(); - return; - } - - // Remove invalid characters - searchTerm = searchTerm.replaceAll("?", ""); - - m_pSearchThread = new SearchAndParseThread( this, sSlug, true ); - } - // Search term given - else - { - // Remove invalid characters - searchTerm = searchTerm.replaceAll("/", ""); - searchTerm = searchTerm.replaceAll("?", ""); - - // 15 results so that invalid and duplicate search results whose names, textcolors etc. are null can be skipped - OUString rSearchURL = "https://addons.mozilla.org/api/v3/addons/search/?q=" + searchTerm + "&type=persona&page_size=15"; - - m_pSearchThread = new SearchAndParseThread( this, rSearchURL, false ); - } - - m_pSearchThread->launch(); -} - -IMPL_LINK_NOARG( SelectPersonaDialog, ActionOK, weld::Button&, void ) -{ - OUString aSelectedPersona = GetSelectedPersona(); - - if( !aSelectedPersona.isEmpty() ) - { - m_pGetPersonaThread = new GetPersonaThread( this, aSelectedPersona ); - m_pGetPersonaThread->launch(); - } - - else - { - if ( m_pSearchThread.is() ) - m_pSearchThread->StopExecution(); - - m_xDialog->response(RET_OK); - } -} - -IMPL_LINK_NOARG( SelectPersonaDialog, ActionCancel, weld::Button&, void ) -{ - if( m_pSearchThread.is() ) - m_pSearchThread->StopExecution(); - if( m_pGetPersonaThread.is() ) - m_pGetPersonaThread->StopExecution(); - - m_xDialog->response(RET_CANCEL); -} - -IMPL_LINK_NOARG( SelectPersonaDialog, SelectCategory, weld::ComboBox&, void ) -{ - OUString searchTerm = m_xCategories->get_active_id(); - OUString rSearchURL; - - if (searchTerm.isEmpty()) - return; - - if( m_pSearchThread.is() ) - m_pSearchThread->StopExecution(); - - // 15 results so that invalid and duplicate search results whose names, textcolors etc. are null can be skipped - if (searchTerm == "featured") - rSearchURL = "https://addons.mozilla.org/api/v3/addons/search/?type=persona&app=firefox&status=public&sort=users&featured=true&page_size=15"; - else - rSearchURL = "https://addons.mozilla.org/api/v3/addons/search/?type=persona&app=firefox&category=" + searchTerm + "&status=public&sort=downloads&page_size=15"; - - m_pSearchThread = new SearchAndParseThread( this, rSearchURL, false ); - - m_pSearchThread->launch(); -} - -IMPL_LINK( SelectPersonaDialog, SelectPersona, weld::Button&, rButton, void ) -{ - if( m_pSearchThread.is() ) - m_pSearchThread->StopExecution(); - if ( m_pGetPersonaThread.is() ) - return; - - for( sal_Int32 index = 0; index < MAX_RESULTS; index++ ) - { - if( &rButton == m_vResultList[index].get() ) - { - if( !m_vPersonaSettings[index].isEmpty() ) - { - m_aSelectedPersona = m_vPersonaSettings[index]; - - // get the persona name from the setting variable to show in the progress. - OUString aName( m_aSelectedPersona.getToken( 1, ';' ) ); - OUString aProgress( CuiResId(RID_SVXSTR_SELECTEDPERSONA) + aName ); - - SetProgress( aProgress ); - } - break; - } - } -} - -void SelectPersonaDialog::SetAppliedPersonaSetting( OUString const & rPersonaSetting ) -{ - m_aAppliedPersona = rPersonaSetting; -} - -const OUString& SelectPersonaDialog::GetAppliedPersonaSetting() const -{ - return m_aAppliedPersona; -} - -void SelectPersonaDialog::SetProgress( const OUString& rProgress ) -{ - if(rProgress.isEmpty()) - m_xProgressLabel->hide(); - else - { - SolarMutexGuard aGuard; - m_xProgressLabel->show(); - m_xProgressLabel->set_label( rProgress ); - m_xDialog->resize_to_request(); //TODO - } -} - -void SelectPersonaDialog::SetImages( VirtualDevice& rImage, const OUString& sName, const sal_Int32& nIndex ) -{ - m_vResultList[nIndex]->set_sensitive(true); - m_vResultList[nIndex]->set_image(&rImage); - m_vResultList[nIndex]->set_tooltip_text( sName ); -} - -void SelectPersonaDialog::AddPersonaSetting( OUString const & rPersonaSetting ) -{ - m_vPersonaSettings.push_back( rPersonaSetting ); -} - -void SelectPersonaDialog::ClearSearchResults() -{ - // for VCL to be able to destroy bitmaps - SolarMutexGuard aGuard; - m_vPersonaSettings.clear(); - m_aSelectedPersona.clear(); - for(auto & nIndex : m_vResultList) - { - nIndex->set_sensitive(false); - nIndex->set_image(nullptr); - } -} - SvxPersonalizationTabPage::SvxPersonalizationTabPage( vcl::Window *pParent, const SfxItemSet &rSet ) : SfxTabPage( pParent, "PersonalizationTabPage", "cui/ui/personalization_tab.ui", &rSet ) { // persona get( m_pNoPersona, "no_persona" ); get( m_pDefaultPersona, "default_persona" ); - get( m_pAppliedThemeLabel, "applied_theme_link" ); - - get( m_pOwnPersona, "own_persona" ); - get( m_pSelectPersona, "select_persona" ); - - // Mozilla API and the Mozilla personas are no longer useful for us - // We will probably remove this altogether before 6.3 - m_pSelectPersona->Disable(); - m_pOwnPersona->Disable(); - m_pSelectPersona->SetQuickHelpText( CuiResId( RID_SVXSTR_MOZAPIUNREACHABLE ) ); - m_pOwnPersona->SetQuickHelpText( CuiResId( RID_SVXSTR_MOZAPIUNREACHABLE ) ); for (sal_uInt32 i = 0; i < MAX_DEFAULT_PERSONAS; ++i) { @@ -415,16 +67,7 @@ SvxPersonalizationTabPage::SvxPersonalizationTabPage( vcl::Window *pParent, cons m_vDefaultPersonaImages[i]->SetClickHdl( LINK( this, SvxPersonalizationTabPage, DefaultPersona ) ); } - get( m_pPersonaList, "installed_personas" ); - m_pPersonaList->SetSelectHdl( LINK( this, SvxPersonalizationTabPage, SelectInstalledPersona ) ); - - get( m_pExtensionPersonaPreview, "persona_preview" ); - - get ( m_pExtensionLabel, "extensions_label" ); - - CheckAppliedTheme(); LoadDefaultImages(); - LoadExtensionThemes(); } SvxPersonalizationTabPage::~SvxPersonalizationTabPage() @@ -436,14 +79,8 @@ void SvxPersonalizationTabPage::dispose() { m_pNoPersona.clear(); m_pDefaultPersona.clear(); - m_pOwnPersona.clear(); - m_pSelectPersona.clear(); for (VclPtr<PushButton> & i : m_vDefaultPersonaImages) i.clear(); - m_pExtensionPersonaPreview.clear(); - m_pPersonaList.clear(); - m_pExtensionLabel.clear(); - m_pAppliedThemeLabel.clear(); SfxTabPage::dispose(); } @@ -459,8 +96,6 @@ bool SvxPersonalizationTabPage::FillItemSet( SfxItemSet * ) OUString aPersona( "default" ); if ( m_pNoPersona->IsChecked() ) aPersona = "no"; - else if ( m_pOwnPersona->IsChecked() ) - aPersona = "own"; bool bModified = false; uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() ); @@ -503,54 +138,10 @@ void SvxPersonalizationTabPage::Reset( const SfxItemSet * ) if ( aPersona == "no" ) m_pNoPersona->Check(); - else if ( aPersona == "own" ) - m_pOwnPersona->Check(); else m_pDefaultPersona->Check(); } -void SvxPersonalizationTabPage::SetPersonaSettings( const OUString& aPersonaSettings ) -{ - m_aPersonaSettings = aPersonaSettings; - ShowAppliedThemeLabel( m_aPersonaSettings ); - m_pOwnPersona->Check(); -} - -void SvxPersonalizationTabPage::CheckAppliedTheme() -{ - uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() ); - OUString aPersona( "default" ), aPersonaSetting; - if ( xContext.is()) - { - aPersona = officecfg::Office::Common::Misc::Persona::get( xContext ); - aPersonaSetting = officecfg::Office::Common::Misc::PersonaSettings::get( xContext ); - } - if(aPersona == "own") - ShowAppliedThemeLabel(aPersonaSetting); -} - -void SvxPersonalizationTabPage::ShowAppliedThemeLabel(const OUString& aPersonaSetting) -{ - OUString aSlug, aName; - sal_Int32 nIndex = 0; - - aSlug = aPersonaSetting.getToken( 0, ';', nIndex ); - - if ( nIndex > 0 ) - aName = "(" + aPersonaSetting.getToken( 0, ';', nIndex ) + ")"; - - if ( !aName.isEmpty() ) - { - m_pAppliedThemeLabel->SetText( aName ); - m_pAppliedThemeLabel->SetURL( "https://addons.mozilla.org/en-US/firefox/addon/" + aSlug + "/" ); - m_pAppliedThemeLabel->Show(); - } - else - { - SAL_WARN("cui.options", "Applied persona doesn't have a name!"); - } -} - void SvxPersonalizationTabPage::LoadDefaultImages() { // Load the pre saved personas @@ -593,71 +184,6 @@ void SvxPersonalizationTabPage::LoadDefaultImages() m_pDefaultPersona->Enable(foundOne); } -void SvxPersonalizationTabPage::LoadExtensionThemes() -{ - // See if any extensions are used to install personas. If yes, load them. - - css::uno::Sequence<OUString> installedPersonas( officecfg::Office::Common::Misc::PersonasList::get()->getElementNames() ); - sal_Int32 nLength = installedPersonas.getLength(); - - if( nLength == 0 ) - return; - - m_pPersonaList->Show(); - m_pExtensionLabel->Show(); - - for( sal_Int32 nIndex = 0; nIndex < nLength; nIndex++ ) - { - Reference< XPropertySet > xPropertySet( officecfg::Office::Common::Misc::PersonasList::get()->getByName( installedPersonas[nIndex] ), UNO_QUERY_THROW ); - OUString aPersonaSlug, aPersonaName, aPreviewFile, aHeaderFile, aFooterFile, aTextColor, aPersonaSettings; - - Any aValue = xPropertySet->getPropertyValue( "Slug" ); - aValue >>= aPersonaSlug; - - aValue = xPropertySet->getPropertyValue( "Name" ); - aValue >>= aPersonaName; - m_pPersonaList->InsertEntry( aPersonaName ); - - aValue = xPropertySet->getPropertyValue( "Preview" ); - aValue >>= aPreviewFile; - - aValue = xPropertySet->getPropertyValue( "Header" ); - aValue >>= aHeaderFile; - - aValue = xPropertySet->getPropertyValue( "Footer" ); - aValue >>= aFooterFile; - - aValue = xPropertySet->getPropertyValue( "TextColor" ); - aValue >>= aTextColor; - - aPersonaSettings = aPersonaSlug + ";" + aPersonaName + ";" + aPreviewFile - + ";" + aHeaderFile + ";" + aFooterFile + ";" + aTextColor; - rtl::Bootstrap::expandMacros( aPersonaSettings ); - m_vExtensionPersonaSettings.push_back( aPersonaSettings ); - } -} - -IMPL_LINK_NOARG( SvxPersonalizationTabPage, SelectPersona, Button*, void ) -{ - m_pOwnPersona->Check(); - SelectPersonaDialog aDialog(GetDialogFrameWeld()); - - if (aDialog.run() == RET_OK) - { - OUString aPersonaSetting(aDialog.GetAppliedPersonaSetting()); - if ( !aPersonaSetting.isEmpty() ) - { - SetPersonaSettings( aPersonaSetting ); - } - } -} - -IMPL_LINK( SvxPersonalizationTabPage, ForceSelect, Button*, pButton, void ) -{ - if ( pButton == m_pOwnPersona && m_aPersonaSettings.isEmpty() ) - SelectPersona( m_pSelectPersona ); -} - IMPL_LINK( SvxPersonalizationTabPage, DefaultPersona, Button*, pButton, void ) { m_pDefaultPersona->Check(); @@ -668,391 +194,4 @@ IMPL_LINK( SvxPersonalizationTabPage, DefaultPersona, Button*, pButton, void ) } } -IMPL_LINK_NOARG( SvxPersonalizationTabPage, SelectInstalledPersona, ListBox&, void) -{ - m_pOwnPersona->Check(); - - // Get the details of the selected theme. - m_pExtensionPersonaPreview->Show(); - sal_Int32 nSelectedPos = m_pPersonaList->GetSelectedEntryPos(); - OUString aSettings = m_vExtensionPersonaSettings[nSelectedPos]; - sal_Int32 nIndex = aSettings.indexOf( ';' ); - OUString aPreviewFile = aSettings.copy( 0, nIndex ); - m_aPersonaSettings = aSettings.copy( nIndex + 1 ); - - // Show the preview file in the button. - GraphicFilter aFilter; - Graphic aGraphic; - INetURLObject aURLObj( aPreviewFile ); - aFilter.ImportGraphic( aGraphic, aURLObj ); - BitmapEx aBmp = aGraphic.GetBitmapEx(); - m_pExtensionPersonaPreview->SetModeImage( Image( aBmp ) ); -} - -SearchAndParseThread::SearchAndParseThread( SelectPersonaDialog* pDialog, - const OUString& rURL, bool bDirectURL ) : - Thread( "cuiPersonasSearchThread" ), - m_pPersonaDialog( pDialog ), - m_aURL( rURL ), - m_bExecute( true ), - m_bDirectURL( bDirectURL ) -{ -} - -SearchAndParseThread::~SearchAndParseThread() -{ -} - -namespace { - -bool getPreviewFile( const PersonaInfo& aPersonaInfo, OUString& pPreviewFile ) -{ - uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY ); - Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() ); - - // copy the images to the user's gallery - OUString gallery = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}"; - rtl::Bootstrap::expandMacros( gallery ); - gallery += "/user/gallery/personas/" + aPersonaInfo.sSlug + "/"; - - OUString aPreviewFile( INetURLObject( aPersonaInfo.sPreviewURL ).getName() ); - OString aPreviewURL = OUStringToOString( aPersonaInfo.sPreviewURL, RTL_TEXTENCODING_UTF8 ); - - try { - osl::Directory::createPath( gallery ); - - if ( !xFileAccess->exists( gallery + aPreviewFile ) ) - curlDownload(aPreviewURL, gallery + aPreviewFile); - } - catch ( const uno::Exception & ) - { - return false; - } - pPreviewFile = gallery + aPreviewFile; - return true; -} - -void parseResponse(const std::string& rResponse, std::vector<PersonaInfo> & aPersonas) -{ - orcus::json::document_tree aJsonDoc; - orcus::json_config aConfig; - - if (rResponse.empty()) - return; - - aJsonDoc.load(rResponse, aConfig); - - auto aDocumentRoot = aJsonDoc.get_document_root(); - if (aDocumentRoot.type() != orcus::json::node_t::object) - { - SAL_WARN("cui.options", "invalid root entries: " << rResponse); - return; - } - - auto resultsArray = aDocumentRoot.child("results"); - - for (size_t i = 0; i < resultsArray.child_count(); ++i) - { - auto arrayElement = resultsArray.child(i); - - try - { - PersonaInfo aNewPersona = { - OStringToOUString( OString(arrayElement.child("slug").string_value().get()), - RTL_TEXTENCODING_UTF8 ), - OStringToOUString( OString(arrayElement.child("name").child("en-US").string_value().get()), - RTL_TEXTENCODING_UTF8 ), - OStringToOUString( OString(arrayElement.child("theme_data").child("previewURL").string_value().get()), - RTL_TEXTENCODING_UTF8 ), - OStringToOUString( OString(arrayElement.child("theme_data").child("headerURL").string_value().get()), - RTL_TEXTENCODING_UTF8 ), - OStringToOUString( OString(arrayElement.child("theme_data").child("footerURL").string_value().get()), - RTL_TEXTENCODING_UTF8 ), - OStringToOUString( OString(arrayElement.child("theme_data").child("textcolor").string_value().get()), - RTL_TEXTENCODING_UTF8 ) - }; - - aPersonas.push_back(aNewPersona); - } - catch(orcus::json::document_error& e) - { - // This usually happens when one of the values is null (type() == orcus::json::node_t::null) - // TODO: Allow null values in personas. - SAL_WARN("cui.options", "Persona JSON parse error: " << e.what()); - } - } -} - -PersonaInfo parseSingleResponse(const std::string& rResponse) -{ - orcus::json::document_tree aJsonDoc; - orcus::json_config aConfig; - - if (rResponse.empty()) - return PersonaInfo(); - - aJsonDoc.load(rResponse, aConfig); - - auto aDocumentRoot = aJsonDoc.get_document_root(); - if (aDocumentRoot.type() != orcus::json::node_t::object) - { - SAL_WARN("cui.options", "invalid root entries: " << rResponse); - return PersonaInfo(); - } - - try - { - auto theme_data = aDocumentRoot.child("theme_data"); - - PersonaInfo aNewPersona = { - OUString(), - OStringToOUString( OString(theme_data.child("name").string_value().get()), - RTL_TEXTENCODING_UTF8 ), - OStringToOUString( OString(theme_data.child("previewURL").string_value().get()), - RTL_TEXTENCODING_UTF8 ), - OStringToOUString( OString(theme_data.child("headerURL").string_value().get()), - RTL_TEXTENCODING_UTF8 ), - OStringToOUString( OString(theme_data.child("footerURL").string_value().get()), - RTL_TEXTENCODING_UTF8 ), - OStringToOUString( OString(theme_data.child("textcolor").string_value().get()), - RTL_TEXTENCODING_UTF8 ) - }; - - return aNewPersona; - } - catch(orcus::json::document_error& e) - { - // This usually happens when one of the values is null (type() == orcus::json::node_t::null) - // TODO: Allow null values in personas. - // TODO: Give a message to the user - SAL_WARN("cui.options", "Persona JSON parse error: " << e.what()); - return PersonaInfo(); - } -} - -} //End of anonymous namespace - -void SearchAndParseThread::execute() -{ - m_pPersonaDialog->ClearSearchResults(); - OUString sProgress( CuiResId( RID_SVXSTR_SEARCHING ) ); - m_pPersonaDialog->SetProgress( sProgress ); - - uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY ); - - if (!m_bDirectURL) - { - OString rURL = OUStringToOString( m_aURL, RTL_TEXTENCODING_UTF8 ); - std::string sResponse = curlGet(rURL); - - std::vector<PersonaInfo> personaInfos; - - parseResponse(sResponse, personaInfos); - - if ( personaInfos.empty() ) - { - sProgress = CuiResId( RID_SVXSTR_NORESULTS ); - m_pPersonaDialog->SetProgress( sProgress ); - return; - } - else - { - //Get Preview Files - sal_Int32 nIndex = 0; - for (const auto & personaInfo : personaInfos) - { - if( !m_bExecute ) - return; - - OUString aPreviewFile; - bool bResult = getPreviewFile(personaInfo, aPreviewFile); - - if (!bResult) - { - SAL_INFO("cui.options", "Couldn't get the preview file. Skipping: " << aPreviewFile); - continue; - } - - - GraphicFilter aFilter; - Graphic aGraphic; - - INetURLObject aURLObj( aPreviewFile ); - - OUString aPersonaSetting = personaInfo.sSlug - + ";" + personaInfo.sName - + ";" + personaInfo.sPreviewURL - + ";" + personaInfo.sHeaderURL - + ";" + personaInfo.sFooterURL - + ";" + personaInfo.sTextColor; - - m_pPersonaDialog->AddPersonaSetting( aPersonaSetting ); - - // for VCL to be able to create bitmaps / do visual changes in the thread - SolarMutexGuard aGuard; - aFilter.ImportGraphic( aGraphic, aURLObj ); - BitmapEx aBmp = aGraphic.GetBitmapEx(); - - ScopedVclPtr<VirtualDevice> xVirDev(VclPtr<VirtualDevice>::Create()); - xVirDev->SetOutputSizePixel(aBmp.GetSizePixel()); - xVirDev->DrawBitmapEx(Point(0, 0), aBmp); - - m_pPersonaDialog->SetImages(*xVirDev, personaInfo.sName, nIndex ); - - if (++nIndex >= MAX_RESULTS) - break; - } - - //TODO: Give a message to the user if nIndex == 0 - } - } - else - { - //Now we have a slug instead a search term in m_aURL - OString rURL = "https://addons.mozilla.org/api/v3/addons/addon/" - + OUStringToOString( m_aURL, RTL_TEXTENCODING_UTF8 ) - + "/"; - std::string sResponse = curlGet(rURL); - - PersonaInfo aPersonaInfo = parseSingleResponse(sResponse); - aPersonaInfo.sSlug = m_aURL; - - if ( aPersonaInfo.sName.isEmpty() ) - { - //TODO: Give error message to user - sProgress = CuiResId( RID_SVXSTR_NORESULTS ); - m_pPersonaDialog->SetProgress( sProgress ); - return; - } - else - { - //Get the preview file - if( !m_bExecute ) - return; - - OUString aPreviewFile; - bool bResult = getPreviewFile(aPersonaInfo, aPreviewFile); - - if (!bResult) - { - //TODO: Inform the user - SAL_WARN("cui.options", "Couldn't get the preview file: " << aPreviewFile); - return; - } - - GraphicFilter aFilter; - Graphic aGraphic; - - INetURLObject aURLObj( aPreviewFile ); - - OUString aPersonaSetting = aPersonaInfo.sSlug - + ";" + aPersonaInfo.sName - + ";" + aPersonaInfo.sPreviewURL - + ";" + aPersonaInfo.sHeaderURL - + ";" + aPersonaInfo.sFooterURL - + ";" + aPersonaInfo.sTextColor; - - m_pPersonaDialog->AddPersonaSetting( aPersonaSetting ); - - // for VCL to be able to create bitmaps / do visual changes in the thread - SolarMutexGuard aGuard; - aFilter.ImportGraphic( aGraphic, aURLObj ); - BitmapEx aBmp = aGraphic.GetBitmapEx(); - - ScopedVclPtr<VirtualDevice> xVirDev(VclPtr<VirtualDevice>::Create()); - xVirDev->SetOutputSizePixel(aBmp.GetSizePixel()); - xVirDev->DrawBitmapEx(Point(0, 0), aBmp); - - m_pPersonaDialog->SetImages( *xVirDev, aPersonaInfo.sName, 0 ); - } - - } - - if( !m_bExecute ) - return; - - SolarMutexGuard aGuard; - sProgress.clear(); - m_pPersonaDialog->SetProgress( sProgress ); -} - -GetPersonaThread::GetPersonaThread( SelectPersonaDialog* pDialog, - const OUString& rSelectedPersona ) : - Thread( "cuiPersonasGetPersonaThread" ), - m_pPersonaDialog( pDialog ), - m_aSelectedPersona( rSelectedPersona ), - m_bExecute( true ) -{ -} - -GetPersonaThread::~GetPersonaThread() -{ - //TODO: Clean-up -} - -void GetPersonaThread::execute() -{ - OUString sProgress( CuiResId( RID_SVXSTR_APPLYPERSONA ) ), sError; - m_pPersonaDialog->SetProgress( sProgress ); - - uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY ); - if ( !xFileAccess.is() ) - return; - - OUString aSlug, aName, aPreviewURL, aHeaderURL, aFooterURL, aTextColor; - OUString aPersonaSetting; - - // get the required fields from m_aSelectedPersona - sal_Int32 nIndex = 0; - - aSlug = m_aSelectedPersona.getToken(0, ';', nIndex); - aName = m_aSelectedPersona.getToken(0, ';', nIndex); - aPreviewURL = m_aSelectedPersona.getToken(0, ';', nIndex); - aHeaderURL = m_aSelectedPersona.getToken(0, ';', nIndex); - aFooterURL = m_aSelectedPersona.getToken(0, ';', nIndex); - aTextColor = m_aSelectedPersona.getToken(0, ';', nIndex); - - // copy the images to the user's gallery - OUString gallery = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}"; - rtl::Bootstrap::expandMacros( gallery ); - gallery += "/user/gallery/personas/"; - - OUString aPreviewFile( aSlug + "/" + INetURLObject( aPreviewURL ).getName() ); - OUString aHeaderFile( aSlug + "/" + INetURLObject( aHeaderURL ).getName() ); - OUString aFooterFile( aSlug + "/" + INetURLObject( aFooterURL ).getName() ); - - try { - osl::Directory::createPath( gallery ); - - if ( !xFileAccess->exists(gallery + aHeaderFile) ) - curlDownload( OUStringToOString(aHeaderURL, RTL_TEXTENCODING_UTF8), gallery + aHeaderFile ); - - if ( !xFileAccess->exists(gallery + aFooterFile) ) - curlDownload( OUStringToOString(aFooterURL, RTL_TEXTENCODING_UTF8), gallery + aFooterFile ); - } - catch ( const uno::Exception & ) - { - SolarMutexGuard aGuard; - sError = CuiResId( RID_SVXSTR_SEARCHERROR ); - sError = sError.replaceAll("%1", m_aSelectedPersona); - m_pPersonaDialog->SetProgress( OUString() ); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr, - VclMessageType::Error, VclButtonsType::Ok, - sError)); - xBox->run(); - return; - } - - if( !m_bExecute ) - return; - - SolarMutexGuard aGuard; - - aPersonaSetting = aSlug + ";" + aName + ";" + aPreviewFile + ";" + aHeaderFile + ";" + aFooterFile - + ";" + aTextColor; - - m_pPersonaDialog->SetAppliedPersonaSetting( aPersonaSetting ); - m_pPersonaDialog->response( RET_OK ); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cui/source/options/personalization.hxx b/cui/source/options/personalization.hxx index d54a8edb2499..dc992ccb07ea 100644 --- a/cui/source/options/personalization.hxx +++ b/cui/source/options/personalization.hxx @@ -11,22 +11,13 @@ #define INCLUDED_CUI_SOURCE_OPTIONS_PERSONALIZATION_HXX #include <sfx2/tabdlg.hxx> -#include <salhelper/thread.hxx> #include <rtl/ref.hxx> -#include <vcl/prgsbar.hxx> #include <vector> #include <array> #include <atomic> -#define MAX_RESULTS 9 // Maximum number of search results #define MAX_DEFAULT_PERSONAS 6 // Maximum number of default personas -class Edit; -class FixedText; -class FixedHyperlink; -class SearchAndParseThread; -class GetPersonaThread; - class SvxPersonalizationTabPage : public SfxTabPage { using SfxTabPage::DeactivatePage; @@ -34,17 +25,10 @@ class SvxPersonalizationTabPage : public SfxTabPage private: VclPtr<RadioButton> m_pNoPersona; ///< Just the default look, without any bitmap VclPtr<RadioButton> m_pDefaultPersona; ///< Use the built-in bitmap - VclPtr<RadioButton> m_pOwnPersona; ///< Use the user-defined bitmap - VclPtr<PushButton> m_pSelectPersona; ///< Let the user select in the 'own' case VclPtr<PushButton> m_vDefaultPersonaImages[MAX_DEFAULT_PERSONAS]; ///< Buttons to show the default persona images - VclPtr<PushButton> m_pExtensionPersonaPreview; ///< Buttons to show the last 3 personas installed via extensions - VclPtr<ListBox> m_pPersonaList; ///< The ListBox to show the list of installed personas OUString m_aPersonaSettings; ///< Header and footer images + color to be set in the settings. - VclPtr<FixedText> m_pExtensionLabel; ///< The "select persona installed via extensions" label - VclPtr<FixedHyperlink> m_pAppliedThemeLabel; ///< The label for showing applied custom theme std::vector<OUString> m_vDefaultPersonaSettings; - std::vector<OUString> m_vExtensionPersonaSettings; public: SvxPersonalizationTabPage( vcl::Window *pParent, const SfxItemSet &rSet ); @@ -59,10 +43,6 @@ public: /// Reset to default settings ([Revert] button). virtual void Reset( const SfxItemSet *rSet ) override; - void SetPersonaSettings( const OUString& ); - void CheckAppliedTheme(); - void ShowAppliedThemeLabel( const OUString& ); - /* * Loads the default personas from the shared personas directory * which resides in the shared gallery. @@ -77,105 +57,13 @@ public: * abstract;Abstract;abstract/preview.jpg;abstract/Header2.jpg;abstract/Footer2.jpg;#ffffff */ void LoadDefaultImages(); - void LoadExtensionThemes(); private: /// Handle the Persona selection DECL_LINK( SelectPersona, Button*, void ); - /// When 'own' is chosen, but the Persona is not chosen yet. - DECL_LINK( ForceSelect, Button*, void ); - /// Handle the default Persona selection DECL_LINK( DefaultPersona, Button*, void ); - - /// Handle the Personas installed through extensions selection - DECL_LINK( SelectInstalledPersona, ListBox&, void ); -}; - -/** Dialog that will allow the user to choose a Persona to use. */ -class SelectPersonaDialog : public weld::GenericDialogController -{ -private: - std::vector<OUString> m_vPersonaSettings; - OUString m_aSelectedPersona; - OUString m_aAppliedPersona; - - std::unique_ptr<weld::Entry> m_xEdit; ///< The input line for the search term - std::unique_ptr<weld::Button> m_xSearchButton; ///< The search button - std::unique_ptr<weld::Label> m_xProgressLabel; ///< The label for showing progress of search - std::unique_ptr<weld::ComboBox> m_xCategories; ///< The list of categories - std::unique_ptr<weld::Button> m_xOkButton; ///< The OK button - std::unique_ptr<weld::Button> m_xCancelButton; ///< The Cancel button - std::unique_ptr<weld::Button> m_vResultList[MAX_RESULTS]; ///< List of buttons to show search results - ::rtl::Reference< SearchAndParseThread > m_pSearchThread; - ::rtl::Reference< GetPersonaThread > m_pGetPersonaThread; - -public: - explicit SelectPersonaDialog(weld::Window *pParent); - virtual ~SelectPersonaDialog() override; - - OUString GetSelectedPersona() const; - void SetProgress( const OUString& ); - /** - * @brief Assigns preview images to result buttons - * @param aPreviewImage Persona preview image - * @param sName Name of the persona - * @param nIndex Index number of the result button - */ - void SetImages( VirtualDevice& rPreviewImage, const OUString& sName, const sal_Int32& nIndex ); - void AddPersonaSetting( OUString const & ); - void ClearSearchResults(); - void SetAppliedPersonaSetting( OUString const & ); - const OUString& GetAppliedPersonaSetting() const; - -private: - /// Handle the Search button - DECL_LINK( SearchPersonas, weld::Button&, void ); - /// Handle persona categories list box - DECL_LINK( SelectCategory, weld::ComboBox&, void ); - DECL_LINK( SelectPersona, weld::Button&, void ); - DECL_LINK( ActionOK, weld::Button&, void ); - DECL_LINK( ActionCancel, weld::Button&, void ); -}; - -class SearchAndParseThread: public salhelper::Thread -{ -private: - - SelectPersonaDialog* m_pPersonaDialog; - OUString m_aURL; - std::atomic<bool> m_bExecute; - bool m_bDirectURL; - - virtual ~SearchAndParseThread() override; - virtual void execute() override; - -public: - - SearchAndParseThread( SelectPersonaDialog* pDialog, - const OUString& rURL, bool bDirectURL ); - - void StopExecution() { m_bExecute = false; } -}; - -class GetPersonaThread: public salhelper::Thread -{ -private: - - SelectPersonaDialog* m_pPersonaDialog; - OUString m_aSelectedPersona; - std::atomic<bool> m_bExecute; - - virtual ~GetPersonaThread() override; - virtual void execute() override; - -public: - - GetPersonaThread( SelectPersonaDialog* pDialog, - const OUString& rSelectedPersona ); - - void StopExecution() { m_bExecute = false; } }; #endif // INCLUDED_CUI_SOURCE_OPTIONS_PERSONALIZATION_HXX diff --git a/cui/uiconfig/ui/personalization_tab.ui b/cui/uiconfig/ui/personalization_tab.ui index cef5483dc108..de2e74ee99f1 100644 --- a/cui/uiconfig/ui/personalization_tab.ui +++ b/cui/uiconfig/ui/personalization_tab.ui @@ -52,7 +52,6 @@ <property name="use_underline">True</property> <property name="xalign">0</property> <property name="draw_indicator">True</property> - <property name="group">own_persona</property> </object> <packing> <property name="expand">False</property> @@ -183,111 +182,6 @@ <property name="position">2</property> </packing> </child> - <child> - <object class="GtkHBox" id="hbox1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">12</property> - <property name="homogeneous">True</property> - <child> - <object class="GtkRadioButton" id="own_persona"> - <property name="label" translatable="yes" context="personalization_tab|own_persona">Own Theme</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="xalign">0</property> - <property name="draw_indicator">True</property> - <property name="group">no_persona</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLinkButton" id="applied_theme_link"> - <property name="label" translatable="no">Applied persona's name and URL</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="relief">none</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="select_persona"> - <property name="label" translatable="yes" context="personalization_tab|select_persona">Load Firefox theme</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="extensions_label"> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="personalization_tab|extensions_label">Or, select from the Themes installed via extensions:</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">4</property> - </packing> - </child> - <child> - <object class="GtkBox" id="box2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">6</property> - <child> - <object class="GtkTreeView" id="installed_personas:border"> - <property name="can_focus">True</property> - <property name="show_expanders">False</property> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection2"/> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="persona_preview"> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">5</property> - </packing> - </child> </object> </child> </object> @@ -296,7 +190,7 @@ <object class="GtkLabel" id="personas_label"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes" context="personalization_tab|personas_label">Firefox Themes</property> + <property name="label" translatable="yes" context="personalization_tab|personas_label">LibreOffice Themes</property> <attributes> <attribute name="weight" value="bold"/> </attributes> @@ -310,9 +204,4 @@ </packing> </child> </object> - <object class="GtkSizeGroup" id="sizegroup1"> - <widgets> - <widget name="select_persona"/> - </widgets> - </object> </interface> diff --git a/cui/uiconfig/ui/select_persona_dialog.ui b/cui/uiconfig/ui/select_persona_dialog.ui deleted file mode 100644 index 9c17e485fa24..000000000000 --- a/cui/uiconfig/ui/select_persona_dialog.ui +++ /dev/null @@ -1,339 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.22.1 --> -<interface domain="cui"> - <requires lib="gtk+" version="3.18"/> - <object class="GtkDialog" id="SelectPersonaDialog"> - <property name="can_focus">False</property> - <property name="border_width">6</property> - <property name="title" translatable="yes" context="select_persona_dialog|SelectPersonaDialog">Select Firefox Theme</property> - <property name="modal">True</property> - <property name="default_width">0</property> - <property name="default_height">0</property> - <property name="type_hint">dialog</property> - <child> - <placeholder/> - </child> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="ok"> - <property name="label">gtk-ok</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="cancel"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="help"> - <property name="label">gtk-help</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - <property name="secondary">True</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="progress_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="hexpand">True</property> - <property name="ellipsize">end</property> - <property name="width_chars">45</property> - <property name="max_width_chars">45</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">3</property> - <property name="secondary">True</property> - <property name="non_homogeneous">True</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkBox" id="box4"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">6</property> - <child> - <object class="GtkEntry" id="search_term"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="activates_default">True</property> - <property name="primary_icon_activatable">False</property> - <property name="secondary_icon_activatable">False</property> - <property name="placeholder_text" translatable="yes" context="select_persona_dialog|search_term">Search term or address</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="search_personas"> - <property name="label" context="select_persona_dialog|search_personas">gtk-find</property> - <property name="width_request">85</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkBox" id="box6"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="categories_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="select_persona_dialog|categories_label">Ca_tegory:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">categoriesCB</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBoxText" id="categoriesCB"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <items> - <item id="abstract" translatable="yes" context="select_persona_dialog|categoriesCB">Abstract</item> - <item id="causes" translatable="yes" context="select_persona_dialog|categoriesCB">Causes</item> - <item id="fashion" translatable="yes" context="select_persona_dialog|categoriesCB">Fashion</item> - <item id="film-and-tv" translatable="yes" context="select_persona_dialog|categoriesCB">Film and TV</item> - <item id="firefox" translatable="yes" context="select_persona_dialog|categoriesCB">Firefox</item> - <item id="foxkeh" translatable="yes" comments="https://addons.mozilla.org/en-US/firefox/themes/" context="select_persona_dialog|categoriesCB">Foxkeh</item> - <item id="holiday" translatable="yes" context="select_persona_dialog|categoriesCB">Holiday</item> - <item id="music" translatable="yes" context="select_persona_dialog|categoriesCB">Music</item> - <item id="nature" translatable="yes" context="select_persona_dialog|categoriesCB">Nature</item> - <item id="other" translatable="yes" context="select_persona_dialog|categoriesCB">Other</item> - <item id="scenery" translatable="yes" context="select_persona_dialog|categoriesCB">Scenery</item> - <item id="seasonal" translatable="yes" context="select_persona_dialog|categoriesCB">Seasonal</item> - <item id="solid" translatable="yes" context="select_persona_dialog|categoriesCB">Solid</item> - <item id="sports" translatable="yes" context="select_persona_dialog|categoriesCB">Sports</item> - <item id="websites" translatable="yes" context="select_persona_dialog|categoriesCB">Websites</item> - <item id="featured" translatable="yes" context="select_persona_dialog|categoriesCB">Featured</item> - </items> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="grid1"> - <property name="width_request">624</property> - <property name="height_request">219</property> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - <property name="row_homogeneous">True</property> - <property name="column_homogeneous">True</property> - <child> - <object class="GtkButton" id="result1"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="result2"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="result3"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="result4"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="result5"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="result6"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="result7"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkButton" id="result8"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkButton" id="result9"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">2</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-5">ok</action-widget> - <action-widget response="-6">cancel</action-widget> - <action-widget response="-11">help</action-widget> - </action-widgets> - </object> -</interface> |