Subversion

HaExcel

?curdirlinks? - Rev 236

?prevdifflink? - Blame


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="ClassSheet" script:language="StarBasic">REM  *****  BASIC  *****

Option Explicit

Global Colors

&apos; =====================================

Dim oDialog As Object

Const PropertyName = &quot;ClassSheet&quot;
Const PropertyExpName = &quot;ClassSheetExp&quot;

&apos; =====================================

Sub NotImplemented
  msgbox &quot;Not Implemented.&quot;
End Sub

&apos; =====================================

Sub Init
  Colors = Array( rgb(255,211, 32),_
                  rgb(174,207,  0),_
                  rgb(204,255,255),_
                  rgb(255,255,204),_
                  rgb(153,153,255),_
                  rgb( 61,235, 61),_
                  rgb(153,204,255),_
                  rgb(255,153,102),_
                  rgb( 35,184,220),_
                  rgb(230,230, 76) )
   
  Dim oDoc, oUserProperties As Object
  oDoc = ThisComponent
  
  REM check if the ClassSheet Property exists
  oUserProperties = GetUserProperties(oDoc)
  If Not oUserProperties.getPropertySetInfo().hasPropertyByName( PropertyClasses ) Then
        REM create the ClassSheet property
        oUserProperties.addProperty( PropertyClasses, com.sun.star.beans.PropertyAttribute.REMOVEABLE, &quot;&quot; )
  End If
  
  &apos;If Not oUserProperties.getPropertySetInfo().hasPropertyByName( PropertyExpName ) Then
  &apos;        REM create the ClassSheetExp property
  &apos;        oUser
  &apos;End If
End Sub

&apos; =====================================

Sub AddClass
  msgbox &quot;Warning [AddClass]: feature incomplete.&quot;
  
  &apos; TEMP
  If IsNull( Colors ) Or IsEmpty( Colors ) Then Init
  
  REM check sheet selection
  &apos; FIXME check the existing classes to see if the addition of this one is valid
  Dim oDoc As Object
  oDoc = ThisComponent
  Dim oRange As Object
  oRange = GetSelectedRange(oDoc)
  
  If IsNull( oRange ) Then
    msgbox &quot;Error: invalid selection.&quot;
    Exit Sub
  End If
  
  REM create dialog control
  oDialog = CreateUnoDialog( DialogLibraries.HaExcelDev.NewClass )
  REM show the dialog
  oDialog.execute()
  oDialog.dispose()
End Sub

&apos; =====================================

Sub DelClass
  msgbox &quot;Warning [DelClass]: feature incomplete.&quot;
  
  &apos; TEMP
  If IsNull( Colors ) Or IsEmpty( Colors ) Then Init
  
  Dim oDoc As Object
  oDoc = ThisComponent
  REM create dialog control
  oDialog = CreateUnoDialog( DialogLibraries.HaExcelDev.DelClass )
  REM initialize dialog data
  Dim classes As Object
  classes = GetClasses( oDoc )
  
  &apos; TODO
  &apos; The button delete is only enabled if one of the classes is selected,
  &apos; and is disabled when the root is selected or there is no selected node.
  
  REM initialize the tree
  Dim treeClasses As Object
  Dim oTreeDataModel As Object
  treeClasses = oDialog.getControl( &quot;treeClasses&quot; )
  oTreeDataModel = createUnoService( &quot;com.sun.star.awt.tree.MutableTreeDataModel&quot; )
  
  REM create root node (&quot;ClassSheets&quot;)
  Dim oRootNode As Object
  oRootNode = oTreeDataModel.createNode( PropertyName , true )
  oTreeDataModel.setRoot(oRootNode)
  
  REM add the classes to the tree
  DelClassAux( oTreeDataModel, classes, 0, oRootNode )
  
  treeClasses.Model.DataModel = oTreeDataModel
  
  
  REM show the dialog
  oDialog.execute()
  oDialog.dispose()
End Sub

&apos; =====================================

