<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<!--***********************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 ***********************************************************-->
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="ScriptBinding" script:language="StarBasic">REM  *****  BASIC  *****

REM ----- Global Variables -----

&apos;bindingDialog can refer to either KeyBinding or MenuBinding dialog
private languages() as String 
private extensions() as Object 
private locations() as String  
private filesysScripts() as String
private filesysCount as integer
private bindingDialog as object
private helpDialog as object
&apos;Couldn&apos;t get redim to work, so scriptDisplayList is and array of arrays
&apos;where the one and only array in scriptDisplayList is an array
&apos;of com.sun.star.beans.PropertyValue, where Name = [logicalName][FunctionName]
&apos;and value is ScriptStorage object
private scriptDisplayList(0)
private testArray() as String
&apos;Array to store lines from the xml file
private xmlFile() as string
&apos;Name of the xml file [writer/calc][menubar/keybindings].xml
private xmlFileName as string
&apos;Number of lines in the xml file
private numberOfLines as integer

&apos;Parallel arrays to store all top-level menu names and line positions
private menuItems() as string
private menuItemLinePosition() as integer
&apos;Counter for the number of top-level menus
private menuCount as integer

&apos;Parallel arrays to store all sub-menu names and line positions for a particular top-level menu
private subMenuItems() as string
private subMenuItemLinePosition() as integer
&apos;Counter for the number of sub-menus
private subMenuCount as integer

&apos;Parallel arrays to store all script names and line positions
private scriptNames() as string
private scriptLinePosition() as integer
&apos;Counter for the number of scripts
private scriptCount as integer

&apos;Array to store all combinations of key bindings
private allKeyBindings() as string

&apos;Array of Arrays
&apos;KeyBindArrayOfArrays(0)  contains array of &quot;SHIFT + CONTROL + F Keys&quot; data
&apos;Similarly
&apos;KeyBindArrayOfArrays(1) contains SHIFT + CONTROL + digits
&apos;KeyBindArrayOfArrays(2) contains SHIFT + CONTROL + letters
&apos;KeyBindArrayOfArrays(3) contains CONTROL + F keys
&apos;KeyBindArrayOfArrays(4) contains CONTROL + digits
&apos;KeyBindArrayOfArrays(5) contains CONTROL + letters 
&apos;KeyBindArrayOfArrays(6) contains SHIFT + F keys
private KeyBindArrayOfArrays(6)

&apos;Each PropertyValue represents a key, Name member contains the script (if a binding exists)
&apos; the Value contains and integer
&apos;       0  means no script bound
&apos;       1  script is bound to an office function
&apos;       &gt;1 line number of entry in xmlfile array
private keyAllocationMap(6,25) as new com.sun.star.beans.PropertyValue
&apos;array to store key group descriptions
private AllKeyGroupsArray(6) as String


&apos;Array of props to store all event bindings for the Applications
private	allEventTypesApp( 14 ) as new com.sun.star.beans.PropertyValue
&apos;Array of props to store all event bindings for the Document
private	allEventTypesDoc( 14 ) as new com.sun.star.beans.PropertyValue
&apos;Array of props to store all event types (Name) and textual description (Value)
private allEventTypes( 14 ) as new com.sun.star.beans.PropertyValue


private dialogName as String
REM ------ Storage Refresh Function ------


sub RefreshUserScripts()
&apos; TDB - change Menu bindings to allow user to refresh all, user, share or document script
   RefreshAppScripts( &quot;USER&quot; )
end sub

sub RefreshAllScripts()
   RefreshAppScripts( &quot;USER&quot; )
   RefreshAppScripts( &quot;SHARE&quot; )
   RefreshDocumentScripts
end sub 

sub RefreshAppScripts( appName as String )
   On Error Goto ErrorHandler
   smgr = getProcessServiceManager()
   context = smgr.getPropertyValue( &quot;DefaultContext&quot; )
   scriptstoragemgr = context.getValueByName( &quot;/singletons/drafts.com.sun.star.script.framework.storage.theScriptStorageManager&quot; )

   scriptstoragemgr.refreshScriptStorage( appName )

   Exit sub

   ErrorHandler:
   reset
   MsgBox (&quot;Error: Unable to refresh Java (scripts)&quot; + chr$(10) + chr$(10)+ &quot;Detail: &quot; &amp; error$ + chr$(10) + chr$(10)+ &quot;Action: Please restart Office&quot;,0,&quot;Error&quot; )
   
end sub 

sub RefreshDocumentScripts()
   On Error Goto ErrorHandler
   smgr = getProcessServiceManager()
   context = smgr.getPropertyValue( &quot;DefaultContext&quot; )
   scriptstoragemgr = context.getValueByName( &quot;/singletons/drafts.com.sun.star.script.framework.storage.theScriptStorageManager&quot; )

   oDocURL = ThisComponent.GetCurrentController.getModel.getURL

   On Error Goto ErrorHandlerDoc
   scriptstoragemgr.refreshScriptStorage( oDocURL )

   Exit sub

   ErrorHandlerDoc:
   reset
   &apos; Ignore document script errors as it will happen when refreshing an unsaved doc
   Exit sub

   ErrorHandler:
   reset
   MsgBox (&quot;Error: Unable to refresh Java (scripts)&quot; + chr$(10) + chr$(10)+ &quot;Detail: &quot; &amp; error$ + chr$(10) + chr$(10)+ &quot;Action: Please restart Office&quot;,0,&quot;Error&quot; )
   
end sub 


REM ----- Launch Functions -----

Sub createAndPopulateKeyArrays()
	&apos;Create SHIFT + CONTROL + F keys array
	&apos;Dim keyGroupProp as new com.sun.star.beans.PropertyValue

	Dim SCFKey( 11 )
	for FKey = 1 to 12
		SCFKey( FKey - 1 ) = &quot;SHIFT + CONTROL + F&quot; + FKey
	next FKey
	
	KeyBindArrayOfArrays(0) = SCFKey()
	
	&apos;Create SHIFT + CONTROL + digits
	Dim SCDKey( 9 )
	for Digit = 0 to 9
		SCDKey( Digit ) = &quot;SHIFT + CONTROL + &quot; + Digit
	next Digit
	KeyBindArrayOfArrays(1) = SCDKey()
	
	&apos;Create SHIFT + CONTROL + letters

	Dim SCLKey( 25 )
	for Alpha = 65 to 90
		SCLKey( Alpha - 65 ) = &quot;SHIFT + CONTROL + &quot; + chr$( Alpha )
	next Alpha
	KeyBindArrayOfArrays(2) = SCLKey()

	&apos;Create CONTROL + F keys	
	Dim CFKey( 11 )
	for FKey = 1 to 12
		CFKey( Fkey - 1 ) = &quot;CONTROL + F&quot; + FKey
	next FKey
	KeyBindArrayOfArrays(3) = CFKey()
	
	&apos;Create CONTROL + digits
	Dim CDKey( 9 )
	for Digit = 0 to 9
		CDKey( Digit ) = &quot;CONTROL + &quot; + Digit
	next Digit
	KeyBindArrayOfArrays(4) = CDKey()
		
	&apos;Create CONTROL + letters
	Dim CLKey( 25 )
	for Alpha = 65 to 90 
		CLKey( Alpha - 65 ) = &quot;CONTROL + &quot; + chr$( Alpha )
	next Alpha	
	KeyBindArrayOfArrays(5) = CLKey()
		
	&apos;Create SHIFT + F Keys
	Dim SFKey( 11 )
	for FKey = 1 to 12
		SFKey( Fkey - 1 ) = &quot;SHIFT + F&quot; + FKey
	next FKey
	KeyBindArrayOfArrays(6) = SFKey()
	
End Sub 

Sub updateMapWithDisabledKeys()
	&apos;disable CONTROL + F1 &amp;
	keyAllocationMap( 3, 0 ).Value = 1
	keyAllocationMap( 3, 0 ).Name = &quot;&quot;
	&apos;disable CONTROL + F4 &amp;
	keyAllocationMap( 3, 3 ).Value = 1
	keyAllocationMap( 3, 3 ).Name = &quot;&quot;	
	&apos;disable CONTROL + F6 
	keyAllocationMap( 3, 5 ).Value = 1
	keyAllocationMap( 3, 5 ).Name = &quot;&quot;


	&apos;disable SHIFT + F1 &amp;
	keyAllocationMap( 6, 0 ).Value = 1
	keyAllocationMap( 6, 0 ).Name = &quot;&quot;
	&apos;disable SHIFT + F2 &amp;
	keyAllocationMap( 6, 1 ).Value = 1
	keyAllocationMap( 6, 1 ).Name = &quot;&quot;
	&apos;disable SHIFT + F6 &amp;
	keyAllocationMap( 6, 5 ).Value = 1
	keyAllocationMap( 6, 5 ).Name = &quot;&quot;

End Sub

Sub initialiseFileExtensions()
	ReDim extensions(ubound(languages())+1) as Object
	oConfigProvider = CreateUnoService( &quot;com.sun.star.configuration.ConfigurationProvider&quot; )
    Dim configArgs(1) as new com.sun.star.beans.PropertyValue
    configargs(0).Name = &quot;nodepath&quot;
    configArgs(0).Value = &quot;org.openoffice.Office.Scripting/ScriptRuntimes&quot;
    configargs(1).Name = &quot;lazywrite&quot;
    configArgs(1).Value = false
    oConfigAccess = oConfigProvider.createInstanceWithArguments(&quot;com.sun.star.configuration.ConfigurationAccess&quot;, configArgs())
    for index = 0 to ubound(languages())
    		if(languages(index) &lt;&gt; &quot;Java&quot;) then
            	xPropSet = oConfigAccess.getByName(languages(index))
            	extns() = xPropSet.getPropertyValue(&quot;SupportedFileExtensions&quot;)
            	extensions(index) = extns()  
            endif
    next index
end sub

Sub ExecuteEditDebug()
        
	locations = Array ( &quot;User&quot;, &quot;Share&quot;, &quot;Document&quot;, &quot;Filesystem&quot; )
	languages = Array ( &quot;BeanShell&quot;, &quot;JavaScript&quot; )
	dialogName = &quot;EditDebug&quot;
	initialiseFileExtensions()  
	bindingDialog = LoadDialog( &quot;ScriptBindingLibrary&quot;, &quot;EditDebug&quot; )

	PopulateLanguageCombo()
	PopulateLocationCombo()
	PopulateScriptList( languages(0), locations(0) )

	bindingDialog.execute()	
End Sub

