[Libreoffice-commits] core.git: Branch 'feature/gsoc14-personas' - cui/source cui/uiconfig

Rachit Gupta rachitgupta1792 at gmail.com
Thu May 22 08:49:42 PDT 2014


 cui/source/options/personalization.cxx    |  129 ++++++++++++++++++++++++-
 cui/source/options/personalization.hxx    |   10 +
 cui/source/options/personasdochandler.hxx |    1 
 cui/uiconfig/ui/select_persona_dialog.ui  |  151 +++++++++++++++++++++++++++---
 4 files changed, 269 insertions(+), 22 deletions(-)

New commits:
commit 62df0a31f5298843586c3c4936434761fdf4268c
Author: Rachit Gupta <rachitgupta1792 at gmail.com>
Date:   Thu May 22 20:48:34 2014 +0530

    The search result images are shown in the dialog.
    
    1. Changed the UI to include a 3x3 grid of images
    2. The preview images are downloaded in the thread
    3. The images are downloaded in their respective folders
    4. A progress label is shown
    
    Change-Id: Id87e72343d28e03b37e0c422e5ebfe1a9a37c1b5

diff --git a/cui/source/options/personalization.cxx b/cui/source/options/personalization.cxx
index b454d17..357d5ab 100644
--- a/cui/source/options/personalization.cxx
+++ b/cui/source/options/personalization.cxx
@@ -35,11 +35,23 @@ using namespace ::com::sun::star::ucb;
 SelectPersonaDialog::SelectPersonaDialog( Window *pParent )
     : ModalDialog( pParent, "SelectPersonaDialog", "cui/ui/select_persona_dialog.ui" )
 {
-    get( pButton, "search_personas" );
-    pButton->SetClickHdl( LINK( this, SelectPersonaDialog, VisitPersonas ) );
+    get( m_pButton, "search_personas" );
+    m_pButton->SetClickHdl( LINK( this, SelectPersonaDialog, VisitPersonas ) );
 
     get( m_pEdit, "search_term" );
     m_pEdit->SetPlaceholderText( "Search term..." );
+
+    get( m_pProgressLabel, "progress_label" );
+
+    get(m_vImageList[0], "image1");
+    get(m_vImageList[1], "image2");
+    get(m_vImageList[2], "image3");
+    get(m_vImageList[3], "image4");
+    get(m_vImageList[4], "image5");
+    get(m_vImageList[5], "image6");
+    get(m_vImageList[6], "image7");
+    get(m_vImageList[7], "image8");
+    get(m_vImageList[8], "image9");
 }
 
 OUString SelectPersonaDialog::GetPersonaURL() const
@@ -55,12 +67,29 @@ OUString SelectPersonaDialog::GetPersonaURL() const
 IMPL_LINK( SelectPersonaDialog, VisitPersonas, PushButton*, /*pButton*/ )
 {
     OUString searchTerm = m_pEdit->GetText();
-    OUString rURL = "https://addons.allizom.org/en-US/firefox/api/1.5/search/" + searchTerm + "/9/";
+    OUString rURL = "https://addons.allizom.org/en-US/firefox/api/1.5/search/" + searchTerm + "/9/9";
     m_aSearchThread = new SearchAndParseThread( this, rURL );
     m_aSearchThread->launch();
     return 0;
 }
 
