LibreOffice und OpenOffice: Schnellstartmenü für häufig genutzte Dokumente
Sie müssen häufig bestimmte Dokumente öffnen und bearbeiten? Dann richten Sie sich in LibreOffice oder OpenOffice per Makro ein eigenes Menü für den schnellen Zugriff ein.
Es hängt von der persönlichen Arbeitsweise ab: Wer seine Dokumente in Ordnern und Unterordnern organisiert hat, verwendet in der Regel den Datei-Manager des Betriebssystems, um die gewünschten Dateien anzusteuern und zu öffnen. Auf die zuletzt geöffneten Dateien bieten LibreOffice oder OpenOffice über den Menüpunkt „Datei -> Zuletzt benutzte Dokumente“ einen schnellen Zugriff. Dieser hat jedoch einen Nachteil. Länger nicht verwendete Dateien verschwinden nach einiger Zeit aus dem Menü, wenn Sie zwischendurch andere Dateien öffnen. Zudem lässt sich die Reihenfolge nicht ändern.
Besser ist daher ein Arbeitsmenü, über das Sie Dateien öffnen, an denen Sie gerade täglich arbeiten oder die Sie häufiger öffnen und ändern müssen. Für diese Lösung benötigen Sie Makros, die ich Ihnen in diesem Artikel vorstelle.
Download zu diesem Artikel:
Arbeitsmenü 2.1:
875 Downloads
Die Makros funktionieren in LibreOffice und OpenOffice ab Version 4.x unter Windows, Linux und Mac OSX. Lediglich bei Ubuntu mit dem Unity-Desktop gibt es eine Einschränkung: Das Menü wird per Makro nicht richtig aktualisiert, sodass neue Einträge erst nach einem Neustart von LibreOffice auftauchen. Eine Lösung für dieses Problem ist mir zurzeit nicht bekannt.
Der Makro-Code ermöglicht die Übernahme des aktuell genutzten Dokuments in ein Menü. Wenn Sie die Arbeit an einem Dokument wieder aufnehmen, wählen Sie einfach den zugehörigen Menü-Eintrag aus. Zusätzlich gibt es einen Dialog, über den Sie die gespeicherten Einträge verwalten. Sie können Einträge aus der Liste löschen, alle Einträge löschen oder die Reihenfolge ändern. Zusätzlich gibt es noch die Komfortfunktion „Öffne Dokument-Ordner“, der im Datei-Manager den Ordner anzeigt, in dem das aktuell geöffnete Dokument liegt. Das ist praktisch, wenn Sie Materialien wie Bilder oder PDFs im gleichen Ordner ablegen. Sie müssen dann den Ordner nicht erst umständlich im Datei-Manager aufrufen, um hier Dateien abzulegen oder zu ändern.
So installieren Sie die Makros
LibreOffice beziehungsweise OpenOffice starten aus Sicherheitsgründen standardmäßig keine Makros aus Dokumenten, die Sie von Ihrer Festplatte laden. Um das zu ändern, gehen Sie auf „Extras -> Optionen“ und dann unter „LibreOffice“ auf „Sicherheit“. Klicken Sie auf „Makrosicherheit“. Stellen Sie das Sicherheitslevel auf „Mittel, klicken Sie auf „OK“ und noch einmal auf „OK“. OpenOffice-Nutzer gehen auf „Extras -> Einstellungen“ und dann auf „OpenOffice“ und „Sicherheit“.
Laden Sie die Datei Arbeitsmenu.zip herunter und Entpacken Sie das Archiv. Öffnen Sie dann Arbeitsmenu.odt per Doppelklick. Bestätigen Sie die Sicherheitsabfrage per Klick auf „Makros aktivieren“. Klicken Sie auf „Arbeitsmenü installieren“. Damit kopieren Sie die Makro-Bibliothek „libArbeitsmenü“ in den Makrospeicher „Meine Makros & Dialoge“. Wenn Sie möchten, stellen Sie das Sicherheitslevel wieder zurück auf „Hoch“.
So nutzen Sie die Makros
Das Makro erzeugt den neuen Eintrag „Arbeitsmenü“ in der Menüleiste. Um ein neues Dokument hinzuzufügen speichern Sie dieses zuerst und klicken dann auf „Arbeitsmenü -> Zum Menü hinzufügen“. Der Pfad zum Dokument erscheint dann im Menü. Wenn Sie später die Arbeit an einem Dokument fortsetzen wollen, klicken Sie den zugehörigen Eintrag im Menü an.
Tipp: Sie können auch Dokumentvorlagen in das Menü aufnehmen. Öffnen Sie die gewünschte Dokumentvorlage über „Datei -> Dokumentvorlage -> Verwalten“ zum Bearbeiten und fügen Sie die Datei über „Arbeitsmenü -> Zum Menü hinzufügen“ hinzu.
Datei-Liste verwalten: Per Klick auf „Arbeitsmenü -> Optionen“ erhalten Sie Zugriff auf die Liste der Einträge. Über die Pfeil-Schaltflächen lässt sich die Reihenfolge ändern. Um einen Eintrag zu entfernen, klicken Sie ihn an und dann auf „Löschen“. „Alle Löschen“ entfernt alle Einträge nach Rückfrage. Über die Schaltfläche „Öffnen“ können Sie das gerade markierte Dokument öffnen und über „Zeigen“ öffnen Sie den Ordner, in dem das Dokument liegt, im Datei-Manager. Diese Funktion erreichen Sie auch direkt über den Menüpunkt „Arbeitsmenü -> Öffne Dokument-Ordner“. Über die Schaltfläche „Speichern und schließen“ übernehmen Sie Änderungen im Dialog und beenden ihn. „Abbrechen“ schließt den Dialog, ohne die Änderungen zu speichern.
Ansichtsoptionen ändern: Nach einem Klick auf „Einstellungen“ können Sie die Ansicht des Menüs ändern. Voreingestellt ist die Anzeige des vollständigen Pfades im Menü. Bei langen Pfaden können die Menüeinträge sehr lang werden. In diesem Fall wählen Sie die Option „Gekürzter Pfad“ und geben hinter „Länge der Anzeige“ die Anzahl der Zeichen ein, die ein Menüpunkt maximal haben soll. Wenn Sie „Nur Dateiname“ wählen, zeigt das Menü nur die Dateinamen. Dann besteht bei gleichnamigen Dokumenten in unterschiedlichen Ordnern jedoch Verwechslungsgefahr. Diese Einstellungen betreffen jedoch nur die Anzeige. Die Makros speichern immer den kompletten Pfad zur Datei.
Makro individuell konfigurieren
Das Makro erstellt standardmäßig nur Menü-Einträge in den Office-Modulen Write und Calc sowie in der Übersichtsseite. Wenn Sie das Arbeitsmenü auch in anderen Modulen verwenden wollen, gehen Sie auf „Extras -> Makros -> Makros verwalten -> LibreOffice Basic“. Gehen Sie unter „Meine Makros“ auf „libArbeitsmenu -> modArbmen“, und klicken Sie auf „Bearbeiten“. Unter „Function GetInterfaces As Array“ sehen Sie die Definition der Office-Module. Wenn Sie beispielsweise das Menü auch in Draw („Zeichung“) sehen wollen, entfernen Sie das Hochkomma vor
myInterfaces(X)="com.sun.star.drawing.DrawingDocument"
Ändern Sie „myInterfaces(X)“ auf „myInterfaces(3)“ und „Dim myInterfaces(2)“ auf „Dim myInterfaces(3)“. Wenn Sie auch Impress hinzufügen möchten, ändern Sie die Zeile
myInterfaces(X)="com.sun.star.presentation.PresentationDocument"
in „myInterfaces(4)“ und erhöhen den Wert für das Array auf „Dim myInterfaces(4)“.
Außerdem können Sie bei Bedarf den Namen der INI-Datei hinter „strIniFileName=“ ändern, in dem das Makro die Menüeinträge speichert. Eine weitere Anpassung kann für Linux erforderlich sein. Da es hier – je nach Distribution – unterschiedliche Datei-Manager zu Einsatz kommen, tragen Sie dessen Namen hinter „strLinuxFileManager=“ ein. Für Ubuntu beispielsweise
Const strLinuxFileManager="nautilus"
Und für Linux Mint:
Const strLinuxFileManager="nemo"
Welches Betriebssystem jeweils zum Einsatz kommt, ermittelt das Makro automatisch.
Technische Informationen zur Arbeitsweise der Makros
Damit das Arbeitsmenü beim Start von LibreOffice beziehungsweise OpenOffice erscheint und dynamisch gefüllt wird, muss das Unterprogramm „ModuleInit()“ automatisch gestartet werden. Die Installations-Routine erzeugt dazu einen passenden Eintrag, den Sie über „Extras -> Anpassen“ auf der Registerkarte „Ereignisse“ hinter „Programmstart“ sehen können. Die Installations-Routine berücksichtigt, ob hier bereits ein von Ihnen selbst erstellter Eintrag vorhanden ist. Es fragt gegebenenfalls, ob dieser ersetzt werden soll. Wenn Sie hier mit „Nein“ antworten, müssen Sie selbst „ModuleInit()“ in Ihre Autostart-Makro aufnehmen. Entsprechend wird auch bei der De-Installation gefragt, ob der Eintrag bei „Programmstart“ unter „Ereignisse“ entfernt werden soll.
Das Makro speichert die Menü-Einträge in der Datei Arbeitsmenu.ini. Diese wird etwa bei LibreOffice unter Windows im Verzeichnis „%appdata%\LibreOffice\4\user\config“ erstellt. „ModuleInit()“ liest die INI-Datei aus und erstellte die Menüeinträge neu. Das Menü wird nicht permanent gespeichert, sondern immer dynamisch erzeugt. Das kann sich ein wenig auf die Startzeit des Office-Pakets auswirken, vor allem, wenn Sie Menüs für mehrere Office-Module erzeugen. Auf einem durchschnittlich schnellen PC sollte die Verzögerung aber kaum spürbar sein.
So de-installieren Sie das Makro
Wenn Sie das Arbeitsmenü nicht mehr verwenden wollen, öffnen Sie erneut die Datei Arbeitsmenu.odt. Klicken Sie auf „Arbeitsmenü de-installieren“.
Sie können die Bibliothek auch manuell entfernen. Dazu gehen Sie auf „Extras -> Makros -> Makros verwalten -> LibreOffice Basic“ und klicken auf die Schaltfläche „Verwalten“. Gehen Sie auf die Registerkarte „Bibliotheken“, wählen die „libArbeitsmenu“ aus, und klicken Sie auf „Löschen“. Danach gehen Sie auf „Extras -> Anpassen“ und die Registerkarte „Ereignisse“. Löschen Sie die Aktion hinter „Programmstart“.
Makros im Quelltext
REM ****** BASIC **********
REM Arbeitsmenu Version 2.1 *
REM *************************
Private oDialog as Variant
Dim oListBox As Variant
Dim ListBoxChanged As Boolean
Dim mySettings(1)
Dim isBusy As Boolean
Dim MyIni
Const strMenuID="vnd.openoffice.org:Arbmenu"
Const strLibName="libArbeitsmenu"
Const strModName="modArbmen"
Const strIniFileName="Arbeitsmenu.ini"
Const strLinuxFileManager="nautilus" ' Ubuntu
'Const strLinuxFileManager="nemo" ' Linux Mint
' get interfaces where menu should be added
'
Function GetInterfaces As Array
Dim myInterfaces(2) As Variant ' increase value when adding more interfaces
myInterfaces(0)="com.sun.star.text.TextDocument" 'show menŸ in Writer
myInterfaces(1)="com.sun.star.sheet.SpreadsheetDocument" 'show menŸ in Calc
myInterfaces(2)="com.sun.star.frame.StartModule" 'show menŸ on start page
' examples
'myInterfaces(3)="com.sun.star.drawing.DrawingDocument" ' show menu in Draw
'myInterfaces(4)="com.sun.star.presentation.PresentationDocument" ' show menu in Impress
GetInterfaces=myInterfaces()
End Function
' create menu and fill with entries
' must be executed on LibreOffice startup (OnStartApp event)
Sub ModuleInit
Dim myInterfaces()
If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then
GlobalScope.BasicLibraries.LoadLibrary("Tools")
End If
myInterfaces()=GetInterfaces ' interfaces where menu should be placed
' CreateTopLevelMenu("<path>","<interface>")
' AddSubMenu("<path>","<menutext>","<interface>")
For i = 0 To UBound(myInterfaces)
If FindMenuByID(strMenuID, myInterfaces(i)) = -1 Then
CreateTopLevelMenu(strMenuID,"Arbeits~menü",myInterfaces(i) )
AddSubMenu(strMenuID, "macro:///"+strLibName+"."+strModName+".AddToMenu()","Zum Menü hinzufügen",0,myInterfaces(i) )
AddSubMenu(strMenuID, "macro:///"+strLibName+"."+strModName+".ArbMenOptions()","Optionen",0,myInterfaces(i))
'add seperator
AddSubMenu(strMenuID, "","",1,myInterfaces(i))
AddSubMenu(strMenuID, "macro:///"+strLibName+"."+strModName+".ShowCurrentDocFolder()","Öffne Dokument-Ordner",0,myInterfaces(i))
'add seperator
AddSubMenu(strMenuID, "","",1,myInterfaces(i))
End If
next i
Dim myItems (1)
myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName)
'create new ini with defaults
If Not checkForFile(myIni) Then
mySettings(0)="3"
mySettings(1)="80"
CreateIniFile(myIni, 0, myItems(), mySettings())
End If
' get entries from ini
For i = 0 To UBound(myInterfaces)
FillMenuFromIni(myInterfaces(i))
Next i
End Sub
' remove documents from menu
Sub cmdClear_Click
Dim sVar as Integer
sVar=MsgBox("Wollen Sie wirklich alle Einträge löschen?",256 + 32 +1,"Alle Löschen?")
If sVar=1 Then
ListBoxChanged=True
ClearListBox
End If
End Sub
' show selected item in dialog
Sub FillLabel
selItem=oListBox.SelectedItemPos()
if selItem=-1 Then Exit Sub
oLabel = oDialog.getControl("Label1")
oLabel.SetText(oListBox.getItem(selItem))
End Sub
' something was modified in dialog?
Sub DialogModified
ListBoxChanged=True
End Sub
' move entry down
Sub cmDown_Click
Dim nCount As Integer
nCount = oListBox.getItemCount()
If nCount = 0 Then Exit Sub
selItem=oListBox.SelectedItemPos()
If selItem = -1 Then Exit Sub
If selItem=nCount-1 Then Exit Sub
ReDim myList(nCount - 1)
ListBoxChanged=True
intIDX = selItem
For i = 0 To nCount - 1
S = oListBox.getItem(i)
' Pos = InStr(1, S, " ")
' S = Mid(S, Pos, Len(S) - Pos + 1)
myList(i) = S
Next i
strItem1 = myList(intIDX)
strItem0 = myList(intIDX + 1)
myList(intIDX + 1) = strItem1
myList(intIDX) = strItem0
ClearListBox
For i = 0 To nCount -1
oListBox.addItem (Trim(myList(i)),i)
Next i
oListBox.selectItemPos(intIDX + 1, True)
'End If
End Sub
' move entry up
Sub cmUp_Click
Dim intIDX, strItem1, strItem0
nCount = oListBox.getItemCount()
If nCount = 0 Then Exit Sub
selItem=oListBox.SelectedItemPos()
If selItem= 0 Then Exit Sub
Dim myList()
ReDim myList(nCount - 1)
ListBoxChanged = True
intIDX = selItem
For i = 0 To nCount -1
S = oListBox.getItem(i)
myList(i) = S
Next i
strItem1 = myList(intIDX)
strItem0 = myList(intIDX - 1)
myList(intIDX - 1) = strItem1
myList(intIDX) = strItem0
ClearListBox
For i = 0 To nCount -1
oListBox.addItem (Trim(myList(i)),i)
Next i
oListBox.selectItemPos(intIDX - 1, True)
End Sub
' add current document to menu
Sub AddToMenu
If isBusy=True Then Exit Sub
isBusy=True
Dim i As Integer
Dim numItems As Integer
Dim myInterfaces()
If GetDocumentURL <> "" Then
myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName)
numItems=getIniValue(myIni, "ArbMenu", "ItemsCount")
numItems=Val(numItems)+1
Dim myItems(numItems)
' read old items from ini
For i = 1 to numItems-1
myItems(i)="Item"+Val(i) + "=" + getIniValue(myIni, "ArbMenu", "Item"+Val(i)) + Chr(13) +Chr(10)
Next i
' get settings from ini
mySettings(0)=getIniValue(myIni, "Settings", "Option")
mySettings(1)=getIniValue(myIni, "Settings", "NumChar")
' add new entry to menu
myItems(numItems)="Item"+Val(numItems)+"="+GetDocumentURL + Chr(13) +Chr(10)
' write ini file
CreateIniFile(myIni, numItems, myItems(),mySettings())
' refresh menu
myInterfaces()=GetInterfaces
For i = 0 To UBound(myInterfaces)
FillMenuFromIni(myInterfaces(i))
Next i
End If
isBusy=False
End Sub
' show options dialog
Sub ArbMenOptions
Dim nCount As Integer
DialogLibraries.LoadLibrary(strLibName)
oDialog = createUnoDialog(DialogLibraries.libArbeitsmenu.dlgArbMen)
oDialog.Model.Step = 1 ' show first page
oListBox = oDialog.getControl("ListBox1")
FillListBoxFromIni ' get menu entries form ini
ListBoxChanged=False
oDialog.execute ' show dialog
End Sub
' remove selected item from list
Sub RemoveSelectedItem
ListBoxChanged=True
selItem=oListBox.SelectedItemPos()
If selItem >=0 Then
oListBox.removeItems(selItem,1)
End If
End Sub
' remove all entries from list
Sub ClearListBox
Dim nCount As Integer
nCount = oListBox.getItemCount()
If nCount >0 Then
For i = 0 to nCount-1
oListBox.removeItems(0,1)
Next i
End If
End Sub
' get menu entries from ini
Sub FillMenuFromIni (myInterface As String)
Dim numItems As Integer
Dim n As Integer
Dim numMenuItems
Dim myOption As Integer
Dim NumChar As Integer
Dim S As String
' we need the tools library (ConvertFromUrl)
If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then
GlobalScope.BasicLibraries.LoadLibrary("Tools")
End If
' remove menu entries starting at 5
numMenuItems=GetNumMenuEntries(strMenuID, myInterface)
If numMenuItems > 5 Then
RemoveSubMenu(strMenuID, numMenuItems-5, myInterface)
End If
myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName)
numItems=getIniValue(myIni, "ArbMenu", "ItemsCount")
'no entries = exit
If numItems=0 Then Exit Sub
myOption=Val(getIniValue(myIni, "Settings", "Option"))
If myOption <=0 Or myOption >=4 Then myOption=3 ' default 3 full path names
NumChar=Val(getIniValue(myIni, "Settings", "NumChar"))
If NumChar=0 Then NumChar=80 ' default 80 characters
'fill menu from ini
For n = 1 to numItems
myDoc=getIniValue(myIni, "ArbMenu", "Item"+Val(n))
Select Case myOption
'1 filename only
Case 1
S=FileNameoutofPath(myDoc)
'2 short path
Case 2
S=LongDirFix(myDoc,NumChar)
'3 full path
Case 3
S=myDoc
End Select
' add new menu entry
AddSubMenu(strMenuID, "macro:///"+strLibName+"."+strModName+".OpenDoc("+Trim(Str(n)) +")",Trim(Str(n) + " " + S),0,myInterface)
Next n
End Sub
' fill dialog listbox from ini
Sub FillListBoxFromIni
ClearListBox
Dim numItems As Integer
Dim n As Integer
Dim myOption As Integer
Dim NumChar As Integer
myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName)
numItems=getIniValue(myIni, "ArbMenu", "ItemsCount")
'settings
myOption=Val(getIniValue(myIni, "Settings", "Option"))
If myOption <=0 Or myOption >=4 Then myOption=3
oCheckbox = oDialog.getControl("OptionButton"+ Trim (Str(myOption)))
oCheckbox.Model.State=1
NumChar=Val(getIniValue(myIni, "Settings", "NumChar"))
If NumChar=0 Then NumChar=80
oTextField=oDialog.getControl("txtLength")
oTextField.Text=Trim(Str(NumChar))
'
For n = 0 to numItems-1
myDoc=getIniValue(myIni, "ArbMenu", "Item"+Val(n+1))
oListBox.addItem( myDoc, n )
Next n
End Sub
' close dialog
Sub CancelDialog
oDialog.endExecute()
End Sub
' close dialog and save
Sub CloseDialogAndSave
Dim myOption As Integer
Dim NumChar As Integer
Dim S As String
If ListBoxChanged=false Then
oDialog.endExecute()
Exit Sub
End If
Dim n As Integer
Dim myInterfaces ()
myInterfaces()=GetInterfaces
myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName)
'remove all menu entries
numItems=getIniValue(myIni, "ArbMenu", "ItemsCount")
For i = 0 To UBound(myInterfaces)
RemoveSubMenu(strMenuID, numItems, myInterfaces(i))
Next i
numItems=oListBox.getItemCount()
Dim myItems(numItems)
'settings
For i = 1 to 3
oCheckbox = oDialog.getControl("OptionButton"+ Trim (Str(i)))
If oCheckbox.Model.State=1 Then myOption = i
Next i
oTextField=oDialog.getControl("txtLength")
NumChar=Trim(Val(oTextField.getText()))
If NumChar=0 Then NumChar=80
mySettings(0)=Trim(Str(myOption))
mySettings(1)=Trim(Str(NumChar))
'write menu from ListBox
For n = 1 to numItems
myItems(n)="Item" + Trim(Str(n)) + "=" + oListBox.getItem(n-1)
Next n
' save ini file
CreateIniFile(myIni, numItems, myItems(), mySettings())
' refresh menu
For i = 0 To UBound(myInterfaces)
FillMenuFromIni(myInterfaces(i))
Next i
oDialog.endExecute() 'close dialog
End Sub
' dialog: switch step 1 or 2
Sub DialogSettings
If oDialog.Model.Step = 1 Then
oDialog.Model.Step = 2
oDialog.Model.cmdSettings.Label="Einträge"
Else
oDialog.Model.Step = 1
oDialog.Model.cmdSettings.Label="Einstellungen"
End If
End Sub
' open doc folder in file manager
Sub OpenFileManager(DocDir)
Dim TheOS
TheOS=OS()
If TheOS="WINDOWS" then
WinDir=Environ("Windir")
Shell(Windir+"\explorer.exe /e,"+DocDir,1) ' Windows
ElseIf TheOS="UNIX" Then
Shell(strLinuxFileManager + " "+ DocDir ,1) ' Linux
ElseIf TheOS="OSX" Then
Shell("open "+ DocDir ,1) ' OSX
End If
End Sub
' open current docs folder in file manager
Sub ShowCurrentDocFolder
dim oDoc as object
oDoc = ThisComponent
If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then
GlobalScope.BasicLibraries.LoadLibrary("Tools")
End If
On error goto ErrH:
If (oDoc.hasLocation) Then ' document saved?
OpenFileManager(DirectoryNameoutofPath(oDoc.getURL(), "/")
Else
MsgBox("Bitte speichern Sie das Dokument, bevor Sie diese Funktion verwenden.",64,"Dokument ist nicht gespeichert")
End If
Exit Sub
ErrH: ' document has no location
MsgBox("Die Funktion steht hier nicht zur Verfügung.",64,"Fehler")
End Sub
' show selected document folder in file manager
Sub ShowDocFolder
Dim selItem
Dim myDoc
If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then
GlobalScope.BasicLibraries.LoadLibrary("Tools")
End If
selItem=oListBox.SelectedItemPos()
If selItem >=0 Then
myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName)
myDoc=getIniValue(myIni, "ArbMenu", "Item"+Val(selItem + 1))
If checkForFile(ConvertToUrl(myDoc))=True Then
OpenFileManager(DirectoryNameoutofPath(ConvertToUrl(myDoc), "/"))
Else
MsgBox("Die Datei " + myDoc +" ist nicht vorhanden" )
End If
Else
oLabel = oDialog.getControl("Label1")
oLabel.SetText("Es ist nichts ausgewählt") ' nothing selected
End If
End Sub
' Dialog: open document
Sub OpenDocFromDialog
Dim selItem
selItem=oListBox.SelectedItemPos()
If selItem >=0 Then
OpenDoc ( selItem + 1 )
'CancelDialog
Else
oLabel = oDialog.getControl("Label1")
oLabel.SetText("Es ist nichts ausgewählt")
End If
End Sub
' open document from menu
Sub OpenDoc (index As Integer)
Dim args (0) as New com.sun.star.beans.PropertyValue
args(0).Name="MacroExecutionMode"
args(0).Value=4
myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName)
myDoc=getIniValue(myIni, "ArbMenu", "Item"+Val(index))
' file exists?
If checkForFile(ConvertToUrl(myDoc))=True Then ' file exists?
TheDoc=StarDesktop.loadComponentFromURL(ConvertToUrl(myDoc),"_blank",0,args())
Else
MsgBox("Die Datei " + myDoc +" ist nicht vorhanden" )
End If
End Sub
' get document path
Function GetDocumentURL As String
Dim oDoc
Dim sDocURL
oDoc = ThisComponent
If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then
GlobalScope.BasicLibraries.LoadLibrary("Tools")
End If
On error goto ErrH:
If (oDoc.hasLocation()) Then
GetDocumentURL= ConvertFromUrl(oDoc.getURL())
Else
MsgBox("Sie müssen das Dokument erst speichern.") ' not saved yet
End If
Exit Function
ErrH:
MsgBox("Die Funktion steht hier nicht zur Verfügung.",64,"Fehler")
End Function
Sub CheckMenu
sMenuBar = "private:resource/menubar/menubar"
oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")
oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(myInterface )
oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true )
iPos=FindMenuByID(strMenuID,myInterface)
oPopupMenu() = oMenuBarSettings.getByIndex( iPos )
oPopupMenuContainer = oPopupMenu(4).Value
nSubNumItems=oPopupMenuContainer.getCount()
oMenuItem()= oPopupMenuContainer.getByIndex(3)
MsgBox(oMenuItem(0).Value)
End Sub
' number of menu entries
Function GetNumMenuEntries (ID As String, Interface As String) As Integer
sMenuBar = "private:resource/menubar/menubar"
oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")
oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface)
oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true )
iPos=FindMenuByID(ID,Interface)
If iPos >= 0 Then
oPopupMenu() = oMenuBarSettings.getByIndex( iPos )
oPopupMenuContainer = oPopupMenu(3).Value
GetNumMenuEntries=oPopupMenuContainer.getCount()
End If
End Function
' remove documents from menu
Sub RemoveSubMenu(ID As String, numItems As integer, Interface As String)
sMenuBar = "private:resource/menubar/menubar"
oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")
oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface)
oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true )
iPos=FindMenuByID(ID, Interface)
If iPos >= 0 Then
oPopupMenu() = oMenuBarSettings.getByIndex( iPos )
oPopupMenuContainer = oPopupMenu(3).Value
nSubNumItems=oPopupMenuContainer.getCount()
For i = 1 to numItems
oPopupMenuContainer.removeByIndex(5)
Next i
oModuleCfgMgr.replaceSettings( sMenuBar, oMenuBarSettings )
End If
End Sub
' add sub menu
Sub AddSubMenu (ID As String, Action As String, Label As String, iType As Integer, Interface As String)
Dim nSubNumItems As Integer
'nSubNumItems=1
'On Error Resume next
sMenuBar = "private:resource/menubar/menubar"
oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")
oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface)
oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true )
iPos=FindMenuByID(ID, Interface)
If iPos >= 0 Then
oPopupMenu() = oMenuBarSettings.getByIndex( iPos )
oPopupMenuContainer = oPopupMenu(3).Value
nSubNumItems=oPopupMenuContainer.getCount()
oMenuItem = CreateMenuItem( Action,Label,iType )
oPopupMenuContainer.insertByIndex( nSubNumItems, oMenuItem )
oModuleCfgMgr.replaceSettings( sMenuBar, oMenuBarSettings )
End If
End Sub
' create main menu entry
Sub CreateTopLevelMenu(ID As String, Label As String, Interface As String)
sMenuBar = "private:resource/menubar/menubar"
sMyPopupMenuCmdId = "vnd.openoffice.org:" +ID
oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")
oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface)
oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true )
nCount = oMenuBarSettings.getCount()
oPopupMenu = CreatePopupMenu( ID, Label, oMenuBarSettings )
'insert after last item
oMenuBarSettings.insertByIndex( nCount, oPopupMenu )
oModuleCfgMgr.replaceSettings( sMenuBar, oMenuBarSettings )
End Sub
' locate menu by ID
Function FindMenuByID (ID As String, Interface As String) As Integer
FindMenuByID=-1
sMenuBar = "private:resource/menubar/menubar"
oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")
oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface)
oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true )
nCount = oMenuBarSettings.getCount()
for i = 0 to nCount-1
oPopupMenu() = oMenuBarSettings.getByIndex( i )
If oPopupMenu(0).Value=ID Then FindMenuByID=i
next i
End Function
' create menu
Function CreatePopupMenu( CommandId, Label, Factory ) as Variant
Dim aPopupMenu(3) as new com.sun.star.beans.PropertyValue
aPopupMenu(0).Name = "CommandURL"
aPopupMenu(0).Value = CommandId
aPopupMenu(1).Name = "Label"
aPopupMenu(1).Value = Label
aPopupMenu(2).Name = "Type"
aPopupMenu(2).Value = 0
aPopupMenu(3).Name = "ItemDescriptorContainer"
aPopupMenu(3).Value = Factory.createInstanceWithContext(GetDefaultContext() )
CreatePopupMenu = aPopupMenu()
End Function
' create menu item
Function CreateMenuItem( Command as String, Label as String, iType As Integer ) as Variant
Dim aMenuItem(2) as new com.sun.star.beans.PropertyValue
aMenuItem(0).Name = "CommandURL"
aMenuItem(0).Value = Command
aMenuItem(1).Name = "Label"
aMenuItem(1).Value = Label
aMenuItem(2).Name = "Type"
aMenuItem(2).Value = iType
CreateMenuItem = aMenuItem()
End Function
Rem ------------------------------------------
rem helper
Rem ------------------------------------------
' which operating system?
function OS()as string
select case getGUIType
case 1: OS="WINDOWS"
case 3: OS="MAC"
case 4: OS=iif(instr(environ("HOME"),"Users")=0,"UNIX","OSX")
end select
end function
'LO/OO config path
Function getConfigPath As String
oPathSettings = CreateUnoService( "com.sun.star.util.PathSettings" )
sPathConfig = oPathSettings.UserConfig
if right(sPathConfig,6) <> "config" then
getConfigPath=""
Else
getConfigPath=sPathConfig
endif
End Function
' shorten path
Function LongDirFix (TargetString As String, Max As Integer) As String
Dim i, LblLen, StringLen As Integer
Dim TempString As String
TempString = TargetString
LblLen = Max
If Len(TempString) <= LblLen Then
LongDirFix = TempString
Exit Function
End If
LblLen = LblLen - 6
For i = Len(TempString) - LblLen To Len(TempString)
If Mid$(TempString, i, 1) = "\" Then Exit For
Next
'On one line:
LongDirFix = Left$(TempString, 3) & "..." & Right$(TempString, Len(TempString) - (i - 1))
End Function
' does sUrl (ini file) exist?
Function checkForFile (sUrl As String) As Boolean
oSimpleFileAccess = createUnoService( "com.sun.star.ucb.SimpleFileAccess" )
If oSimpleFileAccess.exists(sUrl) = TRUE Then
checkForFile=True
Else
checkForFile=False
End If
End Function
' CreateIni
Sub CreateIniFile (myIniFile As String, NumItems As Integer, myItems As Array, mySettings As Array)
Dim i As Integer
fileAccessService = createUnoService("com.sun.star.ucb.SimpleFileAccess")
textOutputStream = createUnoService("com.sun.star.io.TextOutputStream")
'now open the file..
outputStream = fileAccessService.openFileWrite(myIniFile)
outputStream.truncate()
textOutputStream.setOutputStream(outputStream)
textOutputStream.writeString("[Settings]" +Chr(13) +Chr(10))
textOutputStream.writeString("Option=" + mySettings(0)+Chr(13) +Chr(10))
textOutputStream.writeString("NumChar=" + mySettings(1)+Chr(13) +Chr(10))
textOutputStream.writeString("[ArbMenu]" +Chr(13) +Chr(10))
textOutputStream.writeString("ItemsCount=" + Trim(Str(NumItems))+Chr(13) +Chr(10))
If numItems=0 Then ' no items, exit
textOutputStream.writeString(Chr(13) +Chr(10))
textOutputStream.closeOutput()
Exit Sub
End If
For i = 0 to UBound(myItems)
textOutputStream.writeString(myItems(i)+Chr(13) +Chr(10))
Next i
'
textOutputStream.writeString(Chr(13) +Chr(10))
'and don't forget to close it..
textOutputStream.closeOutput()
End Sub
' get value from ini file
Function getIniValue(sIniPath As String, sIniNode As String, sIniKey As String)
oUcb = createUnoService("com.sun.star.ucb.SimpleFileAccess")
iKeyLength = len(sIniKey)
If oUcb.Exists(sIniPath) Then
oInputStream = createUnoService("com.sun.star.io.TextInputStream")
oFile = oUcb.OpenFileReadWrite(sIniPath)
oInputStream.SetInputStream(oFile.GetInputStream)
'find node
Do While Not oInputStream.IsEOF
sLine = oInputStream.ReadLine
If sLine = "[" & sIniNode & "]" Then
sLine = oInputStream.ReadLine
Exit Do 'going out here and start the next loop, searching the key
End If
Loop
'find key
Do While ((Not (Left(sLine, 1) = "[")) AND (Not oInputStream.IsEOF))
If left(sLine, iKeyLength) = sIniKey Then
sValue = mid(sLine,iKeyLength + 2)
Exit Do ' going out, no need for further searching
End If
sLine = oInputStream.Readline
Loop
oInputStream.CloseInput()
Else
msgbox("ini-file:" & sIniPath & " nicht gefunden.")
End If
getIniValue = sValue
End Function
Sie müssen häufig bestimmte Dokumente öffnen und bearbeiten? Dann richten Sie sich in LibreOffice oder OpenOffice per Makro ein eigenes Menü für den schnellen Zugriff ein.
Es hängt von der persönlichen Arbeitsweise ab: Wer seine Dokumente in Ordnern und Unterordnern organisiert hat, verwendet in der Regel den Datei-Manager des Betriebssystems, um die gewünschten Dateien anzusteuern und zu öffnen. Auf die zuletzt geöffneten Dateien bieten LibreOffice oder OpenOffice über den Menüpunkt „Datei -> Zuletzt benutzte Dokumente“ einen schnellen Zugriff. Dieser hat jedoch einen Nachteil. Länger nicht verwendete Dateien verschwinden nach einiger Zeit aus dem Menü, wenn Sie zwischendurch andere Dateien öffnen. Zudem lässt sich die Reihenfolge nicht ändern.
Besser ist daher ein Arbeitsmenü, über das Sie Dateien öffnen, an denen Sie gerade täglich arbeiten oder die Sie häufiger öffnen und ändern müssen. Für diese Lösung benötigen Sie Makros, die ich Ihnen in diesem Artikel vorstelle.
Arbeitsmenü 2.1:
Die Makros funktionieren in LibreOffice und OpenOffice ab Version 4.x unter Windows, Linux und Mac OSX. Lediglich bei Ubuntu mit dem Unity-Desktop gibt es eine Einschränkung: Das Menü wird per Makro nicht richtig aktualisiert, sodass neue Einträge erst nach einem Neustart von LibreOffice auftauchen. Eine Lösung für dieses Problem ist mir zurzeit nicht bekannt.
Der Makro-Code ermöglicht die Übernahme des aktuell genutzten Dokuments in ein Menü. Wenn Sie die Arbeit an einem Dokument wieder aufnehmen, wählen Sie einfach den zugehörigen Menü-Eintrag aus. Zusätzlich gibt es einen Dialog, über den Sie die gespeicherten Einträge verwalten. Sie können Einträge aus der Liste löschen, alle Einträge löschen oder die Reihenfolge ändern. Zusätzlich gibt es noch die Komfortfunktion „Öffne Dokument-Ordner“, der im Datei-Manager den Ordner anzeigt, in dem das aktuell geöffnete Dokument liegt. Das ist praktisch, wenn Sie Materialien wie Bilder oder PDFs im gleichen Ordner ablegen. Sie müssen dann den Ordner nicht erst umständlich im Datei-Manager aufrufen, um hier Dateien abzulegen oder zu ändern.
So installieren Sie die Makros
LibreOffice beziehungsweise OpenOffice starten aus Sicherheitsgründen standardmäßig keine Makros aus Dokumenten, die Sie von Ihrer Festplatte laden. Um das zu ändern, gehen Sie auf „Extras -> Optionen“ und dann unter „LibreOffice“ auf „Sicherheit“. Klicken Sie auf „Makrosicherheit“. Stellen Sie das Sicherheitslevel auf „Mittel, klicken Sie auf „OK“ und noch einmal auf „OK“. OpenOffice-Nutzer gehen auf „Extras -> Einstellungen“ und dann auf „OpenOffice“ und „Sicherheit“.
Laden Sie die Datei Arbeitsmenu.zip herunter und Entpacken Sie das Archiv. Öffnen Sie dann Arbeitsmenu.odt per Doppelklick. Bestätigen Sie die Sicherheitsabfrage per Klick auf „Makros aktivieren“. Klicken Sie auf „Arbeitsmenü installieren“. Damit kopieren Sie die Makro-Bibliothek „libArbeitsmenü“ in den Makrospeicher „Meine Makros & Dialoge“. Wenn Sie möchten, stellen Sie das Sicherheitslevel wieder zurück auf „Hoch“.
So nutzen Sie die Makros
Das Makro erzeugt den neuen Eintrag „Arbeitsmenü“ in der Menüleiste. Um ein neues Dokument hinzuzufügen speichern Sie dieses zuerst und klicken dann auf „Arbeitsmenü -> Zum Menü hinzufügen“. Der Pfad zum Dokument erscheint dann im Menü. Wenn Sie später die Arbeit an einem Dokument fortsetzen wollen, klicken Sie den zugehörigen Eintrag im Menü an.
Tipp: Sie können auch Dokumentvorlagen in das Menü aufnehmen. Öffnen Sie die gewünschte Dokumentvorlage über „Datei -> Dokumentvorlage -> Verwalten“ zum Bearbeiten und fügen Sie die Datei über „Arbeitsmenü -> Zum Menü hinzufügen“ hinzu.
Datei-Liste verwalten: Per Klick auf „Arbeitsmenü -> Optionen“ erhalten Sie Zugriff auf die Liste der Einträge. Über die Pfeil-Schaltflächen lässt sich die Reihenfolge ändern. Um einen Eintrag zu entfernen, klicken Sie ihn an und dann auf „Löschen“. „Alle Löschen“ entfernt alle Einträge nach Rückfrage. Über die Schaltfläche „Öffnen“ können Sie das gerade markierte Dokument öffnen und über „Zeigen“ öffnen Sie den Ordner, in dem das Dokument liegt, im Datei-Manager. Diese Funktion erreichen Sie auch direkt über den Menüpunkt „Arbeitsmenü -> Öffne Dokument-Ordner“. Über die Schaltfläche „Speichern und schließen“ übernehmen Sie Änderungen im Dialog und beenden ihn. „Abbrechen“ schließt den Dialog, ohne die Änderungen zu speichern.
Ansichtsoptionen ändern: Nach einem Klick auf „Einstellungen“ können Sie die Ansicht des Menüs ändern. Voreingestellt ist die Anzeige des vollständigen Pfades im Menü. Bei langen Pfaden können die Menüeinträge sehr lang werden. In diesem Fall wählen Sie die Option „Gekürzter Pfad“ und geben hinter „Länge der Anzeige“ die Anzahl der Zeichen ein, die ein Menüpunkt maximal haben soll. Wenn Sie „Nur Dateiname“ wählen, zeigt das Menü nur die Dateinamen. Dann besteht bei gleichnamigen Dokumenten in unterschiedlichen Ordnern jedoch Verwechslungsgefahr. Diese Einstellungen betreffen jedoch nur die Anzeige. Die Makros speichern immer den kompletten Pfad zur Datei.
Makro individuell konfigurieren
Das Makro erstellt standardmäßig nur Menü-Einträge in den Office-Modulen Write und Calc sowie in der Übersichtsseite. Wenn Sie das Arbeitsmenü auch in anderen Modulen verwenden wollen, gehen Sie auf „Extras -> Makros -> Makros verwalten -> LibreOffice Basic“. Gehen Sie unter „Meine Makros“ auf „libArbeitsmenu -> modArbmen“, und klicken Sie auf „Bearbeiten“. Unter „Function GetInterfaces As Array“ sehen Sie die Definition der Office-Module. Wenn Sie beispielsweise das Menü auch in Draw („Zeichung“) sehen wollen, entfernen Sie das Hochkomma vor
myInterfaces(X)="com.sun.star.drawing.DrawingDocument"
Ändern Sie „myInterfaces(X)“ auf „myInterfaces(3)“ und „Dim myInterfaces(2)“ auf „Dim myInterfaces(3)“. Wenn Sie auch Impress hinzufügen möchten, ändern Sie die Zeile
myInterfaces(X)="com.sun.star.presentation.PresentationDocument"
in „myInterfaces(4)“ und erhöhen den Wert für das Array auf „Dim myInterfaces(4)“.
Außerdem können Sie bei Bedarf den Namen der INI-Datei hinter „strIniFileName=“ ändern, in dem das Makro die Menüeinträge speichert. Eine weitere Anpassung kann für Linux erforderlich sein. Da es hier – je nach Distribution – unterschiedliche Datei-Manager zu Einsatz kommen, tragen Sie dessen Namen hinter „strLinuxFileManager=“ ein. Für Ubuntu beispielsweise
Const strLinuxFileManager="nautilus"
Und für Linux Mint:
Const strLinuxFileManager="nemo"
Welches Betriebssystem jeweils zum Einsatz kommt, ermittelt das Makro automatisch.
Technische Informationen zur Arbeitsweise der Makros
Damit das Arbeitsmenü beim Start von LibreOffice beziehungsweise OpenOffice erscheint und dynamisch gefüllt wird, muss das Unterprogramm „ModuleInit()“ automatisch gestartet werden. Die Installations-Routine erzeugt dazu einen passenden Eintrag, den Sie über „Extras -> Anpassen“ auf der Registerkarte „Ereignisse“ hinter „Programmstart“ sehen können. Die Installations-Routine berücksichtigt, ob hier bereits ein von Ihnen selbst erstellter Eintrag vorhanden ist. Es fragt gegebenenfalls, ob dieser ersetzt werden soll. Wenn Sie hier mit „Nein“ antworten, müssen Sie selbst „ModuleInit()“ in Ihre Autostart-Makro aufnehmen. Entsprechend wird auch bei der De-Installation gefragt, ob der Eintrag bei „Programmstart“ unter „Ereignisse“ entfernt werden soll.
Das Makro speichert die Menü-Einträge in der Datei Arbeitsmenu.ini. Diese wird etwa bei LibreOffice unter Windows im Verzeichnis „%appdata%\LibreOffice\4\user\config“ erstellt. „ModuleInit()“ liest die INI-Datei aus und erstellte die Menüeinträge neu. Das Menü wird nicht permanent gespeichert, sondern immer dynamisch erzeugt. Das kann sich ein wenig auf die Startzeit des Office-Pakets auswirken, vor allem, wenn Sie Menüs für mehrere Office-Module erzeugen. Auf einem durchschnittlich schnellen PC sollte die Verzögerung aber kaum spürbar sein.
So de-installieren Sie das Makro
Wenn Sie das Arbeitsmenü nicht mehr verwenden wollen, öffnen Sie erneut die Datei Arbeitsmenu.odt. Klicken Sie auf „Arbeitsmenü de-installieren“.
Sie können die Bibliothek auch manuell entfernen. Dazu gehen Sie auf „Extras -> Makros -> Makros verwalten -> LibreOffice Basic“ und klicken auf die Schaltfläche „Verwalten“. Gehen Sie auf die Registerkarte „Bibliotheken“, wählen die „libArbeitsmenu“ aus, und klicken Sie auf „Löschen“. Danach gehen Sie auf „Extras -> Anpassen“ und die Registerkarte „Ereignisse“. Löschen Sie die Aktion hinter „Programmstart“.
Makros im Quelltext
REM ****** BASIC ********** REM Arbeitsmenu Version 2.1 * REM ************************* Private oDialog as Variant Dim oListBox As Variant Dim ListBoxChanged As Boolean Dim mySettings(1) Dim isBusy As Boolean Dim MyIni Const strMenuID="vnd.openoffice.org:Arbmenu" Const strLibName="libArbeitsmenu" Const strModName="modArbmen" Const strIniFileName="Arbeitsmenu.ini" Const strLinuxFileManager="nautilus" ' Ubuntu 'Const strLinuxFileManager="nemo" ' Linux Mint ' get interfaces where menu should be added ' Function GetInterfaces As Array Dim myInterfaces(2) As Variant ' increase value when adding more interfaces myInterfaces(0)="com.sun.star.text.TextDocument" 'show menŸ in Writer myInterfaces(1)="com.sun.star.sheet.SpreadsheetDocument" 'show menŸ in Calc myInterfaces(2)="com.sun.star.frame.StartModule" 'show menŸ on start page ' examples 'myInterfaces(3)="com.sun.star.drawing.DrawingDocument" ' show menu in Draw 'myInterfaces(4)="com.sun.star.presentation.PresentationDocument" ' show menu in Impress GetInterfaces=myInterfaces() End Function ' create menu and fill with entries ' must be executed on LibreOffice startup (OnStartApp event) Sub ModuleInit Dim myInterfaces() If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If myInterfaces()=GetInterfaces ' interfaces where menu should be placed ' CreateTopLevelMenu("<path>","<interface>") ' AddSubMenu("<path>","<menutext>","<interface>") For i = 0 To UBound(myInterfaces) If FindMenuByID(strMenuID, myInterfaces(i)) = -1 Then CreateTopLevelMenu(strMenuID,"Arbeits~menü",myInterfaces(i) ) AddSubMenu(strMenuID, "macro:///"+strLibName+"."+strModName+".AddToMenu()","Zum Menü hinzufügen",0,myInterfaces(i) ) AddSubMenu(strMenuID, "macro:///"+strLibName+"."+strModName+".ArbMenOptions()","Optionen",0,myInterfaces(i)) 'add seperator AddSubMenu(strMenuID, "","",1,myInterfaces(i)) AddSubMenu(strMenuID, "macro:///"+strLibName+"."+strModName+".ShowCurrentDocFolder()","Öffne Dokument-Ordner",0,myInterfaces(i)) 'add seperator AddSubMenu(strMenuID, "","",1,myInterfaces(i)) End If next i Dim myItems (1) myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName) 'create new ini with defaults If Not checkForFile(myIni) Then mySettings(0)="3" mySettings(1)="80" CreateIniFile(myIni, 0, myItems(), mySettings()) End If ' get entries from ini For i = 0 To UBound(myInterfaces) FillMenuFromIni(myInterfaces(i)) Next i End Sub ' remove documents from menu Sub cmdClear_Click Dim sVar as Integer sVar=MsgBox("Wollen Sie wirklich alle Einträge löschen?",256 + 32 +1,"Alle Löschen?") If sVar=1 Then ListBoxChanged=True ClearListBox End If End Sub ' show selected item in dialog Sub FillLabel selItem=oListBox.SelectedItemPos() if selItem=-1 Then Exit Sub oLabel = oDialog.getControl("Label1") oLabel.SetText(oListBox.getItem(selItem)) End Sub ' something was modified in dialog? Sub DialogModified ListBoxChanged=True End Sub ' move entry down Sub cmDown_Click Dim nCount As Integer nCount = oListBox.getItemCount() If nCount = 0 Then Exit Sub selItem=oListBox.SelectedItemPos() If selItem = -1 Then Exit Sub If selItem=nCount-1 Then Exit Sub ReDim myList(nCount - 1) ListBoxChanged=True intIDX = selItem For i = 0 To nCount - 1 S = oListBox.getItem(i) ' Pos = InStr(1, S, " ") ' S = Mid(S, Pos, Len(S) - Pos + 1) myList(i) = S Next i strItem1 = myList(intIDX) strItem0 = myList(intIDX + 1) myList(intIDX + 1) = strItem1 myList(intIDX) = strItem0 ClearListBox For i = 0 To nCount -1 oListBox.addItem (Trim(myList(i)),i) Next i oListBox.selectItemPos(intIDX + 1, True) 'End If End Sub ' move entry up Sub cmUp_Click Dim intIDX, strItem1, strItem0 nCount = oListBox.getItemCount() If nCount = 0 Then Exit Sub selItem=oListBox.SelectedItemPos() If selItem= 0 Then Exit Sub Dim myList() ReDim myList(nCount - 1) ListBoxChanged = True intIDX = selItem For i = 0 To nCount -1 S = oListBox.getItem(i) myList(i) = S Next i strItem1 = myList(intIDX) strItem0 = myList(intIDX - 1) myList(intIDX - 1) = strItem1 myList(intIDX) = strItem0 ClearListBox For i = 0 To nCount -1 oListBox.addItem (Trim(myList(i)),i) Next i oListBox.selectItemPos(intIDX - 1, True) End Sub ' add current document to menu Sub AddToMenu If isBusy=True Then Exit Sub isBusy=True Dim i As Integer Dim numItems As Integer Dim myInterfaces() If GetDocumentURL <> "" Then myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName) numItems=getIniValue(myIni, "ArbMenu", "ItemsCount") numItems=Val(numItems)+1 Dim myItems(numItems) ' read old items from ini For i = 1 to numItems-1 myItems(i)="Item"+Val(i) + "=" + getIniValue(myIni, "ArbMenu", "Item"+Val(i)) + Chr(13) +Chr(10) Next i ' get settings from ini mySettings(0)=getIniValue(myIni, "Settings", "Option") mySettings(1)=getIniValue(myIni, "Settings", "NumChar") ' add new entry to menu myItems(numItems)="Item"+Val(numItems)+"="+GetDocumentURL + Chr(13) +Chr(10) ' write ini file CreateIniFile(myIni, numItems, myItems(),mySettings()) ' refresh menu myInterfaces()=GetInterfaces For i = 0 To UBound(myInterfaces) FillMenuFromIni(myInterfaces(i)) Next i End If isBusy=False End Sub ' show options dialog Sub ArbMenOptions Dim nCount As Integer DialogLibraries.LoadLibrary(strLibName) oDialog = createUnoDialog(DialogLibraries.libArbeitsmenu.dlgArbMen) oDialog.Model.Step = 1 ' show first page oListBox = oDialog.getControl("ListBox1") FillListBoxFromIni ' get menu entries form ini ListBoxChanged=False oDialog.execute ' show dialog End Sub ' remove selected item from list Sub RemoveSelectedItem ListBoxChanged=True selItem=oListBox.SelectedItemPos() If selItem >=0 Then oListBox.removeItems(selItem,1) End If End Sub ' remove all entries from list Sub ClearListBox Dim nCount As Integer nCount = oListBox.getItemCount() If nCount >0 Then For i = 0 to nCount-1 oListBox.removeItems(0,1) Next i End If End Sub ' get menu entries from ini Sub FillMenuFromIni (myInterface As String) Dim numItems As Integer Dim n As Integer Dim numMenuItems Dim myOption As Integer Dim NumChar As Integer Dim S As String ' we need the tools library (ConvertFromUrl) If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If ' remove menu entries starting at 5 numMenuItems=GetNumMenuEntries(strMenuID, myInterface) If numMenuItems > 5 Then RemoveSubMenu(strMenuID, numMenuItems-5, myInterface) End If myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName) numItems=getIniValue(myIni, "ArbMenu", "ItemsCount") 'no entries = exit If numItems=0 Then Exit Sub myOption=Val(getIniValue(myIni, "Settings", "Option")) If myOption <=0 Or myOption >=4 Then myOption=3 ' default 3 full path names NumChar=Val(getIniValue(myIni, "Settings", "NumChar")) If NumChar=0 Then NumChar=80 ' default 80 characters 'fill menu from ini For n = 1 to numItems myDoc=getIniValue(myIni, "ArbMenu", "Item"+Val(n)) Select Case myOption '1 filename only Case 1 S=FileNameoutofPath(myDoc) '2 short path Case 2 S=LongDirFix(myDoc,NumChar) '3 full path Case 3 S=myDoc End Select ' add new menu entry AddSubMenu(strMenuID, "macro:///"+strLibName+"."+strModName+".OpenDoc("+Trim(Str(n)) +")",Trim(Str(n) + " " + S),0,myInterface) Next n End Sub ' fill dialog listbox from ini Sub FillListBoxFromIni ClearListBox Dim numItems As Integer Dim n As Integer Dim myOption As Integer Dim NumChar As Integer myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName) numItems=getIniValue(myIni, "ArbMenu", "ItemsCount") 'settings myOption=Val(getIniValue(myIni, "Settings", "Option")) If myOption <=0 Or myOption >=4 Then myOption=3 oCheckbox = oDialog.getControl("OptionButton"+ Trim (Str(myOption))) oCheckbox.Model.State=1 NumChar=Val(getIniValue(myIni, "Settings", "NumChar")) If NumChar=0 Then NumChar=80 oTextField=oDialog.getControl("txtLength") oTextField.Text=Trim(Str(NumChar)) ' For n = 0 to numItems-1 myDoc=getIniValue(myIni, "ArbMenu", "Item"+Val(n+1)) oListBox.addItem( myDoc, n ) Next n End Sub ' close dialog Sub CancelDialog oDialog.endExecute() End Sub ' close dialog and save Sub CloseDialogAndSave Dim myOption As Integer Dim NumChar As Integer Dim S As String If ListBoxChanged=false Then oDialog.endExecute() Exit Sub End If Dim n As Integer Dim myInterfaces () myInterfaces()=GetInterfaces myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName) 'remove all menu entries numItems=getIniValue(myIni, "ArbMenu", "ItemsCount") For i = 0 To UBound(myInterfaces) RemoveSubMenu(strMenuID, numItems, myInterfaces(i)) Next i numItems=oListBox.getItemCount() Dim myItems(numItems) 'settings For i = 1 to 3 oCheckbox = oDialog.getControl("OptionButton"+ Trim (Str(i))) If oCheckbox.Model.State=1 Then myOption = i Next i oTextField=oDialog.getControl("txtLength") NumChar=Trim(Val(oTextField.getText())) If NumChar=0 Then NumChar=80 mySettings(0)=Trim(Str(myOption)) mySettings(1)=Trim(Str(NumChar)) 'write menu from ListBox For n = 1 to numItems myItems(n)="Item" + Trim(Str(n)) + "=" + oListBox.getItem(n-1) Next n ' save ini file CreateIniFile(myIni, numItems, myItems(), mySettings()) ' refresh menu For i = 0 To UBound(myInterfaces) FillMenuFromIni(myInterfaces(i)) Next i oDialog.endExecute() 'close dialog End Sub ' dialog: switch step 1 or 2 Sub DialogSettings If oDialog.Model.Step = 1 Then oDialog.Model.Step = 2 oDialog.Model.cmdSettings.Label="Einträge" Else oDialog.Model.Step = 1 oDialog.Model.cmdSettings.Label="Einstellungen" End If End Sub ' open doc folder in file manager Sub OpenFileManager(DocDir) Dim TheOS TheOS=OS() If TheOS="WINDOWS" then WinDir=Environ("Windir") Shell(Windir+"\explorer.exe /e,"+DocDir,1) ' Windows ElseIf TheOS="UNIX" Then Shell(strLinuxFileManager + " "+ DocDir ,1) ' Linux ElseIf TheOS="OSX" Then Shell("open "+ DocDir ,1) ' OSX End If End Sub ' open current docs folder in file manager Sub ShowCurrentDocFolder dim oDoc as object oDoc = ThisComponent If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If On error goto ErrH: If (oDoc.hasLocation) Then ' document saved? OpenFileManager(DirectoryNameoutofPath(oDoc.getURL(), "/") Else MsgBox("Bitte speichern Sie das Dokument, bevor Sie diese Funktion verwenden.",64,"Dokument ist nicht gespeichert") End If Exit Sub ErrH: ' document has no location MsgBox("Die Funktion steht hier nicht zur Verfügung.",64,"Fehler") End Sub ' show selected document folder in file manager Sub ShowDocFolder Dim selItem Dim myDoc If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If selItem=oListBox.SelectedItemPos() If selItem >=0 Then myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName) myDoc=getIniValue(myIni, "ArbMenu", "Item"+Val(selItem + 1)) If checkForFile(ConvertToUrl(myDoc))=True Then OpenFileManager(DirectoryNameoutofPath(ConvertToUrl(myDoc), "/")) Else MsgBox("Die Datei " + myDoc +" ist nicht vorhanden" ) End If Else oLabel = oDialog.getControl("Label1") oLabel.SetText("Es ist nichts ausgewählt") ' nothing selected End If End Sub ' Dialog: open document Sub OpenDocFromDialog Dim selItem selItem=oListBox.SelectedItemPos() If selItem >=0 Then OpenDoc ( selItem + 1 ) 'CancelDialog Else oLabel = oDialog.getControl("Label1") oLabel.SetText("Es ist nichts ausgewählt") End If End Sub ' open document from menu Sub OpenDoc (index As Integer) Dim args (0) as New com.sun.star.beans.PropertyValue args(0).Name="MacroExecutionMode" args(0).Value=4 myIni=ConvertFromUrl(getConfigPath+ "/" + strIniFileName) myDoc=getIniValue(myIni, "ArbMenu", "Item"+Val(index)) ' file exists? If checkForFile(ConvertToUrl(myDoc))=True Then ' file exists? TheDoc=StarDesktop.loadComponentFromURL(ConvertToUrl(myDoc),"_blank",0,args()) Else MsgBox("Die Datei " + myDoc +" ist nicht vorhanden" ) End If End Sub ' get document path Function GetDocumentURL As String Dim oDoc Dim sDocURL oDoc = ThisComponent If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If On error goto ErrH: If (oDoc.hasLocation()) Then GetDocumentURL= ConvertFromUrl(oDoc.getURL()) Else MsgBox("Sie müssen das Dokument erst speichern.") ' not saved yet End If Exit Function ErrH: MsgBox("Die Funktion steht hier nicht zur Verfügung.",64,"Fehler") End Function Sub CheckMenu sMenuBar = "private:resource/menubar/menubar" oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier") oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(myInterface ) oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true ) iPos=FindMenuByID(strMenuID,myInterface) oPopupMenu() = oMenuBarSettings.getByIndex( iPos ) oPopupMenuContainer = oPopupMenu(4).Value nSubNumItems=oPopupMenuContainer.getCount() oMenuItem()= oPopupMenuContainer.getByIndex(3) MsgBox(oMenuItem(0).Value) End Sub ' number of menu entries Function GetNumMenuEntries (ID As String, Interface As String) As Integer sMenuBar = "private:resource/menubar/menubar" oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier") oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface) oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true ) iPos=FindMenuByID(ID,Interface) If iPos >= 0 Then oPopupMenu() = oMenuBarSettings.getByIndex( iPos ) oPopupMenuContainer = oPopupMenu(3).Value GetNumMenuEntries=oPopupMenuContainer.getCount() End If End Function ' remove documents from menu Sub RemoveSubMenu(ID As String, numItems As integer, Interface As String) sMenuBar = "private:resource/menubar/menubar" oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier") oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface) oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true ) iPos=FindMenuByID(ID, Interface) If iPos >= 0 Then oPopupMenu() = oMenuBarSettings.getByIndex( iPos ) oPopupMenuContainer = oPopupMenu(3).Value nSubNumItems=oPopupMenuContainer.getCount() For i = 1 to numItems oPopupMenuContainer.removeByIndex(5) Next i oModuleCfgMgr.replaceSettings( sMenuBar, oMenuBarSettings ) End If End Sub ' add sub menu Sub AddSubMenu (ID As String, Action As String, Label As String, iType As Integer, Interface As String) Dim nSubNumItems As Integer 'nSubNumItems=1 'On Error Resume next sMenuBar = "private:resource/menubar/menubar" oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier") oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface) oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true ) iPos=FindMenuByID(ID, Interface) If iPos >= 0 Then oPopupMenu() = oMenuBarSettings.getByIndex( iPos ) oPopupMenuContainer = oPopupMenu(3).Value nSubNumItems=oPopupMenuContainer.getCount() oMenuItem = CreateMenuItem( Action,Label,iType ) oPopupMenuContainer.insertByIndex( nSubNumItems, oMenuItem ) oModuleCfgMgr.replaceSettings( sMenuBar, oMenuBarSettings ) End If End Sub ' create main menu entry Sub CreateTopLevelMenu(ID As String, Label As String, Interface As String) sMenuBar = "private:resource/menubar/menubar" sMyPopupMenuCmdId = "vnd.openoffice.org:" +ID oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier") oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface) oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true ) nCount = oMenuBarSettings.getCount() oPopupMenu = CreatePopupMenu( ID, Label, oMenuBarSettings ) 'insert after last item oMenuBarSettings.insertByIndex( nCount, oPopupMenu ) oModuleCfgMgr.replaceSettings( sMenuBar, oMenuBarSettings ) End Sub ' locate menu by ID Function FindMenuByID (ID As String, Interface As String) As Integer FindMenuByID=-1 sMenuBar = "private:resource/menubar/menubar" oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier") oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager(Interface) oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true ) nCount = oMenuBarSettings.getCount() for i = 0 to nCount-1 oPopupMenu() = oMenuBarSettings.getByIndex( i ) If oPopupMenu(0).Value=ID Then FindMenuByID=i next i End Function ' create menu Function CreatePopupMenu( CommandId, Label, Factory ) as Variant Dim aPopupMenu(3) as new com.sun.star.beans.PropertyValue aPopupMenu(0).Name = "CommandURL" aPopupMenu(0).Value = CommandId aPopupMenu(1).Name = "Label" aPopupMenu(1).Value = Label aPopupMenu(2).Name = "Type" aPopupMenu(2).Value = 0 aPopupMenu(3).Name = "ItemDescriptorContainer" aPopupMenu(3).Value = Factory.createInstanceWithContext(GetDefaultContext() ) CreatePopupMenu = aPopupMenu() End Function ' create menu item Function CreateMenuItem( Command as String, Label as String, iType As Integer ) as Variant Dim aMenuItem(2) as new com.sun.star.beans.PropertyValue aMenuItem(0).Name = "CommandURL" aMenuItem(0).Value = Command aMenuItem(1).Name = "Label" aMenuItem(1).Value = Label aMenuItem(2).Name = "Type" aMenuItem(2).Value = iType CreateMenuItem = aMenuItem() End Function Rem ------------------------------------------ rem helper Rem ------------------------------------------ ' which operating system? function OS()as string select case getGUIType case 1: OS="WINDOWS" case 3: OS="MAC" case 4: OS=iif(instr(environ("HOME"),"Users")=0,"UNIX","OSX") end select end function 'LO/OO config path Function getConfigPath As String oPathSettings = CreateUnoService( "com.sun.star.util.PathSettings" ) sPathConfig = oPathSettings.UserConfig if right(sPathConfig,6) <> "config" then getConfigPath="" Else getConfigPath=sPathConfig endif End Function ' shorten path Function LongDirFix (TargetString As String, Max As Integer) As String Dim i, LblLen, StringLen As Integer Dim TempString As String TempString = TargetString LblLen = Max If Len(TempString) <= LblLen Then LongDirFix = TempString Exit Function End If LblLen = LblLen - 6 For i = Len(TempString) - LblLen To Len(TempString) If Mid$(TempString, i, 1) = "\" Then Exit For Next 'On one line: LongDirFix = Left$(TempString, 3) & "..." & Right$(TempString, Len(TempString) - (i - 1)) End Function ' does sUrl (ini file) exist? Function checkForFile (sUrl As String) As Boolean oSimpleFileAccess = createUnoService( "com.sun.star.ucb.SimpleFileAccess" ) If oSimpleFileAccess.exists(sUrl) = TRUE Then checkForFile=True Else checkForFile=False End If End Function ' CreateIni Sub CreateIniFile (myIniFile As String, NumItems As Integer, myItems As Array, mySettings As Array) Dim i As Integer fileAccessService = createUnoService("com.sun.star.ucb.SimpleFileAccess") textOutputStream = createUnoService("com.sun.star.io.TextOutputStream") 'now open the file.. outputStream = fileAccessService.openFileWrite(myIniFile) outputStream.truncate() textOutputStream.setOutputStream(outputStream) textOutputStream.writeString("[Settings]" +Chr(13) +Chr(10)) textOutputStream.writeString("Option=" + mySettings(0)+Chr(13) +Chr(10)) textOutputStream.writeString("NumChar=" + mySettings(1)+Chr(13) +Chr(10)) textOutputStream.writeString("[ArbMenu]" +Chr(13) +Chr(10)) textOutputStream.writeString("ItemsCount=" + Trim(Str(NumItems))+Chr(13) +Chr(10)) If numItems=0 Then ' no items, exit textOutputStream.writeString(Chr(13) +Chr(10)) textOutputStream.closeOutput() Exit Sub End If For i = 0 to UBound(myItems) textOutputStream.writeString(myItems(i)+Chr(13) +Chr(10)) Next i ' textOutputStream.writeString(Chr(13) +Chr(10)) 'and don't forget to close it.. textOutputStream.closeOutput() End Sub ' get value from ini file Function getIniValue(sIniPath As String, sIniNode As String, sIniKey As String) oUcb = createUnoService("com.sun.star.ucb.SimpleFileAccess") iKeyLength = len(sIniKey) If oUcb.Exists(sIniPath) Then oInputStream = createUnoService("com.sun.star.io.TextInputStream") oFile = oUcb.OpenFileReadWrite(sIniPath) oInputStream.SetInputStream(oFile.GetInputStream) 'find node Do While Not oInputStream.IsEOF sLine = oInputStream.ReadLine If sLine = "[" & sIniNode & "]" Then sLine = oInputStream.ReadLine Exit Do 'going out here and start the next loop, searching the key End If Loop 'find key Do While ((Not (Left(sLine, 1) = "[")) AND (Not oInputStream.IsEOF)) If left(sLine, iKeyLength) = sIniKey Then sValue = mid(sLine,iKeyLength + 2) Exit Do ' going out, no need for further searching End If sLine = oInputStream.Readline Loop oInputStream.CloseInput() Else msgbox("ini-file:" & sIniPath & " nicht gefunden.") End If getIniValue = sValue End Function
Hallo, nach der Installation habe ich ein Problem mit dem Tool. Installiert ist LibreOffice 6.1.5.2(64bit), Java 8 201.
Beim Start von LibreOffice kommt eine Fehlermeldung im Makroeditor: BASIC-Laufzeitfehler, Objektvariable nicht belegt.
Im Editor wird die Zeile 506 angezeigt: GetNumMenuEntries=oPopupMenuContainer.getCount().
Das Tool läßt sich nicht mehr deinstallieren, der Menüeintrag bleibt bestehen, und auch nicht mehr korrekt installieren, die Fehlermeldung bleibt hartnäckig bestehen.
Frage: Was kann ich tun?
Mit besten Grüßen
Frank Volberg
Es kann sein, dass es bei neueren Libre-Office-Versionen zu Problemen kommt. Das werde ich bei Gelegenheit durch ein Update beheben.
Wenn die Deinstallation nicht klappt, bitte auf „Extras -> Anpassen“ und dann auf die Registerkarte „Ereignisse“ gehen. Hinter „Speichern in:“ bitte „LibreOffice“ wählen. Dann bei „Programmstart“ den Autostart des Makros löschen.
Auf der Registerkarte „Menüs“ wählen Sie auf der rechten Seite „Arbeitsmenü“ und löschen es über die „x“-Schaltfläche.