Sub ExecuteKeyBinding()
	dialogName = &quot;Key&quot;
    createAndPopulateKeyArrays()
    updateMapWithDisabledKeys()
	xmlFileName = GetDocumentType( &quot;Key&quot; )

	if not (ReadXMLToArray( &quot;Key&quot; )) then
		Exit Sub
	endif

	bindingDialog = LoadDialog( &quot;ScriptBindingLibrary&quot;, &quot;KeyBinding&quot; )
	PopulateKeyBindingList(0)
	initialiseNavigationComboArrays()
    PopulateLanguageCombo()
    PopulateLocationCombo()
	PopulateScriptList( languages(0), locations(0) )
	PopulateTopLevelKeyBindingList()
	bindingDialog.execute()
end Sub

    
Sub initialiseNavigationComboArrays()
    locations = Array ( &quot;User&quot;, &quot;Share&quot;, &quot;Document&quot;, &quot;Filesystem&quot; )
    ReDim languages(0) as String
    ReDim extensions(0) as Object
	languages(0) = &quot;Java&quot;
	REM extensions(0) = &quot;&quot;
	
    &apos; Setup languages array for all supported languages
    oServiceManager = GetProcessServiceManager()
    svrArray = oServiceManager.getAvailableServiceNames
    
    langCount = 1
    for index = 0 to ubound(svrArray)
        iPos = inStr(svrArray(index), &quot;ScriptProviderFor&quot;)

        if (iPos &gt; 0) then
            lang = Mid(svrArray(index), iPos + Len(&quot;ScriptProviderFor&quot;)

            if not (lang = &quot;Java&quot;) then
                &apos;Add to language vector
                ReDim Preserve languages(langCount) as String
                languages(langCount) = lang
                langCount = langCount + 1
            endif
        endif  
    next index
    initialiseFileExtensions()
End Sub


Sub ExecuteEventBinding
	dialogName = &quot;Event&quot;
	createAllEventTypes()
	createAllEventBindings()
	
	&apos;Populate application event bindings array (from config xml file)
	if not (ReadXMLToArray( &quot;Event&quot; )) then
		Exit Sub
	endif
	&apos;Populate document event bindings array (using Office API calls)
	ReadEventsFromDoc()
		
	bindingDialog = LoadDialog( &quot;ScriptBindingLibrary&quot;, &quot;EventsBinding&quot; )
	initialiseNavigationComboArrays()
    PopulateLanguageCombo()
    PopulateLocationCombo()
	PopulateScriptList( languages(0), locations(0) )
	populateEventList( 0 )
	EventListListener()
	bindingDialog.execute()
End Sub

Sub ExecuteMenuBinding()
	dialogName = &quot;Menu&quot;
	xmlFileName = GetDocumentType( &quot;Menu&quot; )
	if not (ReadXMLToArray( &quot;Menu&quot; )) then
		Exit Sub
	endif

	bindingDialog = LoadDialog( &quot;ScriptBindingLibrary&quot;, &quot;MenuBinding&quot; )
	initialiseNavigationComboArrays()
    PopulateLanguageCombo()
    PopulateLocationCombo()
	PopulateScriptList( languages(0), locations(0) )
	PopulateMenuCombo()
	PopulateSubMenuList( 1 )

	subMenuList = bindingDialog.getControl(&quot;SubMenuList&quot;)
	
	subMenuList.selectItemPos( 0, true )

	bindingDialog.execute()	
end Sub


REM ----- Initialising functions -----


function LoadDialog( libName as string, dialogName as string ) as object
	dim library as object
	dim libDialog as object
	dim runtimeDialog as object
	libContainer = DialogLibraries
	libContainer.LoadLibrary( libName )
	library = libContainer.getByName( libname )
	libDialog = library.getByName( dialogName )
	runtimeDialog = CreateUnoDialog( libDialog )
	LoadDialog() = runtimeDialog

end function


function GetDocumentType( bindingType as string ) as string
	document = StarDesktop.ActiveFrame.Controller.Model
	Dim errornumber As Integer
	errornumber = 111
	Error errornumber
	if document.SupportsService(&quot;com.sun.star.sheet.SpreadsheetDocument&quot;) then
		if bindingType = &quot;Key&quot; then
			GetDocumentType() = &quot;calckeybinding.xml&quot;
		else
			if bindingType = &quot;Menu&quot; then
				GetDocumentType() = &quot;calcmenubar.xml&quot;
			end if
		end if
	elseif document.SupportsService(&quot;com.sun.star.text.TextDocument&quot;) then
		if bindingType = &quot;Key&quot; then
			GetDocumentType() = &quot;writerkeybinding.xml&quot;
		else
			if bindingType = &quot;Menu&quot; then
				GetDocumentType() = &quot;writermenubar.xml&quot;
			end if	
		end if
	elseif document.SupportsService(&quot;com.sun.star.presentation.PresentationDocument&quot;) then
		if bindingType = &quot;Key&quot; then
			GetDocumentType() = &quot;impresskeybinding.xml&quot;
		else
			if bindingType = &quot;Menu&quot; then
				GetDocumentType() = &quot;impressmenubar.xml&quot;
			end if	
		end if
	elseif document.SupportsService(&quot;com.sun.star.presentation.PresentationDocument&quot;) then
		if bindingType = &quot;Key&quot; then
			GetDocumentType() = &quot;impresskeybinding.xml&quot;
		else
			if bindingType = &quot;Menu&quot; then
				GetDocumentType() = &quot;impressmenubar.xml&quot;
			end if	
		end if
	elseif document.SupportsService(&quot;com.sun.star.drawing.DrawingDocument&quot;) then
		if bindingType = &quot;Key&quot; then
			GetDocumentType() = &quot;drawkeybinding.xml&quot;
		else
			if bindingType = &quot;Menu&quot; then
				GetDocumentType() = &quot;drawmenubar.xml&quot;
			end if	
		end if
	else
		MsgBox (&quot;Error: Couldn&apos;t determine configuration file type&quot; + chr$(10) + chr$(10) + &quot;Action: Please reinstall Scripting Framework&quot;,0,&quot;Error&quot; )
	end if
end function

function lastIndexOf( targetStr as String, substr as String ) as Integer
	copyStr = targetStr
	while instr(copyStr, substr) &gt; 0
		pos = instr(copyStr, substr)
		tpos = tpos + pos
		copyStr = mid(copyStr, pos+1, len(copyStr)-pos )
	wend
	lastIndexOf() = tpos
end function

function getScriptURI( selectedScript as String ) as String
	combo = bindingDialog.getControl( &quot;LocationCombo&quot; )
	location = combo.text 
	if ( location = &quot;User&quot; ) then 
		location = &quot;user&quot;
	elseif ( location = &quot;Share&quot; ) then
		location = &quot;share&quot;
	elseif ( location = &quot;Filesystem&quot; ) then
		location = &quot;filesystem&quot;
	else
		location = &quot;document&quot;
	end if



	if ( location = &quot;filesystem&quot; ) then
		REM need to build URI here - dcf
		combo = bindingDialog.getControl( &quot;LanguageCombo&quot; )
		language = combo.text
		url = selectedscript
		pos = lastIndexOf( url, &quot;/&quot; )
		locationPath =  mid( url, 1, pos)
        url = mid( url, pos+1, len( url ) - pos )
		functionName = url
		pos = lastIndexOf( url, &quot;.&quot; )
		logicalName = mid( url, 1, pos - 1 )
		getScriptURI() = &quot;script://&quot; + logicalName + &quot;?language=&quot; _
			+ language + &quot;&amp;amp;function=&quot; + functionName _
			+ &quot;&amp;amp;location=filesystem:&quot; + locationPath
	else
		Dim scriptInfo as Object
		scripts() = scriptDisplayList(0)
		for n = LBOUND( scripts() ) to UBOUND( scripts() )

			if ( scripts( n ).Name = selectedScript ) then
				scriptInfo = scripts( n ).Value
				exit for
			end if
		next n
		getScriptURI() = &quot;script://&quot; + scriptInfo.getLogicalName + &quot;?language=&quot; _
			+ scriptInfo.getLanguage() + &quot;&amp;amp;function=&quot; + _
			scriptInfo.getFunctionName() + &quot;&amp;amp;location=&quot; + location 	
	end if
	
end function

function GetOfficePath() as string
	REM Error check and prompt user to manually input Office Path
	settings =  CreateUnoService( &quot;com.sun.star.frame.Settings&quot; )
	path = settings.getByName( &quot;PathSettings&quot; )
	unformattedOfficePath = path.getPropertyValue( &quot;UserPath&quot; )

	dim officePath as string 
	const removeFromEnd = &quot;/user&quot;
	const removeFromEndWindows = &quot;\user&quot;

	REM If Solaris or Linux
	if not ( instr( unformattedOfficePath, removeFromEnd ) = 0 ) then
		endPosition = instr( unformattedOfficePath, removeFromEnd )
		officePath = mid( unformattedOfficePath, 1, endPosition )
	REM If Windows
	else if not ( instr( unformattedOfficePath, removeFromEndWindows ) = 0 ) then
			endPosition = instr( unformattedOfficePath, removeFromEndWindows )
			officePath = mid( unformattedOfficePath, 1, endPosition )
			while instr( officePath, &quot;\&quot; ) &gt; 0
				backSlash = instr( officePath, &quot;\&quot; )
				startPath = mid( officePath, 1, backSlash - 1 )
				endPath = mid( officePath, backslash + 1, len( officePath ) - backSlash )
				officePath = startPath + &quot;/&quot; + endPath
			wend
		else
			MsgBox (&quot;Error: Office path not found&quot; + chr$(10) + chr$(10) + &quot;Action: Please reinstall Scripting Framework&quot;,0,&quot;Error&quot; )
			REM Prompt user
		end if
	end if
	
	GetOfficePath() = officePath
end function



REM ----- File I/O functions -----


function ReadXMLToArray( bindingType as string ) as boolean
	On Error Goto ErrorHandler
	if ( bindingType = &quot;Event&quot; ) then
		xmlfilename = &quot;eventbindings.xml&quot;
	endif
	
	simplefileaccess = CreateUnoService( &quot;com.sun.star.ucb.SimpleFileAccess&quot; )
	filestream = simplefileaccess.openFileRead( &quot;file://&quot; + GetOfficePath() + &quot;user/config/soffice.cfg/&quot; + xmlFileName )

    textin = CreateUnoService( &quot;com.sun.star.io.TextInputStream&quot; )
    textin.setInputStream( filestream )

    redim xmlFile( 400 ) as String
    redim menuItems( 30 ) as String
    redim menuItemLinePosition( 30 ) as Integer
    redim scriptNames( 120 ) as string
    redim scriptLinePosition( 120) as integer
    
    lineCount = 1
    menuCount = 1
    scriptCount = 1
    
    do while not textin.isEOF()
    	xmlline = textin.readLine()
    	xmlFile( lineCount ) = xmlline

 		const menuItemWhiteSpace = 2
 		const menuXMLTag = &quot;&lt;menu:menu&quot;

		if bindingType = &quot;Menu&quot; then
			evaluateForMenu( xmlline, lineCount )
		elseif bindingType = &quot;Key&quot; then
			processKeyXMLLine( lineCount, xmlline )
		elseif bindingType = &quot;Event&quot; then
			evaluateForEvent( xmlline, lineCount )
		else
			MsgBox (&quot;Error: Couldn&apos;t determine file type&quot; + chr$(10) + chr$(10) + &quot;Action: Please reinstall Scripting Framework&quot;,0,&quot;Error&quot; )
		end if
        lineCount = lineCount + 1
    loop
	
	&apos;Set global variable numberOfLines (lineCount is one too many at end of the loop)
	numberOfLines = lineCount - 1
	&apos;Set global variable menuCount (it is one too many at end of the loop)
	menuCount = menuCount - 1
	
    filestream.closeInput()
    ReadXMLToArray( ) = true
	Exit function

	ErrorHandler:
	reset
	MsgBox (&quot;Error: Unable to read Star Office configuration file - &quot; + xmlFileName + chr$(10) + chr$(10) + &quot;Action: Please reinstall Scripting Framework&quot;,0,&quot;Error&quot; )
    ReadXMLToArray( ) = false
end function



sub evaluateForMenu( xmlline as string, lineCount as integer )
	const menuItemWhiteSpace = 2
 	const menuXMLTag = &quot;&lt;menu:menu&quot;
	&apos;If the xml line is a top-level menu
	if instr( xmlline, menuXMLTag ) = menuItemWhiteSpace then
		menuLabel = ExtractLabelFromXMLLine( xmlline )
		menuItems( menuCount ) = menuLabel
		menuItemLinePosition( menuCount ) = lineCount
		menuCount = menuCount + 1
	end if
end sub

sub evaluateForEvent( xmlline as string, lineCount as integer )
	dim eventName as String
	&apos;if the xml line identifies a script or SB macro
	dim scriptName as string
	dim lineNumber as integer
	if instr( xmlline, &quot;event:language=&quot; + chr$(34) + &quot;Script&quot; ) &gt; 0 then 
		eventName = ExtractEventNameFromXMLLine( xmlline ) 
		scriptName = ExtractEventScriptFromXMLLine( xmlline )
		lineNumber = lineCount
	elseif instr( xmlline, &quot;event:language=&quot; + chr$(34) + &quot;StarBasic&quot; ) &gt; 0 then
		eventName = ExtractEventNameFromXMLLine( xmlline )
		scriptName = &quot;Allocated to Office function&quot;
		lineNumber = 1
	end if
	
	&apos;Need to sequence to find the corresponding index for the event type
	for n = 0 to ubound( allEventTypesApp() )
		if ( eventName = allEventTypes( n ).Name ) then
			allEventTypesApp( n ).Name = scriptName
			allEventTypesApp( n ).Value = lineNumber
		end if
	next n	
end sub


function isOKscriptProps( props() as Object, eventName as string ) as Boolean
	On Error Goto ErrorHandler
	props  = ThisComponent.getEvents().getByName( eventName )
	test = ubound( props() )
	isOKscriptProps() = true
	exit function
	
	ErrorHandler:
	isOKscriptProps() = false
end function

sub ReadEventsFromDoc()
	On Error Goto ErrorHandler
	
	eventSupplier = ThisComponent
	for n = 0 to ubound( allEventTypes() )
		Dim scriptProps() as Object
		if (isOKscriptProps( scriptProps(), allEventTypes( n ).Name) ) then
			if ( ubound( scriptProps ) &gt; 0 ) then
				if ( scriptProps(0).Value = &quot;Script&quot; ) then
					&apos;Script binding
					allEventTypesDoc(n).Name = scriptProps(1).Value					
					allEventTypesDoc(n).value = 2
				elseif( scriptProps(0).Value = &quot;StarBasic&quot; ) then
					&apos;StarBasic macro
					allEventTypesDoc(n).Name = &quot;Allocated to Office function&quot;
					allEventTypesDoc(n).value = 1
				end if
			end if
		end if
	next n
	
	exit sub
	
	&apos; eventProps is undefined if there are no event bindings in the doc
	ErrorHandler:
	reset
end sub


sub WriteEventsToDoc()
	On Error Goto ErrorHandler
	
	eventSupplier = ThisComponent
	for n = 0 to ubound( allEventTypes() )
		scriptName = allEventTypesDoc( n ).Name
		eventName = allEventTypes( n ).Name
		if( allEventTypesDoc( n ).Value &gt; 1 ) then &apos;script
			&apos;add to doc
			AddEventToDocViaAPI( scriptName, eventName )
		elseif( allEventTypesDoc( n ).Value = 0 ) then &apos;blank (this will &quot;remove&quot; already blank entries)
			&apos;remove from doc
			RemoveEventFromDocViaAPI( eventName )
		endif
		&apos;Otherwise it is a StarBasic binding - leave alone
	next n
	&apos;Mark document as modified ( should happen automatically as a result of calling the API )
	ThisComponent.CurrentController.getModel().setModified( True )
	exit sub
	
	ErrorHandler:
	reset
	msgbox( &quot;Error calling UNO API for writing event bindings to the document&quot; )
end sub


sub RemoveEventFromDocViaAPI( event as string )
	dim document   as object
	dim dispatcher as object
	dim parser     as object
	dim url        as new com.sun.star.util.URL
	
	document = ThisComponent.CurrentController.Frame
	parser   = createUnoService(&quot;com.sun.star.util.URLTransformer&quot;)
	dim args(0) as new com.sun.star.beans.PropertyValue
	args(0).Name = &quot;&quot;
	args(0).Value = event

	url.Complete = &quot;script://_$ScriptFrmwrkHelper.removeEvent?&quot; _
					+ &quot;language=Java&amp;function=ScriptFrmwrkHelper.removeEvent&quot; _
					+ &quot;&amp;location=share&quot;
					
	parser.parseStrict(url)
	disp = document.queryDispatch(url,&quot;&quot;,0)
	disp.dispatch(url,args())
end sub


sub AddEventToDocViaAPI( scriptName as string, eventName as string )
	dim properties( 1 ) as new com.sun.star.beans.PropertyValue
	properties( 0 ).Name = &quot;EventType&quot;
	properties( 0 ).Value = &quot;Script&quot;
	properties( 1 ).Name = &quot;Script&quot;
	properties( 1 ).Value = scriptName
		
	eventSupplier = ThisComponent
	nameReplace = eventSupplier.getEvents()
	nameReplace.replaceByName( eventName, properties() )
end sub


&apos; returns 0 for Fkey
&apos;         1 for digit
&apos;         2 for letter

function getKeyTypeOffset( key as String ) as integer
	length = Len( key )
	if ( length &gt; 1 ) then
 		getKeyTypeOffset() = 0
		
	elseif  ( key &gt;= &quot;0&quot; AND key &lt;= &quot;9&quot; )  then
 		getKeyTypeOffset() = 1
	else
 		getKeyTypeOffset() = 2
 	end if
end function

function getKeyGroupIndex( key as String, offset as Integer ) as Integer
    &apos; Keys we are interested in are A - Z, F2 - F12, 0 - 9 anything else should
    &apos; ensure -1 is returned
	cutKey = mid( key,2 )

	if ( cutKey &lt;&gt; &quot;&quot; ) then 
		acode = asc ( mid( cutKey,1,1) )
        if ( acode &gt; 57 ) then		
			getKeyGroupIndex() = -1
			exit function
		end if
	end if
	
	select case offset
	case 0:
			num = cint( cutKey )
			getKeyGroupIndex() = num - 1
			exit function
	case 1:	
			num = asc( key ) - 48
			getKeyGroupIndex() = num
			exit function
	case 2: 
			num = asc( key ) - 65
			getKeyGroupIndex() = num
			exit function
	end select
	getKeyGroupIndex() = -1
end function

Sub processKeyXMLLine( lineCount as Integer, xmlline as String )

	if instr( xmlline, &quot;&lt;accel:item&quot; ) &gt; 0 then
		shift = false
		control = false
		if instr( xmlline, &quot;accel:shift=&quot;+chr$(34)+&quot;true&quot;+chr$(34) ) &gt; 0 then
			shift = true
		end if
		if instr( xmlFile( lineCount ), &quot;accel:mod1=&quot;+chr$(34)+&quot;true&quot;+chr$(34) ) &gt; 0 then
			control = true
		end if
		offsetIntoArrayOfArrays = -1 &apos;default unknown
		if ( control AND shift ) then
			offsetIntoArrayOfArrays = 0
		elseif ( control ) then
			offsetIntoArrayOfArrays = 3
		elseif ( shift ) then
			offsetIntoArrayOfArrays = 6
		endif
		&apos; Calculate which of the 7 key group arrays we need to point to
		key = ExtractKeyCodeFromXMLLine( xmlline )
		keyTypeOffset = getKeyTypeOffset( key  )
		offsetIntoArrayOfArrays = offsetIntoArrayOfArrays + keyTypeOffset
		
		&apos; Calculate from the key the offset into key group array we need to point to
		KeyGroupIndex = getKeyGroupIndex( key, keyTypeOffset )
		if ( offsetIntoArrayOfArrays = -1 ) then
			&apos;Unknown key group, no processing necessary
			Exit Sub
		end if 
		if ( KeyGroupIndex &gt; -1 ) then
		
			&apos; Determine if a script framework binding is present or not	
			if  instr( xmlline, &quot;script://&quot; ) &gt; 0 then
				&apos; its one of ours so update its details
				scriptName = ExtractScriptIdFromXMLLine( xmlline )

				keyAllocationMap( offsetIntoArrayOfArrays, KeyGroupIndex ).Value = lineCount
				keyAllocationMap( offsetIntoArrayOfArrays, KeyGroupIndex ).Name = scriptName
			else
				keyAllocationMap( offsetIntoArrayOfArrays, KeyGroupIndex ).Value = 1
				keyAllocationMap( offsetIntoArrayOfArrays, KeyGroupIndex ).Name = &quot;&quot;

			end if
		end if
	end if		
End Sub

Sub WriteXMLFromArray()
	On Error Goto ErrorHandler
	cfgFile =  GetOfficePath() + &quot;user/config/soffice.cfg/&quot; + xmlFileName 
	updateCfgFile( cfgFile )
	&apos;if ( false ) then&apos; config stuff not in build yet
	if ( true ) then
		updateConfig( xmlFileName )
	else
		msgbox (&quot;Office must be restarted before your changes will take effect.&quot;+ chr$(10)+&quot;Also close the Office QuickStarter (Windows and Linux)&quot;, 48, &quot;Assign Script (Java) To Menu&quot; )
	endif
	Exit Sub
	
	ErrorHandler:
	reset
	MsgBox (&quot;Error: Unable to write to Star Office configuration file&quot; + chr$(10) + &quot;/&quot; + GetOfficePath() + &quot;user/config/soffice.cfg/&quot; +xmlFileName + chr$(10) + chr$(10) + &quot;Action: Please make sure you have write access to this file&quot;,0,&quot;Error&quot; )
end Sub


Sub UpdateCfgFile ( fileName as String )
	dim ScriptProvider as Object
	dim Script as Object
	dim args(1)
	dim displayDialogFlag as boolean
	displayDialogFlag = false
	args(0) = ThisComponent
	args(1) = displayDialogFlag
	
	ScriptProvider = createUnoService(&quot;drafts.com.sun.star.script.framework.provider.MasterScriptProvider&quot;)
	ScriptProvider.initialize( args() )
	Script = ScriptProvider.getScript(&quot;script://_$ScriptFrmwrkHelper.updateCfgFile?&quot; _
		+ &quot;language=Java&amp;function=ScriptFrmwrkHelper.updateCfgFile&amp;location=share&quot;)
	Dim inArgs(2)
	Dim outArgs()
	Dim outIndex()
	dim localNumLines as integer

	inArgs(0) = xmlFile()
	inArgs(1) = fileName
	inArgs(2) = numberOfLines
	Script.invoke( inArgs(), outIndex(), outArgs() )
End Sub

sub UpdateConfig( a$ )
       dim document   as object
       dim dispatcher as object
       dim parser     as object
       dim disp     as object
       dim url        as new com.sun.star.util.URL
       document = ThisComponent.CurrentController.Frame
       parser   = createUnoService(&quot;com.sun.star.util.URLTransformer&quot;)
       dim args1(0) as new com.sun.star.beans.PropertyValue
       args1(0).Name = &quot;StreamName&quot;
       args1(0).Value = a$
       url.Complete = &quot;.uno:UpdateConfiguration&quot;
       parser.parseStrict(url)
       disp = document.queryDispatch(url,&quot;&quot;,0)
       disp.dispatch(url,args1())

End Sub


sub AddNewEventBinding( scriptName as string, eventPosition as integer, isApp as boolean )
	event = allEventTypes( eventPosition ).Name
	&apos;dim scriptProp as new com.sun.star.beans.PropertyValue
	if isApp then
		&apos;scriptProp.Name = scriptName
		&apos;scriptProp.Value = numberOfLines
		allEventTypesApp( eventPosition ).Name = scriptName
		allEventTypesApp( eventPosition ).Value = numberOfLines
	
		newline = &quot; &lt;event:event event:name=&quot; + chr$(34) + event + chr$(34)
		newline = newline + &quot; event:language=&quot; + chr$(34) + &quot;Script&quot; + chr$(34) + &quot; xlink:href=&quot; + chr$(34)
		newline = newline + scriptName + chr$(34) + &quot; xlink:type=&quot; + chr$(34) + &quot;simple&quot; + chr$(34) + &quot;/&gt;&quot;	
		xmlFile( numberOfLines ) = newline
		xmlFile( numberOfLines + 1 ) = &quot;&lt;/event:events&gt;&quot;	
		numberOfLines = numberOfLines + 1
	else
		&apos;scriptProp.Name = scriptName
		&apos;scriptProp.Value = 2
		allEventTypesDoc( eventPosition ).Name = scriptName
		allEventTypesDoc( eventPosition ).Value = 2
	end if	
end sub

REM ----- Array update functions -----


sub AddNewMenuBinding( newScript as string, newMenuLabel as string, newLinePosition as integer )
	dim newXmlFile( 400 ) as string
	dim newLineInserted as boolean
	dim lineCounter as integer
	lineCounter = 1
		
	do while lineCounter &lt;= numberOfLines
		if not newLineInserted then
			REM If the line number is the position at which to insert the new line
			if lineCounter = newLinePosition then
				if( instr( xmlFile( lineCounter ), &quot;&lt;menu:menupopup&gt;&quot; ) &gt; 0 ) then
					indent = GetMenuWhiteSpace( xmlFile( newLinePosition + 1 ) )
					newXmlFile( lineCounter ) = xmlFile( lineCounter )
					newXmlFile( lineCounter + 1 ) = ( indent + &quot;&lt;menu:menuitem menu:id=&quot;+chr$(34) + newScript + chr$(34)+&quot; menu:helpid=&quot;+chr$(34)+&quot;1929&quot;+chr$(34)+&quot; menu:label=&quot;+chr$(34)+ newMenuLabel + chr$(34)+&quot;/&gt;&quot; )
				else
					indent = GetMenuWhiteSpace( xmlFile( newLinePosition - 1 ) )
					newXmlFile( lineCounter ) = ( indent + &quot;&lt;menu:menuitem menu:id=&quot;+chr$(34) + newScript + chr$(34)+&quot; menu:helpid=&quot;+chr$(34)+&quot;1929&quot;+chr$(34)+&quot; menu:label=&quot;+chr$(34)+ newMenuLabel + chr$(34)+&quot;/&gt;&quot; )
					newXmlFile( lineCounter + 1 ) = xmlFile( lineCounter )									
				end if
			REM added -1 for debug --&gt;
			&apos;	indent = GetMenuWhiteSpace( xmlFile( newLinePosition ) )
			&apos;	newXmlFile( lineCounter ) = ( indent + &quot;&lt;menu:menuitem menu:id=&quot;+chr$(34)+&quot;script://&quot; + newScript + chr$(34)+&quot; menu:helpid=&quot;+chr$(34)+&quot;1929&quot;+chr$(34)+&quot; menu:label=&quot;+chr$(34)+ newMenuLabel + chr$(34)+&quot;/&gt;&quot; )
			&apos;	newXmlFile( lineCounter + 1 ) = xmlFile( lineCounter )
				newLineInserted = true
			else
				newXmlFile( lineCounter ) = xmlFile( lineCounter )
			end if
		else
			REM if the new line has been inserted the read from one position behind
			newXmlFile( lineCounter + 1 ) = xmlFile( lineCounter )
		end if
		lineCounter = lineCounter + 1
	loop
		
	numberOfLines = numberOfLines + 1
	
	REM read the new file into the global array
	for n = 1 to numberOfLines
		xmlFile( n ) = newXmlFile( n )
	next n
	
end sub


sub AddNewKeyBinding( scriptName as string, shift as boolean, control as boolean, key as string )

	dim keyCombo as string
	newLine = &quot; &lt;accel:item accel:code=&quot;+chr$(34)+&quot;KEY_&quot; + key +chr$(34)
	if shift then
		keyCombo = &quot;SHIFT + &quot;
		newLine = newLine + &quot; accel:shift=&quot;+chr$(34)+&quot;true&quot;+chr$(34)
	end if
	if control then
		keyCombo = keyCombo + &quot;CONTROL + &quot;
		newLine = newLine + &quot; accel:mod1=&quot;+chr$(34)+&quot;true&quot;+chr$(34)
	end if
	keyCombo = keyCombo + key
	newLine = newLine + &quot; xlink:href=&quot;+chr$(34)+ scriptName +chr$(34) +&quot;/&gt;&quot;
	
	if ( control AND shift ) then
		offsetIntoArrayOfArrays = 0
	elseif ( control ) then
		offsetIntoArrayOfArrays = 3	
	elseif ( shift ) then
		offsetIntoArrayOfArrays = 6
	endif

	keyTypeOffset = getKeyTypeOffset( key  )
	offsetIntoArrayOfArrays = offsetIntoArrayOfArrays + keyTypeOffset
	&apos; Calculate from the key the offset into key group array we need to point to
	KeyGroupIndex = getKeyGroupIndex( key, keyTypeOffset )

	&apos; if key is allready allocated to a script then just reallocate
	if ( keyAllocationMap( offsetIntoArrayOfArrays, KeyGroupIndex ).Value &gt; 1 ) then

		keyAllocationMap( offsetIntoArrayOfArrays, KeyGroupIndex ).Name = scriptName
		&apos;replace line in xml file
		xmlFile( keyAllocationMap( offsetIntoArrayOfArrays, KeyGroupIndex ).Value ) = newLine
	else
		&apos; this is a new binding, create a new line in xml file
		for n = 1 to numberOfLines 
			if n = numberOfLines then
				xmlFile( n ) = newLine
				xmlFile( n + 1 ) = &quot;&lt;/accel:acceleratorlist&gt;&quot;
				exit for
			else
				xmlFile( n ) = xmlFile( n )
			end if
		next n

		keyAllocationMap( offsetIntoArrayOfArrays, KeyGroupIndex ).Value = n	
		keyAllocationMap( offsetIntoArrayOfArrays, KeyGroupIndex ).Name = scriptName	
		numberOfLines = numberOfLines + 1
	endif

end sub


Sub RemoveBinding( lineToRemove as Integer )
	xmlFile( lineToRemove ) = &quot;&quot;
end Sub

REM Adds or removes the starting xml line positions for each top-level menu after the menu with the added script
sub UpdateTopLevelMenus( topLevelMenuPosition as integer, addLine as boolean )
	for n = topLevelMenuPosition to 8
		if addLine then
			menuItemLinePosition( n ) = menuItemLinePosition( n ) + 1

		end if
	next n
end sub


REM Remove scriptNames and scriptLinePosition entries
sub RemoveScriptNameAndPosition( keyComboPosition )
	dim updatedScriptNames( 120 ) as string
	dim updatedScriptLinePosition( 120 ) as integer
	dim removedScript as boolean
	removedScript = false
	
	for n = 1 to scriptCount
		if not removedScript then
			if not( n = keyComboPosition ) then
				updatedScriptNames( n ) = scriptNames( n )
			else
				removedScript = true
			end if
		else
			updatedScriptNames( n - 1 ) = scriptNames( n )
		end if
	next n
	scriptCount = scriptCount - 1
	
	for n = 1 to scriptCount
		scriptNames( n ) = updatedScriptNames( n )
	next n
end sub



REM ----- Populating Dialog Controls -----

Sub PopulateLanguageCombo()
	langCombo =  bindingDialog.getControl( &quot;LanguageCombo&quot; )
	langCombo.removeItems( 0, langCombo.getItemCount() )
	for n = LBOUND( languages() ) to UBOUND ( languages() )
		langCombo.addItem( languages( n ), n )
	next n
	langCombo.setDropDownLineCount( n ) 
	langCombo.text = langCombo.getItem( 0 )	
End Sub

Sub PopulateLocationCombo()
	dim ScriptProvider as Object
	dim args(1)
	dim displayDialogFlag as boolean
	displayDialogFlag = false
	args(0) = ThisComponent
	args(1) = displayDialogFlag
	
	ScriptProvider = createUnoService(&quot;drafts.com.sun.star.script.framework.provider.MasterScriptProvider&quot;)
	ScriptProvider.initialize( args() )

	locCombo =  bindingDialog.getControl( &quot;LocationCombo&quot; )
	locCombo.removeItems( 0, locCombo.getItemCount() )
	for n = LBOUND( locations() ) to UBOUND ( locations() )
		locCombo.addItem( locations( n ), n )
	next n
	locCombo.setDropDownLineCount( n ) 
	locCombo.text = locCombo.getItem( 0 )
End Sub

sub PopulateScriptList( lang as String, loc as String )
    Dim detailedView as boolean
    detailedView = bindingDialog.Model.detail.state
	scriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
	scriptList.removeItems( 0, scriptList.getItemCount() )

	smgr = getProcessServiceManager()
   	context = smgr.getPropertyValue( &quot;DefaultContext&quot; )
   	scriptstoragemgr = context.getValueByName( &quot;/singletons/drafts.com.sun.star.script.framework.storage.theScriptStorageManager&quot; ) 
	scriptLocationURI = &quot;USER&quot;
	if ( loc = &quot;Share&quot; ) then
		scriptLocationURI = &quot;SHARE&quot;
	elseif ( loc = &quot;Document&quot; )then
		document = StarDesktop.ActiveFrame.Controller.Model
		scriptLocationURI = document.getURL()
	elseif ( loc = &quot;Filesystem&quot; ) then
		REM populate the list from the filesysScripts list
		if(lang = &quot;Java&quot; ) then
			exit sub
		endif
		length = UBOUND( filesysScripts() )
		if(length = -1) then
			exit sub
		endif
        for langIndex = lbound(languages()) to ubound(languages())
            if ( lang = languages(langIndex)) then
                extns = extensions(langIndex)
                exit for
            endif
        next langIndex
		dim locnDisplayList( length ) as new com.sun.star.beans.PropertyValue
		for index = lbound(filesysScripts()) to ubound(filesysScripts())
			scriptextn = filesysScripts( index )
			pos = lastIndexOf( scriptextn, &quot;.&quot; )
            scriptextn = mid( scriptextn, pos + 1, len( scriptextn ) - pos )
            
            for extnsIndex = lbound(extns()) to ubound(extns())
                extn = extns(extnsIndex)
                if ( scriptextn = extn ) then 
                	if ( detailedView ) then
                    	locnDisplayList( index ).Name = filesysScripts( index )
                    	locnDisplayList( index ).Value = filesysScripts( index )
                	else
						REM replace name with simplified view
						locnDisplayList( index ).Name = filesysScripts( index )
						locnDisplayList( index ).Value = filesysScripts( index )
					end if
				scriptList.addItem( locnDisplayList( index ).Name, index )
				exit for 
                end if
            next extnsIndex
		next index
		ScriptDisplayList(0) = locnDisplayList()
		scriptList.selectItemPos( 0, true )

        REM !!!!At this point we exit the sub!!!!
		exit sub			

	endif

	scriptStorageID = scriptstoragemgr.getScriptStorageID( scriptLocationURI )
	dim resultList() as Object
	if ( scriptStorageID &gt; -1 ) then
		storage = scriptstoragemgr.getScriptStorage( scriptStorageID )
		implementations() = storage.getAllImplementations()
		length = UBOUND( implementations() )
		reservedScriptTag = &quot;_$&quot;
    	if ( length &gt; -1 ) then
    		dim tempDisplayList( length ) as new com.sun.star.beans.PropertyValue
			for n = LBOUND( implementations() ) to UBOUND( implementations() )
				logicalName = implementations( n ).getLogicalName()
				firstTwoChars = LEFT( logicalName, 2 )
				&apos;Only display scripts whose logicalnames don&apos;t begin with &quot;_$&quot;
				if ( firstTwoChars &lt;&gt; reservedScriptTag ) then
					if ( lang = implementations( n ).getLanguage() ) then
						if ( detailedView ) then
							tempDisplayList( n ).Name = logicalName _
								+ &quot; [&quot; + implementations( n ).getFunctionName() + &quot;]&quot;  
							tempDisplayList( n ).Value = implementations( n )
						else
							tempDisplayList( n ).Name = logicalName
							tempDisplayList( n ).Value = implementations( n )
						endif
						scriptList.addItem( tempDisplayList( n ).Name, n )
					endif
				endif
			next n
			resultList = tempDisplayList()
		endif
	ScriptDisplayList(0) = resultList()
	endif
	scriptList.selectItemPos( 0, true )

end sub

sub PopulateMenuCombo()
	menuComboBox = bindingDialog.getControl( &quot;MenuCombo&quot; )
	menuComboBox.removeItems( 0, menuComboBox.getItemCount() )
	for n = 1 to menuCount
		menuComboBox.addItem( menuItems( n ), n - 1 )
	next n
	menuComboBox.setDropDownLineCount( 8 ) 
	menuComboBox.text = menuComboBox.getItem( 0 )
end sub


sub PopulateSubMenuList( menuItemPosition as integer )
	redim subMenuItems( 100 ) as string
	redim subMenuItemLinePosition( 100 ) as integer
	dim lineNumber as integer
	const menuItemWhiteSpace = 4
	const menuXMLTag = &quot;&lt;menu:menu&quot;
	subMenuCount = 1

	REM xmlStartLine and xmlEndLine refer to the first and last lines
	&apos; menuItemPosition of a top-level menu ( 1=File to 8=Help ) add one line
	xmlStartLine = menuItemLinePosition( menuItemPosition ) + 1

	REM If last menu item is chosen
	if menuItemPosition = menuCount then
		xmlEndLine = numberOfLines
	else
		REM Other wise get the line before the next top-level menu begins
		xmlEndLine = menuItemLinePosition( menuItemPosition + 1 ) - 1
	end if
	
	for lineNumber = xmlStartLine to xmlEndLine
		REM Insert all sub-menus and sub-popupmenus
		if not( instr( xmlFile( lineNumber ), menuXMLTag ) = 0 ) and instr( xmlFile( lineNumber ), &quot;menupopup&quot;) = 0 then
			subMenuIndent = GetMenuWhiteSpace( xmlFile( lineNumber ) )
			if subMenuIndent = &quot; &quot; then
				subMenuIndent = &quot;&quot;
			else
				subMenuIndent = subMenuIndent + subMenuIndent 
			end if
			if not( instr( xmlFile( lineNumber ), &quot;menuseparator&quot; ) = 0 ) then
				subMenuItems( subMenuCount ) = subMenuIndent + &quot;----------------&quot;	
			else
				subMenuName = ExtractLabelFromXMLLine( xmlFile( lineNumber ) )
				REM Add script Name if there is one bound to menu item
				if instr( xmlFile( lineNumber ), &quot;script://&quot; ) &gt; 0 then
					script = ExtractScriptIdFromXMLLine( xmlFile( lineNumber ) )
					subMenuItems( subMenuCount ) = ( subMenuIndent + subMenuName + &quot; [&quot; + script + &quot;]&quot; )
				else
					subMenuItems( subMenuCount ) = subMenuIndent + subMenuName
				end if
			end if
			subMenuItemLinePosition( subMenuCount ) = lineNumber
			subMenuCount = subMenuCount + 1
		end if
	next lineNumber

	subMenuList = bindingDialog.getControl( &quot;SubMenuList&quot; )

	currentPosition = subMenuList.getSelectedItemPos()

	subMenuList.removeItems( 0, subMenuList.getItemCount() )
	&apos;If there are no sub-menus i.e. a dynamically generated menu like Format
	&apos;if subMenuCount = 1 then
	if menuItems( menuItemPosition ) = &quot;Format&quot; then
			subMenuList.addItem( &quot;Unable to Assign Scripts to this menu&quot;, 0 )
	else	
		for n = 1 to subMenuCount - 1
			subMenuList.addItem( subMenuItems( n ), n - 1 )
		next n
	end if

	subMenuList.selectItemPos( currentPosition, true )

	SubMenuListListener()
	MenuLabelBoxListener()
end sub



sub PopulateTopLevelKeyBindingList()

    allKeyGroupsArray(0) =  &quot;SHIFT + CONTROL + F keys&quot;
	allKeyGroupsArray(1) = &quot;SHIFT + CONTROL + digits&quot; &apos; CURRENTLY DISABLED
	allKeyGroupsArray(2) = &quot;SHIFT + CONTROL + letters&quot;
	allKeyGroupsArray(3) = &quot;CONTROL + F keys&quot;
	allKeyGroupsArray(4) = &quot;CONTROL + digits&quot;
	allKeyGroupsArray(5) = &quot;CONTROL + letters&quot;
	allKeyGroupsArray(6) = &quot;SHIFT + F keys&quot;
	
	keyCombo = bindingDialog.getControl( &quot;KeyCombo&quot; )
	keyCombo.removeItems( 0, keyCombo.getItemCount() )
	pos = 0
	for n = LBOUND( allKeyGroupsArray() ) to UBOUND( allKeyGroupsArray() )
	&apos; SHIFT + CONTROL + digits group is disabled at the moment, so skip
	&apos; it
		if ( n &lt;&gt; 1 ) then
			keyCombo.addItem( allKeyGroupsArray( n ), pos )
			pos = pos +1
		endif
	next n 
	keyCombo.text = keyCombo.getItem( 0 )
end sub

sub PopulateKeyBindingList( keyGroupIndex as Integer )
	keyList = bindingDialog.getControl( &quot;KeyList&quot; )
	selectedPos = keyList.getSelectedItemPos()
	keyList.removeItems( 0, keyList.getItemCount() )

	ShortCutKeyArray() = KeyBindArrayOfArrays( keyGroupIndex )

	Dim keyProp as new com.sun.star.beans.PropertyValue
	for n = lbound( ShortCutKeyArray() )  to ubound( ShortCutKeyArray() )
		keyName = ShortCutKeyArray( n )
		if ( keyAllocationMap( keyGroupIndex, n ).Value = 1 ) then
			keyName = keyName + &quot; [Allocated to Office function]&quot;

		elseif ( keyAllocationMap( keyGroupIndex, n ).Value &gt; 1 ) then
			keyName = keyName + &quot; &quot; + keyAllocationMap( keyGroupIndex, n ).Name
		endif
		keyList.addItem( keyName, n )
	next n

	if ( selectedPos &lt;&gt; -1 )then
		keyList.selectItemPos( selectedPos, true )
	else
		keyList.selectItemPos( 0, true )
	end if
	KeyListListener()
end sub

sub populateEventList( focusPosition as integer )
	allApps = bindingDialog.getControl( &quot;AllAppsOption&quot; )
	eventList = bindingDialog.getControl( &quot;EventList&quot; )
	eventList.removeItems( 0, eventList.getItemCount() )

	dim isApp as boolean
	if allApps.state = true then  &apos; Application event	
		isApp = true	
	else
		isApp = false
	end if

	&apos; use allEventTypes() to fill list box 
	&apos; for each element compare with allEventTypesApp
	dim scriptName as string
	dim lineNumber as integer	
	for n = 0 to ubound( allEventTypes() ) 	
		&apos; If the line number is 1 then SB macro
		&apos; more than 1 it is the line number of the script
		if isApp and n &gt; 12 then
			exit for
		endif
		if isApp then
			lineNumber = allEventTypesApp( n ).Value
			scriptName = allEventTypesApp( n ).Name
		else
			lineNumber = allEventTypesDoc( n ).Value
			scriptName = allEventTypesDoc( n ).Name			
		end if
		stringToAdd = &quot;&quot;
		if ( lineNumber &gt;= 1 ) then
			stringToAdd = &quot; [&quot; + scriptName + &quot;]&quot;
		end if
		eventList.addItem( allEventTypes( n ).Value + &quot; &quot; + stringToAdd, n )
	next n
	
	eventList.selectItemPos( focusPosition, true )
end sub



sub CreateAllKeyBindings()
	reDim allKeyBindings( 105 ) as string
	keyBindingPosition = 1

	for FKey = 2 to 12
		allKeyBindings( keyBindingPosition ) = &quot;SHIFT + CONTROL + F&quot; + FKey
		keyBindingPosition = keyBindingPosition + 1
	next FKey
	for Digit = 0 to 9
		allKeyBindings( keyBindingPosition ) = &quot;SHIFT + CONTROL + &quot; + Digit
			keyBindingPosition = keyBindingPosition + 1
	next Digit
	for Alpha = 65 to 90
		allKeyBindings( keyBindingPosition ) = &quot;SHIFT + CONTROL + &quot; + chr$( Alpha )
		keyBindingPosition = keyBindingPosition + 1
	next Alpha

	for FKey = 2 to 12
		allKeyBindings( keyBindingPosition ) = &quot;CONTROL + F&quot; + FKey
		keyBindingPosition = keyBindingPosition + 1
	next FKey
	for Digit = 0 to 9
		allKeyBindings( keyBindingPosition ) = &quot;CONTROL + &quot; + Digit
		keyBindingPosition = keyBindingPosition + 1
	next Digit
	for Alpha = 65 to 90
		allKeyBindings( keyBindingPosition ) = &quot;CONTROL + &quot; + chr$( Alpha )
		keyBindingPosition = keyBindingPosition + 1
	next Alpha

	for FKey = 2 to 12
		allKeyBindings( keyBindingPosition ) = &quot;SHIFT + F&quot; + FKey
		keyBindingPosition = keyBindingPosition + 1
	next FKey
end sub


sub createAllEventTypes()
	allEventTypes( 0 ).Name = &quot;OnStartApp&quot;
	allEventTypes( 0 ).Value = &quot;Start Application&quot;
	allEventTypes( 1 ).Name = &quot;OnCloseApp&quot;
	allEventTypes( 1 ).Value = &quot;Close Application&quot;
	allEventTypes( 2 ).Name = &quot;OnNew&quot;
	allEventTypes( 2 ).Value = &quot;Create Document&quot;
	allEventTypes( 3 ).Name = &quot;OnLoad&quot;
	allEventTypes( 3 ).Value = &quot;Open Document&quot;
	allEventTypes( 4 ).Name = &quot;OnSaveAs&quot;
	allEventTypes( 4 ).Value = &quot;Save Document As&quot;
	allEventTypes( 5 ).Name = &quot;OnSaveAsDone&quot;
	allEventTypes( 5 ).Value = &quot;Document has been saved as&quot;
	allEventTypes( 6 ).Name = &quot;OnSave&quot;
	allEventTypes( 6 ).Value = &quot;Save Document&quot;
	allEventTypes( 7 ).Name = &quot;OnSaveDone&quot;
	allEventTypes( 7 ).Value = &quot;Document has been saved&quot;
	allEventTypes( 8 ).Name = &quot;OnPrepareUnload&quot;
	allEventTypes( 8 ).Value = &quot;Close Document&quot;
	allEventTypes( 9 ).Name = &quot;OnUnload&quot;
	allEventTypes( 9 ).Value = &quot;Close Document&quot;
	allEventTypes( 10 ).Name = &quot;OnFocus&quot;
	allEventTypes( 10 ).Value = &quot;Activate document&quot;
	allEventTypes( 11 ).Name = &quot;OnUnfocus&quot;
	allEventTypes( 11 ).Value = &quot;DeActivate document&quot;
	allEventTypes( 12 ).Name = &quot;OnPrint&quot;
	allEventTypes( 12 ).Value = &quot;Print Document&quot;
	REM The following are document-only events
	allEventTypes( 13 ).Name = &quot;OnMailMerge&quot;
	allEventTypes( 13 ).Value = &quot;Print form letters&quot;
	allEventTypes( 14 ).Name = &quot;OnPageCountChange&quot;
	allEventTypes( 14 ).Value = &quot;Changing the page count&quot;
end sub


sub createAllEventBindings()
	&apos;dim props as new com.sun.star.beans.PropertyValue
	&apos;props.Name = &quot;&quot; &apos;Name = script name
	&apos;props.Value = 0 &apos;Value = 0 for empty, 1 for macro, linenumber for script
	
	&apos; Creates all types of event bindings for both Application and Document
	&apos; Initially both arrays have no bindings allocated to the events
	&apos; The value for Doc is only Script/macro name (no need for line number)
	for n = 0 to ubound( allEventTypes() )
		allEventTypesApp( n ).Name = &quot;&quot;
		allEventTypesApp( n ).Value = 0
		allEventTypesDoc( n ).Name = &quot;&quot;
		allEventTypesDoc( n ).Value = 0
	next n
end sub


REM ----- Text Handling Functions -----


function ExtractLabelFromXMLLine( XMLLine as string ) as string
	labelStart = instr( XMLLine, &quot;label=&quot;+chr$(34)) + 7
	labelEnd = instr( XMLLine, chr$(34)+&quot;&gt;&quot; )
	if labelEnd = 0 then
	    labelEnd = instr( XMLLine, chr$(34)+&quot;/&gt;&quot; )
	end if
	labelLength = labelEnd - labelStart

	menuLabelUnformatted = mid( XMLLine, labelStart, labelLength )
	tildePosition = instr( menuLabelUnformatted, &quot;~&quot; )
	select case tildePosition
		case 0
			menuLabel = menuLabelUnformatted
		case 1
			menuLabel = right( menuLabelUnformatted, labelLength - 1 )
		case else
			menuLabelLeft = left( menuLabelUnformatted, tildePosition - 1 )
			menuLabelRight = right( menuLabelUnformatted, labelLength - tildePosition )
			menuLabel = menuLabelLeft + menuLabelRight
	end select

	ExtractLabelFromXMLLine() = menuLabel
end function


function ExtractScriptIdFromXMLLine( XMLLine as string ) as string
	idStart = instr( XMLLine, &quot;script://&quot;) + 9
	if instr( XMLLine, chr$(34)+&quot; menu:helpid=&quot; ) = 0 then
		idEnd = instr( XMLLIne, &quot;?location=&quot; )
	else
		idEnd = instr( XMLLine, &quot;&quot;+chr$(34)+&quot; menu:helpid=&quot; )
	end if
	idLength = idEnd - idStart
	scriptId = mid( XMLLine, idStart, idLength )

	ExtractScriptIdFromXMLLine() = scriptId
end function

function ExtractEventScriptFromXMLLine( xmlline as string )
	if instr( xmlline, &quot;script://&quot; ) &gt; 0 then
		idStart = instr( xmlline, &quot;script://&quot;) + 9
		idEnd = instr( xmlline, chr$(34)+&quot; xlink:type=&quot; )
		idLength = idEnd - idStart
		scriptId = mid( xmlline, idStart, idLength )
	end if
	ExtractEventScriptFromXMLLine() = scriptId
end function


function ExtractEventNameFromXMLLine(  xmlline as string )
	idStart = instr( xmlline, &quot;event:name=&quot; + chr$(34) ) + 12
	idEnd = instr( xmlline, chr$(34)+&quot; event:language&quot; )
	idLength = idEnd - idStart
	event =  mid( xmlline, idStart, idLength )
	
	ExtractEventNameFromXMLLine() = event
end function

function ExtractKeyCodeFromXMLLine( XMLLine as string ) as string
	keyStart = instr( XMLLine, &quot;code=&quot;+chr$(34)+&quot;KEY_&quot;) + 10
	keyCode = mid( XMLLine, keyStart, ( len( XMLLine ) - keyStart ) )
	keyEnd = instr( keyCode, chr$(34) )
	keyCode = mid( keyCode, 1, keyEnd - 1 )
	
	ExtractKeyCodeFromXMLLine() = keyCode
end function


function GetMenuWhiteSpace( MenuXMLLine as string ) as string
	whiteSpace = &quot;&quot;
	numberOfSpaces = instr( MenuXMLLine, &quot;&lt;&quot; ) - 1
	for i = 1 to numberOfSpaces
		whiteSpace = whiteSpace + &quot; &quot;
	next i
	
	GetMenuWhiteSpace() = whiteSpace
end function

function IsAllocatedMenuItem( script as string ) as boolean
	foundMenuItem = false
	Allocated = false
	count = 0
	do 
		count = count + 1
		if strcomp( script, subMenuItems( count ) ) = 0 then
			foundMenuItem = true
		end if	
	loop while not( foundMenuItem ) and count &lt; subMenuCount

	linePosition = subMenuItemLinePosition( count )

	if not( instr( xmlFile( linePosition ), &quot;script://&quot; ) = 0 ) then
		Allocated = true
	end if

	isAllocatedMenuItem() = Allocated
end Function


function HasShiftKey( keyCombo ) as boolean
	if instr( keyCombo, &quot;SHIFT&quot; ) = 0 then
		hasShift = false
	else
		hasShift = true
	end if
		
	HasShiftKey = hasShift
end function


function HasControlKey( keyCombo ) as boolean
	if instr( keyCombo, &quot;CONTROL&quot; ) = 0 then
		hasControl = false
	else
		hasControl = true
	end if
		
	HasControlKey = hasControl
end function


function ExtractKeyFromCombo( keyString as string ) as string
	while not( instr( keyString, &quot;+&quot; ) = 0 )
		removeTo = instr( keyString, &quot;+ &quot; ) + 2
		keyString = mid( keyString, removeTo, ( len( keyString ) - removeTo ) + 1 )
	wend
	ExtractKeyFromCombo() = keyString
end function



REM ------ Event Handling Functions (Listeners) ------


sub KeyListListener()
	keyShortCutList = bindingDialog.getControl( &quot;KeyList&quot; )
	selectedShortCut = keyShortCutList.getSelectedItem()
	combo = bindingDialog.getControl( &quot;KeyCombo&quot; ) 

	menuScriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
	selectedScript = menuScriptList.getSelectedItem()

	keyGroup = combo.text
    dim keyGroupIndex as Integer
    dim selectedKeyIndex as Integer
	for n = lbound ( allKeyGroupsArray() ) to ubound ( allKeyGroupsArray() )
		if ( allKeyGroupsArray( n ) = keyGroup )then
			keyGroupIndex = n
			exit for
		end if
    next n	
    selectedKeyIndex = keyShortCutList.getSelectedItemPos()

	if  keyAllocationMap( keyGroupIndex, selectedKeyIndex ).Value &gt; 1 then 
		bindingDialog.Model.Delete.enabled = true
		bindingDialog.Model.AddOn.enabled = true
		if selectedScript &lt;&gt; &quot;&quot; then
			bindingDialog.Model.NewButton.enabled = true
		endif

	else

		if keyAllocationMap( keyGroupIndex, selectedKeyIndex ).Value  = 1 then
			bindingDialog.Model.Delete.enabled = false
			bindingDialog.Model.AddOn.enabled = false
			bindingDialog.Model.NewButton.enabled = false
		else
			bindingDialog.Model.Delete.enabled = false
			bindingDialog.Model.AddOn.enabled = false
			if selectedScript &lt;&gt; &quot;&quot; then
				bindingDialog.Model.NewButton.enabled = true
			end if
		end if
	end if
end sub


sub SubMenuListListener()
	scriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
	subMenuList = bindingDialog.getControl( &quot;SubMenuList&quot; )
	selectedMenuItem = subMenuList.getSelectedItem()
	if IsAllocatedMenuItem( selectedMenuItem ) then
		bindingDialog.Model.Delete.enabled = true
		bindingDialog.Model.AddOn.enabled = true
	else
		bindingDialog.Model.Delete.enabled = false
		bindingDialog.Model.AddOn.enabled = false
	end if
end sub

REM a keypress listener that in turn fires the MenuCL on a return key even only
sub fireMenuComboListernerOnRet( eventobj as object )
	if (eventobj.KeyCode = 1280 ) then
		MenuComboListener()
	endif
end sub

&apos;Populates the SubMenuList with the appropriate menu items from the Top-level menu selected from the combo box
sub MenuComboListener()
	combo = bindingDialog.getControl( &quot;MenuCombo&quot; ) 
	newToplevelMenu = combo.text
	counter = 0
	do
		counter = counter + 1
	loop while not( newToplevelMenu = menuItems( counter ) )
	
	PopulateSubMenuList( counter )
end sub

REM a keypress listener that in turn fires the LLCL on a return key even only
sub fireLangLocComboListernerOnRet( eventobj as object )
	if (eventobj.KeyCode = 1280 ) then
		LangLocComboListener()
	endif
end sub

sub LangLocComboListener()
   
	combo = bindingDialog.getControl( &quot;LanguageCombo&quot; ) 
	language = combo.text
	combo = bindingDialog.getControl( &quot;LocationCombo&quot; )
	location = combo.text 

	PopulateScriptList( language,location )
	
    &apos;Enable/disable Assign button
    scriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
    if not (dialogName = &quot;EditDebug&quot;) then
        if scriptList.getSelectedItem() = &quot;&quot; then
            bindingDialog.Model.NewButton.enabled = false
        end if
    end if
    
    if ( location = &quot;Filesystem&quot; ) and ( language &lt;&gt; &quot;Java&quot; ) then
    	bindingDialog.Model.Browse.enabled = true
    	if not (dialogName = &quot;EditDebug&quot;) then
    		bindingDialog.Model.fsonly.enabled = true
    	end if
    else
    	bindingDialog.Model.Browse.enabled = false
    	if not (dialogName = &quot;EditDebug&quot;) then
    		bindingDialog.Model.fsonly.enabled = false
    	end if
    endif
    
    &apos; extra dialog dependant processing
    if dialogName = &quot;Menu&quot; then
    	&apos; will set New button to false if no text in LableBox
    	MenuLabelBoxListener()
    elseif dialogName = &quot;Key&quot; then
    	&apos; will set Assigne button to false if appropriate
    	KeyListListener()
    elseif dialogName = &quot;Event&quot; then
    	EventListListener()
    end if
    
end sub

REM a keypress listener that in turn fires the KeyCL on a return key even only
sub fireKeyComboListernerOnRet( eventobj as object )
	if (eventobj.KeyCode = 1280 ) then
		KeyComboListener()
	endif
end sub

&apos;Populates the KeyList with the appropriate key combos from the Top-level key group selected from the combo box
sub KeyComboListener()
	combo = bindingDialog.getControl( &quot;KeyCombo&quot; ) 
	keyGroup = combo.text
	for n = lbound ( allKeyGroupsArray() ) to ubound ( allKeyGroupsArray() )
		if ( allKeyGroupsArray( n ) = keyGroup )then
			keyGroupIndex = n
			exit for
		end if
    next n
	PopulateKeyBindingList( keyGroupIndex )
end sub


sub MenuLabelBoxListener()
	menuScriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
	selectedScript = menuScriptList.getSelectedItem()
	&apos;if the SubMenuList is from a dynamically created menu (e.g. Format)
	&apos;or if the Menu Label text box is empty
	subMenuList = bindingDialog.getControl( &quot;SubMenuList&quot; )
	firstItem = subMenuList.getItem( 0 )
	if bindingDialog.Model.MenuLabelBox.text = &quot;&quot; OR firstItem = &quot;Unable to Assign Scripts to this menu&quot; OR  selectedScript = &quot;&quot; then
		bindingDialog.Model.NewButton.enabled = false
	else
		bindingDialog.Model.NewButton.enabled = true
	end if
end sub

sub AppDocEventListener()
	populateEventList( 0 )
	EventListListener()
end sub


sub EventListListener()
	on error goto ErrorHandler

    eventList = bindingDialog.getControl( &quot;EventList&quot; )
    eventPos = eventList.getSelectedItemPos()

    allApps = bindingDialog.getControl( &quot;AllAppsOption&quot; )

	menuScriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
	selectedScript = menuScriptList.getSelectedItem()
	
    dim binding as integer
    if allApps.state = true then
    	binding = allEventTypesApp( eventPos ).Value
    else
	    binding = allEventTypesDoc( eventPos ).Value
    endif

    if ( binding &gt; 1 ) then
       	bindingDialog.Model.Delete.enabled = true
    else
       	bindingDialog.Model.Delete.enabled = false
    end if
    
	if ( binding = 1 ) then
		&apos; staroffice binding, can&apos;t assign
		bindingDialog.Model.NewButton.enabled = false
	elseif (  selectedScript &lt;&gt; &quot;&quot; ) then
		bindingDialog.Model.NewButton.enabled = true
	end if
    exit sub

    ErrorHandler:
    reset
    bindingDialog.Model.Delete.enabled = false

end sub


REM ------ Event Handling Functions (Buttons) ------

function getFilePicker() as Object
    REM file dialog
    oFilePicker = CreateUnoService( &quot;com.sun.star.ui.dialogs.FilePicker&quot; )

    combo = bindingDialog.getControl( &quot;LanguageCombo&quot; ) 
    language = combo.text
    currentFilter = &quot;&quot;

    for langIndex = 0 to ubound(languages())
        if( languages(langIndex) &lt;&gt; &quot;Java&quot; ) then
        	filterName = languages(langIndex) + &quot; (&quot;
        	filterVal=&quot;&quot;
        	extns = extensions(langIndex)
        	for extnIndex = lbound(extns()) to ubound(extns())
            	filterName = filterName + &quot;*.&quot; + extns(extnIndex) + &quot;,&quot;
           	 	filterVal = filterVal + &quot;*.&quot; + extns(extnIndex) + &quot;,&quot;
        	next extnIndex
        	filterName = left(filterName, len(filterName) -1) + &quot;)&quot;
        	filterVal = left(filterVal, len(filterVal) -1)
        	if(instr(filterName,language) = 1 ) then
            	currentFilter = filterName
        	end if
        	oFilePicker.AppendFilter(filterName, filterVal)
        end if
    next langIndex
    if(len(currentFilter) &gt; 0 ) then
        oFilePicker.SetCurrentFilter( currentFilter )
    end if

    If sFileURL = &quot;&quot; Then
        oSettings = CreateUnoService( &quot;com.sun.star.frame.Settings&quot; )
        oPathSettings = oSettings.getByName( &quot;PathSettings&quot; )
        sFileURL = oPathSettings.getPropertyValue( &quot;Work&quot; )
    End If

    REM set display directory
    oSimpleFileAccess = CreateUnoService( &quot;com.sun.star.ucb.SimpleFileAccess&quot; )

    If oSimpleFileAccess.exists( sFileURL ) And oSimpleFileAccess.isFolder( sFileURL ) Then
        oFilePicker.setDisplayDirectory( sFileURL )
    End If
    getFilePicker() = oFilePicker
end function

Sub DoBrowseAndEdit()
    Dim oFilePicker As Object, oSimpleFileAccess As Object
    Dim oSettings As Object, oPathSettings As Object
    Dim sFileURL As String
    Dim sFiles As Variant

    oFilePicker = getFilePicker()
    REM execute file dialog
    If oFilePicker.execute() Then
        sFiles = oFilePicker.getFiles()

        sFileURL = sFiles(0)
    	oSimpleFileAccess = CreateUnoService( &quot;com.sun.star.ucb.SimpleFileAccess&quot; )
        If oSimpleFileAccess.exists( sFileURL ) Then
            for langIndex = 0 to ubound(languages())
                If (instr(oFilePicker.GetCurrentFilter, languages(langIndex)) = 1 ) then
                	RunDebugger(languages(langIndex), sFileURL, &quot;&quot;)
            	End If
            next langIndex
        End If
        bindingDialog.endExecute()
    End If
End Sub

Sub RunDebugger(lang as String, uri as String, filename as String)
    dim document   as object
    dim dispatcher as object
    dim parser     as object
    dim url        as new com.sun.star.util.URL

    document = ThisComponent.CurrentController.Frame
    parser   = createUnoService(&quot;com.sun.star.util.URLTransformer&quot;)
    dim args(2) as new com.sun.star.beans.PropertyValue
    args(0).Name = &quot;language&quot;
    args(0).Value = lang
    args(1).Name = &quot;uri&quot;
    args(1).Value = uri
    args(2).Name = &quot;filename&quot;
    args(2).Value = filename

    url.Complete = &quot;script://_$DebugRunner.Debug?&quot; _
        + &quot;language=Java&amp;function=DebugRunner.go&quot; _
        + &quot;&amp;location=share&quot;

    parser.parseStrict(url)
    disp = document.queryDispatch(url,&quot;&quot;,0)
    disp.dispatch(url, args())
End Sub

sub DoEdit()
    Dim scriptInfo as Object

    menuScriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
    selectedScript = menuScriptList.getSelectedItem()

    if not (selectedScript = &quot;&quot;) then
        scripts() = scriptDisplayList(0)
        for n = LBOUND( scripts() ) to UBOUND( scripts() )
            if ( scripts( n ).Name = selectedScript ) then
                scriptInfo = scripts( n ).Value
                exit for
            end if
        next n

        RunDebugger(scriptInfo.getLanguage, scriptInfo.getParcelURI, scriptInfo.getFunctionName)
        bindingDialog.endExecute()
    end if
end sub

sub MenuOKButton()
	WriteXMLFromArray()
	bindingDialog.endExecute()
end sub


sub MenuCancelButton()
	bindingDialog.endExecute()
end sub


sub MenuHelpButton()
	helpDialog = LoadDialog( &quot;ScriptBindingLibrary&quot;, &quot;HelpBinding&quot; )
	helpDialog.execute()
end sub


sub MenuDeleteButton()
	subMenuList = bindingDialog.getControl( &quot;SubMenuList&quot; )
	linePos = subMenuItemLinePosition( subMenuList.getSelectedItemPos() + 1 )
	
	RemoveBinding( linePos )

	REM Update the top-level menu&apos;s line positions	
	combo = bindingDialog.getControl( &quot;MenuCombo&quot; ) 
	newToplevelMenu = combo.text
	counter = 0
	do
		counter = counter + 1
	loop while not( newToplevelMenu = menuItems( counter ) )
	UpdateTopLevelMenus( counter + 1, false )	
	
	MenuComboListener()
	
	subMenuList.selectItemPos( subMenuList.getSelectedItemPos(), true )
end sub


sub MenuNewButton()
	menuScriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
	selectedScript = menuScriptList.getSelectedItem()
    scriptURI = getScriptURI( selectedScript )
	newMenuLabel = bindingDialog.Model.MenuLabelBox.text

	subMenuList = bindingDialog.getControl( &quot;SubMenuList&quot; )

	REM Update the top-level menu&apos;s line positions
	combo = bindingDialog.getControl( &quot;MenuCombo&quot; ) 
	newToplevelMenu = combo.text
	counter = 0
	do
		counter = counter + 1
	loop while not( newToplevelMenu = menuItems( counter ) )
	UpdateTopLevelMenus( counter + 1, true )

	REM New line position is one ahead of the selected sub menu item		
	linePos = subMenuItemLinePosition( subMenuList.getSelectedItemPos() + 1 ) + 1
	
	AddNewMenuBinding( scriptURI, newMenuLabel, linePos )

	MenuComboListener()
	subMenuList.selectItemPos( subMenuList.getSelectedItemPos() + 1, true )
	SubMenuListListener()
end sub

sub BrowseButton()
	Dim oFilePicker As Object, oSimpleFileAccess As Object
	Dim oSettings As Object, oPathSettings As Object
	Dim sFileURL As String
	Dim sFiles As Variant

	oFilePicker = getFilePicker()
	
	REM execute file dialog
	If oFilePicker.execute() Then
		sFiles = oFilePicker.getFiles()
		sFileURL = sFiles(0)
		oSimpleFileAccess = CreateUnoService( &quot;com.sun.star.ucb.SimpleFileAccess&quot; )
		If oSimpleFileAccess.exists( sFileURL ) Then
			REM add sFileURL to the list
			ReDim preserve filesysScripts(filesysCount) as String
			filesysScripts( filesysCount ) = sFileURL
			filesysCount=filesysCount+1
			&apos; if user changed filter in file picker then populate
			&apos; language with language associated with that in file picker
			sFilter = oFilePicker.getCurrentFilter()
			langCombo = bindingDialog.getControl( &quot;LanguageCombo&quot; )
			dim items() as String
			items() = langCombo.getItems()
			for index = lbound(items()) to ubound(items())
				iPos = inStr(sFilter,&quot; &quot;)
				Dim theLanguage as String
				if( iPos &gt; 0 ) then
					theLanguage = Left( sFilter, iPos - 1)
				    if ( theLanguage = items( index ) ) then
				 		langCombo.text = items( index )
				 		exit for
				 	end if
				end if
			next index
		End If
	End If		
	LangLocComboListener()
End Sub

sub KeyOKButton()	
	WriteXMLFromArray()
	bindingDialog.endExecute()
end sub


sub KeyCancelButton()
	bindingDialog.endExecute()
end sub


sub KeyHelpButton()
	helpDialog = LoadDialog( &quot;ScriptBindingLibrary&quot;, &quot;HelpBinding&quot; )
	helpDialog.execute()
end sub


sub KeyNewButton()
	combo = bindingDialog.getControl( &quot;KeyCombo&quot; )
	keyGroup = combo.text
	for n = lbound ( allKeyGroupsArray() ) to ubound ( allKeyGroupsArray() )
		if ( allKeyGroupsArray( n ) = keyGroup )then
			keyGroupIndex = n
			exit for
		end if
	next n
	menuScriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
	script = menuScriptList.getSelectedItem()
	scriptURI = getScriptURI( script )
	
	keyList = bindingDialog.getControl( &quot;KeyList&quot; )
	keyIndex = keyList.getSelectedItemPos()
	ShortCutKeyArray() = KeyBindArrayOfArrays( keyGroupIndex )
	keyText = ShortCutKeyArray( keyIndex )
	
	AddNewKeyBinding( scriptURI, HasShiftKey( keyText ), HasControlKey( keyText ), ExtractKeyFromCombo( keyText ) ) 

	KeyComboListener()
end sub


sub KeyDeleteButton()

	keyShortCutList = bindingDialog.getControl( &quot;KeyList&quot; )
	selectedShortCut = keyShortCutList.getSelectedItem()
	combo = bindingDialog.getControl( &quot;KeyCombo&quot; )

	keyGroup = combo.text
	dim keyGroupIndex as Integer
	dim selectedKeyIndex as Integer
	for n = lbound ( allKeyGroupsArray() ) to ubound ( allKeyGroupsArray() ) 
		if ( allKeyGroupsArray( n ) = keyGroup )then
			keyGroupIndex = n
			exit for
		end if
	next n
	selectedKeyIndex = keyShortCutList.getSelectedItemPos()
	linePosition = keyAllocationMap( keyGroupIndex, selectedKeyIndex ).Value
	keyAllocationMap( keyGroupIndex, selectedKeyIndex ).Value = 0
	keyAllocationMap( keyGroupIndex, selectedKeyIndex ).Name = &quot;&quot;
	RemoveBinding( linePosition )
	KeyComboListener()
end sub


sub EventNewButton()
	eventScriptList = bindingDialog.getControl( &quot;ScriptList&quot; )
	selectedScript = eventScriptList.getSelectedItem()
	scriptURI = getScriptURI( selectedScript )
	eventList = bindingDialog.getControl( &quot;EventList&quot; )
	eventPosition = eventList.getSelectedItemPos()

	allApps = bindingDialog.getControl( &quot;AllAppsOption&quot; )
	dim isApp as boolean
	if allApps.state = true then &apos;Application	
		isApp = true
	else &apos;Document
		isApp = false
	end if
	AddNewEventBinding( scriptURI, eventPosition, isApp )

	populateEventList( eventPosition )
	EventListListener()
end sub


sub EventDeleteButton()
	eventList = bindingDialog.getControl( &quot;EventList&quot; )
	REM Check that combo is a script
	eventPosition = eventList.getSelectedItemPos()

	allApps = bindingDialog.getControl( &quot;AllAppsOption&quot; )
	if allApps.state = true then &apos;Application
		linePosition = allEventTypesApp( eventPosition ).Value
		&apos;dim eventProp as new com.sun.star.beans.PropertyValue
		&apos;eventProp.Name = &quot;&quot;
		&apos;eventProp.Value = 0
		allEventTypesApp( eventPosition ).Name = &quot;&quot;
		allEventTypesApp( eventPosition ).Value = 0		
		RemoveBinding( linePosition )
	else &apos;Document
		&apos;DeleteEvent( allEventTypes( eventPosition ) )
		allEventTypesDoc( eventPosition ).Name = &quot;&quot;		
		allEventTypesDoc( eventPosition ).Value = 0
	end if
	
	PopulateEventList( eventPosition )
	EventListListener()
end sub


sub EventOKButton
	WriteEventsToDoc()
	WriteXMLFromArray()
	bindingDialog.endExecute()
end sub


sub HelpOKButton()
	helpDialog.endExecute()
end sub
</script:module>
