<?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="Debug" script:language="StarBasic">REM  *****  BASIC  *****

Sub ActivateReadOnlyFlag()
	SetBasicReadOnlyFlag(True)
End Sub


Sub DeactivateReadOnlyFlag()
	SetBasicReadOnlyFlag(False)
End Sub


Sub SetBasicReadOnlyFlag(bReadOnly as Boolean)
Dim i as Integer
Dim LibName as String
Dim BasicLibNames() as String
	BasicLibNames() = BasicLibraries.ElementNames()
	For i = 0 To Ubound(BasicLibNames())
		LibName = BasicLibNames(i)
		If LibName &lt;&gt; &quot;Standard&quot; Then
			BasicLibraries.SetLibraryReadOnly(LibName, bReadOnly)
		End If
	Next i
End Sub


Sub WritedbgInfo(LocObject as Object)
Dim locUrl as String
Dim oLocDocument as Object
Dim oLocText as Object
Dim oLocCursor as Object
Dim NoArgs()
Dim sObjectStrings(2) as String
Dim sProperties() as String
Dim n as Integer
Dim m as Integer
Dim MaxIndex as Integer
	sObjectStrings(0) = LocObject.dbg_Properties
	sObjectStrings(1) = LocObject.dbg_Methods
	sObjectStrings(2) = LocObject.dbg_SupportedInterfaces
	LocUrl = &quot;private:factory/swriter&quot;
	oLocDocument = StarDesktop.LoadComponentFromURL(LocUrl,&quot;_default&quot;,0,NoArgs)
	oLocText = oLocDocument.text
	oLocCursor = oLocText.createTextCursor()
	oLocCursor.gotoStart(False)
	If Vartype(LocObject) = 9 then	&apos; an Object Variable
		For n = 0 To 2
			sProperties() = ArrayoutofString(sObjectStrings(n),&quot;;&quot;, MaxIndex)
			For m = 0 To MaxIndex
				oLocText.insertString(oLocCursor,sProperties(m),False)
				oLocText.insertControlCharacter(oLocCursor,com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK,False)
			Next m
		Next n
	Elseif Vartype(LocObject) = 8 Then	&apos; a String Variable
		oLocText.insertString(oLocCursor,LocObject,False)
	ElseIf Vartype(LocObject) = 1 Then
		Msgbox(&quot;Variable is Null!&quot;, 16, GetProductName())
	End If
End Sub


Sub WriteDbgString(LocString as string)
Dim oLocDesktop as object
Dim LocUrl as String
Dim oLocDocument as Object
Dim oLocCursor as Object
Dim oLocText as Object

	LocUrl = &quot;private:factory/swriter&quot;
	oLocDocument = StarDesktop.LoadComponentFromURL(LocUrl,&quot;_default&quot;,0,NoArgs)
	oLocText = oLocDocument.text
	oLocCursor = oLocText.createTextCursor()
	oLocCursor.gotoStart(False)
	oLocText.insertString(oLocCursor,LocString,False)
End Sub


Sub printdbgInfo(LocObject)
	If Vartype(LocObject) = 9 then
		Msgbox LocObject.dbg_properties
		Msgbox LocObject.dbg_methods
		Msgbox LocObject.dbg_supportedinterfaces
	Elseif Vartype(LocObject) = 8 Then	&apos; a String Variable
		Msgbox LocObject
	ElseIf Vartype(LocObject) = 0 Then
		Msgbox(&quot;Variable is Null!&quot;, 16, GetProductName())
	Else
		Msgbox(&quot;Type of Variable: &quot; &amp; Typename(LocObject), 48, GetProductName())
	End If
End Sub


Sub ShowArray(LocArray())
Dim i as integer
Dim msgstring
	msgstring = &quot;&quot;
	For i = Lbound(LocArray()) to Ubound(LocArray())
		msgstring = msgstring + LocArray(i) + chr(13)
	Next
	Msgbox msgstring
End Sub


Sub ShowPropertyValues(oLocObject as Object)
Dim PropName as String
Dim sValues as String
	On Local Error Goto NOPROPERTYSETINFO:
	sValues = &quot;&quot;
	For i = 0 To Ubound(oLocObject.PropertySetInfo.Properties)
		Propname = oLocObject.PropertySetInfo.Properties(i).Name
		sValues = sValues &amp; PropName &amp; chr(13) &amp; &quot; = &quot; &amp; oLocObject.GetPropertyValue(PropName) &amp; chr(13)
	Next i
	Msgbox(sValues , 64, GetProductName())
	Exit Sub

