Control klonen bzw. per Makrocode erstellen

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

Steffan
****
Beiträge: 125
Registriert: Mi, 21.06.2006 10:07
Wohnort: Dresden

Control klonen bzw. per Makrocode erstellen

Beitrag von Steffan »

Hallo zusammen,

gibt es eigentlich eine Möglichkeit ein Control eines Dialogfeldes (in meinem Fall CommandButton und ComboBox) zu kopieren und an anderer Stelle zu positionieren? (Für FormularControls habe ich die Methode 'CreateClone' gefunden, aber schon das ändern der Position ist mir nicht gelungen, aber wie gesagt brauche ich das ganze für DialogControls!)
Oder wie kann man alternativ dazu programmgesteuert (Starbasic) ein Control in einem Dialog erstellen und dieses dann positionieren?
Wäre schön, wenn mir da jemand helfen könnte.

Beste Grüße,
Steffan.
Toxitom
********
Beiträge: 3769
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Re: Control klonen bzw. per Makrocode erstellen

Beitrag von Toxitom »

Hey Steffan,

da du den kompletten Dialog per Code erzeugen kannst, ist natürlcih auch das "Klonen" eines Controls möglich. Nur, der Weg ist eben komplett anders. Dann musst du alles per Code erzeugen.
Nimm einfach ein Beispiel und schau dir an, wie so etwas funktioniert. Ich empfehle dir die Erweiterung "Datenmaske", die dynamisch eine Eingabe-Dialogmaske erzeugt. Da kannst du entsprechend lernen.
Die Erweiterung findest du ->hier, und zwar rechts das "CalcAddon Datenmaske". Eine Dokumentation ist auch dabei :-)

Viele Grüße
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Steffan
****
Beiträge: 125
Registriert: Mi, 21.06.2006 10:07
Wohnort: Dresden

Re: Control klonen bzw. per Makrocode erstellen

Beitrag von Steffan »

Hallo Thomas,

besten Dank für den Link, ich werde das gleich ausprobieren. Allerdings erzeugst Du in dem Beispiel ja den Dialog vor dem Anzeigen. Nach Aufruf bleibt deine Datenmaske statisch. Ist auch ein ändern 'on the fly' möglich?
Hintergrund ist folgender: Beim Speichern eines Dokuments erfolgt automatisch ein Eintrag in eine Dokument-DB. Vorher hat der Benutzer die Möglichkeit in einem Dialog eine Projekt- und Adresszuordnung zu treffen bzw. eine vorgeschlagene zu ändern und ergänzende Infos zum Dokument einzugeben (funktioniert alles soweit).
Nun soll auch die Zuordnung zu mehreren Adressen (z.B. Dokumentverteiler) möglich sein. in diesem Fall soll der Nutzer im geöffneten Dialog auf einen Button "mehr ..." klicken, die Combobox mit den Adressen soll kopiert und unter der vorhandenen positioniert werden (ebenso der Button "mehr ...") der Dialog soll um Combobox-Höhe und Abstand größer werden.
Denkst Du das könnte funktionieren? Damit wir uns recht verstehen: Ich will von Dir keine Lösung sondern nur eine Meinung ob der Ansatz realisierbar ist.

Besten Dank im Vorraus,
Steffan.
Toxitom
********
Beiträge: 3769
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Re: Control klonen bzw. per Makrocode erstellen

Beitrag von Toxitom »

Hey Steffan,

ja, das ist realiserbar. Du kannst ja das Modell des Dialoges jederzeit verändern - und damit auch den Dialog. Evt. kanns tdu das sogar über die Step-Funktion lösen, d.h. der Dialog hat verschiedene Ebeen, die Controls liegen auf einer Ebene und sind auch nur hier sichtbar (Ausnahme: Ebene 0 - die sind immer sichtbar).
Zur Not erstellt su den Dialog eben neu - d.h. beneden des alten, einblenden des neuen. Das geht so schnell, dass es für den Benutzer kam ein Unterschied wäre.

Gruss
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Steffan
****
Beiträge: 125
Registriert: Mi, 21.06.2006 10:07
Wohnort: Dresden

Re: Control klonen bzw. per Makrocode erstellen

Beitrag von Steffan »

Hallo zusammen,

es ist mir dank der Vorlage von Thomas gelungen einen dynamischen Dialog zu erstellen, der soweit (zumindest erst einmal mit geklonten Buttons) in der Grundfunktionalität prima klappt. Für alle, die es interessiert, gibts hier einen Beispielcode. Was noch nicht funktioniert ist das Fixieren der Position des Dialogfensters. Aus mir unerfindlichen Gründen wird der Dialog nach Erzeugendes ersten Klons verschoben. Vielleicht hat dazu noch jemand eine Idee?

Beste Grüße,
Steffan.

Code: Alles auswählen

dim oDlg as object

Sub CreateDialog
	dim oDlgM as Object 	'das Modell des Dialogs
	dim oMod as Object 		'nimmt jeweils das Modell der Objekte auf
REM das Dialogmodell erzeugen
	oDlgM = createUnoService("com.sun.star.awt.UnoControlDialogModel")
