Как прервать закрытие документа?

Автор timur0, 29 ноября 2012, 19:33

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

timur0

Пользователь редактирует документ и должен заполнить определенные поля. В некоторый момент он решает закрыть документ. Тут должно происходить следующее:
1. Перехватить команду на закрытие - умею (событие OnPrepareClosing)
2. Проверить, что все что надо заполнено - умею
3. В случае, если не заполнено, сообщить об этом и не закрывать документ; если же заполнено - сохранить и закрыть документ.

Вот последний пункт - как? Как прервать перехваченное закрытие документа?

(желательно, чтобы решение работало для ОО 3.0)

Hasim

Цитата: timur0 от 29 ноября 2012, 18:331. Перехватить команду на закрытие - умею (событие OnPrepareClosing)
Как вы его перехватываете?
Пример, если не трудно.

timur0

Можно в интерфейсе Open Office: меню Сервис/Настройка... закладка События - там выбираешь, локальная привязка (к текущему документу) или глобальная.

Можно это же делать программно, вот пример кода:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub AttachBasicMacroToGlobalEvent(EventName as String, SubPath as String)
Dim PropValue(1) as new com.sun.star.beans.PropertyValue
Dim DocEvents As Object
PropValue(0).Name = "EventType"
PropValue(0).Value = "Script"
PropValue(1).Name = "Script"
PropValue(1).Value = "vnd.sun.star.script:" & SubPath & "?language=Basic&location=application"

oGEB = CreateUnoService("com.sun.star.frame.GlobalEventBroadcaster")
oEvents = oGEB.getEvents()

oEvents.ReplaceByName(EventName, PropValue())
End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub AttachBasicMacroToLocalEvent(oDocument as Object, EventName as String, SubPath as String)
Dim PropValue(1) as new com.sun.star.beans.PropertyValue
Dim DocEvents As Object
PropValue(0).Name = "EventType"
PropValue(0).Value = "Script"
PropValue(1).Name = "Script"
PropValue(1).Value = "vnd.sun.star.script:" & SubPath & "?language=Basic&location=application"

oEvents = oDocument.getEvents()
oEvents.ReplaceByName(EventName, PropValue())
End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub MainG()
' вешаем глобальный перехват на сохранение документа, "Notal System.Temp.BeforeSave" - моя библиотека, модуль, процедура
Dim EventName As String
EventName = "OnSave"
AttachBasicMacroToGlobalEvent(EventName, "Notal System.Temp.BeforeSave") 

Dim oDoc as object
' вешаем перехват на закрытие конкретного документа (текущего в момент вызова этой процедуры)
oDoc = ThisComponent
EventName = "OnPrepareUnload"
AttachBasicMacroToLocalEvent(oDoc, EventName, "Notal System.Temp.BeforeClose") 
End Sub


Процедуры должны содержаться в библиотеке на компе пользователя
(Open Office 3.0 и старше, м.б. работает и в более ранних версиях)

Hasim

Так вы не "перехватываете событие", а просто "назначаете событию макрос".
А вам нужно именно "перехватить событие", то есть "обработать событие" самостоятельно (вместо стандартной обработки программой/ОС).

timur0

Цитата: Hasim от 30 ноября 2012, 11:22А вам нужно именно "перехватить событие", то есть "обработать событие" самостоятельно

Вы совершенно правы! И как это сделать?

Hasim

Перехватчик событий для OOoBasic - Listener.

Цитата: timur0 от 30 ноября 2012, 11:25И как это сделать?

Не знаю. И, похоже, никто не знает, даже Питоньяк.
По крайней мере у него про это нигде не написано.

На иностранных форумах я решение тоже не встречал.
(Может быть, плохо искал, попробуйте поспрашивать на этих форумах.)

Hasim


timur0

Да я уже третий день смотрю в эту сторону - поймать событие получается (привязывается к конкретному документу):

Global oCloseListener as Object

''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function install_closeListener
oCloseListener = CreateUnoListener("ListenCloseSub_", "com.sun.star.util.XCloseListener")
thisComponent.addCloseListener(oCloseListener)
End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function ListenCloseSub_queryClosing(oEvent, GetsOwnership as boolean)
msgbox "!!!"
End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function ListenCloseSub_disposing(oEvent)
End Function


засада в том, что надо как-то программно вызвать исключение CloseVetoException, но вот как это сделать?


timur0

Не, не работает. Само закрытие документа отменить не получается. В этом смысле в Ms Office все намного логичней и проще.

Hasim

#10
Цитата: timur0 от  4 декабря 2012, 12:58Не, не работает. Само закрытие документа отменить не получается.
И не должно получаться. Там же ясным нерусским языком написано [Impossible] Cancel close document - Невозможно отменить закрытие документа.
В смысле - Невозможно отменить закрытие документа из OOoBasic.
Из JAVA теоретически возможно, т.к. в JAVA в принципе можно "выбросить" (throw) любое исключение, в том числе CloseVetoException, а OpenOffice поддерживает макросы (программы) на JAVA, но это только теоретически.
Решения на JAVA я не видел, но и специалистов по JAVA в OpenOffice крайне мало.
Хотя это странно, родным языком для OpenOffice является именно JAVA, ведь даже самое полное и подробное "Руководство по программированию в OpenOffice.org" содержит примеры по программированию исключительно на JAVA.
OOoBasic является просто крайне упрощенной надстройкой для массовых пользователей с синтаксисом похожим на VBA.

А для решения данной задачи, например в Windows, есть кое-какие обходные пути, как написал ms777, на которого ссылаются в той ссылке, которую я привел.
Но для этого нужно знать подробности вашей задачи.