cui/source/dialogs/passwdomdlg.cxx |   83 +++++++++++
 cui/source/inc/passwdomdlg.hxx     |    2 
 cui/uiconfig/ui/password.ui        |  273 +++++++++++++++++++++++++++++--------
 3 files changed, 302 insertions(+), 56 deletions(-)

New commits:
commit 1791a290a82591d5b0609502e86f07ed69acee5c
Author:     Karthik <m...@karthikreddy.org>
AuthorDate: Sun Mar 9 13:27:57 2025 +0530
Commit:     Balazs Varga <balazs.varga.ext...@allotropia.de>
CommitDate: Thu Mar 13 14:31:17 2025 +0100

    tdf#146947 Add show/reveal toggle to "Set Password" dialog
    
    Implement password visibility toggle button in "Set Password" Dialog when 
saving files with password.
    File -> Save-As -> Select "Save with password"
    
    Change-Id: I33de726b8f34c18443cf66b82e725c799d673017
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182693
    Reviewed-by: Balazs Varga <balazs.varga.ext...@allotropia.de>
    Tested-by: Jenkins

diff --git a/cui/source/dialogs/passwdomdlg.cxx 
b/cui/source/dialogs/passwdomdlg.cxx
index 5e90fc88725d..dd67c4e7c565 100644
--- a/cui/source/dialogs/passwdomdlg.cxx
+++ b/cui/source/dialogs/passwdomdlg.cxx
@@ -24,6 +24,7 @@
 #include <passwdomdlg.hxx>
 #include <strings.hrc>
 #include <dialmgr.hxx>