REM Eigenschaften zuweisen
	with oDlgM
		.setPropertyValue("PositionX", 30)
		.setPropertyValue("PositionY", 30)
		.setPropertyValue("Width", 75)
		.setPropertyValue("Height", 100)
		.setPropertyValue("Title", "Dynamischer Dialog")
	end with
REM Textlabel erzeugen
	oMod = oDlgM.createInstance("com.sun.star.awt.UnoControlFixedTextModel")
	with oMod
		.setPropertyValue("Name", "Text2")
		.setPropertyValue("PositionX", 10)
		.setPropertyValue("PositionY", 10)
		.setPropertyValue("Width", 55)
		.setPropertyValue("Height", 20)
		.setPropertyValue("Label", "Klick Klon-Button!")
	end with
	oDlgM.insertByName("Text2", oMod)
	
REM Button erzeugen
	oMod = oDlgM.createInstance("com.sun.star.awt.UnoControlButtonModel")
	with oMod
		.setPropertyValue("Name", "btn")
		.setPropertyValue("PositionX", 5)
		.setPropertyValue("PositionY", 45)
		.setPropertyValue("Width", 65)
		.setPropertyValue("Height", 20)
		.setPropertyValue("Label", "Abbruch" )
	end with
	oDlgM.insertByName("btn", oMod)

REM den eben erzeugten Button klonen (vor der Anzeige des Dialogs)
	oMod = oMod.CreateClone
	oMod.Setpropertyvalue("PositionY",70)
	oMod.Setpropertyvalue("Name","btnClone")
	oMod.SetpropertyValue("Label", "Klon-Button"
	oDlgM.insertByName("btnClone", oMod)

REM Dialog ertellen 
	oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog")
	oDlg.setModel(odlgM)
	
REM Listener für Abbruch-Button
	oListenerClone = CreateUnoListener("btn_", "com.sun.star.awt.XActionListener")
	oControl = oDlg.getControl("btn")
	oControl.addActionListener(oListenerClone)
	
REM Listener für den geklonten Button
	oListenerClone = CreateUnoListener("btnClone_", "com.sun.star.awt.XActionListener")
	oControl = oDlg.getControl("btnClone")
	oControl.addActionListener(oListenerClone)
	
REM Dialog anzeigen
	oWin = createUnoService("com.sun.star.awt.Toolkit")
	oDlg.createPeer(oWin, null)
	oDlg.execute
end sub

'Aktion bei Klick auf 'Abbrechen'
sub btn_actionPerformed(oEvent)
	oDlg.EndExecute
End Sub

'Aktion bei Klick auf einen der geklonten Buttons
sub btnClone_actionPerformed(oEvent)
REM Button klonen bei angezeigtem Dialog
	with oDlg.Model
	' Dialoghöhe vergrößern
		.height= .height + 25
	' Button der geklont werden soll, hat den höchsten Index aller Controls im Dialog
		iMax=ubound(.controlModels)
		oMod2=.ControlModels(iMax).CreateClone
	' Eigenschaften des neuen Buttons anpassen
		oMod2.Setpropertyvalue("PositionY",.Height -30)
		oMod2.Setpropertyvalue("Name","btnClone" & CStr(iMax))
		oMod2.SetpropertyValue("Label", "Klon-Button " 	& CStr(iMax))
	'Button in Dialog einfügen
		.InsertByName("btnClone" & CStr(iMax), oMod2)
	end with
	'Listener für geklonten Button
	oListenerClone = CreateUnoListener("btnClone_", "com.sun.star.awt.XActionListener")
	oControl = oDlg.getControl("btnClone" & cStr(iMax))
	oControl.addActionListener(oListenerClone)
End Sub
Toxitom
********
Beiträge: 3769
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Re: Control klonen bzw. per Makrocode erstellen

Beitrag von Toxitom »

Hallo Stefan,
Was noch nicht funktioniert ist das Fixieren der Position des Dialogfensters. Aus mir unerfindlichen Gründen wird der Dialog nach Erzeugendes ersten Klons verschoben.
Hmm, das ist nicht ganz richtig ;-) Der zuerst aufgerufene Dialog "sitzt" nicht richtig - beim ersten Klonen wird er auf die Stelle geschoben, auf die er hingehört - und die du selbst als Position fixiert hast -> siehe:

Code: Alles auswählen

with oDlgM
      .setPropertyValue("PositionX", 30)
      .setPropertyValue("PositionY", 30)
Und dort genau wird der Dialog plaziert.
Warum er allerdings am Anfang in der Mitte plziert wird, kann ich dir aktuell auch nicht sagen.

Gruß
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Steffan
****
Beiträge: 125
Registriert: Mi, 21.06.2006 10:07
Wohnort: Dresden

Re: Control klonen bzw. per Makrocode erstellen

Beitrag von Steffan »

Hallo Thomas,

ich hab noch mal ein bißchen geschraubt und die Sache mit der Position gelöst. Und zwar funktioniert es, indem NACH Erstellen und VOR der Anzeige des Dialoges im Dialogmodel die Positionseigeschaft gesetzt wird.

Code: Alles auswählen

