Loading a form without stopping execution

Hello,

I’m working on a macro, where a dialogbox is shown when you click on a button in Writer toolbar.
The problem is that the combo box is populated with data retrieved from the database, so the dialog box may take some time to show. In the meantime, the user doesn’t know what’s going on. He may even think that the click didn’t work, so he may try to click a second time.

I created another dialog called frmLoader, but when this dialog is executed, nothing else is executed until I close it… So it’s not working as I expected.

Could you please tell me if there’s a simple way to display something while the data is retrieved and before the dialog box shows ?

You can use Statusbar

Sub waitAmoment 'show some progress in statusbar
	dim oDoc as object, oStatus as object
	oDoc=ThisComponent
	oStatus=oDoc.CurrentController.StatusIndicator
	with oStatus
		.start("Wait a moment", 2) 'initialization of progress bar
		.Value=1
	end with
	
	rem your code
	wait 1500
	
	with oStatus
		.end
		.reset
	end with
End Sub

Thanks for your answer.
It works great.

However it’s not what I had in mind because not everybody will have a look at the bottom of the page…

That’s why I wanted to display something in the middle of the screen, with a loader spinning or something, at least a big message saying “Please wait…”

Isn’t it posible to do something like this ?

Try the property Visible:

	DialogLibraries.LoadLibrary("mylib")
	oDialog=CreateUnoDialog(DialogLibraries.mylib.mydialog)
	oDialog.Visible=true
	rem YOUR CODE
	if oDialog.execute=1 then
	rem ...
	end if

And you can also set the macro to the button OK instead of method .execute

Thanks, I think I’m getting closer.

But I dodn’t fully understand your code…

oDialog.Visible=true

will display the form without stopping the execution, right ?

But I don’t understand :

if oDialog.execute=1 then

From what I could understand in my test, when I close the button on my “loader dialog”, the code restart after this “if”.

But in my case I don’t want to display the close button on this loader dialog, because its goal is to show something while the data is retrieved. So I don’t want the user to be able to close it himself.

Instead, I want this dialog to be closed after the data is retrieved, so I guess I will have to do :

oDialog.Visible=true

?

Actually I made a test and here’s what I did :

	DialogLibraries.LoadLibrary("Standard")
	
	oDialogLoader = CreateUnoDialog(DialogLibraries.Standard.frmLoader)
	oDialogLoader.Visible = True
	
   	oDialog = CreateUnoDialog(DialogLibraries.Standard.frmInsertGlossary)
   	oGlossaryList = oDialog.getControl("cmbGlossaryList")
   	
   	EmptyComboBox(oGlossaryList)
   	sGlossaryCodes = GetGlossaryCodesFromDatabase()
   	If UBound(sGlossaryCodes) = 0 Then
   		oDialogLoader.Visible = False
   		MsgBox "Impossible d'insérer un élément du glossaire !" & vbCrLf & "Le glossaire est vide...", vbExclamation, "Impossible de continuer"
   	Else
   		For iNbItem = 0 to UBound(sGlossaryCodes)
	   		oGlossaryList.addItem(sGlossaryCodes(iNbItem), iNbItem)
	   	Next iNbItem
	   	HideLoader
	   	oDialogLoader.Visible = False
	   	oDialog.Execute
   	End If

And it works exactly as I expected !

Ideally it would be ince to prevent any action at all while the loader is there, but for now it will be enough.

Thanks a lot for your help !!!

I have two last questions :

In my loader dialog, I set the property “Title bar” to “No”, and the title bar (with close button) is still displayed… Any idea why ? And how I could get rid of it ? Maybe in the code ?

And I added a spinning gif as an image inside the dialog. I can see the image while in design mode. But when the code is executed, no image is displayed, only the text that is inside a label. Is it normal ? Is it something to be done to see this spinning image ?

if oDialog.execute=1 is for OK button in dialog, it isn’t necessary :-).
Small example dlg.odt (19.9 kB)

I don’t see the property Title bar. Can you modify my uploaded example?

I don’t know if animated images are allowed in dialogs.You can try Options > Accessibility to allow the animated images, but maybe it hasn’t effect to image in dialog.

