Add an option to create encyrpted PDF files with mailmerge.

With that option user can create encyrpted pdf files with
a password column in database via mailmerge.

Change-Id: I081ef050bc269b1fec24fd01ecc812acd7b857ec
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94709
Tested-by: Jenkins
Reviewed-by: Gülşah Köse <[email protected]>
diff --git a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs
index 1ac8ccb..d049dea 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs
@@ -6201,6 +6201,24 @@
            </info>
          </prop>
        </group>
        <group oor:name="FilePassword">
          <info>
            <desc>Specifies how the file password is built.</desc>
          </info>
          <prop oor:name="Generation" oor:type="xs:boolean" oor:nillable="false" >
            <!--UI hints: Form letter - File output - Generate file password from - Database field-->
            <info>
              <desc>Determines if the file password is generated from a database field.</desc>
            </info>
            <value>false</value>
          </prop>
          <prop oor:name="FromDatabaseField" oor:type="xs:string" oor:nillable="false">
            <info>
              <desc>Specifies the column name to be used as file password.</desc>
            </info>
            <value/>
          </prop>
        </group>
      </group>
    </group>
    <group oor:name="Misc">
diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx
index 20a4323..26c7fee 100644
--- a/sw/inc/dbmgr.hxx
+++ b/sw/inc/dbmgr.hxx
@@ -202,6 +202,10 @@
     */
    OUString                                            sDBcolumn;

    /** DB column to fetch password
     */
    OUString                                            sDBPasswordColumn;

    /** @} */

    /**
diff --git a/sw/inc/modcfg.hxx b/sw/inc/modcfg.hxx
index 7020bd4..218e586 100644
--- a/sw/inc/modcfg.hxx
+++ b/sw/inc/modcfg.hxx
@@ -182,9 +182,11 @@
    bool        m_bNumAlignSize;              // Numbering/Graphic/KeepRatio
    bool        m_bSinglePrintJob;            // FormLetter/PrintOutput/SinglePrintJobs
    bool        m_bIsNameFromColumn;          // FormLetter/FileOutput/FileName/Generation
    bool        m_bIsPasswordFromColumn;      // FormLetter/FileOutput/FilePassword/Generation
    bool        m_bAskForMailMergeInPrint;    // Ask if documents containing fields should be 'mailmerged'
    MailTextFormats m_nMailingFormats;            // FormLetter/MailingOutput/Formats
    OUString    m_sNameFromColumn;            // FormLetter/FileOutput/FileName/FromDatabaseField (string!)
    OUString    m_sPasswordFromColumn;        // FormLetter/FileOutput/FilePassword/FromDatabaseField (string!)
    OUString    m_sMailingPath;               // FormLetter/FileOutput/Path
    OUString    m_sMailName;                  // FormLetter/FileOutput/FileName/FromManualSetting (string!)

@@ -339,6 +341,17 @@
    void        SetNameFromColumn( const OUString& rSet )       { m_aMiscConfig.m_sNameFromColumn = rSet;
                                                                  m_aMiscConfig.SetModified();}

    bool        IsFileEncyrptedFromColumn() const        { return m_aMiscConfig.m_bIsPasswordFromColumn;}
    void        SetIsFileEncyrptedFromColumn( bool bSet )
                        {
                            m_aMiscConfig.SetModified();
                            m_aMiscConfig.m_bIsPasswordFromColumn = bSet;
                        }

    const OUString& GetPasswordFromColumn() const       { return m_aMiscConfig.m_sPasswordFromColumn; }
    void        SetPasswordFromColumn( const OUString& rSet )       { m_aMiscConfig.m_sPasswordFromColumn = rSet;
                                                                      m_aMiscConfig.SetModified();}

    const OUString& GetMailingPath() const          { return m_aMiscConfig.m_sMailingPath; }
    void        SetMailingPath(const OUString& sPath) { m_aMiscConfig.m_sMailingPath = sPath;
                                                        m_aMiscConfig.SetModified();}
diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx
index 3d0d323..3e3bd53 100644
--- a/sw/inc/swabstdlg.hxx
+++ b/sw/inc/swabstdlg.hxx
@@ -152,7 +152,9 @@
    virtual css::uno::Reference< css::sdbc::XResultSet> GetResultSet() const = 0;
    virtual bool IsSaveSingleDoc() const = 0;
    virtual bool IsGenerateFromDataBase() const = 0;
    virtual bool IsFileEncyrptedFromDataBase() const = 0;
    virtual OUString GetColumnName() const = 0;
    virtual OUString GetPasswordColumnName() const = 0;
    virtual OUString GetTargetURL() const = 0;
};

diff --git a/sw/source/ui/dialog/swdlgfact.cxx b/sw/source/ui/dialog/swdlgfact.cxx
index de22333..291ee81 100644
--- a/sw/source/ui/dialog/swdlgfact.cxx
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -654,11 +654,21 @@
    return m_xDlg->IsGenerateFromDataBase();
}

bool AbstractMailMergeDlg_Impl::IsFileEncyrptedFromDataBase() const
{
    return m_xDlg->IsFileEncyrptedFromDataBase();
}

OUString AbstractMailMergeDlg_Impl::GetColumnName() const
{
    return m_xDlg->GetColumnName();
}

OUString AbstractMailMergeDlg_Impl::GetPasswordColumnName() const
{
    return m_xDlg->GetPasswordColumnName();
}

OUString AbstractMailMergeDlg_Impl::GetTargetURL() const
{
    return m_xDlg->GetTargetURL();
diff --git a/sw/source/ui/dialog/swdlgfact.hxx b/sw/source/ui/dialog/swdlgfact.hxx
index 9f84f34..426dafc 100644
--- a/sw/source/ui/dialog/swdlgfact.hxx
+++ b/sw/source/ui/dialog/swdlgfact.hxx
@@ -517,7 +517,9 @@
    virtual css::uno::Reference< css::sdbc::XResultSet> GetResultSet() const override;
    virtual bool IsSaveSingleDoc() const override;
    virtual bool IsGenerateFromDataBase() const override;
    virtual bool IsFileEncyrptedFromDataBase() const override;
    virtual OUString GetColumnName() const override;
    virtual OUString GetPasswordColumnName() const override;
    virtual OUString GetTargetURL() const override;
};

diff --git a/sw/source/ui/envelp/mailmrge.cxx b/sw/source/ui/envelp/mailmrge.cxx
index b29e025..8b7cccb 100644
--- a/sw/source/ui/envelp/mailmrge.cxx
+++ b/sw/source/ui/envelp/mailmrge.cxx
@@ -129,12 +129,15 @@
    , m_xMailingRB(m_xBuilder->weld_radio_button("electronic"))
    , m_xFileRB(m_xBuilder->weld_radio_button("file"))
    , m_xSingleJobsCB(m_xBuilder->weld_check_button("singlejobs"))
    , m_xPasswordCB(m_xBuilder->weld_check_button("passwd-check"))
    , m_xSaveMergedDocumentFT(m_xBuilder->weld_label("savemergeddoclabel"))
    , m_xSaveSingleDocRB(m_xBuilder->weld_radio_button("singledocument"))
    , m_xSaveIndividualRB(m_xBuilder->weld_radio_button("individualdocuments"))
    , m_xGenerateFromDataBaseCB(m_xBuilder->weld_check_button("generate"))
    , m_xColumnFT(m_xBuilder->weld_label("fieldlabel"))
    , m_xColumnLB(m_xBuilder->weld_combo_box("field"))
    , m_xPasswordFT(m_xBuilder->weld_label("passwd-label"))
    , m_xPasswordLB(m_xBuilder->weld_combo_box("passwd-combobox"))
    , m_xPathFT(m_xBuilder->weld_label("pathlabel"))
    , m_xPathED(m_xBuilder->weld_entry("path"))
    , m_xPathPB(m_xBuilder->weld_button("pathpb"))
@@ -164,6 +167,9 @@
    m_xAttachFT->hide();
    m_xAttachED->hide();
    m_xAttachPB->hide();
    m_xPasswordCB->hide();
    m_xPasswordFT->hide();
    m_xPasswordLB->hide();

    uno::Reference< lang::XMultiServiceFactory > xMSF = comphelper::getProcessServiceFactory();
    if(pSelection) {
@@ -241,6 +247,8 @@
    m_xSaveIndividualRB->connect_toggled(LINK(this, SwMailMergeDlg, SaveTypeHdl));
    SaveTypeHdl(*m_xSaveSingleDocRB);

    m_xFilterLB->connect_changed(LINK(this, SwMailMergeDlg, FileFormatHdl));

    Link<weld::SpinButton&,void> aLk2 = LINK(this, SwMailMergeDlg, ModifyHdl);
    m_xFromNF->connect_value_changed(aLk2);
    m_xToNF->connect_value_changed(aLk2);
@@ -253,7 +261,10 @@
    else
        pDBManager->GetColumnNames(*m_xAddressFieldLB, rSourceName, rTableName);
    for(sal_Int32 nEntry = 0, nEntryCount = m_xAddressFieldLB->get_count(); nEntry < nEntryCount; ++nEntry)
    {
        m_xColumnLB->append_text(m_xAddressFieldLB->get_text(nEntry));
        m_xPasswordLB->append_text(m_xAddressFieldLB->get_text(nEntry));
    }

    m_xAddressFieldLB->set_active_text("EMAIL");

@@ -268,15 +279,23 @@
    else
        m_xPathED->set_text(aURL.GetFull());

    if (!bColumn ) {
    if (!bColumn )
    {
        m_xColumnLB->set_active_text("NAME");
    } else
        m_xPasswordLB->set_active_text("PASSWORD");
    }
    else
    {
        m_xColumnLB->set_active_text(pModOpt->GetNameFromColumn());
        m_xPasswordLB->set_active_text(pModOpt->GetPasswordFromColumn());
    }

    if (m_xAddressFieldLB->get_active() == -1)
        m_xAddressFieldLB->set_active(0);
    if (m_xColumnLB->get_active() == -1)
        m_xColumnLB->set_active(0);
    if (m_xPasswordLB->get_active() == -1)
        m_xPasswordLB->set_active(0);

    const bool bEnable = m_aSelection.hasElements();
    m_xMarkedRB->set_sensitive(bEnable);
@@ -355,6 +374,9 @@
        m_xFilterFT->set_sensitive(false);
        m_xFilterLB->set_sensitive(false);
        m_xGenerateFromDataBaseCB->set_sensitive(false);
        m_xPasswordCB->set_sensitive( false );
        m_xPasswordFT->set_sensitive( false );
        m_xPasswordLB->set_sensitive( false );
    }
}

@@ -363,9 +385,12 @@
    bool bIndividual = m_xSaveIndividualRB->get_active();

    m_xGenerateFromDataBaseCB->set_sensitive( bIndividual );
    if( bIndividual ) {
    if( bIndividual )
    {
        FilenameHdl(*m_xGenerateFromDataBaseCB);
    } else {
    }
    else
    {
        m_xColumnFT->set_sensitive(false);
        m_xColumnLB->set_sensitive(false);
        m_xPathFT->set_sensitive( false );
@@ -373,6 +398,9 @@
        m_xPathPB->set_sensitive( false );
        m_xFilterFT->set_sensitive( false );
        m_xFilterLB->set_sensitive( false );
        m_xPasswordCB->set_sensitive( false );
        m_xPasswordFT->set_sensitive( false );
        m_xPasswordLB->set_sensitive( false );
    }
}

@@ -386,6 +414,37 @@
    m_xPathPB->set_sensitive( bEnable );
    m_xFilterFT->set_sensitive( bEnable );
    m_xFilterLB->set_sensitive( bEnable );

    if(m_xFilterLB->get_active_id() == "writer_pdf_Export")
    {
        m_xPasswordCB->show();
        m_xPasswordFT->show();
        m_xPasswordLB->show();

        m_xPasswordCB->set_sensitive( bEnable );
        m_xPasswordFT->set_sensitive( bEnable );
        m_xPasswordLB->set_sensitive( bEnable );
    }
}

IMPL_LINK_NOARG( SwMailMergeDlg, FileFormatHdl, weld::ComboBox&, void )
{
    if(m_xFilterLB->get_active_id() == "writer_pdf_Export")
    {
        m_xPasswordCB->show();
        m_xPasswordFT->show();
        m_xPasswordLB->show();

        m_xPasswordCB->set_sensitive( true );
        m_xPasswordFT->set_sensitive( true );
        m_xPasswordLB->set_sensitive( true );
    }
    else
    {
        m_xPasswordCB->hide();
        m_xPasswordFT->hide();
        m_xPasswordLB->hide();
    }
}

IMPL_LINK_NOARG(SwMailMergeDlg, ModifyHdl, weld::SpinButton&, void)
@@ -425,15 +484,19 @@
        nMergeType = DBMGR_MERGE_FILE;
        pModOpt->SetMailingPath( GetURLfromPath() );
        pModOpt->SetIsNameFromColumn(m_xGenerateFromDataBaseCB->get_active());
        pModOpt->SetIsFileEncyrptedFromColumn(m_xPasswordCB->get_active());

        if (!AskUserFilename()) {
        if (!AskUserFilename())
        {
            pModOpt->SetNameFromColumn(m_xColumnLB->get_active_text());
            pModOpt->SetPasswordFromColumn(m_xPasswordLB->get_active_text());
            if (m_xFilterLB->get_active() != -1)
                m_sSaveFilter = m_xFilterLB->get_active_id();
            m_sFilename = OUString();
        } else {
            //#i97667# reset column name - otherwise it's remembered from the last run
            pModOpt->SetNameFromColumn(OUString());
            pModOpt->SetPasswordFromColumn(OUString());
            //start save as dialog
            OUString sFilter;
            m_sFilename = SwMailMergeHelper::CallSaveAsDialog(m_xDialog.get(), sFilter);
diff --git a/sw/source/uibase/config/modcfg.cxx b/sw/source/uibase/config/modcfg.cxx
index 80727fb..b8838c7 100644
--- a/sw/source/uibase/config/modcfg.cxx
+++ b/sw/source/uibase/config/modcfg.cxx
@@ -1161,6 +1161,7 @@
    m_bNumAlignSize(true),
    m_bSinglePrintJob(false),
    m_bIsNameFromColumn(true),
    m_bIsPasswordFromColumn(false),
    m_bAskForMailMergeInPrint(true),
    m_nMailingFormats(MailTextFormats::NONE)
{
@@ -1187,6 +1188,8 @@
            "FormLetter/FileOutput/FileName/FromManualSetting",   // 9
            "FormLetter/FileOutput/FileName/Generation",//10
            "FormLetter/PrintOutput/AskForMerge"        //11
            "FormLetter/FileOutput/FilePassword/FromDatabaseField",  // 12
            "FormLetter/FileOutput/FilePassword/Generation",//13
    };
    return aNames;
}
@@ -1218,6 +1221,8 @@
            case 9 : pValues[nProp] <<= m_sMailName;        break;
            case 10: pValues[nProp] <<= m_bIsNameFromColumn; break;
            case 11: pValues[nProp] <<= m_bAskForMailMergeInPrint; break;
            case 12: pValues[nProp] <<= m_sPasswordFromColumn; break;
            case 13: pValues[nProp] <<= m_bIsPasswordFromColumn; break;
        }
    }
    PutProperties(aNames, aValues);
@@ -1250,6 +1255,8 @@
                case 9 : pValues[nProp] >>= sTmp; m_sMailName = sTmp;     break;
                case 10: m_bIsNameFromColumn = *o3tl::doAccess<bool>(pValues[nProp]); break;
                case 11: pValues[nProp] >>= m_bAskForMailMergeInPrint; break;
                case 12: m_bIsPasswordFromColumn = *o3tl::doAccess<bool>(pValues[nProp]); break;
                case 13: pValues[nProp] >>= sTmp; m_sPasswordFromColumn = sTmp; break;
            }
        }
    }
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 01da353..3bfb4e1 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -936,6 +936,30 @@
    }
}

static void lcl_PrepareSaveFilterDataOptions(
    const uno::Sequence< beans::PropertyValue >& rInSaveFilterDataptions,
    uno::Sequence< beans::PropertyValue >& rOutSaveFilterDataOptions,
    const OUString& sPassword)
{
    const sal_Int32 nOffset = 2;
    rOutSaveFilterDataOptions.realloc( nOffset );
    rOutSaveFilterDataOptions[ 0 ].Name = "EncryptFile";
    rOutSaveFilterDataOptions[ 0 ].Value <<= true;
    rOutSaveFilterDataOptions[ 1 ].Name = "DocumentOpenPassword";
    rOutSaveFilterDataOptions[ 1 ].Value <<= sPassword;

    // copy other options
    sal_Int32 nIndex = nOffset;
    for( const beans::PropertyValue& rOption : rInSaveFilterDataptions)
    {
         rOutSaveFilterDataOptions.realloc( nIndex + 1 );
         rOutSaveFilterDataOptions[ nIndex ].Name = rOption.Name;
         rOutSaveFilterDataOptions[ nIndex++ ].Value = rOption.Value ;
    }

}


static SfxObjectShell* lcl_CreateWorkingDocument(
    // input
    const WorkingDocType aType, const SwWrtShell &rSourceWrtShell,
@@ -1135,10 +1159,13 @@
    rtl_TextEncoding                    sMailEncoding = ::osl_getThreadTextEncoding();

    uno::Reference< beans::XPropertySet > xColumnProp;
    uno::Reference< beans::XPropertySet > xPasswordColumnProp;

    // Check for (mandatory) email or (optional) filename column
    SwDBFormatData aColumnDBFormat;
    bool bColumnName = !rMergeDescriptor.sDBcolumn.isEmpty();
    bool bPasswordColumnName = !rMergeDescriptor.sDBPasswordColumn.isEmpty();

    if( ! bColumnName )
    {
        if( bMT_EMAIL )
@@ -1153,6 +1180,12 @@
        uno::Any aCol = xCols->getByName( rMergeDescriptor.sDBcolumn );
        aCol >>= xColumnProp;

        if(bPasswordColumnName)
        {
            aCol = xCols->getByName( rMergeDescriptor.sDBPasswordColumn );
            aCol >>= xPasswordColumnProp;
        }

        aColumnDBFormat.xFormatter = m_pImpl->pMergeData->xFormatter;
        aColumnDBFormat.aNullDate  = m_pImpl->pMergeData->aNullDate;

@@ -1363,6 +1396,15 @@
                }
            }

            OUString sPasswordColumnData;
            uno::Sequence< beans::PropertyValue > aSaveToFilterDataOptions( rMergeDescriptor.aSaveToFilterData );

            if( bMT_EMAIL || bPasswordColumnName )
            {
                sPasswordColumnData = GetDBField( xPasswordColumnProp, aColumnDBFormat );
                lcl_PrepareSaveFilterDataOptions( rMergeDescriptor.aSaveToFilterData, aSaveToFilterDataOptions, sPasswordColumnData );
            }

            if( IsMergeOk() )
            {
                std::unique_ptr< INetURLObject > aTempFileURL;
@@ -1489,7 +1531,7 @@
                    // save merged document
                    OUString sFileURL;
                    if( !lcl_SaveDoc( aTempFileURL.get(), pStoreToFilter, pStoreToFilterOptions,
                                    &rMergeDescriptor.aSaveToFilterData, bIsPDFexport,
                                    &aSaveToFilterDataOptions, bIsPDFexport,
                                    xWorkDocSh, *pWorkShell, &sFileURL ) )
                    {
                        m_aMergeStatus = MergeStatus::Error;
@@ -3011,9 +3053,14 @@
        aMergeDesc.bCreateSingleFile = m_pImpl->pMergeDialog->IsSaveSingleDoc();
        aMergeDesc.bPrefixIsFilename = aMergeDesc.bCreateSingleFile;
        aMergeDesc.sPrefix = m_pImpl->pMergeDialog->GetTargetURL();
        if( !aMergeDesc.bCreateSingleFile && m_pImpl->pMergeDialog->IsGenerateFromDataBase() )

        if(!aMergeDesc.bCreateSingleFile)
        {
            aMergeDesc.sDBcolumn = m_pImpl->pMergeDialog->GetColumnName();
            if(m_pImpl->pMergeDialog->IsGenerateFromDataBase())
                aMergeDesc.sDBcolumn = m_pImpl->pMergeDialog->GetColumnName();

            if(m_pImpl->pMergeDialog->IsFileEncyrptedFromDataBase())
                aMergeDesc.sDBPasswordColumn = m_pImpl->pMergeDialog->GetPasswordColumnName();
        }

        Merge( aMergeDesc );
diff --git a/sw/source/uibase/inc/mailmrge.hxx b/sw/source/uibase/inc/mailmrge.hxx
index fca25ac..f954500 100644
--- a/sw/source/uibase/inc/mailmrge.hxx
+++ b/sw/source/uibase/inc/mailmrge.hxx
@@ -70,6 +70,7 @@
    std::unique_ptr<weld::RadioButton> m_xFileRB;

    std::unique_ptr<weld::CheckButton> m_xSingleJobsCB;
    std::unique_ptr<weld::CheckButton> m_xPasswordCB;

    std::unique_ptr<weld::Label> m_xSaveMergedDocumentFT;
    std::unique_ptr<weld::RadioButton> m_xSaveSingleDocRB;
@@ -79,6 +80,8 @@

    std::unique_ptr<weld::Label> m_xColumnFT;
    std::unique_ptr<weld::ComboBox> m_xColumnLB;
    std::unique_ptr<weld::Label> m_xPasswordFT;
    std::unique_ptr<weld::ComboBox> m_xPasswordLB;
    std::unique_ptr<weld::Label> m_xPathFT;
    std::unique_ptr<weld::Entry> m_xPathED;
    std::unique_ptr<weld::Button> m_xPathPB;
@@ -104,6 +107,7 @@
    DECL_LINK( FilenameHdl, weld::ToggleButton&, void );
    DECL_LINK( ModifyHdl, weld::SpinButton&, void );
    DECL_LINK( SaveTypeHdl, weld::ToggleButton&, void );
    DECL_LINK( FileFormatHdl, weld::ComboBox&, void );

    bool            ExecQryShell();
    bool            AskUserFilename() const;
@@ -122,7 +126,9 @@

    bool IsSaveSingleDoc() const { return m_xSaveSingleDocRB->get_active(); }
    bool IsGenerateFromDataBase() const { return m_xGenerateFromDataBaseCB->get_active(); }
    bool IsFileEncyrptedFromDataBase() const { return m_xPasswordCB->get_active(); }
    OUString GetColumnName() const { return m_xColumnLB->get_active_text(); }
    OUString GetPasswordColumnName() const { return m_xPasswordLB->get_active_text(); }
    OUString GetTargetURL() const;

    const OUString& GetSaveFilter() const {return m_sSaveFilter;}
diff --git a/sw/uiconfig/swriter/ui/mailmerge.ui b/sw/uiconfig/swriter/ui/mailmerge.ui
index aa97299..6c3becb 100644
--- a/sw/uiconfig/swriter/ui/mailmerge.ui
+++ b/sw/uiconfig/swriter/ui/mailmerge.ui
@@ -508,7 +508,7 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">0</property>
                                                    <property name="top_attach">5</property>
                                                    <property name="top_attach">7</property>
                                                  </packing>
                                                </child>
                                                <child>
@@ -520,7 +520,7 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">1</property>
                                                    <property name="top_attach">5</property>
                                                    <property name="top_attach">7</property>
                                                  </packing>
                                                </child>
                                                <child>
@@ -535,7 +535,7 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">0</property>
                                                    <property name="top_attach">6</property>
                                                    <property name="top_attach">8</property>
                                                  </packing>
                                                </child>
                                                <child>
@@ -547,7 +547,7 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">1</property>
                                                    <property name="top_attach">6</property>
                                                    <property name="top_attach">8</property>
                                                  </packing>
                                                </child>
                                                <child>
@@ -561,7 +561,7 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">2</property>
                                                    <property name="top_attach">6</property>
                                                    <property name="top_attach">8</property>
                                                  </packing>
                                                </child>
                                                <child>
@@ -575,7 +575,7 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">0</property>
                                                    <property name="top_attach">7</property>
                                                    <property name="top_attach">9</property>
                                                  </packing>
                                                </child>
                                                <child>
@@ -586,7 +586,7 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">1</property>
                                                    <property name="top_attach">4</property>
                                                    <property name="top_attach">6</property>
                                                  </packing>
                                                </child>
                                                <child>
@@ -602,7 +602,7 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">1</property>
                                                    <property name="top_attach">7</property>
                                                    <property name="top_attach">9</property>
                                                  </packing>
                                                </child>
                                                <child>
@@ -618,7 +618,7 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">1</property>
                                                    <property name="top_attach">8</property>
                                                    <property name="top_attach">10</property>
                                                  </packing>
                                                </child>
                                                <child>
@@ -634,10 +634,55 @@
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">1</property>
                                                    <property name="top_attach">9</property>
                                                    <property name="top_attach">11</property>
                                                  </packing>
                                                </child>
                                                <child>
                                                  <object class="GtkCheckButton" id="passwd-check">
                                                    <property name="label" translatable="yes" context="mailmerge|passwd-check">Save with password</property>
                                                    <property name="visible">True</property>
                                                    <property name="can_focus">True</property>
                                                    <property name="receives_default">False</property>
                                                    <property name="draw_indicator">True</property>
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">0</property>
                                                    <property name="top_attach">4</property>
                                                    <property name="width">2</property>
                                                  </packing>
                                                </child>
                                                <child>
                                                  <object class="GtkLabel" id="passwd-label">
                                                    <property name="visible">True</property>
                                                    <property name="can_focus">False</property>
                                                    <property name="halign">start</property>
                                                    <property name="label" translatable="yes" context="mailmerge|passwd-label">Password field:</property>
                                                    <property name="use_underline">True</property>
                                                    <property name="mnemonic_widget">passwd-combobox</property>
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">0</property>
                                                    <property name="top_attach">5</property>
                                                  </packing>
                                                </child>
                                                <child>
                                                  <object class="GtkComboBoxText" id="passwd-combobox">
                                                    <property name="visible">True</property>
                                                    <property name="can_focus">False</property>
                                                    <property name="hexpand">True</property>
                                                  </object>
                                                  <packing>
                                                    <property name="left_attach">1</property>
                                                    <property name="top_attach">5</property>
                                                  </packing>
                                                </child>
                                                <child>
                                                  <placeholder/>
                                                </child>
                                                <child>
                                                  <placeholder/>
                                                </child>
                                                <child>
                                                  <placeholder/>
                                                </child>
                                                <child>