Function DelClassAux (oTreeDataModel As Object, classes As Object, i As Integer, oParentNode As Object) As Integer
  Dim c      As Object
  Dim c2     As String
  Dim res    As Integer
  Dim n, rn  As String
  Dim cdepth As Long
  Dim oNode  As Object
  
  If i &gt; UBound( classes ) Then
    DelClassAux = i
    Exit Function
  End If
  
  c  = classes(i)
  n  = GetClassName( c )      &apos; n  - c Name
  rn = GetClassRangeName( c ) &apos; rn - c Range Name
  cdepth = GetClassDepth( c ) &apos; cdepth - c Depth
  
  oNode = oTreeDataModel.createNode( n &amp; &quot; (&quot; &amp; rn &amp; &quot;)&quot; , true )
  oParentNode.appendChild(oNode)
  
  res = i+1
  
  REM check if there are more classes, and process them (deeper level)
  If res &lt;= UBound( classes ) Then
    c2  = classes( res )
    cdepth2 = GetClassDepth( c2 ) &apos; cdepth2 - c2 Depth
  
    REM check if the next class is an inner class
    If cdepth &lt; cdepth2 Then
      res = DelClassAux( oTreeDataModel, classes, res, oNode)
    End If
  End If
  
  REM check if there are more classes, and process them (same level)
  If res &lt;= UBound( classes ) Then
    c2  = classes( res )
    cdepth2 = GetClassDepth( c2 ) &apos; cdepth2 - c2 Depth
    
    REM continue with the remaining classes on the same level
    If cdepth = cdepth2 Then
      res = DelClassAux( oTreeDataModel, classes, res, oParentNode )
    End If
  End If
  
  DelClassAux = res
End Function

&apos; =====================================

Sub SetColsRepeatable
  msgbox &quot;SetColsRepeatable not implemented&quot;
  
  &apos; TEMP
  If IsNull( Colors ) Or IsEmpty( Colors ) Then Init
End Sub

&apos; =====================================

Sub SetRowsRepeatable
  msgbox &quot;SetRowsRepeatable not implemented&quot;
  
  &apos; TEMP
  If IsNull( Colors ) Or IsEmpty( Colors ) Then Init
End Sub

&apos; =====================================

Function GetUserProperties (oDoc As Object) As Object
  GetUserProperties = oDoc.DocumentProperties.UserDefinedProperties
End Function

&apos; =====================================

Sub NewClass_btnOk_Click
  Dim oDoc As Object
  Dim oUserProperties As Object
  Dim classes,newClass As String

  oDoc = ThisComponent
  oUserProperties = GetUserProperties(oDoc)
  
  REM get the range of the selection
  Dim oRange As Object
  Dim range$
  oRange = GetSelectedRange(oDoc)
  If IsNull(oRange) Then
        Exit Sub
  End If
  
  REM get the new class&apos; name
  newClass = oDialog.Model.txtClassName.Text
  REM add the new class and update the list
  classes = AddClassToList( oDoc, newClass, oRange )
  If classes = &quot;&quot; Then
    msgbox &quot;Error: invalid selection.&quot;
    oDialog.endExecute()
    Exit Sub
  End If
  classes = oUserProperties.setPropertyValue( PropertyName, classes )
  REM stop the dialog&apos;s execution
  oDialog.endExecute()
End Sub

&apos; =====================================

Sub NewClass_txtClassName_Changed
  Dim oButton As Object

  oButton = oDialog.getControl(&quot;btnOk&quot;)
  If (oDialog.Model.txtClassName.Text &lt;&gt; &quot;&quot;) Then
    oButton.setEnable(True)
  Else
        oButton.setEnable(False)
  End If
End Sub

&apos; =====================================

Function GetSelectedRange (oDoc As Object) As Object
  Dim oSelection As Object
  
  oSelection = oDoc.getCurrentSelection

  if HasUnoInterfaces(oSelection, &quot;com.sun.star.lang.XServiceInfo&quot;) then
    if oSelection.supportsService(&quot;com.sun.star.sheet.SheetCellRanges&quot;) then
      &apos;More than one range selected
      &apos;msgbox &quot;Multiple selection not supported.&quot;
    elseif oSelection.supportsService(&quot;com.sun.star.table.CellRange&quot;) then
      &apos;Only one range but more than one cell
      GetSelectedRange = oSelection
    elseif oSelection.supportsService(&quot;com.sun.star.sheet.SheetCell&quot;) then
      &apos;only one cell selected
      GetSelectedRange = oSelection
   end if
  end if