...
REM Dialog anzeigen
	oDlg.Model.PositionX=50
	oDlg.Model.Positiony=50
	oWin = createUnoService("com.sun.star.awt.Toolkit")
	oDlg.createPeer(oWin, null)
	oDlg.execute
end sub
Dementsrechend kann dies Posionzuweisung am Anfang entfallen.

Beste Grüße,
Steffan

Zum Abschluss noch der vollständige Code:

Code: Alles auswählen

dim oDlg as object
Sub CreateDialog
	dim oDlgM as Object 	'das Modell des Dialogs
	dim oMod as Object 		'nimmt jeweils das Modell der Objekte auf
	dim iDlgH as integer 	'Höhe des Dialoges
REM das Dialogmodell erzeugen
	oDlgM = createUnoService("com.sun.star.awt.UnoControlDialogModel")
REM Eigenschaften zuweisen
	with oDlgM
'		.setPropertyValue("PositionX", 30)
'		.setPropertyValue("PositionY", 30)
		.setPropertyValue("Width", 75)
		.setPropertyValue("Height", 100)
		.setPropertyValue("Title", "Dynamischer Dialog")
	end with
REM Textlabel erzeugen
	oMod = oDlgM.createInstance("com.sun.star.awt.UnoControlFixedTextModel")
	with oMod
		.setPropertyValue("Name", "Text2")
		.setPropertyValue("Align", 1)
		.setPropertyValue("PositionX", 10)
		.setPropertyValue("PositionY", 10)
		.setPropertyValue("Width", 55)
		.setPropertyValue("Height", 20)
		.setPropertyValue("Label", "Klick Klon-Button!")
	end with
	oDlgM.insertByName("Text2", oMod)
	
REM Button erzeugen
	oMod = oDlgM.createInstance("com.sun.star.awt.UnoControlButtonModel")
	with oMod
		.setPropertyValue("Name", "btn")
		.setPropertyValue("PositionX", 5)
		.setPropertyValue("PositionY", 45)
		.setPropertyValue("Width", 65)
		.setPropertyValue("Height", 20)
		.setPropertyValue("Label", "Abbruch" )
	end with
	oDlgM.insertByName("btn", oMod)

REM Button klonen (vor der Anzeige des Dialogs)
	oMod = oMod.CreateClone
	oMod.Setpropertyvalue("PositionY",70)
	oMod.Setpropertyvalue("Name","btnClone")
	oMod.SetpropertyValue("Label", "Klon-Button"
	oDlgM.insertByName("btnClone", oMod)

REM Dialog ertellen 
	oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog")
	oDlg.setModel(odlgM)
	
REM Listener für Button und  Klon
	oListenerClone = CreateUnoListener("btn_", "com.sun.star.awt.XActionListener")
	oControl = oDlg.getControl("btn")
	oControl.addActionListener(oListenerClone)
	oListenerClone = CreateUnoListener("btnClone_", "com.sun.star.awt.XActionListener")
	oControl = oDlg.getControl("btnClone")
	oControl.addActionListener(oListenerClone)
	
	
REM Dialog anzeigen
	oDlg.Model.PositionX=50
	oDlg.Model.Positiony=50
	oWin = createUnoService("com.sun.star.awt.Toolkit")
	oDlg.createPeer(oWin, null)
	oDlg.execute
end sub

sub btnClone_actionPerformed(oEvent)
REM Button klonen bei angezeigtem Dialog
	with oDlg.Model
	' Dialoghöhe vergrößern
		.height= .height + 25
	' Button der geklont werden soll, hat den höchsten Index aller Controls im Dialog
		iMax=ubound(.controlModels)
		oMod2=.ControlModels(iMax).CreateClone
	' Eigenschaften des neuen Buttons anpassen
		oMod2.Setpropertyvalue("PositionY",.Height -30)
		oMod2.Setpropertyvalue("Name","btnClone" & CStr(iMax))
		oMod2.SetpropertyValue("Label", "Klon-Button " 	& CStr(iMax))
	'Button in Dialog einfügen
		.InsertByName("btnClone" & CStr(iMax), oMod2)
	end with
	'Listener für geklonten Button
	oListenerClone = CreateUnoListener("btnClone_", "com.sun.star.awt.XActionListener")
	oControl = oDlg.getControl("btnClone" & cStr(iMax))
	oControl.addActionListener(oListenerClone)
End Sub

sub  btn_actionPerformed(oEvent)
	oDlg.EndExecute
End Sub
pauliv_de
*
Beiträge: 17
Registriert: Fr, 31.08.2007 08:56

Re: Control klonen bzw. per Makrocode erstellen

Beitrag von pauliv_de »

Hallo Steffan, habe Deinen Beitrag mit Interesse gelesen und sofort getestet, weil ich was ähnliches suche.
Allerdings fällt mir auf, dass der Dialog mit jedem Klon-Button um 3 Einheiten schmaler wird... finde in Deinem Programm keine Erklärung dafür.

Tritt der Effekt auch bei anderen auf, oder wie ist das Problem zu lösen ?
Vielen Dank im Voraus
Paul
Antworten