+void SelectPersonaDialog::SetProgress( OUString& rProgress )
+{
+    if(rProgress.isEmpty())
+        m_pProgressLabel->Hide();
+    else
+        m_pProgressLabel->SetText( rProgress );
+}
+
+void SelectPersonaDialog::SetImages( std::vector<Image> &rImageList )
+{
+    sal_Int32 nCount = 0;
+    for( std::vector<Image>::iterator it=rImageList.begin(); it!=rImageList.end(); ++it )
+    {
+        m_vImageList[nCount++]->SetImage( *it );
+    }
+}
+
 SvxPersonalizationTabPage::SvxPersonalizationTabPage( Window *pParent, const SfxItemSet &rSet )
     : SfxTabPage( pParent, "PersonalizationTabPage", "cui/ui/personalization_tab.ui", rSet )
 {
@@ -187,7 +216,9 @@ static OUString searchValue( const OString &rBuffer, sal_Int32 from, const OStri
 }
 
 /// Parse the Persona web page, and find where to get the bitmaps + the color values.
-static bool parsePersonaInfo( const OString &rBuffer, OUString *pHeaderURL, OUString *pFooterURL, OUString *pTextColor, OUString *pAccentColor )
+static bool parsePersonaInfo( const OString &rBuffer, OUString *pHeaderURL, OUString *pFooterURL,
+                              OUString *pTextColor, OUString *pAccentColor, OUString *pPreviewURL,
+                              OUString *pName )
 {
     // it is the first attribute that contains "persona="
     sal_Int32 persona = rBuffer.indexOf( "data-browsertheme=\"{" );
@@ -211,6 +242,14 @@ static bool parsePersonaInfo( const OString &rBuffer, OUString *pHeaderURL, OUSt
     if ( pAccentColor->isEmpty() )
         return false;
 
+    *pPreviewURL = searchValue( rBuffer, persona, ""previewURL":"" );
+    if ( pAccentColor->isEmpty() )
+        return false;
+
+    *pName = searchValue( rBuffer, persona, ""name":"" );
+    if ( pAccentColor->isEmpty() )
+        return false;
+
     return true;
 }
 
@@ -249,9 +288,9 @@ bool SvxPersonalizationTabPage::CopyPersonaToGallery( const OUString &rURL )
     xStream->closeInput();
 
     // get the important bits of info
-    OUString aHeaderURL, aFooterURL, aTextColor, aAccentColor;
+    OUString aHeaderURL, aFooterURL, aTextColor, aAccentColor, aPreviewURL, aName;
 
-    if ( !parsePersonaInfo( aBuffer.makeStringAndClear(), &aHeaderURL, &aFooterURL, &aTextColor, &aAccentColor ) )
+    if ( !parsePersonaInfo( aBuffer.makeStringAndClear(), &aHeaderURL, &aFooterURL, &aTextColor, &aAccentColor, &aPreviewURL, &aName ) ) // Temp
         return false;
 
     // copy the images to the user's gallery
@@ -292,6 +331,8 @@ SearchAndParseThread::~SearchAndParseThread()
 
 void SearchAndParseThread::execute()
 {
+    OUString sProgress( "Searching.. Please Wait.." );
+    m_pPersonaDialog->SetProgress( sProgress );
     Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
     Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(xContext);
     PersonasDocHandler* pHandler = new PersonasDocHandler();
@@ -313,6 +354,82 @@ void SearchAndParseThread::execute()
     xml::sax::InputSource aParserInput;
     aParserInput.aInputStream = xStream;
     xParser->parseStream( aParserInput );
+
+    std::vector<OUString> vLearnmoreURLs = pHandler->getLearnmoreURLs();
+    std::vector<OUString>::iterator it;
+    std::vector<Image> vImageList;
+    GraphicFilter aFilter;
+    Graphic aGraphic;
+
+    for( it = vLearnmoreURLs.begin(); it!=vLearnmoreURLs.end(); ++it )
+    {
+        OUString sHeaderFile = getPreviewFile( *it );
+        INetURLObject aURLObj( sHeaderFile );
+        aFilter.ImportGraphic( aGraphic, aURLObj );
+        Bitmap aBmp = aGraphic.GetBitmap();
+        vImageList.push_back( Image( aBmp ) );
+    }
+    m_pPersonaDialog->SetImages( vImageList );
+    sProgress = "";
+    m_pPersonaDialog->SetProgress( sProgress );
 }
 
+// TODO: Think of some way to retrieve only the preview image and skip the rest!
+OUString SearchAndParseThread::getPreviewFile( const OUString& rURL )
+{
+    uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY );
+    if ( !xFileAccess.is() )
+        return OUString();
+
+    uno::Reference< io::XInputStream > xStream;
+    try {
+        xStream = xFileAccess->openFileRead( rURL );
+    }
+    catch (...)
+    {
+        return OUString();
+    }
+    if ( !xStream.is() )
+        return OUString();
+
+    // read the persona specification
+    // NOTE: Parsing for real is an overkill here; and worse - I tried, and
+    // the HTML the site provides is not 100% valid ;-)
+    const sal_Int32 BUF_LEN = 8000;
+    uno::Sequence< sal_Int8 > buffer( BUF_LEN );
+    OStringBuffer aBuffer( 64000 );
+
+    sal_Int32 nRead = 0;
+    while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN )
+        aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
+
+    if ( nRead > 0 )
+        aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
+
+    xStream->closeInput();
+
+    // get the important bits of info
+    OUString aHeaderURL, aFooterURL, aTextColor, aAccentColor, aPreviewURL, aName;
+
+    if ( !parsePersonaInfo( aBuffer.makeStringAndClear(), &aHeaderURL, &aFooterURL, &aTextColor, &aAccentColor, &aPreviewURL, &aName ) )
+        return OUString();
+
+    // 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/";
+    gallery += aName + "/";
+    osl::Directory::createPath( gallery );
+
+    OUString aPreviewFile( INetURLObject( aPreviewURL ).getName() );
+
+    try {
+        xFileAccess->copy( aPreviewURL, gallery + aPreviewFile );
+    }
+    catch ( const uno::Exception & )
+    {
+        return OUString();
+    }
+    return gallery + aPreviewFile;
+}
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/personalization.hxx b/cui/source/options/personalization.hxx
index 906a969..e7f02c9 100644
--- a/cui/source/options/personalization.hxx
+++ b/cui/source/options/personalization.hxx
@@ -15,6 +15,8 @@
 #include <rtl/ref.hxx>
 #include <vcl/prgsbar.hxx>
 
+#include <vector>
+
 class FixedText;
 class SearchAndParseThread;
 
@@ -61,8 +63,9 @@ class SelectPersonaDialog : public ModalDialog
 {
 private:
     Edit *m_pEdit;                          ///< The input line for the Persona URL
-    PushButton *pButton;
-
+    PushButton *m_pButton;
+    FixedText *m_pProgressLabel;
+    FixedImage *m_vImageList[9];
 
 public:
     SelectPersonaDialog( Window *pParent );
@@ -70,6 +73,8 @@ public:
 
     /// Get the URL from the Edit field.
     OUString GetPersonaURL() const;
+    void SetProgress( OUString& );
+    void SetImages( std::vector<Image> &);
 
 private:
     /// Handle the [Visit Firefox Personas] button
@@ -85,6 +90,7 @@ private:
 
     virtual ~SearchAndParseThread();
     virtual void execute() SAL_OVERRIDE;
+    OUString getPreviewFile( const OUString& );
 
 public:
 
diff --git a/cui/source/options/personasdochandler.hxx b/cui/source/options/personasdochandler.hxx
index 29be26d..d38f0f3 100644
--- a/cui/source/options/personasdochandler.hxx
+++ b/cui/source/options/personasdochandler.hxx
@@ -22,6 +22,7 @@ private:
     bool m_bLearnmoreTag;
 public:
     PersonasDocHandler(){ m_bLearnmoreTag = false; }
+    std::vector<OUString> getLearnmoreURLs() { return m_vLearnmoreURLs; }
     // XDocumentHandler
     virtual void SAL_CALL startDocument()
         throw ( css::xml::sax::SAXException, css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
diff --git a/cui/uiconfig/ui/select_persona_dialog.ui b/cui/uiconfig/ui/select_persona_dialog.ui
index fd3ca9b..ab4c89c 100644
--- a/cui/uiconfig/ui/select_persona_dialog.ui
+++ b/cui/uiconfig/ui/select_persona_dialog.ui
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.16.1 -->
 <interface>
-  <!-- interface-requires gtk+ 3.0 -->
+  <requires lib="gtk+" version="3.0"/>
   <object class="GtkDialog" id="SelectPersonaDialog">
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
@@ -11,7 +12,7 @@
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">12</property>
-        <child internal-child="action_area">"e
+        <child internal-child="action_area">
           <object class="GtkButtonBox" id="dialog-action_area1">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
@@ -104,33 +105,155 @@
               </packing>
             </child>
             <child>
-              <object class="GtkBox" id="box2">
+              <object class="GtkButton" id="search_personas">
+                <property name="label" translatable="yes">Search</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>
+            <child>
+              <object class="GtkLabel" id="progress_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="grid1">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <child>
-                  <placeholder/>
+                  <object class="GtkImage" id="image1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-missing-image</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
                 </child>
                 <child>
-                  <object class="GtkButton" id="search_personas">
-                    <property name="label" translatable="yes">Search</property>
+                  <object class="GtkImage" id="image2">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-missing-image</property>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
-                  <placeholder/>
+                  <object class="GtkImage" id="image3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-missing-image</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage" id="image4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-missing-image</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage" id="image5">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-missing-image</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage" id="image6">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-missing-image</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage" id="image7">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-missing-image</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage" id="image8">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-missing-image</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage" id="image9">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-missing-image</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
                 </child>
               </object>
               <packing>
-                <property name="expand">True</property>
+                <property name="expand">False</property>
                 <property name="fill">True</property>
-                <property name="position">2</property>
+                <property name="position">4</property>
               </packing>
             </child>
           </object>


More information about the Libreoffice-commits mailing list