Listener for a spreadsheet rename event
Listener for a spreadsheet rename event
Hello,
is there an event listener in the UNO API which is fired when the user renames a calc spreadsheet interactively? I can't find one.
Regards
Ralf
is there an event listener in the UNO API which is fired when the user renames a calc spreadsheet interactively? I can't find one.
Regards
Ralf
LibreOffice 3.5 on Ubuntu 12.04
- Charlie Young
- Volunteer
- Posts: 1559
- Joined: Fri May 14, 2010 1:07 am
Re: Listener for a spreadsheet rename event
Do you mean rename the document, or rename a sheet within it?Ralf wrote:Hello,
is there an event listener in the UNO API which is fired when the user renames a calc spreadsheet interactively? I can't find one.
Regards
Ralf
Apache OpenOffice 4.1.1
Windows XP
Windows XP
Re: Listener for a spreadsheet rename event
I ment a single sheet within the calc document.
LibreOffice 3.5 on Ubuntu 12.04
- Charlie Young
- Volunteer
- Posts: 1559
- Joined: Fri May 14, 2010 1:07 am
Re: Listener for a spreadsheet rename event
I tried XPropertyChangeListener and XVetoableChangeListener, which looked promising, but I didn't have any luck there. An XModifyListener attached to the document is triggered by renaming a sheet, but by lots of other things as well, so that was a bust.Ralf wrote:I ment a single sheet within the calc document.
But, if undo is enabled, we can attach an XUndoManagerListener to ThisComponent.UndoManager, and then check newly added undo actions for "Rename Sheet."
Here I'm just displaying the old name and the new one. As usual, all the listener methods have to be implemented, even though I'm only using one of them for now.
Code: Select all
Global oListener As Object
Sub SetupListener()
Dim oDoc As Object
oDoc = ThisComponent
oListener = createUnoListener("Undoer_", "com.sun.star.document.XUndoManagerListener")
oDoc.UndoManager.addUndoManagerListener(oListener)
End Sub
Sub Undoer_undoActionAdded(oEvent)
Dim oDoc As Object
Dim oSheet As Object
Dim UnDoMgr As Object
Dim oldName As String
Dim newName As String
oDoc = ThisComponent
oSheet = oDoc.CurrentController.ActiveSheet
UnDoMgr = oDoc.getUndoManager()
If UnDoMgr.getCurrentUndoActionTitle() = "Rename Sheet" Then
UnDoMgr.removeUndoManagerListener(oListener)
UnDoMgr.undo()
oldName = oSheet.getName()
UnDoMgr.redo()
newName = oSheet.getName()
MsgBox(oldName)
MsgBox(newName)
UnDoMgr.addUndoManagerListener(oListener)
EndIf
End Sub
Sub Undoer_actionUndone(oEvent)
End Sub
Sub Undoer_actionRedone(oEvent)
End Sub
Sub Undoer_allActionsCleared(oEvent)
End Sub
Sub Undoer_cancelledContext(oEvent)
End Sub
Sub Undoer_disposing(oEvent)
End Sub
Sub Undoer_enteredContext(oEvent)
End Sub
Sub Undoer_enteredHiddenContext(oEvent)
End Sub
Sub Undoer_leftContext(oEvent)
End Sub
Sub Undoer_leftHiddenContext(oEvent)
End Sub
Sub Undoer_redoActionsCleared(oEvent)
End Sub
Sub Undoer_resetAll(oEvent)
End Sub
Sub ClearListener
Dim oDoc As Object
Dim UnDoMgr As Object
oDoc = ThisComponent
UnDoMgr = oDoc.getUndoManager()
UnDoMgr.removeUndoManagerListener(oListener)
End Sub
Apache OpenOffice 4.1.1
Windows XP
Windows XP
Re: Listener for a spreadsheet rename event
You remove the UndoManagerListener in Sub Undoer_undoActionAdded() just because you execute UnDoMgr.undo() to get oldName for the MsgBox. For a "normal" application, UnDoMgr.removeUndoManagerListener() would not be required.
Is that assumption correct?
Is that assumption correct?
LibreOffice 3.5 on Ubuntu 12.04
- Charlie Young
- Volunteer
- Posts: 1559
- Joined: Fri May 14, 2010 1:07 am
Re: Listener for a spreadsheet rename event
Nice catch. I put the remove then add back, in as a precaution, because I feared a race condition. I never bothered testing it without the remove/add, but now it seems it isn't required anyway. I don't think it hurts much, but if it isn't necessary, don't bother. Apparently the undo/redo doesn't add a new undoAction.Ralf wrote:You remove the UndoManagerListener in Sub Undoer_undoActionAdded() just because you execute UnDoMgr.undo() to get oldName for the MsgBox. For a "normal" application, UnDoMgr.removeUndoManagerListener() would not be required.
Is that assumption correct?
Apache OpenOffice 4.1.1
Windows XP
Windows XP
Re: Listener for a spreadsheet rename event
Code: Select all
If UnDoMgr.getCurrentUndoActionTitle() = "Rename Sheet" Then
...
EndIf
There is still one issue left. You define the undo action title as "Rename Sheet". With my German installaton the title is defined as "Tabelle umbenennen". Is there a (UNO API internal) possibility to suppress the internationalization, and force English message strings?
LibreOffice 3.5 on Ubuntu 12.04
Re: Listener for a spreadsheet rename event
Hallo Ralf
Warum änderst du nicht "Rename Sheet" zu "Tabelle umbenennen" ?
Why don't you change "_______''______" to "__________'''______" ?
Edit:Translate..
Karolus
Warum änderst du nicht "Rename Sheet" zu "Tabelle umbenennen" ?
Why don't you change "_______''______" to "__________'''______" ?
Edit:Translate..
Karolus
Last edited by karolus on Mon Nov 05, 2012 11:43 pm, edited 1 time in total.
Libreoffice 7.4 on Debian 12 (Bookworm) (on RaspberryPI4)
Libreoffice 7.6 flatpak on Debian 12 (Bookworm) (on RaspberryPI4)
Re: Listener for a spreadsheet rename event
Hello Karolus,
(Weil ich dieses Projekt auch Anderen zur Verfügung stellen werde. Zur Not kann ich entsprechende Derivate kompilieren, würde allerdings eine elegantere Lösung vorziehen.)
because I have planned to provide this code to others. I could compile a derivate for every language but I prefer an elegant solution.
Ralf
(Weil ich dieses Projekt auch Anderen zur Verfügung stellen werde. Zur Not kann ich entsprechende Derivate kompilieren, würde allerdings eine elegantere Lösung vorziehen.)
because I have planned to provide this code to others. I could compile a derivate for every language but I prefer an elegant solution.
Ralf
Last edited by Ralf on Tue Nov 06, 2012 3:40 pm, edited 1 time in total.
LibreOffice 3.5 on Ubuntu 12.04
- Hagar Delest
- Moderator
- Posts: 32668
- Joined: Sun Oct 07, 2007 9:07 pm
- Location: France
Re: Listener for a spreadsheet rename event
Please remember that this is an English forum. Your discussion may be of interest for other users. You could at least give a translation in English.
Else, there is the German forum, you can make a thread over there and link to this one.
Else, there is the German forum, you can make a thread over there and link to this one.
LibreOffice 7.6.2.1 on Xubuntu 23.10 and 7.6.4.1 portable on Windows 10
Re: Listener for a spreadsheet rename event
Here is an other solution than using 'XUndoManagerListener' with its localised 'UndoManagerEvent.UndoActionTitle'.
This solution maintains a local variable 'Base::activeSheetName'. This variable is updated with every 'XActivationEventListener' event and it is evaluated with every 'XModifyListener' event to detect a sheet-rename. I think there is no big difference in using 'XUndoManagerListener' instead of 'XModifyListener', because they seem to fire mostly at the same occasions.
Here is an example code implementation in C++, I skipped the declaration sections.
Class Base connects to Office Calc or opens an instance of Calc, it instantiates and registers the required listeners, and provides the member functions to update local variable Base::activeSheetName:
ActivationEventListener detects a change of the actve sheet and updates the active sheet in class Base accordingly:
ModifyListener calls Base::renameSheet() with every invocation and lets class Base decide, whether this event was a sheet-rename or not:
This solution maintains a local variable 'Base::activeSheetName'. This variable is updated with every 'XActivationEventListener' event and it is evaluated with every 'XModifyListener' event to detect a sheet-rename. I think there is no big difference in using 'XUndoManagerListener' instead of 'XModifyListener', because they seem to fire mostly at the same occasions.
Here is an example code implementation in C++, I skipped the declaration sections.
Class Base connects to Office Calc or opens an instance of Calc, it instantiates and registers the required listeners, and provides the member functions to update local variable Base::activeSheetName:
Code: Select all
Base::Base(OUString fileURL) :
xActivationEventListener(static_cast<XActivationEventListener*>(new ActivationEventListener(this))),
xModifyListener(static_cast<XModifyListener*>(new ModifyListener(this))),
xUndoManagerListener(static_cast<XUndoManagerListener*>(new UndoManagerListener())),
xComponentContext(bootstrap(), UNO_QUERY_THROW),
xServiceManager(xComponentContext->getServiceManager(), UNO_QUERY_THROW),
xDesktop(xServiceManager->createInstanceWithContext(OUString::createFromAscii("com.sun.star.frame.Desktop"), xComponentContext), UNO_QUERY_THROW),
xComponentLoader(xDesktop, UNO_QUERY_THROW),
xComponent(xComponentLoader->loadComponentFromURL(fileURL, OUString::createFromAscii("_blank"), 0, Sequence<PropertyValue>()), UNO_QUERY_THROW),
xSpreadsheetDocument(xComponent, UNO_QUERY_THROW),
xModel(xSpreadsheetDocument, UNO_QUERY_THROW),
xSpreadsheetView(xModel->getCurrentController(), UNO_QUERY_THROW),
xActivationBroadcaster(xSpreadsheetView, UNO_QUERY_THROW),
xModifyBroadcaster(xSpreadsheetDocument, UNO_QUERY_THROW),
xUndoManagerSupplier(xSpreadsheetDocument, UNO_QUERY_THROW)
{
cout << "Constructor" << endl;
xActivationBroadcaster->addActivationEventListener(xActivationEventListener);
xModifyBroadcaster->addModifyListener(xModifyListener);
xUndoManagerSupplier->getUndoManager()->addUndoManagerListener(xUndoManagerListener);
activeSheet(xSpreadsheetView->getActiveSheet());
}
void Base::activeSheet(const Reference<XSpreadsheet>& sheet)
{
xActiveSheet = sheet;
Reference<XNamed> xNamed(sheet, UNO_QUERY_THROW);
activeSheetName = xNamed->getName();
cout << "Base::activeSheet: " << activeSheetName << endl;
}
void Base::renameSheet()
{
Reference<XNamed> xNamed(xActiveSheet, UNO_QUERY_THROW);
if (activeSheetName != xNamed->getName()) {
cout << "Base::renameSheet: Old name: " << activeSheetName << " New name: " << xNamed->getName() << endl;
activeSheetName = xNamed->getName();
}
}
Code: Select all
ActivationEventListener::ActivationEventListener(Base* b)
{
base = b;
cout << "ActivationEventListener::ActivationEventListener: Constructor" << endl;
}
ActivationEventListener::~ActivationEventListener()
{
cout << "ActivationEventListener::~ActivationEventListener: Destructor" << endl;
}
void SAL_CALL ActivationEventListener::activeSpreadsheetChanged(const ActivationEvent& event) throw (RuntimeException)
{
cout << "ActivationEventListener::activeSpreadsheetChanged: " << "ActivationEvent" << endl;
base->activeSheet(event.ActiveSheet);
}
void SAL_CALL ActivationEventListener::disposing(const EventObject& event) throw (RuntimeException)
{
cout << "ActivationEventListener::disposing: " << "Object listened to will be disposed." << endl;
}
Code: Select all
ModifyListener::ModifyListener(Base* b)
{
base = b;
cout << "ModifyListener::ModifyListener: Constructor" << endl;
}
ModifyListener::~ModifyListener()
{
cout << "ModifyListener::~ModifyListener: Destructor" << endl;
}
void SAL_CALL ModifyListener::modified(const EventObject& event) throw (RuntimeException)
{
cout << "ModifyListener::modified: " << "EventObject" << endl;
base->renameSheet();
}
void SAL_CALL ModifyListener::disposing(const EventObject& event) throw (RuntimeException)
{
cout << "ModifyListener::disposing: " << "Object listened to will be disposed." << endl;
}
LibreOffice 3.5 on Ubuntu 12.04