End Function

&apos; =====================================

&apos; Return the new list or empty on error
&apos; TODO
&apos;  - suport for multi-class classes (classes that are spread across other classes)

Function AddClassToList (oDoc As Object, className As String, oRange As Object) As String
  Dim classes As Object
  
  classes = GetClasses( oDoc )
  
  Dim newList(0) As String
  If LBound( classes ) &lt;= UBound( classes ) Then
    ReDim newList(UBound(classes) + 1) As String
  End If
  
  Dim color As Long
  color = Colors( (UBound(classes) - LBound(classes) + 1) MOD (UBound(Colors) - LBound(Colors) + 1) )
  
  Dim depth As Long
  Dim newClass As String
  depth = 1
  newClass = &quot;&quot;
  
  Dim i As Integer
  Dim c, rn, n As String
  Dim cdepth As Long
  Dim r As Object &apos; Range
  Dim sn As Object &apos; array of strings
  i = LBound( classes )
  While newClass = &quot;&quot; And i &lt;= UBound( classes )
    c  = classes(i)             &apos; c  - Class
    rn = GetClassRangeName( c ) &apos; rn - Class&apos; Range Name
    n  = GetClassName( c )      &apos; n  - Class&apos; Name
    sn = Split(rn,&quot;.&quot;)          &apos; sn - Class&apos; Sheet Name (with &apos;$&apos; in the name)
    r = oDoc.Sheets.getByName( Replace( sn(0), &quot;$&quot;, &quot;&quot; ) ).getCellRangeByName( sn(1) ) &apos; r - Class Range

    cdepth = GetClassDepth( c ) &apos; cdepth - Class Depth
    
    If cdepth &lt; depth Then
      REM create new class
      newClass = CreateClass( oDoc, className, oRange, depth, color )
      REM add class
      &apos; copy array until the spot for the new class
      for j = LBound( classes ) to (i - 1)
        newList(j) = classes(j)
      next j
      &apos; add the new class to the right place
      newList(i) = newClass
      &apos; copy the remaining items of the initial array
      for j = i to (UBound( classes ))
        newList(j+1) = classes(j)
      next j
    End If
    
    If RangesOverlap( oDoc, oRange, r ) Then
      If InRange( oDoc, oRange, r ) Then
        REM check sub-classes
        depth = depth + 1
      Else
        REM Invalid
        AddClassToList = &quot;&quot;
        Exit Function
      End If
    End If
    
    i = i + 1
  WEnd
  
  If newClass = &quot;&quot; Then
    REM the new class is a root class: add at the end
    for i = LBound( classes ) to UBound( classes )
      newList(i) = classes(i)
    next i
    
    If UBound( classes ) &lt; LBound( classes ) Then
      &apos; the list is empty
      oDoc = oDoc
      className = className
      oRange = oRange
      depth = depth
      color = color
      newList( 0 ) = CreateClass( oDoc, className, oRange, depth, color )
    Else
      for i = LBound( classes ) to UBound( classes )
        newList(i) = classes(i)
      next i
      newList(i) = CreateClass( oDoc, className, oRange, depth, color )
    End If
  End If
  
  AddClassToList = join(newList, &quot;;&quot;)
End Function

&apos; =====================================

Function CreateClass (oDoc As Object, class As String, oRange As Object, depth As Integer, color As Long) As String
  Dim addr, range, newClass
  addr  = oRange.getRangeAddress()
  range = &quot;$&quot; &amp; oDoc.Sheets( addr.Sheet ).getName() _
      &amp; &quot;.$&quot; &amp; oDoc.Sheets( addr.Sheet ).Columns( addr.StartColumn ).getName() _
      &amp; &quot;$&quot; &amp; ( addr.StartRow + 1 ) &amp; &quot;:$&quot; _
      &amp; oDoc.Sheets( addr.Sheet ).Columns( addr.EndColumn ).getName() &amp; &quot;$&quot; &amp; ( addr.EndRow + 1 )
  CreateClass = class &amp; &quot;,&quot; &amp; range &amp; &quot;,&quot; &amp; depth &amp; &quot;,&quot; &amp; color
  
  &apos; update spreadsheet
  oRange.CellBackColor = color
