xmlsecurity/inc/certificatechooser.hxx             |   10 ++
 xmlsecurity/source/dialogs/certificatechooser.cxx  |   78 ++++++++++++++-------
 xmlsecurity/uiconfig/ui/selectcertificatedialog.ui |   27 +++++--
 3 files changed, 86 insertions(+), 29 deletions(-)

New commits:
commit ad6f23d2a3842c40f7c812003af4031150ea8183
Author:     TokieSan <elto...@aucegypt.edu>
AuthorDate: Tue Jul 18 21:54:31 2023 +0300
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Thu Jul 20 13:05:14 2023 +0200

    Added searching and filtering features to certificate chooser dialog
    
    Added a new search box in the certificate chooser dialog, introduced
    local caching for certificates to allow instantaneous filtering and
    searching. Modified viewing signatures function to allow searching
    functionality.
    
    Change-Id: I361a47da7bd5d24efcbfc17065935851db951c44
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154630
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git a/xmlsecurity/inc/certificatechooser.hxx 
b/xmlsecurity/inc/certificatechooser.hxx
index 8ad4c3190f29..8b1f5563d85f 100644
--- a/xmlsecurity/inc/certificatechooser.hxx
+++ b/xmlsecurity/inc/certificatechooser.hxx
@@ -22,6 +22,8 @@
 #include <com/sun/star/uno/Sequence.hxx>
 #include <vcl/weld.hxx>
 #include <unotools/resmgr.hxx>
