Событие "Вставить лист"

Автор Sliv0210, 13 декабря 2020, 06:31

0 Пользователи и 1 гость просматривают эту тему.

Sliv0210

Добрый день...
Подскажите пжлста, есть ли возможность назначить макрос на событие "Вставить лист"
в перечне событий, который предлагается LO такого нет.
Необходимо создать аналог процедуре vba:

Private Sub Workbook_NewSheet(ByVal SH As Object)
With Application
   Application.ScreenUpdating = False
   Application.DisplayAlerts = False
   SH.Delete
   Application.DisplayAlerts = True
   Application.ScreenUpdating = True
End With
MsgBox "Нельзя добавить новый лист"
End Sub

economist

Через Listner можно всё. Но м.б. будет достаточно защиты книги с паролем?
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

eeigor

#2
Невероятно сложен поиск решения для новичка.
Однозначно ответить на вопрос не могу. Пусть подскажут мастера. Изучив всю информацию ниже (видимо, недостаточно хорошо), я не могу сразу сказать, как правильно написать требуемый код (на что "вешать" обработчик). Однако ясно, что задача выполнима, и код несложный.
Обязательно отпишитесь, когда найдёте решение.

Для самостоятельного изучения вопроса могу порекомендовать:
1. У А.Питоньяка: InspectListenerMethods(), DisplayDbgInfoStr().
2. Файл "Event Listeners & Handlers.ods" (ooCalc-файл с программным кодом OOoBasic для проверки событий-слушателей). Найдёте здесь. Показано что и как кодировать. Информация о событиях выводится в строку состояния. Разобраться сложно, потому что автор пишет о разных багах, задваивании событий и пр.
3. Процедура ниже (события документа, что на вкладке Сервис/Настройка.../События). Но требуемого, похоже, нет.
Sub DisplayAvailableEvents()
   ''' Display document events '''
   Dim geb As Object  'com.sun.star.frame.GlobalEventBroadcaster
   Dim events() As String
   geb = CreateUnoService("com.sun.star.frame.GlobalEventBroadcaster")
   events = geb.Events.ElementNames()
   MsgBox Join(events, "; ")
End Sub


UPD:
Задал вопрос здесь. Подождём...
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

eeigor

#3
По ссылке выше на форуме ответили, но требуется адаптация примера под заданный вопрос...

UPD:
Предположительно, если верить наводке, решение в следующем подходе, по аналогии:
    If ThisComponent.getUndoManager() _
     .getCurrentUndoActionTitle() = "Rename Sheet" Then ...

Вероятно, одним из ActionTitle и будет добавление листа. Нет возможности проверить.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

Добрый день! Указанные выше ответы не (в полной мере) учитывают, что наряду с Undo надо обрабатывать также и Redo.
Можно, например, следующим образом запретить изменение числа листов документа. Для старта выполнить процедуру SetupListener, для завершения обработки ClearListener. На заголовок события (getCurrentUndoActionTitle в #3) вряд ли стоит ориентироваться, так как он зависит от локализации.
Global oListener As Object
Global nSheets As Long     ' охраняемое число листов документа
   
Sub SetupListener()
   oListener = createUnoListener("Undo_", "com.sun.star.document.XUndoManagerListener")
   ThisComponent.UndoManager.addUndoManagerListener(oListener)
   nSheets=ThisComponent.Sheets.Count
End Sub

Sub ClearListener
   ThisComponent.UndoManager.removeUndoManagerListener(oListener)
End Sub

Sub Undo_undoActionAdded(oEvent)
  With oEvent.source
    If Ubound(.AllUndoActionTitles)>=0 Then
      If .CurrentUndoActionTitle<>"" Then  ' Undo!
        If nSheets<>ThisComponent.Sheets.Count Then
          Msgbox "В этом документе нельзя удалять и добавлять листы", MB_ICONEXCLAMATION
          ThisComponent.UndoManager.Undo
          nSheets=ThisComponent.Sheets.Count  ' для предупреждения зацикливания
        End If 
      End If
    End If   
  End With 
End Sub

' мусор
Sub Undo_actionUndone(oEvent)
End Sub

Sub Undo_actionRedone(oEvent)
End Sub

Sub Undo_allActionsCleared(oEvent)
End Sub

Sub Undo_cancelledContext(oEvent)
End Sub

Sub Undo_disposing(oEvent)
End Sub

Sub Undo_enteredContext(oEvent)
End Sub

Sub Undo_enteredHiddenContext(oEvent)
End Sub

Sub Undo_leftContext(oEvent)
End Sub

Sub Undo_leftHiddenContext(oEvent)
End Sub

Sub Undo_redoActionsCleared(oEvent)
End Sub

Sub Undo_resetAll(oEvent)
End Sub
Владимир.

eeigor

#5
Цитата: sokol92 от 14 декабря 2020, 18:46наряду с Undo надо обрабатывать также и Redo
Возможно, хотя по той ссылке выше сказали: "Apparently the undo/redo doesn't add a new undoAction". Не проверял ни я, ни они.
Решение понятно. Надеюсь, что и я здесь поучаствовал...
sokol92, вы может все эти локализованные ActionTitles назвать? Не могу найти, где это есть.
При добавлении листа: ActionTitle = "Вставить лист"|"Добавить лист"
sokol92, ваш код не позволяет вставить лист, но не препятствует его добавлению в конец списка.

Другие звучат так: "Переименовать лист", "Переместить листы", "Скрыть лист", "Показать лист", "Установить защиту листа", "Снять защиту листа", "Цветной ярлык"; диапазоны ячеек: "Ввод", "Удалить", "Копировать", "Переместить", "Объединить" и т. д.

Зачем только это локализовали, непонятно...

Эта тема оказалась по-своему интересной и новой для меня.

Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community