weld SfxAcceleratorConfigPage
fixes a leak in the KeyList too
Change-Id: I603218ff99481bc006df329c770ea6fe6f147483
Reviewed-on: https://gerrit.libreoffice.org/68694
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/cui/source/customize/acccfg.cxx b/cui/source/customize/acccfg.cxx
index a5a63ee..4146be2a 100644
--- a/cui/source/customize/acccfg.cxx
+++ b/cui/source/customize/acccfg.cxx
@@ -779,43 +779,6 @@ static const sal_uInt16 KEYCODE_ARRAY[] =
static const sal_uInt16 KEYCODE_ARRAY_SIZE = SAL_N_ELEMENTS(KEYCODE_ARRAY);
// seems to be needed to layout the list box, which shows all
// assignable shortcuts
static const long AccCfgTabs[] =
{
0,
120 // Function
};
class SfxAccCfgLBoxString_Impl : public SvLBoxString
{
public:
explicit SfxAccCfgLBoxString_Impl(const OUString& sText);
virtual void Paint(const Point& aPos, SvTreeListBox& rDevice, vcl::RenderContext& rRenderContext,
const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) override;
};
SfxAccCfgLBoxString_Impl::SfxAccCfgLBoxString_Impl(const OUString& sText)
: SvLBoxString(sText)
{}
void SfxAccCfgLBoxString_Impl::Paint(const Point& aPos, SvTreeListBox& /*rDevice*/, vcl::RenderContext& rRenderContext,
const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry)
{
TAccInfo* pUserData = static_cast<TAccInfo*>(rEntry.GetUserData());
if (!pUserData)
return;
if (pUserData->m_bIsConfigurable)
rRenderContext.DrawText(aPos, GetText());
else
rRenderContext.DrawCtrlText(aPos, GetText(), 0, -1, DrawTextFlags::Disable);
}
extern "C" SAL_DLLPUBLIC_EXPORT void makeSfxAccCfgTabListBox(VclPtr<vcl::Window> & rRet, VclPtr<vcl::Window> & pParent, VclBuilder::stringmap & rMap)
{
WinBits nWinBits = WB_TABSTOP;
@@ -876,8 +839,8 @@ void SfxAccCfgTabListBox_Impl::KeyInput(const KeyEvent& aKey)
SvTabListBox::KeyInput(aKey);
}
SfxAcceleratorConfigPage::SfxAcceleratorConfigPage( vcl::Window* pParent, const SfxItemSet& aSet )
: SfxTabPage(pParent, "AccelConfigPage", "cui/ui/accelconfigpage.ui", &aSet)
SfxAcceleratorConfigPage::SfxAcceleratorConfigPage(TabPageParent pParent, const SfxItemSet& aSet )
: SfxTabPage(pParent, "cui/ui/accelconfigpage.ui", "AccelConfigPage", &aSet)
, m_pMacroInfoItem()
, aLoadAccelConfigStr(CuiResId(RID_SVXSTR_LOADACCELCONFIG))
, aSaveAccelConfigStr(CuiResId(RID_SVXSTR_SAVEACCELCONFIG))
@@ -886,70 +849,60 @@ SfxAcceleratorConfigPage::SfxAcceleratorConfigPage( vcl::Window* pParent, const
, m_xGlobal()
, m_xModule()
, m_xAct()
, m_aUpdateDataTimer("UpdateDataTimer")
, m_xEntriesBox(m_xBuilder->weld_tree_view("shortcuts"))
, m_xOfficeButton(m_xBuilder->weld_radio_button("office"))
, m_xModuleButton(m_xBuilder->weld_radio_button("module"))
, m_xChangeButton(m_xBuilder->weld_button("change"))
, m_xRemoveButton(m_xBuilder->weld_button("delete"))
, m_xGroupLBox(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("category")))
, m_xFunctionBox(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("function")))
, m_xKeyBox(m_xBuilder->weld_tree_view("keys"))
, m_xSearchEdit(m_xBuilder->weld_entry("searchEntry"))
, m_xLoadButton(m_xBuilder->weld_button("load"))
, m_xSaveButton(m_xBuilder->weld_button("save"))
, m_xResetButton(m_xBuilder->weld_button("reset"))
{
get(m_pOfficeButton, "office");
get(m_pModuleButton, "module");
get(m_pChangeButton, "change");
get(m_pRemoveButton, "delete");
get(m_pLoadButton, "load");
get(m_pSaveButton, "save");
get(m_pResetButton, "reset");
get(m_pEntriesBox, "shortcuts");
Size aSize(LogicToPixel(Size(174, 100), MapMode(MapUnit::MapAppFont)));
m_pEntriesBox->set_width_request(aSize.Width());
m_pEntriesBox->set_height_request(aSize.Height());
get(m_pGroupLBox, "category");
m_xEntriesBox->set_size_request(aSize.Width(), aSize.Height());
aSize = LogicToPixel(Size(78 , 91), MapMode(MapUnit::MapAppFont));
m_pGroupLBox->set_width_request(aSize.Width());
m_pGroupLBox->set_height_request(aSize.Height());
get(m_pFunctionBox, "function");
m_xGroupLBox->set_size_request(aSize.Width(), aSize.Height());
aSize = LogicToPixel(Size(88, 91), MapMode(MapUnit::MapAppFont));
m_pFunctionBox->set_width_request(aSize.Width());
m_pFunctionBox->set_height_request(aSize.Height());
get(m_pKeyBox, "keys");
m_xFunctionBox->set_size_request(aSize.Width(), aSize.Height());
aSize = LogicToPixel(Size(80, 91), MapMode(MapUnit::MapAppFont));
m_pKeyBox->set_width_request(aSize.Width());
m_pKeyBox->set_height_request(aSize.Height());
get(m_pSearchEdit, "searchEntry");
m_xKeyBox->set_size_request(aSize.Width(), aSize.Height());
aFilterAllStr = SfxResId( STR_SFX_FILTERNAME_ALL );
// install handler functions
m_pChangeButton->SetClickHdl( LINK( this, SfxAcceleratorConfigPage, ChangeHdl ));
m_pRemoveButton->SetClickHdl( LINK( this, SfxAcceleratorConfigPage, RemoveHdl ));
m_pEntriesBox->SetSelectHdl ( LINK( this, SfxAcceleratorConfigPage, SelectHdl ));
m_pGroupLBox->SetSelectHdl ( LINK( this, SfxAcceleratorConfigPage, SelectHdl ));
m_pFunctionBox->SetSelectHdl( LINK( this, SfxAcceleratorConfigPage, SelectHdl ));
m_pKeyBox->SetSelectHdl ( LINK( this, SfxAcceleratorConfigPage, SelectHdl ));
m_pLoadButton->SetClickHdl ( LINK( this, SfxAcceleratorConfigPage, Load ));
m_pSaveButton->SetClickHdl ( LINK( this, SfxAcceleratorConfigPage, Save ));
m_pResetButton->SetClickHdl ( LINK( this, SfxAcceleratorConfigPage, Default ));
m_pOfficeButton->SetClickHdl( LINK( this, SfxAcceleratorConfigPage, RadioHdl ));
m_pModuleButton->SetClickHdl( LINK( this, SfxAcceleratorConfigPage, RadioHdl ));
m_pSearchEdit->SetUpdateDataHdl ( LINK( this, SfxAcceleratorConfigPage, SearchUpdateHdl ));
m_pSearchEdit->EnableUpdateData();
// initialize Entriesbox
m_pEntriesBox->SetStyle(m_pEntriesBox->GetStyle()|WB_HSCROLL|WB_CLIPCHILDREN);
m_pEntriesBox->SetSelectionMode(SelectionMode::Single);
m_pEntriesBox->SetTabs(SAL_N_ELEMENTS(AccCfgTabs), AccCfgTabs);
m_pEntriesBox->Resize(); // OS: Hack for right selection
m_pEntriesBox->SetSpaceBetweenEntries(0);
m_pEntriesBox->SetDragDropMode(DragDropMode::NONE);
m_xChangeButton->connect_clicked( LINK( this, SfxAcceleratorConfigPage, ChangeHdl ));
m_xRemoveButton->connect_clicked( LINK( this, SfxAcceleratorConfigPage, RemoveHdl ));
m_xEntriesBox->connect_changed ( LINK( this, SfxAcceleratorConfigPage, SelectHdl ));
m_xGroupLBox->connect_changed ( LINK( this, SfxAcceleratorConfigPage, SelectHdl ));
m_xFunctionBox->connect_changed( LINK( this, SfxAcceleratorConfigPage, SelectHdl ));
m_xKeyBox->connect_changed ( LINK( this, SfxAcceleratorConfigPage, SelectHdl ));
m_xLoadButton->connect_clicked ( LINK( this, SfxAcceleratorConfigPage, Load ));
m_xSaveButton->connect_clicked ( LINK( this, SfxAcceleratorConfigPage, Save ));
m_xResetButton->connect_clicked ( LINK( this, SfxAcceleratorConfigPage, Default ));
m_xOfficeButton->connect_clicked( LINK( this, SfxAcceleratorConfigPage, RadioHdl ));
m_xModuleButton->connect_clicked( LINK( this, SfxAcceleratorConfigPage, RadioHdl ));
m_xSearchEdit->connect_changed( LINK( this, SfxAcceleratorConfigPage, SearchUpdateHdl ));
// detect max keyname width
long nMaxWidth = 0;
int nMaxWidth = 0;
for (unsigned short i : KEYCODE_ARRAY)
{
long nTmp = GetTextWidth( vcl::KeyCode( i ).GetName() );
int nTmp = m_xEntriesBox->get_pixel_size(vcl::KeyCode(i).GetName()).Width();
if ( nTmp > nMaxWidth )
nMaxWidth = nTmp;
}
// recalc second tab
long nNewTab = PixelToLogic(Size(nMaxWidth, 0), MapMode(MapUnit::MapAppFont)).Width();
nNewTab = nNewTab + 5; // additional space
m_pEntriesBox->SetTab( 1, nNewTab );
auto nNewTab = nMaxWidth + 5; // additional space
// initialize Entriesbox
std::vector<int> aWidths;
aWidths.push_back(nNewTab);
m_xEntriesBox->set_column_fixed_widths(aWidths);
//Initialize search util
m_options.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
@@ -957,10 +910,18 @@ SfxAcceleratorConfigPage::SfxAcceleratorConfigPage( vcl::Window* pParent, const
m_options.searchFlag |= (util::SearchFlags::REG_NOT_BEGINOFLINE |
util::SearchFlags::REG_NOT_ENDOFLINE);
// initialize GroupBox
m_pGroupLBox->SetFunctionListBox(m_pFunctionBox);
m_xGroupLBox->SetFunctionListBox(m_xFunctionBox.get());
// initialize KeyBox
m_pKeyBox->SetStyle(m_pKeyBox->GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_SORT);
m_xKeyBox->make_sorted();
m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SfxAcceleratorConfigPage, ImplUpdateDataHdl));
m_aUpdateDataTimer.SetDebugName( "SfxAcceleratorConfigPage UpdateDataTimer" );
m_aUpdateDataTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
m_aFillGroupIdle.SetInvokeHandler(LINK(this, SfxAcceleratorConfigPage, TimeOut_Impl));
m_aFillGroupIdle.SetPriority(TaskPriority::HIGHEST);
m_aFillGroupIdle.SetDebugName("SfxAcceleratorConfigPage m_aFillGroupIdle");
}
SfxAcceleratorConfigPage::~SfxAcceleratorConfigPage()
@@ -970,40 +931,15 @@ SfxAcceleratorConfigPage::~SfxAcceleratorConfigPage()
void SfxAcceleratorConfigPage::dispose()
{
m_aFillGroupIdle.Stop();
// free memory - remove all dynamic user data
SvTreeListEntry* pEntry = m_pEntriesBox->First();
while (pEntry)
for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
{
TAccInfo* pUserData = static_cast<TAccInfo*>(pEntry->GetUserData());
TAccInfo* pUserData = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(i).toInt64());
delete pUserData;
pEntry = m_pEntriesBox->Next(pEntry);
}
pEntry = m_pKeyBox->First();
while (pEntry)
{
TAccInfo* pUserData = static_cast<TAccInfo*>(pEntry->GetUserData());
delete pUserData;
pEntry = m_pKeyBox->Next(pEntry);
}
m_pEntriesBox->Clear();
m_pKeyBox->Clear();
m_pFileDlg.reset();
m_pEntriesBox.clear();
m_pOfficeButton.clear();
m_pModuleButton.clear();
m_pChangeButton.clear();
m_pRemoveButton.clear();
m_pGroupLBox.clear();
m_pFunctionBox.clear();
m_pKeyBox.clear();
m_pSearchEdit.clear();
m_pLoadButton.clear();
m_pSaveButton.clear();
m_pResetButton.clear();
SfxTabPage::dispose();
}
@@ -1057,19 +993,6 @@ void SfxAcceleratorConfigPage::InitAccCfg()
}
}
/** Initialize text columns with own class to enable custom painting
This is needed as we have to paint disabled entries by ourself. No support for that in the
original SvTabListBox!
*/
void SfxAcceleratorConfigPage::CreateCustomItems(SvTreeListEntry* pEntry,
const OUString& sCol1 ,
const OUString& sCol2)
{
pEntry->ReplaceItem(std::make_unique<SfxAccCfgLBoxString_Impl>(sCol1), 1);
pEntry->ReplaceItem(std::make_unique<SfxAccCfgLBoxString_Impl>(sCol2), 2);
}
void SfxAcceleratorConfigPage::Init(const uno::Reference<ui::XAcceleratorConfiguration>& xAccMgr)
{
if (!xAccMgr.is())
@@ -1085,7 +1008,7 @@ void SfxAcceleratorConfigPage::Init(const uno::Reference<ui::XAcceleratorConfigu
xModel = xController->getModel();
m_aStylesInfo.init(m_sModuleLongName, xModel);
m_pGroupLBox->SetStylesInfo(&m_aStylesInfo);
m_xGroupLBox->SetStylesInfo(&m_aStylesInfo);
m_bStylesInfoInitialized = true;
}
@@ -1099,15 +1022,14 @@ void SfxAcceleratorConfigPage::Init(const uno::Reference<ui::XAcceleratorConfigu
if (sKey.isEmpty())
continue;
TAccInfo* pEntry = new TAccInfo(i1, 0/*nListPos*/, aKey);
SvTreeListEntry* pLBEntry = m_pEntriesBox->InsertEntryToColumn(sKey, nullptr, TREELIST_APPEND, 0xFFFF);
pLBEntry->SetUserData(pEntry);
m_xEntriesBox->append(OUString::number(reinterpret_cast<sal_Int64>(pEntry)), sKey);
m_xEntriesBox->set_text(m_xEntriesBox->n_children() - 1, OUString(), 1);
}
// Assign all commands to its shortcuts - reading the accelerator config.
uno::Sequence<awt::KeyEvent> lKeys = xAccMgr->getAllKeyEvents();
sal_Int32 c2 = lKeys.getLength();
sal_Int32 i2 = 0;
sal_uInt16 nCol = m_pEntriesBox->TabCount()-1;
for (i2=0; i2<c2; ++i2)
{
@@ -1120,14 +1042,12 @@ void SfxAcceleratorConfigPage::Init(const uno::Reference<ui::XAcceleratorConfigu
if (nPos == -1)
continue;
m_pEntriesBox->SetEntryText(sLabel, nPos, nCol);
m_xEntriesBox->set_text(nPos, sLabel, 1);
SvTreeListEntry* pLBEntry = m_pEntriesBox->GetEntry(nullptr, nPos);
TAccInfo* pEntry = static_cast<TAccInfo*>(pLBEntry->GetUserData());
TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(nPos).toInt64());
pEntry->m_bIsConfigurable = true;
pEntry->m_sCommand = sCommand;
CreateCustomItems(pLBEntry, SvTabListBox::GetEntryText(pLBEntry, 0), sLabel);
}
// Map the VCL hardcoded key codes and mark them as not changeable
@@ -1142,11 +1062,10 @@ void SfxAcceleratorConfigPage::Init(const uno::Reference<ui::XAcceleratorConfigu
continue;
// Hardcoded function mapped so no ID possible and mark entry as not changeable
SvTreeListEntry* pLBEntry = m_pEntriesBox->GetEntry(nullptr, nPos);
TAccInfo* pEntry = static_cast<TAccInfo*>(pLBEntry->GetUserData());
TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(nPos).toInt64());
pEntry->m_bIsConfigurable = false;
CreateCustomItems(pLBEntry, SvTabListBox::GetEntryText(pLBEntry, 0), OUString());
m_xEntriesBox->set_sensitive(nPos, false);
}
}
@@ -1158,10 +1077,9 @@ void SfxAcceleratorConfigPage::Apply(const uno::Reference<ui::XAcceleratorConfig
// Go through the list from the bottom to the top ...
// because logical accelerator must be preferred instead of
// physical ones!
SvTreeListEntry* pEntry = m_pEntriesBox->First();
while (pEntry)
for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
{
TAccInfo* pUserData = static_cast<TAccInfo*>(pEntry->GetUserData());
TAccInfo* pUserData = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(i).toInt64());
OUString sCommand;
awt::KeyEvent aAWTKey;
@@ -1178,214 +1096,218 @@ void SfxAcceleratorConfigPage::Apply(const uno::Reference<ui::XAcceleratorConfig
else
xAccMgr->removeKeyEvent(aAWTKey);
}
catch(const uno::RuntimeException&)
catch (const uno::RuntimeException&)
{
throw;
}
catch(const uno::Exception&)
catch (const uno::Exception&)
{
}
pEntry = m_pEntriesBox->Next(pEntry);
}
}
void SfxAcceleratorConfigPage::ResetConfig()
{
m_pEntriesBox->Clear();
m_xEntriesBox->clear();
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, SearchUpdateHdl, Edit&, void)
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, ImplUpdateDataHdl, Timer*, void)
{
m_pGroupLBox->GetSelectHdl().Call( m_pGroupLBox );
SelectHdl(m_xGroupLBox->get_widget());
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Load, Button*, void)
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, SearchUpdateHdl, weld::Entry&, void)
{
m_aUpdateDataTimer.Start();
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Load, weld::Button&, void)
{
// ask for filename, where we should load the new config data from
StartFileDialog( StartFileDialogType::Open, aLoadAccelConfigStr );
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Save, Button*, void)
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Save, weld::Button&, void)
{
StartFileDialog( StartFileDialogType::SaveAs, aSaveAccelConfigStr );
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Default, Button*, void)
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Default, weld::Button&, void)
{
uno::Reference<form::XReset> xReset(m_xAct, uno::UNO_QUERY);
if (xReset.is())
xReset->reset();
m_pEntriesBox->SetUpdateMode(false);
m_xEntriesBox->freeze();
ResetConfig();
Init(m_xAct);
m_pEntriesBox->SetUpdateMode(true);
m_pEntriesBox->Invalidate();
m_pEntriesBox->Select(m_pEntriesBox->GetEntry(nullptr, 0));
m_xEntriesBox->thaw();
m_xEntriesBox->select(0);
SelectHdl(*m_xEntriesBox);
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, ChangeHdl, Button*, void)
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, ChangeHdl, weld::Button&, void)
{
sal_uLong nPos = SvTreeList::GetRelPos( m_pEntriesBox->FirstSelected() );
TAccInfo* pEntry = static_cast<TAccInfo*>(m_pEntriesBox->GetEntry(nullptr, nPos)->GetUserData());
OUString sNewCommand = m_pFunctionBox->GetCurCommand();
OUString sLabel = m_pFunctionBox->GetCurLabel();
int nPos = m_xEntriesBox->get_selected_index();
if (nPos == -1)
return;
TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(nPos).toInt64());
OUString sNewCommand = m_xFunctionBox->GetCurCommand();
OUString sLabel = m_xFunctionBox->GetCurLabel();
if (sLabel.isEmpty())
sLabel = GetLabel4Command(sNewCommand);
pEntry->m_sCommand = sNewCommand;
sal_uInt16 nCol = m_pEntriesBox->TabCount() - 1;
m_pEntriesBox->SetEntryText(sLabel, nPos, nCol);
m_xEntriesBox->set_text(nPos, sLabel, 1);
m_pFunctionBox->GetSelectHdl().Call( m_pFunctionBox );
SelectHdl(m_xFunctionBox->get_widget());
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, RemoveHdl, Button*, void)
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, RemoveHdl, weld::Button&, void)
{
// get selected entry
sal_uLong nPos = SvTreeList::GetRelPos( m_pEntriesBox->FirstSelected() );
TAccInfo* pEntry = static_cast<TAccInfo*>(m_pEntriesBox->GetEntry(nullptr, nPos)->GetUserData());
int nPos = m_xEntriesBox->get_selected_index();
if (nPos == -1)
return;
TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(nPos).toInt64());
// remove function name from selected entry
sal_uInt16 nCol = m_pEntriesBox->TabCount() - 1;
m_pEntriesBox->SetEntryText( OUString(), nPos, nCol );
m_xEntriesBox->set_text(nPos, OUString(), 1);
pEntry->m_sCommand.clear();
m_pFunctionBox->GetSelectHdl().Call( m_pFunctionBox );
SelectHdl(m_xFunctionBox->get_widget());
}
IMPL_LINK( SfxAcceleratorConfigPage, SelectHdl, SvTreeListBox*, pListBox, void )
IMPL_LINK(SfxAcceleratorConfigPage, SelectHdl, weld::TreeView&, rListBox, void)
{
// disable help
Help::ShowBalloon( this, Point(), ::tools::Rectangle(), OUString() );
if (pListBox == m_pEntriesBox)
if (&rListBox == m_xEntriesBox.get())
{
sal_uLong nPos = SvTreeList::GetRelPos( m_pEntriesBox->FirstSelected() );
TAccInfo* pEntry = static_cast<TAccInfo*>(m_pEntriesBox->GetEntry(nullptr, nPos)->GetUserData());
OUString sPossibleNewCommand = m_pFunctionBox->GetCurCommand();
TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_selected_id().toInt64());
m_pRemoveButton->Enable( false );
m_pChangeButton->Enable( false );
OUString sPossibleNewCommand = m_xFunctionBox->GetCurCommand();
m_xRemoveButton->set_sensitive( false );
m_xChangeButton->set_sensitive( false );
if (pEntry->m_bIsConfigurable)
{
if (pEntry->isConfigured())
m_pRemoveButton->Enable();
m_pChangeButton->Enable( pEntry->m_sCommand != sPossibleNewCommand );
m_xRemoveButton->set_sensitive(true);
m_xChangeButton->set_sensitive( pEntry->m_sCommand != sPossibleNewCommand );
}
}
else if ( pListBox == m_pGroupLBox )
else if (&rListBox == &m_xGroupLBox->get_widget())
{
m_pGroupLBox->GroupSelected();
m_xGroupLBox->GroupSelected();
// Pause redraw (Do not redraw at each removal)
m_pFunctionBox->SetUpdateMode(false);
m_xFunctionBox->freeze();
// Apply the search filter to the functions list
OUString aSearchTerm( m_pSearchEdit->GetText() );
SvTreeListEntry* aMatchFound = applySearchFilter(aSearchTerm, m_pFunctionBox);
OUString aSearchTerm(m_xSearchEdit->get_text());
int nMatchFound = applySearchFilter(aSearchTerm);
// Resume redraw
m_pFunctionBox->SetUpdateMode(true);
if (aMatchFound)
m_pFunctionBox->Select(aMatchFound);
m_xFunctionBox->thaw();
if (nMatchFound != -1)
{
m_xFunctionBox->select(nMatchFound);
SelectHdl(m_xFunctionBox->get_widget());
}
else
m_pKeyBox->Clear();
if ( !m_pFunctionBox->FirstSelected() )
m_pChangeButton->Enable( false );
{
m_xKeyBox->clear();
m_xChangeButton->set_sensitive(false);
}
}
else if ( pListBox == m_pFunctionBox )
else if (&rListBox == &m_xFunctionBox->get_widget())
{
m_pRemoveButton->Enable( false );
m_pChangeButton->Enable( false );
m_xRemoveButton->set_sensitive( false );
m_xChangeButton->set_sensitive( false );
// #i36994 First selected can return zero!
SvTreeListEntry* pLBEntry = m_pEntriesBox->FirstSelected();
if ( pLBEntry != nullptr )
TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_selected_id().toInt64());
if (pEntry)
{
sal_uLong nPos = SvTreeList::GetRelPos( pLBEntry );
TAccInfo* pEntry = static_cast<TAccInfo*>(m_pEntriesBox->GetEntry(nullptr, nPos)->GetUserData());
OUString sPossibleNewCommand = m_pFunctionBox->GetCurCommand();
OUString sPossibleNewCommand = m_xFunctionBox->GetCurCommand();
if (pEntry->m_bIsConfigurable)
{
if (pEntry->isConfigured())
m_pRemoveButton->Enable();
m_pChangeButton->Enable( pEntry->m_sCommand != sPossibleNewCommand );
m_xRemoveButton->set_sensitive(true);
m_xChangeButton->set_sensitive( pEntry->m_sCommand != sPossibleNewCommand );
}
// update key box
m_pKeyBox->Clear();
SvTreeListEntry* pIt = m_pEntriesBox->First();
while ( pIt )
m_xKeyBox->clear();
for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
{
TAccInfo* pUserData = static_cast<TAccInfo*>(pIt->GetUserData());
if ( pUserData && pUserData->m_sCommand == sPossibleNewCommand )
TAccInfo* pUserData = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(i).toInt64());
if (pUserData && pUserData->m_sCommand == sPossibleNewCommand)
{
TAccInfo* pU1 = new TAccInfo(-1, -1, pUserData->m_aKey);
SvTreeListEntry* pE1 = m_pKeyBox->InsertEntry( pUserData->m_aKey.GetName(), nullptr, true );
pE1->SetUserData(pU1);
pE1->EnableChildrenOnDemand( false );
m_xKeyBox->append(OUString::number(reinterpret_cast<sal_Int64>(pUserData)), pUserData->m_aKey.GetName());
}
pIt = m_pEntriesBox->Next(pIt);
}
}
}
else
{
// goto selected "key" entry of the key box
SvTreeListEntry* pE2 = nullptr;
TAccInfo* pU2 = nullptr;
sal_Int32 nP2 = -1;
SvTreeListEntry* pE3 = nullptr;
pE2 = m_pKeyBox->FirstSelected();
if (pE2)
pU2 = static_cast<TAccInfo*>(pE2->GetUserData());
int nP2 = -1;
TAccInfo* pU2 = reinterpret_cast<TAccInfo*>(m_xKeyBox->get_selected_id().toInt64());
if (pU2)
nP2 = MapKeyCodeToPos(pU2->m_aKey);
if (nP2 != -1)
pE3 = m_pEntriesBox->GetEntry( nullptr, nP2 );
if (pE3)
{
m_pEntriesBox->Select( pE3 );
m_pEntriesBox->MakeVisible( pE3 );
m_xEntriesBox->select(nP2);
m_xEntriesBox->scroll_to_row(nP2);
SelectHdl(*m_xEntriesBox);
}
}
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, RadioHdl, Button*, void)
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, RadioHdl, weld::Button&, void)
{
uno::Reference<ui::XAcceleratorConfiguration> xOld = m_xAct;
if (m_pOfficeButton->IsChecked())
if (m_xOfficeButton->get_active())
m_xAct = m_xGlobal;
else if (m_pModuleButton->IsChecked())
else if (m_xModuleButton->get_active())
m_xAct = m_xModule;
// nothing changed? => do nothing!
if ( m_xAct.is() && ( xOld == m_xAct ) )
return;
m_pEntriesBox->SetUpdateMode( false );
m_xEntriesBox->freeze();
ResetConfig();
Init(m_xAct);
m_pEntriesBox->SetUpdateMode( true );
m_pEntriesBox->Invalidate();
m_xEntriesBox->thaw();
m_pGroupLBox->Init(m_xContext, m_xFrame, m_sModuleLongName, true);
m_xGroupLBox->Init(m_xContext, m_xFrame, m_sModuleLongName, true);
// pb: #133213# do not select NULL entries
SvTreeListEntry* pEntry = m_pEntriesBox->GetEntry( nullptr, 0 );
if ( pEntry )
m_pEntriesBox->Select( pEntry );
pEntry = m_pGroupLBox->GetEntry( nullptr, 0 );
if ( pEntry )
m_pGroupLBox->Select( pEntry );
if (m_xEntriesBox->n_children())
m_xEntriesBox->select(0);
m_pFunctionBox->GetSelectHdl().Call( m_pFunctionBox );
m_aFillGroupIdle.Start();
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, TimeOut_Impl, Timer*, void)
{
// activating the selection, typically "all commands", can take a long time
// -> show wait cursor and disable input
weld::Window* pDialog = GetDialogFrameWeld();
// perhaps the tabpage is part of a SingleTabDialog then pDialog == nullptr
std::unique_ptr<weld::WaitObject> xWait(pDialog ? new weld::WaitObject(pDialog) : nullptr);
weld::TreeView& rTreeView = m_xGroupLBox->get_widget();
SelectHdl(rTreeView);
SelectHdl(m_xFunctionBox->get_widget());
}
IMPL_LINK_NOARG(SfxAcceleratorConfigPage, LoadHdl, sfx2::FileDialogHelper*, void)
{
@@ -1425,13 +1347,15 @@ IMPL_LINK_NOARG(SfxAcceleratorConfigPage, LoadHdl, sfx2::FileDialogHelper*, void
// open the configuration and update our UI
uno::Reference<ui::XAcceleratorConfiguration> xTempAccMgr(xCfgMgr->getShortCutManager(), uno::UNO_QUERY_THROW);
m_pEntriesBox->SetUpdateMode(false);
m_xEntriesBox->freeze();
ResetConfig();
Init(xTempAccMgr);
m_pEntriesBox->SetUpdateMode(true);
m_pEntriesBox->Invalidate();
m_pEntriesBox->Select(m_pEntriesBox->GetEntry(nullptr, 0));
m_xEntriesBox->thaw();
if (m_xEntriesBox->n_children())
{
m_xEntriesBox->select(0);
SelectHdl(m_xFunctionBox->get_widget());
}
}
// don't forget to close the new opened storage!
@@ -1587,45 +1511,40 @@ void SfxAcceleratorConfigPage::Reset( const SfxItemSet* rSet )
// change the description of the radio button, which switch to the module
// dependent accelerator configuration
OUString sButtonText = m_pModuleButton->GetText();
OUString sButtonText = m_xModuleButton->get_label();
sButtonText = sButtonText.replaceFirst("$(MODULE)", m_sModuleUIName);
m_pModuleButton->SetText(sButtonText);
m_xModuleButton->set_label(sButtonText);
if (m_xModule.is())
m_pModuleButton->Check();
m_xModuleButton->set_active(true);
else
{
m_pModuleButton->Hide();
m_pOfficeButton->Check();
m_xModuleButton->hide();
m_xOfficeButton->set_active(true);
}
RadioHdl(nullptr);
RadioHdl(*m_xOfficeButton);
const SfxPoolItem* pMacroItem=nullptr;
if( SfxItemState::SET == rSet->GetItemState( SID_MACROINFO, true, &pMacroItem ) )
{
m_pMacroInfoItem = &dynamic_cast<const SfxMacroInfoItem&>(*pMacroItem);
m_pGroupLBox->SelectMacro( m_pMacroInfoItem );
m_xGroupLBox->SelectMacro( m_pMacroInfoItem );
}
}
sal_Int32 SfxAcceleratorConfigPage::MapKeyCodeToPos(const vcl::KeyCode& aKey) const
{
sal_uInt16 nCode1 = aKey.GetCode() + aKey.GetModifier();
SvTreeListEntry* pEntry = m_pEntriesBox->First();
sal_Int32 i = 0;
while (pEntry)
for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
{
TAccInfo* pUserData = static_cast<TAccInfo*>(pEntry->GetUserData());
TAccInfo* pUserData = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(i).toInt64());
if (pUserData)
{
sal_uInt16 nCode2 = pUserData->m_aKey.GetCode()+pUserData->m_aKey.GetModifier();
if (nCode1 == nCode2)
return i;
}
pEntry = m_pEntriesBox->Next(pEntry);
++i;
}
return -1;
@@ -1669,39 +1588,26 @@ OUString SfxAcceleratorConfigPage::GetLabel4Command(const OUString& sCommand)
/*
* Remove entries which doesn't contain the search term
*/
SvTreeListEntry* SfxAcceleratorConfigPage::applySearchFilter(OUString const & rSearchTerm, SvTreeListBox* rListBox)
int SfxAcceleratorConfigPage::applySearchFilter(OUString const & rSearchTerm)
{
if ( rSearchTerm.isEmpty() || !rListBox )
{
return nullptr;
}
SvTreeListEntry* pFirstMatch = nullptr;
SvTreeListEntry* pEntry = rListBox->First();
if (rSearchTerm.isEmpty())
return -1;
m_options.searchString = rSearchTerm;
utl::TextSearch textSearch( m_options );
while(pEntry)
for (int i = m_xFunctionBox->n_children(); i > 0; --i)
{
OUString aStr = rListBox->GetEntryText(pEntry);
SvTreeListEntry* pNextEntry = rListBox->Next(pEntry);
int nEntry = i - 1;
OUString aStr = m_xFunctionBox->get_text(nEntry);
sal_Int32 aStartPos = 0;
sal_Int32 aEndPos = aStr.getLength();
if (!textSearch.SearchForward( aStr, &aStartPos, &aEndPos ))
{
rListBox->RemoveEntry(pEntry);
}
else if (!pFirstMatch)
{
pFirstMatch = pEntry;
}
pEntry = pNextEntry;
m_xFunctionBox->remove(nEntry);
}
return pFirstMatch;
return m_xFunctionBox->n_children() ? 0 : -1;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/cfg.cxx b/cui/source/customize/cfg.cxx
index 63db3c5..0fd8d4a 100644
--- a/cui/source/customize/cfg.cxx
+++ b/cui/source/customize/cfg.cxx
@@ -188,7 +188,7 @@ static VclPtr<SfxTabPage> CreateSvxContextMenuConfigPage( TabPageParent pParent,
static VclPtr<SfxTabPage> CreateKeyboardConfigPage( TabPageParent pParent, const SfxItemSet* rSet )
{
return VclPtr<SfxAcceleratorConfigPage>::Create( pParent.pParent, *rSet );
return VclPtr<SfxAcceleratorConfigPage>::Create(pParent, *rSet);
}
static VclPtr<SfxTabPage> CreateSvxToolbarConfigPage( TabPageParent pParent, const SfxItemSet* rSet )
diff --git a/cui/source/customize/cfgutil.cxx b/cui/source/customize/cfgutil.cxx
index c00d17e..2510066 100644
--- a/cui/source/customize/cfgutil.cxx
+++ b/cui/source/customize/cfgutil.cxx
@@ -351,24 +351,23 @@ OUString CuiConfigFunctionListBox::GetHelpText( bool bConsiderParent )
return OUString();
}
OUString SfxConfigFunctionListBox::GetCurCommand()
OUString CuiConfigFunctionListBox::GetCurCommand()
{
SvTreeListEntry *pEntry = FirstSelected();
if (!pEntry)
int nSelected = m_xTreeView->get_selected_index();
if (nSelected == -1)
return OUString();
SfxGroupInfo_Impl *pData = static_cast<SfxGroupInfo_Impl*>(pEntry->GetUserData());
SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(m_xTreeView->get_id(nSelected).toInt64());
if (!pData)
return OUString();
return pData->sCommand;
}
OUString SfxConfigFunctionListBox::GetCurLabel()
OUString CuiConfigFunctionListBox::GetCurLabel()
{
SvTreeListEntry *pEntry = FirstSelected();
if (!pEntry)
int nSelected = m_xTreeView->get_selected_index();
if (nSelected == -1)
return OUString();
SfxGroupInfo_Impl *pData = static_cast<SfxGroupInfo_Impl*>(pEntry->GetUserData());
SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(m_xTreeView->get_id(nSelected).toInt64());
if (!pData)
return OUString();
if (!pData->sLabel.isEmpty())
@@ -431,42 +430,11 @@ OUString CuiConfigFunctionListBox::GetSelectedScriptURI()
return OUString();
}
struct SvxConfigGroupBoxResource_Impl
{
Image m_hdImage;
Image m_libImage;
Image m_macImage;
Image m_docImage;
OUString m_sMyMacros;
OUString m_sProdMacros;
OUString m_sMacros;
OUString m_sDlgMacros;
OUString m_aStrGroupStyles;
Image m_collapsedImage;
Image m_expandedImage;
SvxConfigGroupBoxResource_Impl();
};
SvxConfigGroupBoxResource_Impl::SvxConfigGroupBoxResource_Impl() :
m_hdImage(StockImage::Yes, RID_CUIBMP_HARDDISK),
m_libImage(StockImage::Yes, RID_CUIBMP_LIB),
m_macImage(StockImage::Yes, RID_CUIBMP_MACRO),
m_docImage(StockImage::Yes, RID_CUIBMP_DOC),
m_sMyMacros(CuiResId(RID_SVXSTR_MYMACROS)),
m_sProdMacros(CuiResId(RID_SVXSTR_PRODMACROS)),
m_sMacros(CuiResId(RID_SVXSTR_BASICMACROS)),
m_sDlgMacros(CuiResId(RID_SVXSTR_PRODMACROS)),
m_aStrGroupStyles(CuiResId(RID_SVXSTR_GROUP_STYLES)),
m_collapsedImage(StockImage::Yes, RID_CUIBMP_COLLAPSED),
m_expandedImage(StockImage::Yes, RID_CUIBMP_EXPANDED)
{
}
struct CuiConfigGroupBoxResource_Impl
{
OUString m_sMyMacros;
OUString m_sProdMacros;
OUString m_sMacros;
OUString m_sDlgMacros;
OUString m_aStrGroupStyles;
@@ -476,109 +444,17 @@ struct CuiConfigGroupBoxResource_Impl
CuiConfigGroupBoxResource_Impl::CuiConfigGroupBoxResource_Impl() :
m_sMyMacros(CuiResId(RID_SVXSTR_MYMACROS)),
m_sProdMacros(CuiResId(RID_SVXSTR_PRODMACROS)),
m_sMacros(CuiResId(RID_SVXSTR_BASICMACROS)),
m_sDlgMacros(CuiResId(RID_SVXSTR_PRODMACROS)),
m_aStrGroupStyles(CuiResId(RID_SVXSTR_GROUP_STYLES))
{
}
SfxConfigGroupListBox::SfxConfigGroupListBox(vcl::Window* pParent, WinBits nStyle)
: SvTreeListBox(pParent, nStyle)
, xImp(new SvxConfigGroupBoxResource_Impl())
, pFunctionListBox(nullptr)
, pStylesInfo(nullptr)
{
SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT );
SetNodeBitmaps(xImp->m_collapsedImage, xImp->m_expandedImage);
}
VCL_BUILDER_FACTORY_CONSTRUCTOR(SfxConfigGroupListBox, WB_TABSTOP)
SfxConfigGroupListBox::~SfxConfigGroupListBox()
{
disposeOnce();
}
void SfxConfigGroupListBox::dispose()
{
ClearAll();
pFunctionListBox.clear();
SvTreeListBox::dispose();
}
void SfxConfigGroupListBox::ClearAll()
{
sal_uInt16 nCount = aArr.size();
for ( sal_uInt16 i=0; i<nCount; ++i )
{
SfxGroupInfo_Impl *pData = aArr[i].get();
if (pData->nKind == SfxCfgKind::GROUP_SCRIPTCONTAINER)
{
XInterface* xi = static_cast<XInterface *>(pData->pObject);
if (xi != nullptr)
{
xi->release();
}
}
}
aArr.clear();
Clear();
}
void SfxConfigGroupListBox::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
{
pStylesInfo = pStyles;
}
void CuiConfigGroupListBox::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
{
m_pStylesInfo = pStyles;
}
void SfxConfigGroupListBox::InitModule()
{
try
{
css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider(m_xFrame, css::uno::UNO_QUERY_THROW);
css::uno::Sequence< sal_Int16 > lGroups = xProvider->getSupportedCommandGroups();
sal_Int32 c1 = lGroups.getLength();
sal_Int32 i1 = 0;
if ( c1 )
{
// Add All Commands category
SvTreeListEntry* pEntry = InsertEntry( CuiResId(RID_SVXSTR_ALLFUNCTIONS) );
aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_ALLFUNCTIONS, 0 ) );
pEntry->SetUserData(aArr.back().get());
}
for (i1=0; i1<c1; ++i1)
{
sal_Int16& rGroupID = lGroups[i1];
OUString sGroupID = OUString::number(rGroupID);
OUString sGroupName ;
try
{
m_xModuleCategoryInfo->getByName(sGroupID) >>= sGroupName;
if (sGroupName.isEmpty())
continue;
}
catch(const css::container::NoSuchElementException&)
{ continue; }
SvTreeListEntry* pEntry = InsertEntry(sGroupName);
aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_FUNCTION, rGroupID ) );
pEntry->SetUserData(aArr.back().get());
}
}
catch(const css::uno::RuntimeException&)
{ throw; }
catch(const css::uno::Exception&)
{}
}
namespace
{
@@ -631,602 +507,6 @@ namespace
}
}
void SfxConfigGroupListBox::FillScriptList(const css::uno::Reference< css::script::browse::XBrowseNode >& xRootNode,
SvTreeListEntry* pParentEntry, bool bCheapChildrenOnDemand)
{
try {
if ( xRootNode->hasChildNodes() )
{
// tdf#120362: Don't ask to enable disabled Java when filling script list
css::uno::ContextLayer layer(
new comphelper::NoEnableJavaInteractionContext(css::uno::getCurrentContext()));
Sequence< Reference< browse::XBrowseNode > > children =
xRootNode->getChildNodes();
bool bIsRootNode = false;
OUString user("user");
OUString share("share");
if ( xRootNode->getName() == "Root" )
{
bIsRootNode = true;
}
//To mimic current starbasic behaviour we
//need to make sure that only the current document
//is displayed in the config tree. Tests below
//set the bDisplay flag to FALSE if the current
//node is a first level child of the Root and is NOT
//either the current document, user or share
OUString currentDocTitle;
Reference< XModel > xDocument( lcl_getScriptableDocument_nothrow( m_xFrame ) );
if ( xDocument.is() )
{
currentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xDocument );
}
for ( sal_Int32 n = 0; n < children.getLength(); ++n )
{
Reference< browse::XBrowseNode >& theChild = children[n];
bool bDisplay = true;
OUString uiName = theChild->getName();
if ( bIsRootNode )
{
if ( ! (theChild->getName() == user || theChild->getName() == share ||
theChild->getName() == currentDocTitle ) )
{
bDisplay=false;
}
else
{
if ( uiName == user )
{
uiName = xImp->m_sMyMacros;
}
else if ( uiName == share )
{
uiName = xImp->m_sProdMacros;
}
}
}
if (children[n]->getType() != browse::BrowseNodeTypes::SCRIPT && bDisplay )
{
// We call acquire on the XBrowseNode so that it does not
// get autodestructed and become invalid when accessed later.
theChild->acquire();
Image aImage = GetImage( theChild, m_xContext, bIsRootNode );
SvTreeListEntry* pNewEntry =
InsertEntry( uiName, pParentEntry );
SetExpandedEntryBmp( pNewEntry, aImage );
SetCollapsedEntryBmp( pNewEntry, aImage );
aArr.push_back( std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SCRIPTCONTAINER,
0, static_cast<void *>( theChild.get())));
pNewEntry->SetUserData( aArr.back().get() );
if ( !bCheapChildrenOnDemand && children[n]->hasChildNodes() )
{
Sequence< Reference< browse::XBrowseNode > > grandchildren =
children[n]->getChildNodes();
for ( sal_Int32 m = 0; m < grandchildren.getLength(); ++m )
{
if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER )
{
pNewEntry->EnableChildrenOnDemand();
m = grandchildren.getLength();
}
}
}
else
{
/* i30923 - Would be nice if there was a better
* way to determine if a basic lib had children
* without having to ask for them (which forces
* the library to be loaded */
pNewEntry->EnableChildrenOnDemand();
}
}
}
}
}
catch (RuntimeException&) {
// do nothing, the entry will not be displayed in the UI
}
}
void SfxConfigGroupListBox::FillFunctionsList(const css::uno::Sequence<DispatchInformation>& xCommands)
{
for (const auto & rInfo : xCommands)
{
OUString sUIName = MapCommand2UIName(rInfo.Command);
SvTreeListEntry* pFuncEntry = pFunctionListBox->InsertEntry(sUIName );
aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SLOT, 0 ) );
SfxGroupInfo_Impl* pGrpInfo = aArr.back().get();
pGrpInfo->sCommand = rInfo.Command;
pGrpInfo->sLabel = sUIName;
pFuncEntry->SetUserData(pGrpInfo);
}
}
void SfxConfigGroupListBox::Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
const css::uno::Reference< css::frame::XFrame >& xFrame,
const OUString& sModuleLongName,
bool bEventMode)
{
SetUpdateMode(false);
ClearAll(); // Remove all old entries from treelist box
m_xContext = xContext;
m_xFrame = xFrame;
if( bEventMode )
{
m_sModuleLongName = sModuleLongName;
m_xGlobalCategoryInfo = css::ui::theUICategoryDescription::get( m_xContext );
m_xModuleCategoryInfo.set(m_xGlobalCategoryInfo->getByName(m_sModuleLongName), css::uno::UNO_QUERY_THROW);
m_xUICmdDescription = css::frame::theUICommandDescription::get( m_xContext );
InitModule();
}
SAL_INFO("cui.customize", "** ** About to initialise SF Scripts");
// Add Scripting Framework entries
Reference< browse::XBrowseNode > rootNode;
try
{
Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get( m_xContext );
rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
}
catch( Exception& e )
{
SAL_INFO("cui.customize", "Caught some exception whilst retrieving browse nodes from factory... Exception: " << e);
// TODO exception handling
}
if ( rootNode.is() )
{
if ( bEventMode )
{
//We call acquire on the XBrowseNode so that it does not
//get autodestructed and become invalid when accessed later.
rootNode->acquire();
aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_SCRIPTCONTAINER, 0,
static_cast<void *>(rootNode.get())));
OUString aTitle(xImp->m_sDlgMacros);
SvTreeListEntry *pNewEntry = InsertEntry( aTitle );
pNewEntry->SetUserData( aArr.back().get() );
pNewEntry->EnableChildrenOnDemand();
}
else
{
//We are only showing scripts not slot APIs so skip
//Root node and show location nodes
FillScriptList(rootNode, nullptr, false);
}
}
// add styles
if ( bEventMode )
{
OUString sStyle(xImp->m_aStrGroupStyles);
SvTreeListEntry *pEntry = InsertEntry( sStyle );
aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, nullptr ) ); // TODO last parameter should contain user data
pEntry->SetUserData( aArr.back().get() );
pEntry->EnableChildrenOnDemand();
}
MakeVisible( GetEntry( nullptr,0 ) );
SetUpdateMode( true );
}
Image SfxConfigGroupListBox::GetImage(
const Reference< browse::XBrowseNode >& node,
Reference< XComponentContext > const & xCtx,
bool bIsRootNode
)
{
Image aImage;
if ( bIsRootNode )
{
if (node->getName() == "user" || node->getName() == "share" )
{
aImage = xImp->m_hdImage;
}
else
{
OUString factoryURL;
OUString nodeName = node->getName();
Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
if ( xDocumentModel.is() )
{
Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
// get the long name of the document:
OUString appModule( xModuleManager->identify(
xDocumentModel ) );
Sequence<beans::PropertyValue> moduleDescr;
Any aAny = xModuleManager->getByName(appModule);
if( !( aAny >>= moduleDescr ) )
{
throw RuntimeException("SFTreeListBox::Init: failed to get PropertyValue");
}
beans::PropertyValue const * pmoduleDescr =
moduleDescr.getConstArray();
for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
{
if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
{
pmoduleDescr[ pos ].Value >>= factoryURL;
SAL_INFO("cui.customize", "factory url for doc images is " << factoryURL);
break;
}
}
}
if( !factoryURL.isEmpty() )
{
aImage = SvFileInformationManager::GetFileImage( INetURLObject(factoryURL) );
}
else
{
aImage = xImp->m_docImage;
}
}
}
else
{
if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
aImage = xImp->m_macImage;
else
aImage = xImp->m_libImage;
}
return aImage;
}
Reference< XInterface >
SfxConfigGroupListBox::getDocumentModel( Reference< XComponentContext > const & xCtx, OUString const & docName )
{
Reference< XInterface > xModel;
Reference< frame::XDesktop2 > desktop = frame::Desktop::create( xCtx );
Reference< container::XEnumerationAccess > componentsAccess =
desktop->getComponents();
Reference< container::XEnumeration > components =
componentsAccess->createEnumeration();
while (components->hasMoreElements())
{
Reference< frame::XModel > model(
components->nextElement(), UNO_QUERY );
if ( model.is() )
{
OUString sTdocUrl =
::comphelper::DocumentInfo::getDocumentTitle( model );
if( sTdocUrl == docName )
{
xModel = model;
break;
}
}
}
return xModel;
}
OUString SfxConfigGroupListBox::MapCommand2UIName(const OUString& sCommand)
{
OUString sUIName;
try
{
css::uno::Reference< css::container::XNameAccess > xModuleConf;
m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
if (xModuleConf.is())
{
::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
sUIName = lProps.getUnpackedValueOrDefault("Name", OUString());
}
}
catch(const css::uno::RuntimeException&)
{ throw; }
catch(css::uno::Exception&)
{ sUIName.clear(); }
// fallback for missing UINames !?
if (sUIName.isEmpty())
{
sUIName = sCommand;
}
return sUIName;
}
void SfxConfigGroupListBox::GroupSelected()
/* Description
A function group or a basic module has been selected.
All functions/macros are displayed in the functionlistbox.
*/
{
SvTreeListEntry *pEntry = FirstSelected();
SfxGroupInfo_Impl *pInfo = static_cast<SfxGroupInfo_Impl*>(pEntry->GetUserData());
pFunctionListBox->SetUpdateMode(false);
pFunctionListBox->ClearAll();
switch ( pInfo->nKind )
{
case SfxCfgKind::GROUP_ALLFUNCTIONS:
{
css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider( m_xFrame, UNO_QUERY );
SvTreeListEntry *pCurrEntry = First();
while( pCurrEntry )
{
SfxGroupInfo_Impl *pCurrentInfo = static_cast<SfxGroupInfo_Impl*>(pCurrEntry->GetUserData());
if (pCurrentInfo->nKind == SfxCfgKind::GROUP_FUNCTION)
{
css::uno::Sequence< css::frame::DispatchInformation > lCommands;
try
{
lCommands = xProvider->getConfigurableDispatchInformation( pCurrentInfo->nUniqueID );
FillFunctionsList( lCommands );
}
catch ( container::NoSuchElementException& )
{
}
}
pCurrEntry = Next( pCurrEntry );
}
break;
}
case SfxCfgKind::GROUP_FUNCTION :
{
sal_uInt16 nGroup = pInfo->nUniqueID;
css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider (m_xFrame, css::uno::UNO_QUERY_THROW);
css::uno::Sequence< css::frame::DispatchInformation > lCommands = xProvider->getConfigurableDispatchInformation(nGroup);
FillFunctionsList( lCommands );
break;
}
case SfxCfgKind::GROUP_SCRIPTCONTAINER:
{
if ( !GetChildCount( pEntry ) )
{
Reference< browse::XBrowseNode > rootNode(
static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
try {
if ( rootNode->hasChildNodes() )
{
Sequence< Reference< browse::XBrowseNode > > children =
rootNode->getChildNodes();
for ( sal_Int32 n = 0; n < children.getLength(); ++n )
{
if (children[n]->getType() == browse::BrowseNodeTypes::SCRIPT)
{
OUString uri, description;
Reference < beans::XPropertySet >xPropSet( children[n], UNO_QUERY );
if (!xPropSet.is())
{
continue;
}
Any value =
xPropSet->getPropertyValue("URI");
value >>= uri;
try
{
value = xPropSet->getPropertyValue("Description");
value >>= description;
}
catch (Exception &) {
// do nothing, the description will be empty
}
OUString* pScriptURI = new OUString( uri );
Image aImage = GetImage( children[n], Reference< XComponentContext >(), false );
SvTreeListEntry* pNewEntry =
pFunctionListBox->InsertEntry( children[n]->getName() );
pFunctionListBox->SetExpandedEntryBmp( pNewEntry, aImage );
pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage );
pFunctionListBox->aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SCRIPT, 0, pScriptURI ));
pFunctionListBox->aArr.back()->sCommand = uri;
pFunctionListBox->aArr.back()->sLabel = children[n]->getName();
pFunctionListBox->aArr.back()->sHelpText = description;
pNewEntry->SetUserData( pFunctionListBox->aArr.back().get() );
}
}
}
}
catch (RuntimeException&) {
// do nothing, the entry will not be displayed in the UI
}
}
break;
}
case SfxCfgKind::GROUP_STYLES :
{
SfxStyleInfo_Impl* pFamily = static_cast<SfxStyleInfo_Impl*>(pInfo->pObject);
if (pFamily)
{
const std::vector< SfxStyleInfo_Impl > lStyles = pStylesInfo->getStyles(pFamily->sFamily);
for (auto const& lStyle : lStyles)
{
SfxStyleInfo_Impl* pStyle = new SfxStyleInfo_Impl(lStyle);
SvTreeListEntry* pFuncEntry = pFunctionListBox->InsertEntry( pStyle->sLabel );
pFunctionListBox->aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, pStyle ) );
pFunctionListBox->aArr.back()->sCommand = pStyle->sCommand;
pFunctionListBox->aArr.back()->sLabel = pStyle->sLabel;
pFuncEntry->SetUserData( pFunctionListBox->aArr.back().get() );
}
}
break;
}
default:
// Do nothing, the list box will stay empty
SAL_INFO( "cui.customize", "Ignoring unexpected SfxCfgKind: " << static_cast<int>(pInfo->nKind) );
break;
}
if ( pFunctionListBox->GetEntryCount() )
pFunctionListBox->Select( pFunctionListBox->GetEntry( nullptr, 0 ) );
pFunctionListBox->SetUpdateMode(true);
}
bool SfxConfigGroupListBox::Expand( SvTreeListEntry* pParent )
{
bool bRet = SvTreeListBox::Expand( pParent );
if ( bRet )
{
sal_uLong nEntries = GetOutputSizePixel().Height() / GetEntryHeight();
sal_uLong nChildCount = GetVisibleChildCount( pParent );
if ( nChildCount+1 > nEntries )
{
MakeVisible( pParent, true );
}
else
{
SvTreeListEntry *pEntry = GetFirstEntryInView();
sal_uLong nParentPos = 0;
while ( pEntry && pEntry != pParent )
{
++nParentPos;
pEntry = GetNextEntryInView( pEntry );
}
if ( nParentPos + nChildCount + 1 > nEntries )
ScrollOutputArea( static_cast<short>( nEntries - ( nParentPos + nChildCount + 1 ) ) );
}
}
return bRet;
}
void SfxConfigGroupListBox::RequestingChildren( SvTreeListEntry *pEntry )
/* Description
A basic or a library is opened.
*/
{
SfxGroupInfo_Impl *pInfo = static_cast<SfxGroupInfo_Impl*>(pEntry->GetUserData());
switch ( pInfo->nKind )
{
case SfxCfgKind::GROUP_SCRIPTCONTAINER:
{
if ( !GetChildCount( pEntry ) )
{
Reference< browse::XBrowseNode > rootNode(
static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
FillScriptList(rootNode, pEntry, true /* i30923 */ );
}
break;
}
case SfxCfgKind::GROUP_STYLES:
{
if ( !GetChildCount( pEntry ) )
{
const std::vector< SfxStyleInfo_Impl > lStyleFamilies = pStylesInfo->getStyleFamilies();
for (auto const& lStyleFamily : lStyleFamilies)
{
SfxStyleInfo_Impl* pFamily = new SfxStyleInfo_Impl(lStyleFamily);
SvTreeListEntry* pStyleEntry = InsertEntry( pFamily->sLabel, pEntry );
aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, pFamily ));
pStyleEntry->SetUserData( aArr.back().get() );
pStyleEntry->EnableChildrenOnDemand( false );
}
}
break;
}
default:
OSL_FAIL( "Wrong group type!" );
break;
}
}
void SfxConfigGroupListBox::SelectMacro( const SfxMacroInfoItem *pItem )
{
SelectMacro( pItem->GetBasicManager()->GetName(),
pItem->GetQualifiedName() );
}
void SfxConfigGroupListBox::SelectMacro( const OUString& rBasic,
const OUString& rMacro )
{
const OUString aBasicName(rBasic + " " + xImp->m_sMacros);
sal_Int32 nIdx {rMacro.lastIndexOf('.')};
const OUString aMethod( rMacro.copy(nIdx+1) );
OUString aLib;
OUString aModule;
if ( nIdx>0 )
{
// string contains at least 2 tokens
nIdx = rMacro.lastIndexOf('.', nIdx);
if (nIdx>=0)
{
// string contains at least 3 tokens
aLib = rMacro.getToken( 0, '.' );
aModule = rMacro.getToken( 0, '.', ++nIdx );
}
}
SvTreeListEntry *pEntry = FirstChild(nullptr);
while ( pEntry )
{
OUString aEntryBas = GetEntryText( pEntry );
if ( aEntryBas == aBasicName )
{
Expand( pEntry );
SvTreeListEntry *pLib = FirstChild( pEntry );
while ( pLib )
{
OUString aEntryLib = GetEntryText( pLib );
if ( aEntryLib == aLib )
{
Expand( pLib );
SvTreeListEntry *pMod = FirstChild( pLib );
while ( pMod )
{
OUString aEntryMod = GetEntryText( pMod );
if ( aEntryMod == aModule )
{
Expand( pMod );
MakeVisible( pMod );
Select( pMod );
SvTreeListEntry *pMethod = pFunctionListBox->First();
while ( pMethod )
{
OUString aEntryMethod = GetEntryText( pMethod );
if ( aEntryMethod == aMethod )
{
pFunctionListBox->Select( pMethod );
pFunctionListBox->MakeVisible( pMethod );
return;
}
pMethod = pFunctionListBox->Next( pMethod );
}
}
pMod = pMod->NextSibling();
}
}
pLib = pLib->NextSibling();
}
}
pEntry = pEntry->NextSibling();
}
}
CuiConfigGroupListBox::CuiConfigGroupListBox(std::unique_ptr<weld::TreeView> xTreeView)
: xImp(new CuiConfigGroupBoxResource_Impl())
, m_pFunctionListBox(nullptr)
@@ -1424,6 +704,7 @@ void CuiConfigGroupListBox::FillScriptList(const css::uno::Reference< css::scrip
void CuiConfigGroupListBox::FillFunctionsList(const css::uno::Sequence<DispatchInformation>& xCommands)
{
m_pFunctionListBox->freeze();
for (const auto & rInfo : xCommands)
{
OUString sUIName = MapCommand2UIName(rInfo.Command);
@@ -1433,6 +714,7 @@ void CuiConfigGroupListBox::FillFunctionsList(const css::uno::Sequence<DispatchI
pGrpInfo->sLabel = sUIName;
m_pFunctionListBox->append(OUString::number(reinterpret_cast<sal_Int64>(pGrpInfo)), sUIName);
}
m_pFunctionListBox->thaw();
}
void CuiConfigGroupListBox::Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
@@ -1803,6 +1085,82 @@ IMPL_LINK(CuiConfigGroupListBox, ExpandingHdl, weld::TreeIter&, rIter, bool)
return true;
}
void CuiConfigGroupListBox::SelectMacro( const SfxMacroInfoItem *pItem )
{
SelectMacro( pItem->GetBasicManager()->GetName(),
pItem->GetQualifiedName() );
}
void CuiConfigGroupListBox::SelectMacro( const OUString& rBasic,
const OUString& rMacro )
{
const OUString aBasicName(rBasic + " " + xImp->m_sMacros);
sal_Int32 nIdx {rMacro.lastIndexOf('.')};
const OUString aMethod( rMacro.copy(nIdx+1) );
OUString aLib;
OUString aModule;
if ( nIdx>0 )
{
// string contains at least 2 tokens
nIdx = rMacro.lastIndexOf('.', nIdx);
if (nIdx>=0)
{
// string contains at least 3 tokens
aLib = rMacro.getToken( 0, '.' );
aModule = rMacro.getToken( 0, '.', ++nIdx );
}
}
std::unique_ptr<weld::TreeIter> xIter = m_xTreeView->make_iterator();
if (!m_xTreeView->get_iter_first(*xIter))
return;
do
{
OUString aEntryBas = m_xTreeView->get_text(*xIter);
if (aEntryBas == aBasicName)
{
m_xTreeView->expand_row(*xIter);
std::unique_ptr<weld::TreeIter> xLibIter = m_xTreeView->make_iterator(xIter.get());
if (m_xTreeView->get_iter_first(*xLibIter))
{
do
{
OUString aEntryLib = m_xTreeView->get_text(*xLibIter);
if (aEntryLib == aLib)
{
m_xTreeView->expand_row(*xLibIter);
std::unique_ptr<weld::TreeIter> xModIter = m_xTreeView->make_iterator(xLibIter.get());
if (m_xTreeView->get_iter_first(*xModIter))
{
do
{
OUString aEntryMod = m_xTreeView->get_text(*xModIter);
if ( aEntryMod == aModule )
{
m_xTreeView->expand_row(*xModIter);
m_xTreeView->scroll_to_row(*xModIter);
m_xTreeView->select(*xModIter);
for (int i = 0, nCount = m_pFunctionListBox->n_children(); i < nCount; ++i)
{
OUString aEntryMethod = m_pFunctionListBox->get_text(i);
if (aEntryMethod == aMethod)
{
m_pFunctionListBox->select(i);
m_pFunctionListBox->scroll_to_row(i);
return;
}
}
}
} while (m_xTreeView->iter_next_sibling(*xModIter));
}
}
} while (m_xTreeView->iter_next_sibling(*xLibIter));
}
}
} while (m_xTreeView->iter_next_sibling(*xIter));
}
/*
* Implementation of SvxScriptSelectorDialog
*
diff --git a/cui/source/inc/acccfg.hxx b/cui/source/inc/acccfg.hxx
index 436fbbe..b4bbae8 100644
--- a/cui/source/inc/acccfg.hxx
+++ b/cui/source/inc/acccfg.hxx
@@ -100,18 +100,6 @@ private:
const SfxMacroInfoItem* m_pMacroInfoItem;
std::unique_ptr<sfx2::FileDialogHelper> m_pFileDlg;
VclPtr<SfxAccCfgTabListBox_Impl> m_pEntriesBox;
VclPtr<RadioButton> m_pOfficeButton;
VclPtr<RadioButton> m_pModuleButton;
VclPtr<PushButton> m_pChangeButton;
VclPtr<PushButton> m_pRemoveButton;
VclPtr<SfxConfigGroupListBox> m_pGroupLBox;
VclPtr<SfxConfigFunctionListBox> m_pFunctionBox;
VclPtr<SvTreeListBox> m_pKeyBox;
VclPtr<Edit> m_pSearchEdit;
VclPtr<PushButton> m_pLoadButton;
VclPtr<PushButton> m_pSaveButton;
VclPtr<PushButton> m_pResetButton;
OUString aLoadAccelConfigStr;
OUString aSaveAccelConfigStr;
OUString aFilterAllStr;
@@ -130,22 +118,40 @@ private:
OUString m_sModuleUIName;
// For search
Timer m_aUpdateDataTimer;
i18nutil::SearchOptions2 m_options;
DECL_LINK(ChangeHdl, Button *, void);
DECL_LINK(RemoveHdl, Button *, void);
DECL_LINK(SelectHdl, SvTreeListBox*, void);
DECL_LINK(SearchUpdateHdl, Edit&, void);
DECL_LINK(Save, Button *, void);
DECL_LINK(Load, Button *, void);
DECL_LINK(Default, Button *, void);
DECL_LINK(RadioHdl, Button *, void);
Idle m_aFillGroupIdle;
std::unique_ptr<weld::TreeView> m_xEntriesBox;
std::unique_ptr<weld::RadioButton> m_xOfficeButton;
std::unique_ptr<weld::RadioButton> m_xModuleButton;
std::unique_ptr<weld::Button> m_xChangeButton;
std::unique_ptr<weld::Button> m_xRemoveButton;
std::unique_ptr<CuiConfigGroupListBox> m_xGroupLBox;
std::unique_ptr<CuiConfigFunctionListBox> m_xFunctionBox;
std::unique_ptr<weld::TreeView> m_xKeyBox;
std::unique_ptr<weld::Entry> m_xSearchEdit;
std::unique_ptr<weld::Button> m_xLoadButton;
std::unique_ptr<weld::Button> m_xSaveButton;
std::unique_ptr<weld::Button> m_xResetButton;
DECL_LINK(ChangeHdl, weld::Button&, void);
DECL_LINK(RemoveHdl, weld::Button&, void);
DECL_LINK(SelectHdl, weld::TreeView&, void);
DECL_LINK(SearchUpdateHdl, weld::Entry&, void);
DECL_LINK(Save, weld::Button&, void);
DECL_LINK(Load, weld::Button&, void);
DECL_LINK(Default, weld::Button&, void);
DECL_LINK(RadioHdl, weld::Button&, void);
DECL_LINK(ImplUpdateDataHdl, Timer*, void);
DECL_LINK(TimeOut_Impl, Timer*, void);
DECL_LINK(LoadHdl, sfx2::FileDialogHelper *, void);
DECL_LINK(SaveHdl, sfx2::FileDialogHelper *, void);
OUString GetLabel4Command(const OUString& rCommand);
SvTreeListEntry* applySearchFilter(OUString const & rSearchTerm, SvTreeListBox* rListBox);
int applySearchFilter(OUString const & rSearchTerm);
void InitAccCfg();
sal_Int32 MapKeyCodeToPos(const vcl::KeyCode &rCode) const;
void StartFileDialog( StartFileDialogType nType, const OUString& rTitle );
@@ -153,10 +159,8 @@ private:
void Init(const css::uno::Reference< css::ui::XAcceleratorConfiguration >& pAccMgr);
void ResetConfig();
static void CreateCustomItems( SvTreeListEntry* pEntry, const OUString& aCol1, const OUString& aCol2 );
public:
SfxAcceleratorConfigPage( vcl::Window *pParent, const SfxItemSet& rItemSet );
SfxAcceleratorConfigPage(TabPageParent pParent, const SfxItemSet& rItemSet);
virtual ~SfxAcceleratorConfigPage() override;
virtual void dispose() override;
diff --git a/cui/source/inc/cfgutil.hxx b/cui/source/inc/cfgutil.hxx
index ed1ccd1..423cb05 100644
--- a/cui/source/inc/cfgutil.hxx
+++ b/cui/source/inc/cfgutil.hxx
@@ -106,7 +106,6 @@ typedef std::vector<std::unique_ptr<SfxGroupInfo_Impl> > SfxGroupInfoArr_Impl;
class SfxConfigFunctionListBox : public SvTreeListBox
{
friend class SfxConfigGroupListBox;
SfxGroupInfoArr_Impl aArr;
virtual void MouseMove( const MouseEvent& rMEvt ) override;
@@ -142,79 +141,30 @@ public:
{
m_xTreeView->insert(nullptr, -1, &rStr, &rId, nullptr, nullptr, &rImage, false, nullptr);
}
void remove(int nPos) { m_xTreeView->remove(nPos); }
int n_children() const { return m_xTreeView->n_children(); }
void select(int pos) { m_xTreeView->select(pos); }
std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig = nullptr) const { return m_xTreeView->make_iterator(pOrig); }
bool get_iter_first(weld::TreeIter& rIter) const { return m_xTreeView->get_iter_first(rIter); }
// set iter to point to next node, depth first, then sibling
bool iter_next(weld::TreeIter& rIter) const { return m_xTreeView->iter_next(rIter); }
bool iter_next_sibling(weld::TreeIter& rIter) const { return m_xTreeView->iter_next_sibling(rIter); }
OUString get_text(const weld::TreeIter& rIter) const { return m_xTreeView->get_text(rIter); }
OUString get_text(int nPos) const { return m_xTreeView->get_text(nPos); }
OUString get_id(const weld::TreeIter& rIter) const { return m_xTreeView->get_id(rIter); }
bool get_selected(weld::TreeIter* pIter) const { return m_xTreeView->get_selected(pIter); }
void scroll_to_row(const weld::TreeIter& rIter) { return m_xTreeView->scroll_to_row(rIter); }
void scroll_to_row(int nRow) { return m_xTreeView->scroll_to_row(nRow); }
void select(const weld::TreeIter& rIter) { m_xTreeView->select(rIter); }
void select(int pos) { m_xTreeView->select(pos); }
void set_size_request(int nWidth, int nHeight) { m_xTreeView->set_size_request(nWidth, nHeight); }
weld::TreeView& get_widget() { return *m_xTreeView; }
~CuiConfigFunctionListBox();
void ClearAll();
OUString GetSelectedScriptURI();
OUString GetHelpText( bool bConsiderParent = true );
};
struct SvxConfigGroupBoxResource_Impl;
class SfxConfigGroupListBox : public SvTreeListBox
{
std::unique_ptr<SvxConfigGroupBoxResource_Impl> xImp;
VclPtr<SfxConfigFunctionListBox> pFunctionListBox;
SfxGroupInfoArr_Impl aArr;
OUString m_sModuleLongName;
css::uno::Reference< css::uno::XComponentContext > m_xContext;
css::uno::Reference< css::frame::XFrame > m_xFrame;
css::uno::Reference< css::container::XNameAccess > m_xGlobalCategoryInfo;
css::uno::Reference< css::container::XNameAccess > m_xModuleCategoryInfo;
css::uno::Reference< css::container::XNameAccess > m_xUICmdDescription;
Image GetImage(
const css::uno::Reference< css::script::browse::XBrowseNode >& node,
css::uno::Reference< css::uno::XComponentContext > const & xCtx,
bool bIsRootNode
);
static css::uno::Reference< css::uno::XInterface > getDocumentModel(
css::uno::Reference< css::uno::XComponentContext > const & xCtx,
OUString const & docName
);
void InitModule();
void FillScriptList(const css::uno::Reference< css::script::browse::XBrowseNode >& xRootNode,
SvTreeListEntry* pParentEntry, bool bCheapChildrenOnDemand);
void FillFunctionsList(const css::uno::Sequence< css::frame::DispatchInformation >& xCommands);
OUString MapCommand2UIName(const OUString& sCommand);
SfxStylesInfo_Impl* pStylesInfo;
protected:
virtual void RequestingChildren( SvTreeListEntry *pEntry) override;
virtual bool Expand( SvTreeListEntry* pParent ) override;
public:
SfxConfigGroupListBox(vcl::Window* pParent, WinBits nStyle);
virtual ~SfxConfigGroupListBox() override;
virtual void dispose() override;
void ClearAll();
void Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
const css::uno::Reference< css::frame::XFrame >& xFrame,
const OUString& sModuleLongName,
bool bEventMode);
void SetFunctionListBox( SfxConfigFunctionListBox *pBox )
{ pFunctionListBox = pBox; }
void GroupSelected();
void SelectMacro( const SfxMacroInfoItem* );
void SelectMacro( const OUString&, const OUString& );
void SetStylesInfo(SfxStylesInfo_Impl* pStyles);
OUString GetCurCommand();
OUString GetCurLabel();
};
struct CuiConfigGroupBoxResource_Impl;
@@ -254,7 +204,8 @@ public:
CuiConfigGroupListBox(std::unique_ptr<weld::TreeView> xTreeView);
void set_sensitive(bool bSensitive) { m_xTreeView->set_sensitive(bSensitive); }
void connect_changed(const Link<weld::TreeView&, void>& rLink) { m_xTreeView->connect_changed(rLink); }
const weld::TreeView& get_widget() const { return *m_xTreeView; }
void set_size_request(int nWidth, int nHeight) { m_xTreeView->set_size_request(nWidth, nHeight); }
weld::TreeView& get_widget() { return *m_xTreeView; }
~CuiConfigGroupListBox();
void ClearAll();
@@ -265,6 +216,8 @@ public:
void SetFunctionListBox( CuiConfigFunctionListBox *pBox )
{ m_pFunctionListBox = pBox; }
void GroupSelected();
void SelectMacro(const SfxMacroInfoItem*);
void SelectMacro(const OUString&, const OUString&);
void SetStylesInfo(SfxStylesInfo_Impl* pStyles);
};
diff --git a/cui/uiconfig/ui/accelconfigpage.ui b/cui/uiconfig/ui/accelconfigpage.ui
index 17827e0..d651300 100644
--- a/cui/uiconfig/ui/accelconfigpage.ui
+++ b/cui/uiconfig/ui/accelconfigpage.ui
@@ -1,8 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="cui">
<requires lib="gtk+" version="3.18"/>
<requires lib="LibreOffice" version="1.0"/>
<object class="GtkTreeStore" id="liststore1">
<columns>
<!-- column-name text -->
<column type="gchararray"/>
<!-- column-name id -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkTreeStore" id="liststore2">
<columns>
<!-- column-name text -->
<column type="gchararray"/>
<!-- column-name id -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkTreeStore" id="liststore3">
<columns>
<!-- column-name text -->
<column type="gchararray"/>
<!-- column-name text2 -->
<column type="gchararray"/>
<!-- column-name id -->
<column type="gchararray"/>
<!-- column-name sensitive -->
<column type="gboolean"/>
</columns>
</object>
<object class="GtkTreeStore" id="liststore4">
<columns>
<!-- column-name text -->
<column type="gchararray"/>
<!-- column-name id -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkGrid" id="AccelConfigPage">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -35,13 +70,51 @@
<property name="yalign">0</property>
<property name="top_padding">6</property>
<child>
<object class="cuilo-SfxAccCfgTabListBox" id="shortcuts:border">
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="AccCfgTabListBox-selection"/>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="shortcuts">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="model">liststore3</property>
<property name="headers_visible">False</property>
<property name="search_column">0</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="Macro Library List-selection2"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn3">
<property name="resizable">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkCellRendererText" id="cellrenderer1"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn4">
<property name="resizable">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkCellRendererText" id="cellrenderer2"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
@@ -53,7 +126,7 @@
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="accelconfigpage|label21">Shortcu_t Keys</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">shortcuts:border</property>
<property name="mnemonic_widget">shortcuts</property>
</object>
</child>
</object>
@@ -83,8 +156,8 @@
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">module</property>
</object>
<packing>
<property name="expand">False</property>
@@ -266,7 +339,7 @@
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="accelconfigpage|label23">_Category</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">category:border</property>
<property name="mnemonic_widget">category</property>
<property name="xalign">0</property>
</object>
<packing>
@@ -280,7 +353,7 @@
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="accelconfigpage|label24">_Function</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">function:border</property>
<property name="mnemonic_widget">function</property>
<property name="xalign">0</property>
</object>
<packing>
@@ -294,7 +367,7 @@
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="accelconfigpage|label25">_Keys</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">keys:border</property>
<property name="mnemonic_widget">keys</property>
<property name="xalign">0</property>
</object>
<packing>
@@ -303,13 +376,39 @@
</packing>
</child>
<child>
<object class="cuilo-SfxConfigGroupListBox" id="category:border">
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="ConfigGroup ListBox-selection"/>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="category">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="model">liststore1</property>
<property name="headers_visible">False</property>
<property name="search_column">0</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="Macro Library List-selection1"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
<property name="resizable">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkCellRendererText" id="cellrenderer4"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
@@ -318,13 +417,39 @@
</packing>
</child>
<child>
<object class="cuilo-SfxConfigFunctionListBox" id="function:border">
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="ConfigGroupFunction ListBox-selection"/>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="function">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="model">liststore2</property>
<property name="headers_visible">False</property>
<property name="search_column">0</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="Macro Library List-selection3"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn5">
<property name="resizable">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkCellRendererText" id="cellrenderer5"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
@@ -333,13 +458,39 @@
</packing>
</child>
<child>
<object class="vcllo-SvTreeListBox" id="keys:border">
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="Tree List-selection"/>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="keys">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="model">liststore4</property>
<property name="headers_visible">False</property>
<property name="search_column">0</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="Macro Library List-selection4"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn6">
<property name="resizable">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkCellRendererText" id="cellrenderer7"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index ac23c4e..967ee3c 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -186,12 +186,6 @@
<glade-widget-class title="SwDBTreeList" name="swlo-SwDBTreeList"
generic-name="SwDBTreeList" parent="GtkTreeView"
icon-name="widget-gtk-treeview"/>
<glade-widget-class title="ConfigGroup ListBox" name="cuilo-SfxConfigGroupListBox"
generic-name="ConfigGroup ListBox" parent="GtkTreeView"
icon-name="widget-gtk-treeview"/>
<glade-widget-class title="SfxAccCfgTabListBox" name="cuilo-SfxAccCfgTabListBox"
generic-name="AccCfgTabListBox" parent="GtkTreeView"
icon-name="widget-gtk-treeview"/>
<glade-widget-class title="ConfigGroupFunction ListBox" name="cuilo-SfxConfigFunctionListBox"
generic-name="ConfigGroupFunction ListBox" parent="GtkTreeView"
icon-name="widget-gtk-treeview"/>
diff --git a/include/vcl/treelistbox.hxx b/include/vcl/treelistbox.hxx
index adf35cb..c03f300 100644
--- a/include/vcl/treelistbox.hxx
+++ b/include/vcl/treelistbox.hxx
@@ -133,12 +133,16 @@ public:
class VCL_DLLPUBLIC SvLBoxItem
{
protected:
bool mbDisabled;
public:
SvLBoxItem();
virtual ~SvLBoxItem();
virtual SvLBoxItemType GetType() const = 0;
const Size& GetSize(const SvTreeListBox* pView, const SvTreeListEntry* pEntry) const;
static const Size& GetSize(const SvViewDataEntry* pData, sal_uInt16 nItemPos);
void Enable(bool bEnabled) { mbDisabled = !bEnabled; }
virtual void Paint(const Point& rPos, SvTreeListBox& rOutDev, vcl::RenderContext& rRenderContext, const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) = 0;
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 5511879..e25911f 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -576,6 +576,7 @@ public:
virtual void remove(int pos) = 0;
virtual OUString get_text(int row, int col = -1) const = 0;
virtual void set_text(int row, const OUString& rText, int col = -1) = 0;
virtual void set_sensitive(int row, bool bSensitive, int col = -1) = 0;
virtual void set_id(int row, const OUString& rId) = 0;
virtual void set_toggle(int row, bool bOn, int col) = 0;
virtual bool get_toggle(int row, int col) const = 0;
@@ -692,6 +693,8 @@ public:
virtual int count_selected_rows() const = 0;
void set_toggle_columns_as_radio(const std::vector<int>& rCols) { m_aRadioIndexes = rCols; }
using Widget::set_sensitive;
};
class VCL_DLLPUBLIC Button : virtual public Container
diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index 6f3094a..4e9b590 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -487,9 +487,7 @@ custom_widgets = [
'SearchResultsBox',
'SelectionListBox',
'SentenceEditWindow',
'SfxAccCfgTabListBox',
'SfxConfigFunctionListBox',
'SfxConfigGroupListBox',
'ShowNupOrderWindow',
'ShowNupOrderWindow',
'SidebarDialControl',
diff --git a/solenv/sanitizers/ui/cui.suppr b/solenv/sanitizers/ui/cui.suppr
index 8ea1c0e..cea9c99 100644
--- a/solenv/sanitizers/ui/cui.suppr
+++ b/solenv/sanitizers/ui/cui.suppr
@@ -263,7 +263,6 @@ cui/uiconfig/ui/linestyletabpage.ui://GtkSpinButton[@id='NUM_FLD_2'] no-labelled
cui/uiconfig/ui/linestyletabpage.ui://GtkSpinButton[@id='MTR_FLD_LENGTH_2'] no-labelled-by
cui/uiconfig/ui/macroselectordialog.ui://GtkLabel[@id='helpmacro'] orphan-label
cui/uiconfig/ui/macroselectordialog.ui://GtkLabel[@id='helptoolbar'] orphan-label
cui/uiconfig/ui/macroselectordialog.ui://cuilo-SfxConfigGroupListBox[@id='categories:border'] no-labelled-by
cui/uiconfig/ui/macroselectordialog.ui://GtkLabel[@id='libraryft'] orphan-label
cui/uiconfig/ui/macroselectordialog.ui://GtkLabel[@id='categoryft'] orphan-label
cui/uiconfig/ui/macroselectordialog.ui://cuilo-SfxConfigFunctionListBox[@id='commands:border'] no-labelled-by
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index f0efbf9..35bf1e6 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -2344,8 +2344,10 @@ public:
virtual void remove(int pos) override
{
disable_notify_events();
SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
m_xTreeView->RemoveEntry(pEntry);
enable_notify_events();
}
virtual int find_text(const OUString& rText) const override
@@ -2502,6 +2504,41 @@ public:
set_text(pEntry, rText, col);
}
void set_sensitive(SvTreeListEntry* pEntry, bool bSensitive, int col)
{
if (col == -1)
{
const sal_uInt16 nCount = pEntry->ItemCount();
for (sal_uInt16 nCur = 0; nCur < nCount; ++nCur)
{
SvLBoxItem& rItem = pEntry->GetItem(nCur);
if (rItem.GetType() == SvLBoxItemType::String)
{
rItem.Enable(bSensitive);
m_xTreeView->ModelHasEntryInvalidated(pEntry);
break;
}
}
return;
}
++col; //skip dummy/expander column
assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
SvLBoxItem& rItem = pEntry->GetItem(col);
rItem.Enable(bSensitive);
m_xTreeView->ModelHasEntryInvalidated(pEntry);
}
using SalInstanceWidget::set_sensitive;
virtual void set_sensitive(int pos, bool bSensitive, int col) override
{
SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
set_sensitive(pEntry, bSensitive, col);
}
virtual bool get_toggle(int pos, int col) const override
{
SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
@@ -2693,8 +2730,10 @@ public:
virtual void remove(const weld::TreeIter& rIter) override
{
disable_notify_events();
const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
m_xTreeView->RemoveEntry(rVclIter.iter);
enable_notify_events();
}
virtual void select(const weld::TreeIter& rIter) override
diff --git a/vcl/source/treelist/svlbitm.cxx b/vcl/source/treelist/svlbitm.cxx
index 7f45fdf..8edd585 100644
--- a/vcl/source/treelist/svlbitm.cxx
+++ b/vcl/source/treelist/svlbitm.cxx
@@ -173,11 +173,11 @@ bool SvLBoxButtonData::IsRadio() {
SvLBoxString::SvLBoxString(const OUString& rStr)
: maText(rStr)
{
SetText(rStr);
}
SvLBoxString::SvLBoxString() : SvLBoxItem()
SvLBoxString::SvLBoxString()
{
}
@@ -195,7 +195,7 @@ void SvLBoxString::Paint(
const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry)
{
Size aSize = GetSize(&rDev, &rEntry);
DrawTextFlags nStyle = rDev.IsEnabled() ? DrawTextFlags::NONE : DrawTextFlags::Disable;
DrawTextFlags nStyle = (rDev.IsEnabled() && !mbDisabled) ? DrawTextFlags::NONE : DrawTextFlags::Disable;
if (rDev.IsEntryMnemonicsEnabled())
nStyle |= DrawTextFlags::Mnemonic;
if (rDev.TextCenterAndClipEnabled())
diff --git a/vcl/source/treelist/treelistbox.cxx b/vcl/source/treelist/treelistbox.cxx
index cfaccea..7355f06 100644
--- a/vcl/source/treelist/treelistbox.cxx
+++ b/vcl/source/treelist/treelistbox.cxx
@@ -295,6 +295,7 @@ long SvLBoxTab::CalcOffset( long nItemWidth, long nTabWidth )
SvLBoxItem::SvLBoxItem()
: mbDisabled(false)
{
}
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 222bd91..a11c943 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -6000,7 +6000,7 @@ public:
col = m_nTextCol;
else
col = get_model_col(col);
return set(pos, col, rText);
set(pos, col, rText);
}
virtual bool get_toggle(int pos, int col) const override
@@ -6013,7 +6013,17 @@ public:
col = get_model_col(col);
// checkbuttons are invisible until toggled on or off
set(pos, m_aToggleVisMap[col], true);
return set(pos, col, bOn);
set(pos, col, bOn);
}
using GtkInstanceWidget::set_sensitive;
virtual void set_sensitive(int pos, bool bSensitive, int col) override
{
col = get_model_col(col);
++col; // skip over id column
col += m_aToggleVisMap.size(); // skip over toggle columns
set(pos, col, bSensitive);
}
virtual void set_image(int pos, const OUString& rImage, int col) override