NOPROPERTYSETINFO:
	Msgbox(&quot;Sorry, No PropertySetInfo attached to the object&quot;, 16, GetProductName())
	Resume LEAVEPROC
	LEAVEPROC:
End Sub


Sub ShowNameValuePair(Pair())
Dim i as Integer
Dim ShowString as String
	ShowString = &quot;&quot;
	On Local Error Resume Next
	For i = 0 To Ubound(Pair())
		ShowString = ShowString &amp; Pair(i).Name &amp; &quot; = &quot;
		ShowString = ShowString &amp; Pair(i).Value &amp; chr(13)
	Next i
	Msgbox ShowString
End Sub


&apos; Retrieves all the Elements of aSequence of an object, with the
&apos; possibility to define a filter(sfilter &lt;&gt; &quot;&quot;)
Sub ShowElementNames(oLocElements() as Object, Optional sFiltername as String)
Dim i as Integer
Dim NameString as String
	NameString = &quot;&quot;
	For i = 0 To Ubound(oLocElements())
		If Not IsMissIng(sFilterName) Then
			If Instr(1, oLocElements(i), sFilterName) Then
				NameString = NameString &amp; oLocElements(i) &amp; chr(13)
			End If
		Else
			NameString = NameString &amp; oLocElements(i) &amp; chr(13)
		End If
	Next i
	Msgbox(NameString, 64, GetProductName())
End Sub


&apos; Retrieves all the supported servicenames of an object, with the
&apos; possibility to define a filter(sfilter &lt;&gt; &quot;&quot;)
Sub ShowSupportedServiceNames(oLocObject as Object, Optional sFilterName as String)
	On Local Error Goto NOSERVICENAMES
	If IsMissing(sFilterName) Then
		ShowElementNames(oLocobject.SupportedServiceNames())
	Else
		ShowElementNames(oLocobject.SupportedServiceNames(), sFilterName)
	End If
	Exit Sub

	NOSERVICENAMES:
	Msgbox(&quot;Sorry, No &apos;SupportedServiceNames&apos; - Property attached to the object&quot;, 16, GetProductName())
	Resume LEAVEPROC
	LEAVEPROC:
End Sub


&apos; Retrieves all the available Servicenames of an object, with the
&apos; possibility to define a filter(sfilter &lt;&gt; &quot;&quot;)
Sub ShowAvailableServiceNames(oLocObject as Object, Optional sFilterName as String)
	On Local Error Goto NOSERVICENAMES
	If IsMissing(sFilterName) Then
		ShowElementNames(oLocobject.AvailableServiceNames)
	Else
		ShowElementNames(oLocobject.AvailableServiceNames, sFilterName)
	End If
	Exit Sub

	NOSERVICENAMES:
	Msgbox(&quot;Sorry, No &apos;AvailableServiceNames&apos; - Property attached to the object&quot;, 16, GetProductName())
	Resume LEAVEPROC
	LEAVEPROC:
End Sub


Sub ShowCommands(oLocObject as Object)
	On Local Error Goto NOCOMMANDS
	ShowElementNames(oLocObject.QueryCommands)
	Exit Sub
	NOCOMMANDS:
	Msgbox(&quot;Sorry, No &apos;QueryCommands&apos; - Property attached to the object&quot;, 16, GetProductName())
	Resume LEAVEPROC
	LEAVEPROC:
End Sub


Sub ProtectCurrentSheets()
Dim oDocument as Object
Dim sDocType as String
Dim iResult as Integer
Dim oSheets as Object
Dim i as Integer
Dim bDoProtect as Boolean
	oDocument = StarDesktop.ActiveFrame.Controller.Model
	sDocType = GetDocumentType(oDocument)
	If sDocType = &quot;scalc&quot; Then
		oSheets = oDocument.Sheets
		bDoProtect = False
		For i = 0 To oSheets.Count-1
			If Not oSheets(i).IsProtected Then
				bDoProtect = True
			End If
		Next i
		If bDoProtect Then
			iResult = Msgbox( &quot;Do you want to protect all sheets of this document?&quot;,35, GetProductName())
			If iResult = 6 Then
				ProtectSheets(oDocument.Sheets)
			End If
		End If
	End If
End Sub


Sub FillDocument()
	oMyReport = createUNOService(&quot;com.sun.star.wizards.report.CallReportWizard&quot;)
	oMyReport.trigger(&quot;fill&quot;)
End Sub

</script:module>