+#include <bitmaps.hlst>
 
 IMPL_LINK_NOARG(PasswordToOpenModifyDialog, OkBtnClickHdl, weld::Button&, void)
 {
@@ -168,6 +169,23 @@ 
PasswordToOpenModifyDialog::PasswordToOpenModifyDialog(weld::Window * pParent, s
     m_xOk->connect_clicked(LINK(this, PasswordToOpenModifyDialog, 
OkBtnClickHdl));
     m_xPasswdToOpenED->connect_changed(LINK(this, PasswordToOpenModifyDialog, 
ChangeHdl));
     m_xPasswdToModifyED->connect_changed(LINK(this, 
PasswordToOpenModifyDialog, ChangeHdl));
+
+    m_xPass[0] = m_xBuilder->weld_toggle_button(u"togglebt1"_ustr);
+    m_xPass[1] = m_xBuilder->weld_toggle_button(u"togglebt2"_ustr);
+    m_xPass[2] = m_xBuilder->weld_toggle_button(u"togglebt3"_ustr);
+    m_xPass[3] = m_xBuilder->weld_toggle_button(u"togglebt4"_ustr);
+
+    Link<weld::Toggleable&, void> aToggleLink = LINK(this, 
PasswordToOpenModifyDialog, ShowHdl);
+
+    for (auto& aPass : m_xPass)
+    {
+        if (aPass->get_active())
+            aPass->set_from_icon_name(RID_SVXBMP_SHOWPASS);
+        else
+            aPass->set_from_icon_name(RID_SVXBMP_HIDEPASS);
+        aPass->connect_toggled(aToggleLink);
+    }
+
     if(m_oPasswordPolicy || nMaxPasswdLen)
     {
         m_xReenterPasswdToOpenED->connect_changed(LINK(this, 
PasswordToOpenModifyDialog, ChangeHdl));
@@ -270,4 +288,69 @@ IMPL_LINK_NOARG(PasswordToOpenModifyDialog, 
ReadonlyOnOffHdl, weld::Toggleable&,
     m_xReenterPasswdToModifyFT->set_sensitive(bEnable);
 }
 
+IMPL_LINK(PasswordToOpenModifyDialog, ShowHdl, weld::Toggleable&, rToggleable, 
void)
+{
+    bool bChecked = rToggleable.get_active();
+    if (&rToggleable == m_xPass[0].get())
+    {
+        if (bChecked)
+        {
+            m_xPass[0]->set_from_icon_name(RID_SVXBMP_SHOWPASS);
+            m_xPasswdToOpenED->set_visibility(true);
+            m_xPasswdToOpenED->grab_focus();
+        }
+        else
+        {
+            m_xPass[0]->set_from_icon_name(RID_SVXBMP_HIDEPASS);
+            m_xPasswdToOpenED->set_visibility(false);
+            m_xPasswdToOpenED->grab_focus();
+        }
+    }
+    else if (&rToggleable == m_xPass[1].get())
+    {
+        if (bChecked)
+        {
+            m_xPass[1]->set_from_icon_name(RID_SVXBMP_SHOWPASS);
+            m_xReenterPasswdToOpenED->set_visibility(true);
+            m_xReenterPasswdToOpenED->grab_focus();
+        }
+        else
+        {
+            m_xPass[1]->set_from_icon_name(RID_SVXBMP_HIDEPASS);
+            m_xReenterPasswdToOpenED->set_visibility(false);
+            m_xReenterPasswdToOpenED->grab_focus();
+        }
+    }
+    else if (&rToggleable == m_xPass[2].get())
+    {
+        if (bChecked)
+        {
+            m_xPass[2]->set_from_icon_name(RID_SVXBMP_SHOWPASS);
+            m_xPasswdToModifyED->set_visibility(true);
+            m_xPasswdToModifyED->grab_focus();
+        }
+        else
+        {
+            m_xPass[2]->set_from_icon_name(RID_SVXBMP_HIDEPASS);
+            m_xPasswdToModifyED->set_visibility(false);
+            m_xPasswdToModifyED->grab_focus();
+        }
+    }
+    else if (&rToggleable == m_xPass[3].get())
+    {
+        if (bChecked)
+        {
+            m_xPass[3]->set_from_icon_name(RID_SVXBMP_SHOWPASS);
+            m_xReenterPasswdToModifyED->set_visibility(true);
+            m_xReenterPasswdToModifyED->grab_focus();
+        }
+        else
+        {
+            m_xPass[3]->set_from_icon_name(RID_SVXBMP_HIDEPASS);
+            m_xReenterPasswdToModifyED->set_visibility(false);
+            m_xReenterPasswdToModifyED->grab_focus();
+        }
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/passwdomdlg.hxx b/cui/source/inc/passwdomdlg.hxx
index 1077195f7a85..eba379cf8a2b 100644
--- a/cui/source/inc/passwdomdlg.hxx
+++ b/cui/source/inc/passwdomdlg.hxx
@@ -39,6 +39,7 @@ class PasswordToOpenModifyDialog : public SfxDialogController
     std::unique_ptr<weld::Entry> m_xReenterPasswdToModifyED;
     std::unique_ptr<weld::Label> m_xReenterPasswdToModifyInd;
     std::shared_ptr<weld::MessageDialog> m_xErrorBox;
+    std::array<std::unique_ptr<weld::ToggleButton>, 4> m_xPass;
 
     OUString                    m_aOneMismatch;
     OUString                    m_aTwoMismatch;
@@ -54,6 +55,7 @@ class PasswordToOpenModifyDialog : public SfxDialogController
     DECL_LINK(OkBtnClickHdl, weld::Button&, void);
     DECL_LINK(ReadonlyOnOffHdl, weld::Toggleable&, void);
     DECL_LINK(ChangeHdl, weld::Entry&, void);
+    DECL_LINK(ShowHdl, weld::Toggleable&, void);
 
     PasswordToOpenModifyDialog( const PasswordToOpenModifyDialog & ) = delete;
     PasswordToOpenModifyDialog & operator = ( const PasswordToOpenModifyDialog 
& ) = delete;
diff --git a/cui/uiconfig/ui/password.ui b/cui/uiconfig/ui/password.ui
index e7bc05e138e4..9cd30eeed3f6 100644
--- a/cui/uiconfig/ui/password.ui
+++ b/cui/uiconfig/ui/password.ui
@@ -1,7 +1,27 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 -->
+<!-- Generated with glade 3.40.0 -->
 <interface domain="cui">
   <requires lib="gtk+" version="3.20"/>
+  <object class="GtkImage" id="passimg1">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="icon-name">res/hidepass.png</property>
+  </object>
+  <object class="GtkImage" id="passimg2">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="icon-name">res/hidepass.png</property>
+  </object>
+  <object class="GtkImage" id="passimg3">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="icon-name">res/hidepass.png</property>
+  </object>
+  <object class="GtkImage" id="passimg4">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="icon-name">res/hidepass.png</property>
+  </object>
   <object class="GtkDialog" id="PasswordDialog">
     <property name="can-focus">False</property>
     <property name="border-width">6</property>
@@ -130,36 +150,6 @@
                                     <property name="top-attach">0</property>
                                   </packing>
                                 </child>
-                                <child>
-                                  <object class="GtkEntry" id="newpassroEntry">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">True</property>
-                                    <property name="hexpand">True</property>
-                                    <property 
name="visibility">False</property>
-                                    <property 
name="activates-default">True</property>
-                                    <property 
name="truncate-multiline">True</property>
-                                    <property 
name="input-purpose">password</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left-attach">0</property>
-                                    <property name="top-attach">2</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkEntry" 
id="confirmropassEntry">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">True</property>
-                                    <property name="hexpand">True</property>
-                                    <property 
name="visibility">False</property>
-                                    <property 
name="activates-default">True</property>
-                                    <property 
name="truncate-multiline">True</property>
-                                    <property 
name="input-purpose">password</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left-attach">0</property>
-                                    <property name="top-attach">5</property>
-                                  </packing>
-                                </child>
                                 <child>
                                   <!-- n-columns=2 n-rows=1 -->
                                   <object class="GtkGrid">
@@ -172,7 +162,6 @@
                                         <property 
name="can-focus">False</property>
                                         <property name="label" 
translatable="yes" context="password|label7">Enter password to allow 
editing</property>
                                         <property 
name="use-underline">True</property>
-                                        <property 
name="mnemonic-widget">newpassroEntry</property>
                                         <property name="xalign">0</property>
                                       </object>
                                       <packing>
@@ -217,7 +206,6 @@
                                         <property 
name="can-focus">False</property>
                                         <property name="label" 
translatable="yes" context="password|label8">Confirm password</property>
                                         <property 
name="use-underline">True</property>
-                                        <property 
name="mnemonic-widget">confirmropassEntry</property>
                                         <property name="xalign">0</property>
                                       </object>
                                       <packing>
@@ -253,12 +241,120 @@
                                   <object class="GtkLevelBar" 
id="ropasslevelbar">
                                     <property name="visible">True</property>
                                     <property name="can-focus">False</property>
+                                    <child internal-child="accessible">
+                                      <object class="AtkObject" 
id="ropasslevelbar-atkobject">
+                                        <property 
name="AtkObject::accessible-name" translatable="yes" 
context="passsword|ropasslevelbar-atkobject">Password Level Bar</property>
+                                        <property 
name="AtkObject::accessible-description" translatable="yes" 
context="passsword|extended_tip|ropasslevelbar">Shows the strength of 
password</property>
+                                      </object>
+                                    </child>
                                   </object>
                                   <packing>
                                     <property name="left-attach">0</property>
                                     <property name="top-attach">3</property>
                                   </packing>
                                 </child>
+                                <child>
+                                  <object class="GtkBox" id="newpassrobox">
+                                    <property name="visible">True</property>
+                                    <property name="can-focus">False</property>
+                                    <property name="hexpand">True</property>
+                                    <child>
+                                      <object class="GtkEntry" 
id="newpassroEntry">
+                                        <property 
name="visible">True</property>
+                                        <property 
name="can-focus">True</property>
+                                        <property 
name="hexpand">True</property>
+                                        <property 
name="visibility">False</property>
+                                        <property 
name="activates-default">True</property>
+                                        <property 
name="truncate-multiline">True</property>
+                                        <property 
name="input-purpose">password</property>
+                                        <child internal-child="accessible">
+                                          <object class="AtkObject" 
id="newpassroEntry-atkobject">
+                                            <property 
name="AtkObject::accessible-description" translatable="yes" 
context="password|extended_tip|newpassEntry">Type a password. A password is 
case sensitive.</property>
+                                          </object>
+                                        </child>
+                                      </object>
+                                      <packing>
+                                        <property 
name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkToggleButton" 
id="togglebt3">
+                                        <property 
name="visible">True</property>
+                                        <property 
name="can-focus">True</property>
+                                        <property 
name="receives-default">True</property>
+                                        <property 
name="image">passimg3</property>
+                                        <child internal-child="accessible">
+                                          <object class="AtkObject" 
id="togglebt3-atkobject">
+                                            <property 
name="AtkObject::accessible-name" translatable="yes" 
context="password|togglebt3-atkobject">Show characters</property>
+                                            <property 
name="AtkObject::accessible-description" translatable="yes" 
context="password|extended_tip|togglebt3">Show or hide password 
characters</property>
+                                          </object>
+                                        </child>
+                                      </object>
+                                      <packing>
+                                        <property 
name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="left-attach">0</property>
+                                    <property name="top-attach">2</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkBox" id="confirmropassbox">
+                                    <property name="visible">True</property>
+                                    <property name="can-focus">False</property>
+                                    <property name="hexpand">True</property>
+                                    <child>
+                                      <object class="GtkEntry" 
id="confirmropassEntry">
+                                        <property 
name="visible">True</property>
+                                        <property 
name="can-focus">True</property>
+                                        <property 
name="hexpand">True</property>
+                                        <property 
name="visibility">False</property>
+                                        <property 
name="activates-default">True</property>
+                                        <property 
name="truncate-multiline">True</property>
+                                        <property 
name="input-purpose">password</property>
+                                        <child internal-child="accessible">
+                                          <object class="AtkObject" 
id="confirmropassEntry-atkobject">
+                                            <property 
name="AtkObject::accessible-description" translatable="yes" 
context="password|extended_tip|confirmpassEntry">Re-enter the 
password.</property>
+                                          </object>
+                                        </child>
+                                      </object>
+                                      <packing>
+                                        <property 
name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkToggleButton" 
id="togglebt4">
+                                        <property 
name="visible">True</property>
+                                        <property 
name="can-focus">True</property>
+                                        <property 
name="receives-default">True</property>
+                                        <property 
name="image">passimg4</property>
+                                        <child internal-child="accessible">
+                                          <object class="AtkObject" 
id="togglebt4-atkobject">
+                                            <property 
name="AtkObject::accessible-name" translatable="yes" 
context="password|togglebt4-atkobject">Show characters</property>
+                                            <property 
name="AtkObject::accessible-description" translatable="yes" 
context="password|extended_tip|togglebt4">Show or hide password 
characters</property>
+                                          </object>
+                                        </child>
+                                      </object>
+                                      <packing>
+                                        <property 
name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="left-attach">0</property>
+                                    <property name="top-attach">5</property>
+                                  </packing>
+                                </child>
                               </object>
                             </child>
                             <child type="label">
@@ -304,7 +400,6 @@
                             <property name="can-focus">False</property>
                             <property name="label" translatable="yes" 
context="password|label4">_Enter password to open</property>
                             <property name="use-underline">True</property>
-                            <property 
name="mnemonic-widget">newpassEntry</property>
                             <property name="xalign">0</property>
                           </object>
                           <packing>
@@ -349,7 +444,6 @@
                             <property name="can-focus">False</property>
                             <property name="label" translatable="yes" 
context="password|label5">Confirm password</property>
                             <property name="use-underline">True</property>
-                            <property 
name="mnemonic-widget">confirmpassEntry</property>
                             <property name="xalign">0</property>
                           </object>
                           <packing>
@@ -382,50 +476,117 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkEntry" id="confirmpassEntry">
+                      <object class="GtkBox" id="newpassbox">
                         <property name="visible">True</property>
-                        <property name="can-focus">True</property>
+                        <property name="can-focus">False</property>
                         <property name="hexpand">True</property>
-                        <property name="visibility">False</property>
-                        <property name="activates-default">True</property>
-                        <property name="truncate-multiline">True</property>
-                        <property name="input-purpose">password</property>
-                        <child internal-child="accessible">
-                          <object class="AtkObject" 
id="confirmpassEntry-atkobject">
-                            <property name="AtkObject::accessible-description" 
translatable="yes" context="password|extended_tip|confirmpassEntry">Re-enter 
the password.</property>
+                        <child>
+                          <object class="GtkEntry" id="newpassEntry">
+                            <property name="visible">True</property>
+                            <property name="can-focus">True</property>
+                            <property name="hexpand">True</property>
+                            <property name="visibility">False</property>
+                            <property name="activates-default">True</property>
+                            <property name="truncate-multiline">True</property>
+                            <property name="input-purpose">password</property>
+                            <child internal-child="accessible">
+                              <object class="AtkObject" 
id="newpassEntry-atkobject">
+                                <property 
name="AtkObject::accessible-description" translatable="yes" 
context="password|extended_tip|newpassEntry">Type a password. A password is 
case sensitive.</property>
+                              </object>
+                            </child>
                           </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkToggleButton" id="togglebt1">
+                            <property name="visible">True</property>
+                            <property name="can-focus">True</property>
+                            <property name="receives-default">True</property>
+                            <property name="image">passimg1</property>
+                            <child internal-child="accessible">
+                              <object class="AtkObject" 
id="togglebt1-atkobject">
+                                <property name="AtkObject::accessible-name" 
translatable="yes" context="password|togglebt1-atkobject">Show 
characters</property>
+                                <property 
name="AtkObject::accessible-description" translatable="yes" 
context="password|extended_tip|togglebt1">Show or hide password 
characters</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
                         </child>
                       </object>
                       <packing>
                         <property name="left-attach">0</property>
-                        <property name="top-attach">4</property>
+                        <property name="top-attach">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkEntry" id="newpassEntry">
+                      <object class="GtkBox" id="confirmpassbox">
                         <property name="visible">True</property>
-                        <property name="can-focus">True</property>
+                        <property name="can-focus">False</property>
                         <property name="hexpand">True</property>
-                        <property name="visibility">False</property>
-                        <property name="activates-default">True</property>
-                        <property name="width-chars">50</property>
-                        <property name="truncate-multiline">True</property>
-                        <property name="input-purpose">password</property>
-                        <child internal-child="accessible">
-                          <object class="AtkObject" 
id="newpassEntry-atkobject">
-                            <property name="AtkObject::accessible-description" 
translatable="yes" context="password|extended_tip|newpassEntry">Type a 
password. A password is case sensitive.</property>
+                        <child>
+                          <object class="GtkEntry" id="confirmpassEntry">
+                            <property name="visible">True</property>
+                            <property name="can-focus">True</property>
+                            <property name="hexpand">True</property>
+                            <property name="visibility">False</property>
+                            <property name="activates-default">True</property>
+                            <property name="truncate-multiline">True</property>
+                            <property name="input-purpose">password</property>
+                            <child internal-child="accessible">
+                              <object class="AtkObject" 
id="confirmpassEntry-atkobject">
+                                <property 
name="AtkObject::accessible-description" translatable="yes" 
context="password|extended_tip|confirmpassEntry">Re-enter the 
password.</property>
+                              </object>
+                            </child>
                           </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkToggleButton" id="togglebt2">
+                            <property name="visible">True</property>
+                            <property name="can-focus">True</property>
+                            <property name="receives-default">True</property>
+                            <property name="image">passimg2</property>
+                            <child internal-child="accessible">
+                              <object class="AtkObject" 
id="togglebt2-atkobject">
+                                <property name="AtkObject::accessible-name" 
translatable="yes" context="password|togglebt2-atkobject">Show 
characters</property>
+                                <property 
name="AtkObject::accessible-description" translatable="yes" 
context="password|extended_tip|togglebt2">Show or hide password 
characters</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
                         </child>
                       </object>
                       <packing>
                         <property name="left-attach">0</property>
-                        <property name="top-attach">1</property>
+                        <property name="top-attach">4</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkLevelBar" id="passlevelbar">
                         <property name="visible">True</property>
                         <property name="can-focus">False</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" 
id="passlevelbar-atkobject">
+                            <property name="AtkObject::accessible-name" 
translatable="yes" context="passsword|passlevelbar-atkobject">Password Level 
Bar</property>
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="passsword|extended_tip|passlevelbar">Shows the 
strength of password</property>
+                          </object>
+                        </child>
                       </object>
                       <packing>
                         <property name="left-attach">0</property>

Reply via email to