+#include <unotools/useroptions.hxx>
+#include <unordered_map>
 
 namespace com::sun::star {
     namespace security { class XCertificate; }
@@ -64,13 +66,19 @@ private:
     std::unique_ptr<weld::Button>   m_xOKBtn;
     std::unique_ptr<weld::Label>    m_xFTDescription;
     std::unique_ptr<weld::Entry>    m_xDescriptionED;
+    std::unique_ptr<weld::Entry>    m_xSearchBox;
+
+    std::unordered_map<css::uno::Reference< 
css::xml::crypto::XXMLSecurityContext>,
+        css::uno::Sequence< css::uno::Reference< css::security::XCertificate > 
> > xMemCerts;
+
 
     DECL_LINK(ViewButtonHdl, weld::Button&, void);
     DECL_LINK(CertificateHighlightHdl, weld::TreeView&, void);
     DECL_LINK(CertificateSelectHdl, weld::TreeView&, bool);
+    DECL_LINK(SearchModifyHdl, weld::Entry&, void);
 
     void ImplShowCertificateDetails();
-    void ImplInitialize();
+    void ImplInitialize(bool mbSearch = false);
 
     static void HandleOneUsageBit(OUString& string, int& bits, int bit, 
TranslateId name);
 
diff --git a/xmlsecurity/source/dialogs/certificatechooser.cxx 
b/xmlsecurity/source/dialogs/certificatechooser.cxx
index 3ac503521e72..c7f055deea16 100644
--- a/xmlsecurity/source/dialogs/certificatechooser.cxx
+++ b/xmlsecurity/source/dialogs/certificatechooser.cxx
@@ -30,7 +30,8 @@
 
 #include <o3tl/safeint.hxx>
 #include <unotools/datetime.hxx>
-#include <unotools/useroptions.hxx>
+#include <unotools/charclass.hxx>
+
 
 #include <resourcemanager.hxx>
 #include <strings.hrc>
@@ -50,9 +51,11 @@ CertificateChooser::CertificateChooser(weld::Window* 
_pParent,
     , m_xOKBtn(m_xBuilder->weld_button("ok"))
     , m_xFTDescription(m_xBuilder->weld_label("description-label"))
     , m_xDescriptionED(m_xBuilder->weld_entry("description"))
+    , m_xSearchBox(m_xBuilder->weld_entry("searchbox"))
 {
     auto nControlWidth = m_xCertLB->get_approximate_digit_width() * 105;
     m_xCertLB->set_size_request(nControlWidth, m_xCertLB->get_height_rows(12));
+    m_xCertLB->make_sorted();
 
     std::vector<int> aWidths
     {
@@ -65,6 +68,7 @@ CertificateChooser::CertificateChooser(weld::Window* _pParent,
     m_xCertLB->connect_changed( LINK( this, CertificateChooser, 
CertificateHighlightHdl ) );
     m_xCertLB->connect_row_activated( LINK( this, CertificateChooser, 
CertificateSelectHdl ) );
     m_xViewBtn->connect_clicked( LINK( this, CertificateChooser, ViewButtonHdl 
) );
+    m_xSearchBox->connect_changed(LINK(this, CertificateChooser, 
SearchModifyHdl));
 
     mxSecurityContexts = std::move(rxSecurityContexts);
     mbInitialized = false;
@@ -132,13 +136,20 @@ OUString CertificateChooser::UsageInClearText(int bits)
     return result;
 }
 
-void CertificateChooser::ImplInitialize()
+void CertificateChooser::ImplInitialize(bool mbSearch)
 {
-    if ( mbInitialized )
+    if (mbInitialized && !mbSearch)
         return;
 
+    m_xCertLB->clear();
+    m_xCertLB->freeze();
+
     SvtUserOptions aUserOpts;
 
+    SvtSysLocale aSysLocale;
+    const CharClass& rCharClass = aSysLocale.GetCharClass();
+    const OUString aSearchStr(rCharClass.uppercase(m_xSearchBox->get_text()));
+
     switch (meAction)
     {
         case UserAction::Sign:
@@ -164,7 +175,8 @@ void CertificateChooser::ImplInitialize()
 
     }
 
-    for (auto &secContext : mxSecurityContexts)
+    uno::Sequence<uno::Reference< security::XCertificate>> xCerts;
+    for (auto& secContext : mxSecurityContexts)
     {
         if (!secContext.is())
             continue;
@@ -172,33 +184,39 @@ void CertificateChooser::ImplInitialize()
         if (!secEnvironment.is())
             continue;
 
-        uno::Sequence< uno::Reference< security::XCertificate > > xCerts;
         try
         {
-            if ( meAction == UserAction::Sign || meAction == 
UserAction::SelectSign)
-                xCerts = secEnvironment->getPersonalCertificates();
+            if (xMemCerts.count(secContext))
+            {
+                xCerts = xMemCerts[secContext];
+            }
             else
-                xCerts = secEnvironment->getAllCertificates();
+            {
+                if (meAction == UserAction::Sign || meAction == 
UserAction::SelectSign)
+                    xCerts = secEnvironment->getPersonalCertificates();
+                else
+                    xCerts = secEnvironment->getAllCertificates();
+
+                for (sal_Int32 nCert = xCerts.getLength(); nCert;)
+                {
+                    uno::Reference< security::XCertificate > xCert = xCerts[ 
--nCert ];
+                    // Check if we have a private key for this...
+                    tools::Long nCertificateCharacters = 
secEnvironment->getCertificateCharacters(xCert);
+
+                    if (!(nCertificateCharacters & 
security::CertificateCharacters::HAS_PRIVATE_KEY))
+                    {
+                        ::comphelper::removeElementAt( xCerts, nCert );
+                    }
+                }
+                xMemCerts[secContext] = xCerts;
+            }
         }
         catch (security::NoPasswordException&)
         {
         }
 
-        for( sal_Int32 nCert = xCerts.getLength(); nCert; )
-        {
-            uno::Reference< security::XCertificate > xCert = xCerts[ --nCert ];
-            // Check if we have a private key for this...
-            tools::Long nCertificateCharacters = 
secEnvironment->getCertificateCharacters(xCert);
-
-            if (!(nCertificateCharacters & 
security::CertificateCharacters::HAS_PRIVATE_KEY))
-            {
-                ::comphelper::removeElementAt( xCerts, nCert );
-            }
-        }
-
-
         // fill list of certificates; the first entry will be selected
-        for ( const auto& xCert : std::as_const(xCerts) )
+        for (const auto& xCert : std::as_const(xCerts))
         {
             std::shared_ptr<UserData> userData = std::make_shared<UserData>();
             userData->xCertificate = xCert;
@@ -208,6 +226,13 @@ void CertificateChooser::ImplInitialize()
 
             OUString sIssuer = xmlsec::GetContentPart( xCert->getIssuerName(), 
xCert->getCertificateKind());
 
+            // If we are searching and there is no match skip
+            if (mbSearch
+                && rCharClass.uppercase(sIssuer).indexOf(aSearchStr) < 0
+                && rCharClass.uppercase(sIssuer).indexOf(aSearchStr) < 0
+                && !aSearchStr.isEmpty())
+                    continue;
+
             m_xCertLB->append();
             int nRow = m_xCertLB->n_children() - 1;
             m_xCertLB->set_text(nRow, 
xmlsec::GetContentPart(xCert->getSubjectName(), xCert->getCertificateKind()), 
0);
@@ -234,7 +259,9 @@ void CertificateChooser::ImplInitialize()
         }
     }
 
-    // enable/disable buttons
+    m_xCertLB->thaw();
+    m_xCertLB->unselect_all();
+
     CertificateHighlightHdl(*m_xCertLB);
     mbInitialized = true;
 }
@@ -295,6 +322,11 @@ OUString CertificateChooser::GetUsageText()
         UsageInClearText(xCerts[0]->getCertificateUsage()) : OUString();
 }
 
+IMPL_LINK_NOARG(CertificateChooser, SearchModifyHdl, weld::Entry&, void)
+{
+    ImplInitialize(true);
+}
+
 IMPL_LINK_NOARG(CertificateChooser, CertificateHighlightHdl, weld::TreeView&, 
void)
 {
     bool bEnable = m_xCertLB->get_selected_index() != -1;
diff --git a/xmlsecurity/uiconfig/ui/selectcertificatedialog.ui 
b/xmlsecurity/uiconfig/ui/selectcertificatedialog.ui
index fde094088e91..08a4c6d7366e 100644
--- a/xmlsecurity/uiconfig/ui/selectcertificatedialog.ui
+++ b/xmlsecurity/uiconfig/ui/selectcertificatedialog.ui
@@ -88,7 +88,7 @@
           </packing>
         </child>
         <child>
-          <!-- n-columns=1 n-rows=5 -->
+          <!-- n-columns=1 n-rows=6 -->
           <object class="GtkGrid" id="grid1">
             <property name="visible">True</property>
             <property name="can-focus">False</property>
@@ -136,7 +136,7 @@
                     <property name="search-column">0</property>
                     <property name="show-expanders">False</property>
                     <child internal-child="selection">
-                      <object class="GtkTreeSelection" id="Macro Library 
List-selection2"/>
+                      <object class="GtkTreeSelection"/>
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn" id="treeviewcolumn3">
@@ -223,7 +223,7 @@
               </object>
               <packing>
                 <property name="left-attach">0</property>
-                <property name="top-attach">2</property>
+                <property name="top-attach">3</property>
               </packing>
             </child>
             <child>
@@ -241,7 +241,24 @@
               </object>
               <packing>
                 <property name="left-attach">0</property>
-                <property name="top-attach">3</property>
+                <property name="top-attach">4</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="searchbox">
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="activates-default">True</property>
+                <property name="truncate-multiline">True</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" id="searchbox-atkobject">
+                    <property name="AtkObject::accessible-description" 
translatable="yes" 
context="selectcertificatedialog|extended_tip|searchbox">Type certificate for 
searching.</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">2</property>
               </packing>
             </child>
             <child>
@@ -282,7 +299,7 @@
               </object>
               <packing>
                 <property name="left-attach">0</property>
-                <property name="top-attach">4</property>
+                <property name="top-attach">5</property>
               </packing>
             </child>
           </object>

Reply via email to