Title is not displayed but the close button remains there at the top right of the dialog… so anyone can click on it to close it, which I don’t want…

About the animated gif, I did as you said but you were right, it doesn’t affect images in dialog.
This is less important, I will simply remove the image and only keep the text : “Please wait while retrieving data…”

It is possible to make the Dialog only via macro, and if the listener for Dialog window isn’t set, then the window is shown and closing cross in Title bar isn’t functional.
But still it is possible to run some commands from Menu or press some keyboard shortcut, so the macro could be disturbed.


Run macro Main, it will show the dialog. You can select some item from listbox and then the dialog will be closed. Now, the dialog is closed automatically after 5 seconds.
For activation the closing cross uncomment the line: '.addTopWindowListener

global DLG as object

Sub Main
	showDlg
	rem SOME CODE
	wait 5000 : DLG.dispose
End Sub

Sub disposeDLG 'if you will do some error then the dialog stays shown, so dispose it "handly"
	DLG.dispose
End Sub

Sub showDlg 'show dialog window
	dim oDoc as object, oDlgModel as object, oSize as new com.sun.star.awt.Rectangle, arr()
	oDoc=ThisComponent
	if NOT isNull(DLG) then DLG.dispose 'dialog exists so close it
	DLG=CreateUnoService("com.sun.star.awt.UnoControlDialog")
	oDlgModel=CreateUnoService("com.sun.star.awt.UnoControlDialogModel")
	with oDlgModel
		.Width=200
		.Height=100
	end with
	oSize=oDoc.CurrentController.Frame.ContainerWindow.GetPosSize 'size of LibreOffice window
	with DLG
		.setModel(oDlgModel)
		.Visible=false
		.createPeer(CreateUnoService("com.sun.star.awt.Toolkit"), oDoc.CurrentController.Frame.ContainerWindow) 'create Dialog
		.setPosSize((oSize.Width-DLG.Size.Width)/2, (oSize.Height-DLG.Size.Height)/2, 0, 0, 3) 'center dialog in Libre window
		rem add items to dialog
		.DesignMode=true 'sometimes it was a little bit faster for me
		arr=array("I was at work", "It was nice day", "Because the depression was small") 'items to Listbox
		insertListbox(DLG, "List1", 80, 45, 10, 10, arr)
		.DesignMode=false
		'.addTopWindowListener(CreateUnoListener("DLG_", "com.sun.star.awt.XTopWindowListener")) 'it is possible to add listener for dialog window
		.Visible=true 'show dialog
	end with
End Sub

Function insertListbox(oDlg as object, sName$, width%, height%, posX%, posY%, aList() ) 'create Listbox
	on local error goto bug
	dim o as object
	o=oDlg.Model.createInstance("com.sun.star.awt.UnoControlListBoxModel") 'also from: com.sun.star.form.component.
	with o
		.Name=sName
		.Width=width
		.Height=height
		.PositionX=posX
		.PositionY=posY : 
		.StringItemList=aList()
		.SelectedItems=array(1)
		.DropDown=true
	end with
	oDlg.Model.insertByName(sName, o)
	o=oDlg.getControl(sName)
	o.addActionListener(CreateUnoListener(sName & "Action_", "com.sun.star.awt.XActionListener")) 'action listener
	exit function
bug:
	bug(Erl, Err, Error, "insertListbox")
End Function

rem listeners for action
Sub List1Action_actionPerformed(optional oEvt as object)
	msgbox oEvt.Source.SelectedItemPos & " : " & oEvt.Source.SelectedItem
	DLG.dispose
End Sub

Sub List1Action_disposing
End Sub

rem listeners for dialog window
Sub DLG_windowClosing 'closing cross in Title bar, or Esc
	DLG.dispose
End Sub

Sub DLG_disposing
End Sub

Sub DLG_windowOpened
End Sub

Sub DLG_windowClosed
End Sub

Sub DLG_windowMinimized
End Sub

Sub DLG_windowNormalized
End Sub

Sub DLG_windowActivated
End Sub

Sub DLG_windowDeactivated
End Sub
1 Like

Thanks a lot for your help !