[Solved] Disable the exit button with the C++ SDK
[Solved] Disable the exit button with the C++ SDK
Hi !
There is a way to disable the exit button with the C++ SDK when LibreOffice 7.5.2 is embebed in QT.
------------------------------
Reference< XComponentContext > xContext( ::cppu::bootstrap() );
Reference< XMultiComponentFactory > xServiceManager(xContext->getServiceManager() );
Reference<XDesktop2> xDesktop = Desktop::create(xContext);
Reference<XComponentLoader> xComponentLoader(xDesktop, UNO_QUERY);
Sequence<PropertyValue> loadProps;
Reference<XComponent> xComponent = xComponentLoader->loadComponentFromURL("private:factory/scalc", start_document, 0, loadProps);
Reference<XModel> xModel(xComponent, UNO_QUERY);
Reference<XFrame> xFrame = xModel->getCurrentController()->getFrame();
Reference<XWindow> xWindow = xFrame->getContainerWindow();
Reference<XSystemDependentWindowPeer> xWindowPeer;
css::uno::Any windowPeer = xWindow->queryInterface(XSystemDependentWindowPeer::static_type());
windowPeer >>= xWindowPeer;
-->> xComponent ? disable exit button ?
------------------------------
Thank you
There is a way to disable the exit button with the C++ SDK when LibreOffice 7.5.2 is embebed in QT.
------------------------------
Reference< XComponentContext > xContext( ::cppu::bootstrap() );
Reference< XMultiComponentFactory > xServiceManager(xContext->getServiceManager() );
Reference<XDesktop2> xDesktop = Desktop::create(xContext);
Reference<XComponentLoader> xComponentLoader(xDesktop, UNO_QUERY);
Sequence<PropertyValue> loadProps;
Reference<XComponent> xComponent = xComponentLoader->loadComponentFromURL("private:factory/scalc", start_document, 0, loadProps);
Reference<XModel> xModel(xComponent, UNO_QUERY);
Reference<XFrame> xFrame = xModel->getCurrentController()->getFrame();
Reference<XWindow> xWindow = xFrame->getContainerWindow();
Reference<XSystemDependentWindowPeer> xWindowPeer;
css::uno::Any windowPeer = xWindow->queryInterface(XSystemDependentWindowPeer::static_type());
windowPeer >>= xWindowPeer;
-->> xComponent ? disable exit button ?
------------------------------
Thank you
- Attachments
-
- disable_button.png (65.65 KiB) Viewed 7355 times
Last edited by Hagar Delest on Thu Apr 13, 2023 7:54 am, edited 1 time in total.
Reason: tagged solved.
Reason: tagged solved.
LibreOffice 7.5.2 WINDOWS
Re: Disable the exit button with the C++ SDK
You can disable menu items, remove them, hide them, via the frame's layoutmanager. Look for the element with the ResourceURL "private:resource/menubar/menubar" (in OO - I presume it will be the same URL in LO)
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Re: Disable the exit button with the C++ SDK
Thank you, JeJe, for your prompt response.
I have tried multiple methods, but in the end, either the object used to set the property is null or the property is not being considered.
Do you have any ideas about the object path I need to take and how to set the property? Any suggestions you could offer?
I have tried multiple methods, but in the end, either the object used to set the property is null or the property is not being considered.
Do you have any ideas about the object path I need to take and how to set the property? Any suggestions you could offer?
LibreOffice 7.5.2 WINDOWS
Re: Disable the exit button with the C++ SDK
I don't know C++. All I can do is tell you how to access that menu item in the frame using Basic (for all frames a different route is needed). You'll need to replace that item with one with the disabled property value and update settings which isn't done below.
You can use MRI to see what code it produces for the objects for C++
eg MRI thiscomponent followed by clicking on currentcontroller frame and layout manager produces.
Edit: note the file menu is called Picklist and the index to get it may be different than the one I used. I've also used OO not LO - but it should be similar.
Code: Select all
els=thiscomponent.currentcontroller.frame.layoutmanager.elements
for i = 0 to ubound(els)
if right(els(i).resourceurl,7) = "menubar" then
sets = els(i).getsettings(true)
menuitems= sets.getbyindex(0)(2).value
mri menuitems
for j=0 to menuitems.count -1
itm = menuitems.getbyindex(j)
for k = 0 to ubound(itm)
if itm(k).name = "CommandURL" then
if itm(k).value = ".uno:Quit" then
mri itm(k)
exit sub
end if
end if
next
next
end if
next
eg MRI thiscomponent followed by clicking on currentcontroller frame and layout manager produces.
Code: Select all
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XLayoutManager.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/uno/XInterface.hpp>
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::rtl;
void snippet(const Reference< XComponentContext > &xContext, const Reference< XInterface > &oInitialTarget)
{
try
{
Reference< XController > xController = oInitialTarget->getCurrentController();
Reference< XFrame > xFrame = xController->getFrame();
Reference< XPropertySet > xPropSet(xFrame, UNO_QUERY);
XLayoutManager xLayoutManager;
xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LayoutManager"))) >>= xLayoutManager;
}
catch (WrappedTargetException &e)
{
// getPropertyValue
//printf(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
}
catch (UnknownPropertyException &e)
{
// getPropertyValue
//printf(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
}
}
Edit: note the file menu is called Picklist and the index to get it may be different than the one I used. I've also used OO not LO - but it should be similar.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Re: Disable the exit button with the C++ SDK
Thank you again JeJe...you will become my best friend!
Your comment was very helpful! MRI is a great tool and it has changed the way I understand the object path.
I think I have found exactly what I need, except that when I remove the exit button, the FileMenu looks disabled and the popup never appears.
I believe there are two possible reasons:
1) It seems that I made some changes to the interface and I need a specific refresh call.
2) Perhaps my cast is incorrect in this line? Reference<XPopupMenu> xFileMenu = xMenuBar->getPopupMenu(menu_file_id);
Note: When I removed the "Window Menu" from the menuBar, everything looked good.
Note: I tried removing the exit button using the MRI interface and it worked!
Do you have any suggestions?
Your comment was very helpful! MRI is a great tool and it has changed the way I understand the object path.
I think I have found exactly what I need, except that when I remove the exit button, the FileMenu looks disabled and the popup never appears.
I believe there are two possible reasons:
1) It seems that I made some changes to the interface and I need a specific refresh call.
2) Perhaps my cast is incorrect in this line? Reference<XPopupMenu> xFileMenu = xMenuBar->getPopupMenu(menu_file_id);
Note: When I removed the "Window Menu" from the menuBar, everything looked good.
Note: I tried removing the exit button using the MRI interface and it worked!
Do you have any suggestions?
Code: Select all
Reference<XLayoutManager> xLayoutManager;
{
Reference< XPropertySet > xPropSet(xFrame, UNO_QUERY);
xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LayoutManager"))) >>= xLayoutManager;
}
Sequence<Reference<XUIElement>> elements = xLayoutManager->getElements();
for (auto & e : elements)
{
OUString url = e.get()->getResourceURL();
if (url == "private:resource/menubar/menubar")
{
Reference<XMenuBar> xMenuBar;
{
Reference< XPropertySet > xPropSet(e, UNO_QUERY);
xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("XMenuBar"))) >>= xMenuBar;
}
xMenuBar->removeItem(9,1); // Remove the Window Menu (10e) in the menubar (Working Good !)
int xMenuBar_count = xMenuBar->getItemCount();
::sal_Int16 menu_file_pos = 0; // First Position in the MenuBar
::sal_Int16 menu_file_id = xMenuBar->getItemId(menu_file_pos);
Reference<XPopupMenu> xFileMenu = xMenuBar->getPopupMenu(menu_file_id);
::sal_Int16 action_exit_pos = 34; // 35e Exit Button in the FileMenu
::sal_Int16 action_exit_pos_id = xFileMenu->getItemId(action_exit_pos);
xFileMenu->removeItem(action_exit_pos, 1); // Error >> FileMenu look disable and the popup doens't work
// Need a refresh ?
int error = 0;
}
}
LibreOffice 7.5.2 WINDOWS
Re: Disable the exit button with the C++ SDK
Here's the full Basic code to remove that item, works for me in OO
Code: Select all
els=thiscomponent.currentcontroller.frame.layoutmanager.elements
for i = 0 to ubound(els)
if right(els(i).resourceurl,7) = "menubar" then
sets = els(i).getsettings(true)
menuitems= sets.getbyindex(0)(2).value
for j=0 to menuitems.count -1
itm = menuitems.getbyindex(j)
for k = 0 to ubound(itm)
if itm(k).name = "CommandURL" then
if itm(k).value = ".uno:Quit" then
menuitems.removeByIndex(j)
els(i).setsettings(sets)
els(i).update
exit sub
end if
end if
next
next
end if
next
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Re: Disable the exit button with the C++ SDK
Thank you again again JeJe...
Working with the object's complexity, it will be a little more complicated in C++. However, everything is functioning properly! See below >>
Initially, my mistake was using a readonly interface, but I have now followed your last comment exactly.
Thank you, JeJe!
Working with the object's complexity, it will be a little more complicated in C++. However, everything is functioning properly! See below >>
Initially, my mistake was using a readonly interface, but I have now followed your last comment exactly.
Thank you, JeJe!
Code: Select all
Reference<XLayoutManager> xLayoutManager;
{
Reference< XPropertySet > xPropSet(xFrame, UNO_QUERY);
xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LayoutManager"))) >>= xLayoutManager;
}
Sequence<Reference<XUIElement>> elements = xLayoutManager->getElements();
for (auto & xUIElement : elements)
{
OUString url = xUIElement.get()->getResourceURL();
if (url == "private:resource/menubar/menubar")
{
Reference<XUIElementSettings> xUIElementSettings(xUIElement, UNO_QUERY);
if (xUIElementSettings.is())
{
Reference<XIndexAccess> xIndexAccess = xUIElementSettings->getSettings(true);
int c =xIndexAccess->getCount();
Sequence<PropertyValue> menuBarSequencePropertyValue;
::css::uno::Any menuBarSequencePropertyValueAny = xIndexAccess->getByIndex(0);
menuBarSequencePropertyValueAny >>= menuBarSequencePropertyValue;
Reference<XIndexAccess> xIndexAccess_menuBar_item;
::css::uno::Any xIndexAccess_menuBar_item_any = menuBarSequencePropertyValue[2].Value;
xIndexAccess_menuBar_item_any >>= xIndexAccess_menuBar_item;
// Access i=0 to the first Menu of the menu bar
int i=0; //for (int i=0;i<xIndexAccess_menuBar_item->getCount();i++)
{
Sequence<PropertyValue> menuBarFileMenuSequencePropertyValue;
::css::uno::Any menuBarfileMenuSequencePropertyValueAny = xIndexAccess->getByIndex(i);
menuBarfileMenuSequencePropertyValueAny >>= menuBarFileMenuSequencePropertyValue;
Reference<XIndexAccess> xIndexAccess_action_item;
::css::uno::Any action_items_any = menuBarFileMenuSequencePropertyValue[2].Value;
action_items_any >>= xIndexAccess_action_item;
int key_to_erase = -1;
for(int j=0;j<xIndexAccess_action_item->getCount();j++)
{
Sequence<PropertyValue> action_item;
::css::uno::Any action_item_any = xIndexAccess_action_item->getByIndex(j);
action_item_any >>= action_item;
for (int k = 0; k < action_item.getLength(); k++)
{
if (action_item[k].Name == "CommandURL")
{
::css::uno::Any value = action_item[k].Value;
OUString data;
value >>= data;
if (data == ".uno:Quit")
{
key_to_erase = j;
break;
}
}
if (key_to_erase != -1){break;}
}
}
if (key_to_erase != -1)
{
Reference<XIndexContainer> xReplace(xIndexAccess_action_item, UNO_QUERY);
if (xReplace.is())
{
xReplace->removeByIndex(key_to_erase);
}
xUIElementSettings->setSettings(xIndexAccess);
xUIElementSettings->updateSettings();
}
}
}
}
}
LibreOffice 7.5.2 WINDOWS
Re: Disable the exit button with the C++ SDK
For info only :
I found the refresh function to solve the previous readonly interface problem.
The solution is better and doesn't affect the other LibreOffice instances.
I found the refresh function to solve the previous readonly interface problem.
The solution is better and doesn't affect the other LibreOffice instances.
Code: Select all
Reference<XLayoutManager> xLayoutManager;
{
Reference< XPropertySet > xPropSet(xFrame, UNO_QUERY);
xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LayoutManager"))) >>= xLayoutManager;
}
Sequence<Reference<XUIElement>> elements = xLayoutManager->getElements();
for (auto & e : elements)
{
OUString url = e.get()->getResourceURL();
if (url == "private:resource/menubar/menubar")
{
Reference<XMenuBar> xMenuBar;
{
Reference< XPropertySet > xPropSet(e, UNO_QUERY);
xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("XMenuBar"))) >>= xMenuBar;
}
xMenuBar->removeItem(9,1); // Remove the Window Menu (10e) in the menubar (Working Good !)
int xMenuBar_count = xMenuBar->getItemCount();
::sal_Int16 menu_file_pos = 0; // First Position in the MenuBar
::sal_Int16 menu_file_id = xMenuBar->getItemId(menu_file_pos);
Reference<XPopupMenu> xFileMenu = xMenuBar->getPopupMenu(menu_file_id);
::sal_Int16 action_exit_pos = 34; // 35e Exit Button in the FileMenu
::sal_Int16 action_exit_pos_id = xFileMenu->getItemId(action_exit_pos);
xFileMenu->removeItem(action_exit_pos, 1); // Error >> FileMenu look disable and the popup doens't work
// Need a refresh ?
xMenuBar->setPopupMenu(menu_file_id,xFileMenu); // Refresh the current menu
}
}
LibreOffice 7.5.2 WINDOWS