End Function

&apos; =====================================

Function GetClasses (oDoc As Object) As Object
  Dim oUserProperties, classes As Object
  Dim strClasses As String
  
  oUserProperties = GetUserProperties( oDoc )
  
  strClasses = oUserProperties.getPropertyValue( PropertyName )
  
  classes = Split( strClasses, &quot;;&quot; )
  
  GetClasses = classes
End Function

&apos; =====================================

Function GetRootClasses (oDoc As Object) As Object
  Dim allClasses
  Dim classes(0) As String
  Dim count,i As Integer
  count = 0
  
  allClasses = GetClasses( oDoc )
  ReDim classes( UBound(allClasses) )
  
  For i = LBound( allClasses ) To UBound( allClasses )
    If GetClassDepth( allclasses(i) ) = 1 Then
      classes(count) = allClasses(i)
      count = count + 1
    End If
  Next i
  
  ReDim Preserve classes( count-1 )
  
  GetRootClasses = classes
End Function

&apos; =====================================

Function InRangeByNames (oDoc As Object, inner As String, outer As String) As Boolean
  i = Split(inner,&quot;.&quot;)
  o = Split(outer,&quot;.&quot;)

  oInner = oDoc.Sheets.getByName( Replace( i(0), &quot;$&quot;, &quot;&quot; ) ).getCellRangeByName( i(1) )
  oOuter = oDoc.Sheets.getByName( Replace( o(0), &quot;$&quot;, &quot;&quot; ) ).getCellRangeByName( o(1) )
  
  InRangeByNames = InRange( oDoc, oInner, oOuter )
End Function

&apos; =====================================

Function InRange (oDoc As Object, oInner As Object, oOuter As Object) As Boolean
  InRange = False
  
  Dim aI, aO As Object
  aI = oInner.getRangeAddress()
  aO = oOuter.getRangeAddress()
  
  If aI.Sheet &lt;&gt; aO.Sheet Then Exit Function

  If aI.StartColumn &gt;= aO.StartColumn  _
      And aI.EndColumn &lt;= aO.EndColumn _
      And aI.StartRow &gt;= aO.StartRow   _
      And aI.EndRow &lt;= aO.EndRow Then
    InRange = True
  End If
End Function

&apos; =====================================

Function RangesOverlap (oDoc As Object, oLeft As Object, oRight As Object) As Boolean
  RangesOverlap = False

  Dim aL, aR As Object
  aL = oLeft.RangeAddress
  aR = oRight.RangeAddress
  
  If aL.Sheet &lt;&gt; aR.Sheet Then Exit Function
 
  If RangesOverlapTest( aL, aR ) Or RangesOverlapTest( aR, aL ) Then
    RangesOverlap = True
  End If
End Function

&apos; =====================================

Function RangesOverlapTest (addrLeft As Object, addrRight As Object) As Boolean
  RangesOverlapTest = True
  
  Dim aL, aR As Object
  aL = addrLeft
  aR = addrRight
  
  If (aL.StartRow &gt; aR.EndRow Or aL.EndRow &lt; aR.StartRow) Then
    RangesOverlapTest = False
  End If
  
  If (aL.StartColumn &gt; aR.EndColumn Or aL.EndColumn &lt; aR.StartColumn) Then
    RangesOverlapTest = False
  End If
  
End Function

&apos; =====================================

Function GetClassName (class As String) As String
  Dim values As Object
  
  values = Split( class, &quot;,&quot; )
  GetClassName = values(0)
End Function

&apos; =====================================

Function GetClassRangeName (class As String) As String
  Dim values As Object
  
  values = Split( class, &quot;,&quot; )
  GetClassRangeName = values(1)
End Function

&apos; =====================================

Function GetClassDepth (class As String) As Integer
  Dim values As Object
  
  values = Split( class, &quot;,&quot; )
  GetClassDepth = CInt(values(2))
