Подвесил запуск макросов в главное меню (через Настройки). И озадачился следующим вопросом: возможно ли теперь как-то повлиять на эти пункты меню из макроса? Например, в зависимости от контекста делать их активными/неактивными (это интересует в первую очередь), или сделать их флажками/радиокнопками?
Пока докопался до такой цепочки
ThisComponent.CurrentController.Frame.LayoutManager.getElements()(3).getRealInterface()
Дальше, вероятно, должно быть
.getMenuHandle(ProcessId, SystemType)
но тут я уже завяз.. в SystemType скорее всего пойдёт что-то вроде com.sun.star.lang.SystemDependent.SYSTEM_XWINDOW, а вот где брать ProcessId - ни как не разберу.
Пробовал посмотреть на эту ветку (https://forumooo.ru/index.php?topic=9245.0), но там вроде потрошат конфиг-файл, динамическое поведение через который вряд ли организуешь, максимум - подпись поменять можно будет.
Ах да, чуть не забыл:
Version: 7.4.3.2 / LibreOffice Community
Build ID: 1048a8393ae2eeec98dff31b5c133c5f1d08b890
CPU threads: 2; OS: Linux 5.15; UI render: default; VCL: gtk3
Locale: ru-RU (ru_RU.UTF-8); UI: ru-RU
Calc: threaded
Я бы предложил более привычный путь enableItem (https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1awt_1_1XMenu.html#a9ab3929bd3eb7c349ecad40f4d4915e8).
Цитата: sokol92 от 28 декабря 2022, 18:06более привычный путь enableItem (https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1awt_1_1XMenu.html#a9ab3929bd3eb7c349ecad40f4d4915e8).
Да я не против, собственно.. Вопрос только, куда этот enableItem приложить, чтоб заработало )
Т.е. - как получить ссылку на объект главного меню (не уровня диалога, а уровня приложения Calc). Там уже да, должно быть что-то вроде enableItem, setItemText и прочие потроха от XMenu. Наверное... Я на это сильно надеюсь.
Попробовал этот путь - не сработало. Ладно, есть запасные (прогулка часа на два)... :)
Вот что получилось на скорую "ногу" (необходимо проверить). Дорожные карты взяты отсюда (https://www.libreoffice-forum.de/viewtopic.php?t=12825).
Option Explicit
Const MenuResource As String="private:resource/menubar/menubar"
Const DocType As String="com.sun.star.sheet.SpreadsheetDocument"
' В Calc отключаем первый пункт (индекс 0) пользовательского меню с индексом 11 (после "Справка").
Sub test()
setItemEnabled 11, 0, False
End Sub
' Отключение/включение пунктов основного меню Calc.
' Параметры:
' PopupIx Индекс пункта главного меню (от 0)
' ItemIx Индекс пункта вложенного меню (от 0)
' Enable True - включить (отблокировать) пункт меню, False - выключить (заблокировать)
Sub setItemEnabled (Byval PopupIx As Long, _
Byval ItemIx As Long, _
Byval Enable As Boolean)_
Dim oCfgMng, Settings, ItemContainer, Item
Dim Prop As New com.sun.star.beans.PropertyValue
Dim i As Long, Exist As Boolean
oCfgMng=GetDefaultContext.getValueByName("/singletons/com.sun.star.ui.theModuleUIConfigurationManagerSupplier").getUIConfigurationManager(DocType)
Settings = oCfgMng.getSettings(MenuResource, True)
ItemContainer = getItemContainer (PopupIx, Settings)
Item = ItemContainer.getByIndex (ItemIx)
' Ищем свойство Enabled
For i = 0 TO uBound(Item)
If Item(i).Name = "Enabled" Then
Item(i).Value = Enable
Exist = True
Exit For
End If
Next i
IF Not Exist Then
ReDim Preserve Item(uBound(Item) + 1)
Prop.Name = "Enabled"
Prop.Value = Enable
Item(uBound(Item)) = Prop
End If
ItemContainer.replaceByIndex ItemIx, Item
oCfgMng.replaceSettings MenuResource, Settings
End Sub
Function getItemContainer(ByVal PopupIndex As Long, Byval Settings) As Object
Dim Popup, i As Long
Popup = Settings.getByIndex (PopupIndex)
For i = 0 TO uBound (Popup)
If Popup(i).Name = "ItemDescriptorContainer" Then
getItemContainer = Popup(i).Value
Exit Function
End If
Next i
End Function
Забористо, но...
во-первых, похоже, что в ?коллекцию? confManager.getSettings() не попадают пользовательские меню (только стандартные .uno:PickList ... .uno:HelpMenu);
во-вторых, ?свойство? "Enabled" ему до лампочки от слова совсем;
в-третьих, в текущем документе ему подобные изменения в принципе до лампочки, а вот созданный после них новый документ изменение "Label" таки подхватывает.. но только до тех пор, пока не перезапустишь LO - потом изменения слетают.
В любом случае - спасибо за наводку, тут есть ещё что пощупать, так что будем посмотреть.
Хоть и странно такие вещи через конфиг делать.
Цитата: sokol92 от 28 декабря 2022, 20:49oCfgMng=GetDefaultContext.getValueByName("/singletons/com.sun.star.ui.theModuleUIConfigurationManagerSupplier").getUIConfigurationManager(DocType)
Или немного проще:
oCfgMng=com.sun.star.ui.theModuleUIConfigurationManagerSupplier.get().getUIConfigurationManager(DocType)
Цитата: Narrnika от 28 декабря 2022, 15:12Подвесил запуск макросов в главное меню (через Настройки).
Давайте проведем эксперимент вместе.
1. Записываем в любой модуль библиотеки Мои макросы / Standard макросы:
Sub Show1()
Msgbox "Первый пункт меню"
End Sub
Sub Show2()
Msgbox "Второй пункт меню"
End Sub
2. Создаем в Calc новое меню после пункта "Справка" (Сервис / Настройки / Меню / кнопка справа от элемента "Цель" / Добавить). В это меню добавляем два пункта, на которые назначаем макросы из пункта 1. Проверяем работоспособность этих пунктов меню. Перестартуем LibreOffice и еше раз проверяем работоспособность пунктов нового меню. Новое меню должно быть 12м по счету ("Файл" - 1, ..., "Справка" - 11).
3. Выполняем макрос Test из #4. В новом меню первый пункт должен быть выключен (disabled). Второй - работает.
4. Перестартуем LO. Оба пункта меню включены, поскольку мы не сохранили изменения, внесенные в пункте 3.
Проверял на системах Win10 LO 7.4.2.3, AstraLinux LO 7.3.6.2.
Цитата: Narrnika от 28 декабря 2022, 22:47похоже, что в ?коллекцию? confManager.getSettings() не попадают пользовательские меню (только стандартные .uno:PickList ... .uno:HelpMenu)
Возможно, проблема в хранилище кастомизации меню. Синглетон
theModuleUIConfigurationManagerSupplier предоставляет доступ к менеджерам компонентов. А если Вы сохраняете кастомизацию в документе, то Вам понадобится интерфейс
XUIConfigurationManagerSupplier, реализуемый моделями документов - т.е. Вы можете выполнить
oCfgMng=thisComponent.getUIConfigurationManager()
Цитата: mikekaganski от 29 декабря 2022, 11:06Или немного проще:
Чтобы не писать "com.sun.star" я использую функцию:
' Возвращает ссылку на экземпляр сервиса или синглтон, имена которых начинаются на "com.sun.star.".
' Если параметр не начинается на "com.sun.star." ' то к нему слева добавляется "com.sun.star.".
' - ServiceName: имя сервиса или синглтона.
' Имя, которое начинается на "the" (регистронезависимо) интерпретируется как имя синглтона.
' При неудаче возвращается Nothing.
Function Service_Create(Byval ServiceName As String) As Object
Const prf As String="com.sun.star."
Dim arr
Service_Create=Nothing
If Left(lcase(ServiceName), len(prf))<>prf Then ServiceName=prf & ServiceName
On Error GoTo errLabel
arr=Split(ServiceName, ".")
If Lcase(Left(arr(Ubound(arr)), 3))="the" Then
Service_Create=GetDefaultContext.getValueByName("/singletons/" & ServiceName)
Else
Service_Create=CreateUnoService(ServiceName)
End If
ErrLabel:
End Function
Sub Test_Service_Create()
Dim v
v=Service_Create("ui.theModuleUIConfigurationManagerSupplier")
End Sub
Цитата: mikekaganski от 29 декабря 2022, 13:00Возможно, проблема в хранилище кастомизации меню.
Да, вы правы, после
oCfgMng=thisComponent.getUIConfigurationManager()
стало повеселее. Состояние не сохраняется, но это и не требуется, всё равно его на изменение выделения подвешивать.
Сейчас ещё потестирую, а пока вынужден задать вопрос - у меня одного на LO-7.4.3.2 следующая проблема: в Настройки/Меню задаём область видимости на файл, в поле Цель создаём новое меню, закидываем в него любой пункт (макрос или команда LO), жмём Ок - всё, LO уходит в себя и не на что не реагирует, через пару минут предлагает закрыться или подождать ещё. Проверял для Calc/Writer/Impress. При этом AOO-4.1.12 и родной для системы LO-6.4.7.2 ведут себя нормально.
Пока это касалось только создания меню - меня это не сильно напрягало - создал в LO6, переоткрыл тот же файл в LO7 и всё, норм. Но теперь LO7 ещё и при попытке изменить состояние пункта меню завис, а в LO6 всё нормально сработало - сдаётся мне, эта та же проблема с другой стороны вылезла. Не пойму, то ли в 7-ой версии баг, то ли она у меня встала неудачно.
Цитата: sokol92 от 29 декабря 2022, 12:35Давайте проведем эксперимент вместе.
Да, именно в такой конфигурации всё сходится. В смысле, результат такой же, как у вас.
Меня вчера сбило с толку то, что моё меню действительно записано в файл и через
theModuleUIConfigurationManagerSupplier не отобразилось - из-за чего я начал пытаться прощупать хотя бы то, что есть - т.е. стандартные меню Calc'а, а на них скрипт почти никак не влияет.
Цитата: Narrnika от 29 декабря 2022, 16:59следующая проблема: в Настройки/Меню задаём область видимости на файл, в поле Цель создаём новое меню, закидываем в него любой пункт (макрос или команда LO), жмём Ок - всё, LO уходит в себя и не на что не реагирует
В "родной" версии
Version: 7.3.6.2 / LibreOffice Community
Build ID: 30(Build:2)
CPU threads: 4; OS: Linux 5.15; UI render: default; VCL: kf5 (cairo+xcb)
Locale: ru-RU (ru_RU.UTF-8); UI: ru-RU
Debian package version: 1:7.3.6-0ubuntu0.22.04.1~bpo20.04.1+ci202210040905+astra5
Calc: threaded
проблемы нет.