So far, weld::TreeView::enable_toggle_buttons was doing two things: * enable a special "toggle button column" to be accessed with a special column index of -1 in the weld::TreeView API (as documented) * switch the type of *all* toggle buttons used in all cells/columns of the TreeView to the type passed as a parameter (not only set the type of the toggle buttons for the special toggle button column at index -1) Untangle these 2 things by splitting this to two methods: * weld::TreeView::enable_toggle_buttons now only enables the special toggle button column at index -1. * The new weld::TreeView::set_toggle_button_type sets the type of all toggle buttons used in the table. This makes the API clearer and will allow using one of the two without necessarily also using the other, which will allow further simplification/improvements in upcoming commits. It could also make it easier to support only setting the type of single columns to use radio buttons in the future (i.e. have one column using radio buttons and another one using check buttons in the same table), but that would require further rework in the underlying toolkit-specific implementations (in particular the vcl one). One case where mixing the two things together results in non-optimal behavior is the "Assign Styles" dialog with the vcl implementation: While the special toggle column with index -1 isn't actually used, the SwAddStylesDlg_Impl ctor still calls weld::TreeView::enable_toggle_buttons, presumably only to enable the use of radio buttons for the actually used toggle columns at the end. As a consequence, the style names in the first column are indented for no good reason (but only to leave space for drawing the toggle buttons for the special toggle button column that was enabled without actually being needed). This will be adjusted in an upcoming commit. Initially, just replace all callers of weld::TreeView::enable_toggle_buttons passing weld::ColumnToggleType::Radio for the type with calls to both methods, to keep the existing behavior and be able to further look into further improvements separately. Change-Id: I098feb474162d61c5452c3496293a420118e2f4f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207250 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
246 lines
8.6 KiB
C++
246 lines
8.6 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include <officecfg/Office/Common.hxx>
|
|
#include <osl/file.hxx>
|
|
#include <osl/security.hxx>
|
|
#include <sfx2/filedlghelper.hxx>
|
|
#include <comphelper/diagnose_ex.hxx>
|
|
#include <vcl/vclenum.hxx>
|
|
#include <vcl/weld/Builder.hxx>
|
|
#include <vcl/weld/Dialog.hxx>
|
|
#include "certpath.hxx"
|
|
|
|
#include <com/sun/star/xml/crypto/NSSInitializer.hpp>
|
|
#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
|
|
#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
|
|
#include <comphelper/processfactory.hxx>
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
CertPathDialog::CertPathDialog(weld::Window* pParent)
|
|
: GenericDialogController(pParent, u"cui/ui/certdialog.ui"_ustr, u"CertDialog"_ustr)
|
|
, m_xManualButton(m_xBuilder->weld_button(u"add"_ustr))
|
|
, m_xOKButton(m_xBuilder->weld_button(u"ok"_ustr))
|
|
, m_xCertPathList(m_xBuilder->weld_tree_view(u"paths"_ustr))
|
|
, m_sAddDialogText(m_xBuilder->weld_label(u"certdir"_ustr)->get_label())
|
|
, m_sManualLabel(m_xBuilder->weld_label(u"manual"_ustr)->get_label())
|
|
{
|
|
m_xCertPathList->set_size_request(m_xCertPathList->get_approximate_digit_width() * 140,
|
|
m_xCertPathList->get_height_rows(6));
|
|
|
|
// needed for VCLPLUGIN != gtk3 (e.g. "gen")
|
|
int nControlWidth = m_xCertPathList->get_approximate_digit_width() * 40;
|
|
m_xCertPathList->set_column_fixed_widths({nControlWidth});
|
|
|
|
m_xCertPathList->enable_toggle_buttons();
|
|
m_xCertPathList->set_toggle_button_type(weld::ColumnToggleType::Radio);
|
|
m_xCertPathList->connect_toggled(LINK(this, CertPathDialog, CheckHdl_Impl));
|
|
|
|
m_xManualButton->connect_clicked( LINK( this, CertPathDialog, ManualHdl_Impl ) );
|
|
m_xOKButton->connect_clicked( LINK( this, CertPathDialog, OKHdl_Impl ) );
|
|
}
|
|
|
|
void CertPathDialog::Init()
|
|
{
|
|
m_xCertPathList->clear();
|
|
m_xCertPathList->set_sensitive(true);
|
|
|
|
try
|
|
{
|
|
const uno::Reference<uno::XComponentContext>& xContext = comphelper::getProcessComponentContext();
|
|
uno::Reference<xml::crypto::XNSSInitializer> xCipherContextSupplier = xml::crypto::NSSInitializer::create(xContext);
|
|
|
|
OUString sActivePath = xCipherContextSupplier->getNSSPath();
|
|
auto aProductList = xCipherContextSupplier->getNSSProfiles();
|
|
|
|
// these map to the integer values of mozilla::MozillaProductType
|
|
const char* const productNames[4] = {
|
|
"",
|
|
"mozilla",
|
|
"firefox",
|
|
"thunderbird"
|
|
};
|
|
|
|
for (const auto& rNSSProfile : aProductList)
|
|
{
|
|
if (rNSSProfile.Type == mozilla::MozillaProductType_Default)
|
|
{
|
|
if (rNSSProfile.Name == "MOZILLA_CERTIFICATE_FOLDER" && !rNSSProfile.Path.isEmpty())
|
|
{
|
|
AddCertPath(u"$MOZILLA_CERTIFICATE_FOLDER"_ustr, rNSSProfile.Path);
|
|
m_xCertPathList->set_sensitive(false);
|
|
}
|
|
else if (rNSSProfile.Name == "MANUAL")
|
|
AddManualCertPath(rNSSProfile.Path);
|
|
}
|
|
else
|
|
{
|
|
OUString sEntry = OUString::createFromAscii(
|
|
productNames[static_cast<int>(rNSSProfile.Type)]) + ":" + rNSSProfile.Name;
|
|
AddCertPath(sEntry, rNSSProfile.Path, rNSSProfile.Path == sActivePath);
|
|
}
|
|
}
|
|
|
|
OUString sManualCertPath = officecfg::Office::Common::Security::Scripting::ManualCertDir::get();
|
|
if (!sManualCertPath.isEmpty())
|
|
AddManualCertPath(sManualCertPath, false);
|
|
}
|
|
catch (const uno::Exception&)
|
|
{
|
|
}
|
|
}
|
|
|
|
void CertPathDialog::AddManualCertPath(const OUString& sUserSetCertPath, bool bSelect)
|
|
{
|
|
if (sUserSetCertPath.isEmpty())
|
|
return;
|
|
|
|
::osl::DirectoryItem aUserPathItem;
|
|
OUString sUserSetCertURLPath;
|
|
osl::FileBase::getFileURLFromSystemPath(sUserSetCertPath, sUserSetCertURLPath);
|
|
if (::osl::FileBase::E_None == ::osl::DirectoryItem::get(sUserSetCertURLPath, aUserPathItem))
|
|
{
|
|
::osl::FileStatus aStatus( osl_FileStatus_Mask_Validate );
|
|
if (::osl::FileBase::E_None == aUserPathItem.getFileStatus(aStatus))
|
|
// the cert path exists
|
|
AddCertPath(m_sManualLabel, sUserSetCertPath, bSelect);
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(CertPathDialog, OKHdl_Impl, weld::Button&, void)
|
|
{
|
|
try
|
|
{
|
|
std::shared_ptr< comphelper::ConfigurationChanges > batch(
|
|
comphelper::ConfigurationChanges::create());
|
|
const int nEntry = m_xCertPathList->get_selected_index();
|
|
officecfg::Office::Common::Security::Scripting::CertDir::set(
|
|
nEntry == -1 ? OUString() : m_xCertPathList->get_id(nEntry), batch);
|
|
officecfg::Office::Common::Security::Scripting::ManualCertDir::set(m_sManualPath, batch);
|
|
batch->commit();
|
|
}
|
|
catch (const uno::Exception &)
|
|
{
|
|
TOOLS_WARN_EXCEPTION("cui.options", "CertPathDialog::OKHdl_Impl()");
|
|
}
|
|
|
|
m_xDialog->response(RET_OK);
|
|
}
|
|
|
|
bool CertPathDialog::isActiveServicePath() const
|
|
{
|
|
int nEntry = m_xCertPathList->get_selected_index();
|
|
if (nEntry == -1)
|
|
return true;
|
|
|
|
try
|
|
{
|
|
const uno::Reference<uno::XComponentContext>& xContext = comphelper::getProcessComponentContext();
|
|
uno::Reference<xml::crypto::XNSSInitializer> xCipherContextSupplier = xml::crypto::NSSInitializer::create(xContext);
|
|
|
|
if (!xCipherContextSupplier->getIsNSSinitialized())
|
|
return true;
|
|
return (xCipherContextSupplier->getNSSPath() == m_xCertPathList->get_id(nEntry));
|
|
}
|
|
catch (const uno::Exception&)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
CertPathDialog::~CertPathDialog()
|
|
{
|
|
}
|
|
|
|
IMPL_LINK(CertPathDialog, CheckHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
|
|
{
|
|
HandleEntryChecked(m_xCertPathList->get_iter_index_in_parent(rRowCol.first));
|
|
}
|
|
|
|
void CertPathDialog::HandleEntryChecked(int nRow)
|
|
{
|
|
const bool bChecked = m_xCertPathList->get_toggle(nRow) == TRISTATE_TRUE;
|
|
if (bChecked)
|
|
{
|
|
// we have radio button behavior -> so uncheck the other entries
|
|
m_xCertPathList->select(nRow);
|
|
const int nCount = m_xCertPathList->n_children();
|
|
for (int i = 0; i < nCount; ++i)
|
|
{
|
|
if (i != nRow)
|
|
m_xCertPathList->set_toggle(i, TRISTATE_FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CertPathDialog::AddCertPath(const OUString &rProfile, const OUString &rPath, const bool bSelect)
|
|
{
|
|
int nRow = -1;
|
|
for (int i = 0, nCount = m_xCertPathList->n_children(); i < nCount; ++i)
|
|
{
|
|
OUString sCertPath = m_xCertPathList->get_id(i);
|
|
//already exists, just select the original one
|
|
if (sCertPath == rPath)
|
|
{
|
|
const bool bWantSelected = bSelect || m_xCertPathList->get_toggle(i);
|
|
m_xCertPathList->set_toggle(i, bWantSelected ? TRISTATE_TRUE : TRISTATE_FALSE);
|
|
HandleEntryChecked(i);
|
|
return;
|
|
}
|
|
else if (m_xCertPathList->get_text(i, 0) == rProfile)
|
|
nRow = i;
|
|
}
|
|
|
|
if (m_sManualLabel == rProfile)
|
|
m_sManualPath = rPath;
|
|
|
|
if (nRow < 0)
|
|
{
|
|
m_xCertPathList->append();
|
|
nRow = m_xCertPathList->n_children() - 1;
|
|
}
|
|
m_xCertPathList->set_toggle(nRow, bSelect ? TRISTATE_TRUE : TRISTATE_FALSE);
|
|
m_xCertPathList->set_text(nRow, rProfile, 0);
|
|
m_xCertPathList->set_text(nRow, rPath, 1);
|
|
m_xCertPathList->set_id(nRow, rPath);
|
|
HandleEntryChecked(nRow);
|
|
}
|
|
|
|
IMPL_LINK_NOARG(CertPathDialog, ManualHdl_Impl, weld::Button&, void)
|
|
{
|
|
try
|
|
{
|
|
uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = sfx2::createFolderPicker(
|
|
comphelper::getProcessComponentContext(), m_xDialog.get());
|
|
|
|
OUString sURL;
|
|
if (!m_sManualPath.isEmpty())
|
|
osl::FileBase::getFileURLFromSystemPath(m_sManualPath, sURL);
|
|
if (sURL.isEmpty())
|
|
osl::Security().getHomeDir(sURL);
|
|
xFolderPicker->setDisplayDirectory(sURL);
|
|
xFolderPicker->setDescription(m_sAddDialogText);
|
|
|
|
if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
|
|
{
|
|
sURL = xFolderPicker->getDirectory();
|
|
OUString aPath;
|
|
if (osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(sURL, aPath))
|
|
AddCertPath(m_sManualLabel, aPath);
|
|
}
|
|
}
|
|
catch (const uno::Exception &)
|
|
{
|
|
TOOLS_WARN_EXCEPTION("cui.options", "");
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|