End Function

&apos; =====================================

Function GetClassColor (class As String) As Long
  Dim values As Object
  
  values = Split( class, &quot;,&quot; )
  GetClassRangeName = CLng(values(3))
End Function

&apos; =====================================

&apos; iModel -&gt; index of model&apos;s sheet
&apos; iData  -&gt; index of data&apos;s sheet
Sub CreateDataTemplate (oDoc as Object, iModel As Integer, iData As Integer)
  modelsheet = oDoc.Sheets( iModel )
  datasheet  = oDoc.Sheets( iData )
  classes    = GetRootClasses( oDoc )
  
  For i=LBound( classes ) To UBound( classes )
    &apos; get range from class
    rangeName = GetClassRangeName( classes(i) )
    &apos;oRange = 
    &apos; copy the cells from the model sheet to the data sheet
    &apos; -------------------------------------------------------------------------
    &apos; For later:
    &apos;  - load the cells from the model
    &apos;  - process the cells from the model
    &apos;  - write the processed cells to the data sheet
  Next i
End Sub

&apos; =====================================

Function RangeToString (oRange As Object) As String
  addr  = oRange.getRangeAddress()
  range = &quot;$&quot; &amp; oDoc.Sheets( addr.Sheet ).getName() _
      &amp; &quot;.$&quot; &amp; oDoc.Sheets( addr.Sheet ).Columns( addr.StartColumn ).getName() _
      &amp; &quot;$&quot; &amp; ( addr.StartRow + 1 ) &amp; &quot;:$&quot; _
      &amp; oDoc.Sheets( addr.Sheet ).Columns( addr.EndColumn ).getName() &amp; &quot;$&quot; &amp; ( addr.EndRow + 1 )
  RangeToString = range
End Function

&apos; =====================================

&apos; TESTED (1/1 OK)
Function StringToRange (oDoc As Object, range As String) As Object &apos; com.sun.star.table.CellRangeAddress
  Dim oSheet, oRange As Object
  Dim sheetTail As Object
  Dim sheet As String
  
  sheetTail = Split( range, &quot;.&quot; )
  sheet     = sheetTail(0)
  sheet     = Replace( sheet, &quot;$&quot;, &quot;&quot; )
  oSheet    = oDoc.getSheets.getByName( sheet )
  oRange    = oSheet.getCellRangeByName( sheetTail(1) )
  
  StringToRange = oRange
  
&apos;  &apos; Old version
&apos;  Dim addr As New com.sun.star.table.CellRangeAddress
&apos;  
&apos;  Dim sheet As String  
&apos;  sheetTail = Split( range, &quot;.&quot; )
&apos;  sheet = sheetTail(0)
&apos;  startCellTail = Split( sheetTail(1) , &quot;:&quot; )
&apos;  startCell = startCellTail(0)
&apos;  endCell = startCellTail(1)
&apos;  
&apos;  startCellElems  = Replace( startCell, &quot;$&quot;, &quot; &quot; )
&apos;  startCellElems  = Trim( startCellElems )
&apos;  startCellValues = Split( startCellElems, &quot; &quot; )
&apos;  
&apos;  endCellElems  = Replace( endCell, &quot;$&quot;, &quot; &quot; )
&apos;  endCellElems  = Trim( endCellElems )
&apos;  endCellValues = Split( endCellElems, &quot; &quot; )
&apos;  
&apos;  &apos; TODO sheet name to sheet index
&apos;  addr.StartColumn = startCellValues(0)
&apos;  addr.StartRow = CInt( startCellValues(1) ) - 1
&apos;  addr.EndColumn = endCellValues(0)
&apos;  addr.EndRow = CInt( endCellValues(1) ) - 1
&apos;  
&apos;  StringToRange = addr
End Function

&apos; =====================================

&apos; Instantiates a model.
&apos; Arguments:
&apos;  - oDoc -- the document with the model and data sheet
&apos;  - dataSheet -- the index of the data sheet in the document data sheets
&apos;
Sub InstantiateModel (oDoc As Object, dataSheet As Integer)
  Dim classes, exps As Object
  Dim i As Integer

  &apos; iterate over classes and instantiate them
  classes = GetRootClasses( oDoc )
  For i=LBound( classes ) To UBound( classes )
    InstantiateClass( oDoc, classes(i), dataSheet )
  Next i

  &apos; iterate over expansions and instantiate them  
  exps = GetExpansions( oDoc )
  For i=LBound( exps ) To UBound( exps )
    InstantiateExpansion( oDoc, exps(i), dataSheet )
  Next i
End Sub

&apos; =====================================

&apos; Creates an instance of a model class.
&apos; Arguments:
&apos;  - class -- string representation of the class
&apos;
Sub InstantiateClass (oDoc As Object, class As String, dataSheet As Integer)
  Dim rangeName As String
  Dim oRange, oAddr, i , j, oCell, oDest
  rangeName = GetClassRangeName( class )
  oRange = StringToRange( oDoc, rangeName )
  
  oAddr = oRange.getRangeAddress()
  For i=oAddr.StartColumn To oAddr.EndColumn
    For j=oAddr.StartRow To oAddr.EndRow
      oCell = oDoc.Sheets(oAddr.Sheet).getCellByPosition( i, j )
      oDest = oDoc.Sheets(dataSheet).getCellByPosition( i, j )
      InstantiateCell( oCell, oDest )
    Next j
  Next i
End Sub

&apos; =====================================

&apos; Creates an instance of a model cell.
&apos; Arguments:
&apos;  - oCell -- the model cell
&apos;  - oDest -- the destination cell
&apos;
&apos; TODO maybe name the destination cell
&apos;
Sub InstantiateCell (oCell As com.sun.star.sheet.SheetCell, oDest As com.sun.star.sheet.SheetCell)
  &apos; determine the type of the cell, and instantiate it
  
  &apos; types of cells:
  &apos;  - label (just alphanumeric characters)
  &apos;  - formula (label &apos;=&apos; [Class &apos;.&apos;] ( cell ref | cell label ))
  Dim parts As Object
  Dim label, formula As String
  
  If (oCell.String = &quot;&quot;) Then
    oDest.String = &quot;&quot;
    Exit Sub
  EndIf
  
  parts = Split( oCell.String, &quot;=&quot; )
  
  label = parts(0)
  If (UBound(parts) &gt; 0) _
    Then
      oDest.Formula = &quot;=&quot; &amp; parts(1)
    Else
      oDest.String = label
  EndIf
End Sub

&apos; =====================================

&apos; Creates an instance of a expansion.
&apos; Arguments:
&apos;  - oCell     -- the model cell
&apos;  - exp       -- string representation of the expansion
&apos;  - dataSheet -- index of the data sheet
&apos;
Sub InstantiateExpansion (oDoc As Object, exp As String, dataSheet As Integer)
  Dim oForm, oButton, oShape As Object
  Dim oSheet, oRange, oAddr As Object
  Dim str_name, str_range, form_name, btn_name As String
  Dim etype As Integer
  
  str_name  = GetExpansionName( exp )
  str_range = GetExpansionRangeName( exp )
  etype     = GetExpansionType( exp )

  oRange = StringToRange( oDoc, str_range )
  oAddr  = oRange.getRangeAddress()
  &apos;oSheet = oDoc.Sheets( oAddr.Sheet )
  oSheet = oDoc.Sheets( dataSheet )
  
  &apos; ===== FORM =====
  
  form_name = &quot;HaExcel_&quot; &amp; str_name &amp; &quot;_&quot; &amp; etype
  btn_name  = form_name &amp; &quot;_button&quot;
  
  oForm = GetForm( oSheet, form_name )
  
  If oForm &lt;&gt; Null Then &apos; form exists
    &apos;
    &apos; TODO check if button exists
    &apos;
  Else &apos; form does not exist
    &apos; create the form
    &apos;oForm = createUnoService(&quot;com.sun.star.form.FormComponent&quot;)
    oForm = createUnoService(&quot;com.sun.star.form.component.Form&quot;)
    oForm.Name = form_name
    
    &apos;AddForm( oSheet, oForm )
    AddFormWithName( oSheet, oForm, form_name )
  End If
  
  &apos; ===== BUTTON =====
  
  &apos; positionShape( oShape, 1000, 1000 + 800, 5000, 600 ) &apos;http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Forms/Programmatic_Assignment_of_Scripts_to_Events
  Dim oPos as new com.sun.star.awt.Point
  Dim oSize as new com.sun.star.awt.Size
  Dim oStartCell, oEndCell As Object
  
  If etype &lt;&gt; 0 Then
    oButton = CreateExpandButton ( btn_name, True )

    &apos; calculate the position and the size of the button
    oStartCell   = oSheet.getCellByPosition( oAddr.StartColumn, oAddr.EndRow + 1 )
    oEndCell     = oSheet.getCellByPosition( oAddr.EndColumn  , oAddr.EndRow + 1 )
    oPos.X       = oStartCell.Position.X
    oPos.Y       = oStartCell.Position.Y
    oSize.Width  = oEndCell.Position.X + oEndCell.Size.Width
    oSize.Height = oEndCell.Size.Height - 100 &apos; or oStartCell.Size.Height ... it&apos;s all in the same row
  Else
    oButton = CreateExpandButton ( btn_name, False )
    
    &apos; calculate the position and the size of the button
    oStartCell   = oSheet.getCellByPosition( oAddr.EndColumn+1, oAddr.StartRow )
    oEndCell     = oSheet.getCellByPosition( oAddr.EndColumn+1, oAddr.EndRow   )
    oPos.X       = oStartCell.Position.X
    oPos.Y       = oStartCell.Position.Y
    oSize.Width  = oEndCell.Size.Width - 100 &apos; or oStartCell.Size.Width ... it&apos;s all in the same column
    oSize.Height = oEndCell.Position.Y + oEndCell.Size.Height
  End If
  
  oForm.insertByIndex( etype, oButton )
  
  &apos; ===== SHAPE =====
  
  &apos;oShape = createUnoService( &quot;com.sun.star.drawing.ControlShape&quot; )
  oShape = oDoc.createInstance(&quot;com.sun.star.drawing.ControlShape&quot;)
  
  oShape.setPosition( oPos )
  oShape.setSize( oSize )
  
  Erase oPos
  Erase oSize  

  oShape.Control = oButton
  
  oSheet.DrawPage.add( oShape )
  
  &apos; ===== EVENT =====
  
  &apos; http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Forms/Programmatic_Assignment_of_Scripts_to_Events
  
  &apos; we want to add the equivalent of an com.sun.star.awt.XItemListener
  Dim sListenerInterfaceName As String
  sListenerInterfaceName = &quot;XActionListener&quot; &apos; &quot;com.sun.star.awt.XItemListener&quot;
  Dim sListenerMethodName As String
  sListenerMethodName = &quot;actionPerformed&quot;
     
  &apos; we want the onColorChange function in this module to be called
  Dim sMacroLocation As String
  &apos; TODO correct the path to the macro
  &apos;sMacroLocation = &quot;application:HaExcelDev.ClassSheet.NotImplemented&quot;
  sMacroLocation = &quot;vnd.sun.star.script:HaExcelDev.ClassSheet.NotImplemented?language=Basic&amp;location=application&quot;
      &apos; note that this assumes that the module is called macro_assignment, and
      &apos; resides in the &quot;Standard&quot; library of the application-wide Basic macros
  
  &apos; bind a macro to the &quot;stateChanged&quot; event
  Dim oEvent as new com.sun.star.script.ScriptEventDescriptor
    oEvent.AddListenerParam = &quot;&quot;
    oEvent.ListenerType     = sListenerInterfaceName
    oEvent.EventMethod      = sListenerMethodName
    oEvent.ScriptType       = &quot;Script&quot;
    oEvent.ScriptCode       = sMacroLocation
    oForm.registerScriptEvent( 0, oEvent )
  Erase oEvent
End Sub

&apos; =====================================

&apos; Checks if a form exists.
&apos; Arguments:
&apos;  - oSheet -- the sheet to search in
&apos;  - str    -- the name of the form
&apos; Returns: true if form exists; otherwise false
&apos;
Function FormExists (oSheet As Object, str As String) As Boolean
  FormExists = oSheet.DrawPage.Forms.hasByName( str )
End Function

&apos; =====================================

&apos; Gets a form from a sheet
&apos; Arguments:
&apos;  - oSheet -- the sheet to search in
&apos;  - str    -- the name of the form
&apos; Returns: the form if it exists; otherwise Nothing
&apos;
Function GetForm (oSheet As Object, str As String) As com.sun.star.form.Form
  If FormExists( oSheet, str ) Then
    GetForm = oSheet.DrawPage.Forms.getByName( str )
  Else
    GetForm = Nothing
  End If
End Function

&apos; =====================================

&apos; Appends a form to a sheet.
&apos; Arguments:
&apos;  - oSheet -- the sheet where to append the form
&apos;  - oForm  -- the form to append
&apos;
Sub AddForm (oSheet As Object, oForm As com.sun.star.form.Form)
  Dim count As Long
  count = oSheet.DrawPage.Forms.getCount
  oSheet.DrawPage.Forms.insertByIndex( count+1, oForm )
End Sub

&apos; =====================================

&apos; Inserts a form with a given name to a sheet.
&apos; Arguments:
&apos;  - oSheet -- the sheet where to append the form
&apos;  - oForm  -- the form to append
&apos;  - str    -- the name of the form
&apos;
Sub AddFormWithName (oSheet As Object, oForm As com.sun.star.form.Form, str As String)
  Dim oForms as Object
  oForms = oSheet.DrawPage.Forms
  oForms.insertByName( str, oForm )
  &apos;oSheet.DrawPage.Forms.insertByName( str, oForm )
End Sub

&apos; =====================================

&apos; Creates a button to expand columns/rows.
&apos; Arguments:
&apos;  - str  -- the name of the button to create
&apos;  - h    -- true for horizontal button (expand rows); otherwise false.
&apos; Returns: the created button
&apos;
Function CreateExpandButton (str As String, h As Boolean) As com.sun.star.form.component.CommandButton
  Dim oControlModel As Object
  
  oControlModel = createUnoService(&quot;com.sun.star.form.component.CommandButton&quot;)
  oControlModel.Name = str
  
  If h Then
    oControlModel.Label = &quot;⋮&quot;
  Else
    oControlModel.Label = &quot;⋯&quot;
  End If

  CreateExpandButton = oControlModel
End Function

&apos; =====================================

&apos; Event function for the expand button press
&apos; Arguments:
&apos;  - oEvent -- the event information
&apos;
Sub doExpandRows (oEvent As Object)
  Dim oSrc As Object
  
  oSrc = oEvent.Source
  
  &apos; TODO get info from button and its respective form
  &apos;      and call ExpanRows with the right arguments
End Sub

&apos; =====================================

&apos; Creates an expansion of rows.
&apos; Arguments:
&apos;  - oDoc        -- the document where to make the changes
&apos;  - oModelRange -- the range of the cells from the model to instantiate
&apos;  - oDest       -- the address of the top left cell where to insert the instantiation
&apos;
Sub ExpandRows(oDoc        As Object                              , _
               oModelRange As com.sun.star.table.CellRangeAddress , _
               oDest As com.sun.star.table.CellAddress            )
  Dim oDestSheet As Object
  Dim oDestRange As New com.sun.star.table.CellRangeAddress
  
  oDestSheet = oDoc.Sheets(oDest.Sheet)
  
  With oDestRange
    .Sheet       = oDest.Sheet
    .StartColumn = oDest.Column
    .StartRow    = oDest.Row
    .EndColumn   = oDest.Column + ( oModelRange.EndColumn - oModelRange.StartColumn )
    .EndRow      = oDest.Row    + ( oModelRange.EndRow    - oModelRange.StartRow    )
  End With

  oDestSheet.insertCells(oDestRange, com.sun.star.sheet.CellInsertMode.DOWN)
  
  &apos; TODO intantiate the cells
End Sub

&apos; =====================================

</script:module>

Generated by GNU Enscript 1.6.5.90.

Theme by Vikram Singh | Powered by WebSVN v2.3.3