home learn tableau about
legalific swsom swsom diagram swapps ahk ue

swsom wrapper
[Overview] Application - CurrentNote DB - Notes ocrBase - OpenTranscripts Permission - Views
Download :: Diagram
swsom wrapper

(Wrapping the DB object was a bit more complicated compared to other objects, might take some back and forth before the best approach is worked out.)

Most of the properties that were prefixed with 'Get' e.g. .GetColumnName, are written in VB as functions. The most basic of the methods, like .MoveFirst seem to be working fine but there are many more, and many more properties, that I haven't been able to test yet. The testing I did do seemed to indicate that some of the entry points probably won't work as expected in the current .Net implementation. I looked at the standard ADO Field properties that appeared to be supported within Summation/VBScript and created a new Field (nested in Fields class) class for them. You can create a new Field object and from there access Value and other properties:

    Dim summary As New sw.DB.Field("Summary")
    Dim currsummary As String = summary.Value
    summary.Value = currsummary & " new info for summary field"
    currsummary = summary.Value

As an experiment I put a .GetFields into Fields, which will return a typed/Generic List for the current record:

    List<sw.DB.Field> flds = sw.DB.Fields.GetFields();
    foreach (sw.DB.Field fld in flds)
        string myField = fld.Name + "  " + fld.Value;

Often though, as long as read-only data is acceptable and the recordset is not too large, the best approach can be to use .Clone and .Cull, which will be returning a true ADODB.Recordset. This is especially true in Enterprise, whose DB object sometimes runs into problems when it comes to reading data. First you will likely need to add a Reference to your project in order to get access to the ADODB namespace. Then see below for some sample usage:

    //Num of displayed fields vs. total num of fields
    long fieldCount = sw.DB.Fields.Count;
    string delim = "|";
    string displayedFields = sw.DB.GetDisplayedCols(delim);
    int displayedFieldCount = displayedFields.Split(delim.ToCharArray()).Length;
    string displayedVsAllFields = String.Format("Of {0} fields in total, {1} 
        are in the current display", fieldCount, displayedFieldCount);

    int allRecords = 1;
    bool hyphenatedDate = false;
    ADODB.Recordset displayedRecs = sw.DB.Clone(allRecords, displayedFields, delim, hyphenatedDate);

    //which fields in Cloned recordset are of Integer datatype
    string displayedIntegerFields = "Fields from current display that are Integer dataype:\r\n";
    foreach (ADODB.Field adoField in displayedRecs.Fields)
        if (adoField.Type == ADODB.DataTypeEnum.adInteger)
            displayedIntegerFields += adoField.Name + "\r\n";

    //make delimited string of the docids in the Cloned recordset
    string docids = "";
    for (int i = 1; i <= displayedRecs.RecordCount; i++)
        docids += displayedRecs.Fields["Docid"].Value + delim;


All properties, all nice and simple.


DBGrid is another complicated object, where it is accessed via an existing View, instead allowing for a direct connection. Implementation may change down the line but for now DBGrid is an instance class and may be accessed at least three different ways, each displayed below. There isn't yet a Field/Fields sub-class either, so the only way of accessing the data via the wrapper is to .Clone it first, at which point you would be dealing with a standard, read-only ADODB recordset.

Create DBGrid object by passing in a viewId integer:

    Dim peoplePath As String = Path.Combine(sw.CurrentCase.SharedProfileDir, "People.udl")
    Dim viewId As Integer = sw.Views.CreateGrid(peoplePath, "People via CreateGrid")
    'give it 10 seconds to fully open
    Dim peopleGrid As sw.DBGrid = New sw.DBGrid(viewId)
    Dim recordCount As Integer = peopleGrid.RecordCount

If you know the currently active View is a DBGrid object:

    Dim grid As sw.DBGrid = sw.Views.ActiveView_AsDBGrid()
    recordCount = grid.RecordCount
    grid.AbsolutePosition = recordCount
    grid = Nothing

Pass in a View name (of DBGrid type) as a string:

    Dim people As sw.DBGrid = New sw.DBGrid("People")
    Const markedRecords As Integer = 2
    Dim clone As ADODB.Recordset

    recordCount = people.RecordCount
    people.MarkRows(1, recordCount - 1)
    clone = people.Clone(markedRecords)

    Dim firstRow As String = "First row in clone:" & vbCrLf
    For Each fld As ADODB.Field In clone.Fields
        Dim fieldValue As String
        If IsDBNull(fld.Value) Then
            fieldValue = "(null)"
            fieldValue = fld.Value
        End If
        firstRow = firstRow & fld.Name & vbTab & vbTab & fieldValue & vbCrLf
    clone = Nothing


Not much available in eDocs and of what is there, not all would appear to work correctly, even with native Summation application. Below attempts to retrieve the eDocs in the current case and grab the text from the eDoc viewer for the first record (assumes eDoc view is open and in Text mode):

    if (sw.DB.RecordCount > 0)    
        sw.Views.View eDocView = new sw.Views.View(sw.Views.View.ViewType.eDoc);    
        object eDocViewObject = eDocView.GetObject;    
        string eDocText = "Text of first eDoc:\r\n\r\n";    
        if (eDocViewObject as mshtml.HTMLDocument != null)    
            mshtml.HTMLDocument hDoc = (mshtml.HTMLDocument)eDocViewObject;    
            eDocText += hDoc.body.innerText;    
            eDocText += "(failed to retrieve)";    


The Img object is pretty straightforward but has many properties and methods and I've tested relatively few. The below assumes a PictureBox has been created on an existing VB WinForm. It grabs the pathing info of the current image in Summation and displays. Clicking PictureBox1 will loop through each page of the image, as long as it is not a true multipage image file. The image is re-saved as a bitmap, endorsed with the image tag and page number at the top left and the label (Stamp and Label Setup in Summation image viewer) if any, at the bottom left. PictureBox1 is loaded with the resulting .bmp file:

    Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 
            Handles PictureBox1.Click
        If Not sw.Img.IsCurDocMultipage Then
            Dim numPage As Long = sw.Img.NumPages
            Dim tempFilePath = Path.Combine(sw.Application.AppProfile, "endorsedImage.bmp")

            ApplyLabelToImage(sw.Img.GetNthImgFile(sw.Img.DefDir, sw.Img.ImgFiles, _currPage), 
                _currPage, tempFilePath)
            Me.PictureBox1.ImageLocation = tempFilePath

            If _currPage < numPage Then
                _currPage = _currPage + 1
                _currPage = 1
            End If
        End If
    End Sub

    Sub ApplyLabelToImage(ByVal imageFilePath As String, ByVal currPage As Long, 
            ByVal tempFilePath As String)
        Dim singleImageFilePath As String = sw.Img.GetNthImgFile(sw.Img.DefDir, sw.Img.ImgFiles, 
        If Not File.Exists(singleImageFilePath) Then
            singleImageFilePath = Path.Combine(sw.Application.AppDir, "noimage.tif")
        End If

        Dim newImg As Image = Drawing.Image.FromFile(singleImageFilePath)
        Dim newBmp As New Drawing.Bitmap(newImg, PictureBox1.Width, PictureBox1.Height)
        Dim g As Drawing.Graphics = Drawing.Graphics.FromImage(newBmp)
        Dim myFont As Font = New Font(Me.Font, FontStyle.Bold)
        Dim myBrush As New SolidBrush(Color.Red)

        Dim docSpecs, docLabel As String
        docSpecs = sw.Img.DocName & vbTab & "Page: " & currPage
        docLabel = sw.Img.GetDocLabel()

        g.DrawString(docSpecs, myFont, myBrush, 10, 10)
        g.DrawString(docLabel, myFont, myBrush, 10, Me.PictureBox1.Height - 20)
        newBmp.Save(tempFilePath, Drawing.Imaging.ImageFormat.Bmp)
    End Sub


One of the smaller objects, with less than fifteen total properties and methods. First example is in C#, where each of the available parameters for Img.OCR.OcrImage is being passed in:

    string outputFilePath = @"C:\test\output.txt";
    bool appendTheText = false;
    bool ocrBaseStyle = false;
    string tempFilePath = @"C:\test\tempfile.txt";
    string imageFile = Path.Combine(sw.Application.AppDir, 
        @"CaseData\P. FRANC VS. K. MORRIS (version 2.5)\IMAGES\BK000001.tif");
    sw.Img.OCR.ImageFile = imageFile;
    sw.Img.OCR.OcrImage(imageFile, outputFilePath, appendTheText, ocrBaseStyle, tempFilePath);

while the second illustrates the use of a different overload on Img.OCR.OcrImage, the one that passes in the only parameter required by the Summation app, for image file path:

    sw.Img.OCR.ImageFile = Path.Combine(sw.Application.AppDir, 
        "CaseData\P. FRANC VS. K. MORRIS (version 2.5)\IMAGES\BK000001.tif")

Either way this particular method results in the OCR UI appearing in the Summation app, where it must be handled somehow.


Described as very similar to CurrentNote object, where presumably the main difference is that CurrentNote requires the Note UI be open. This was the first object in which I noticed problems that were due solely to swsom actions, or more accurately, problems that only manifested themselves in terms of external access. The three Retrieve methods (RetrieveAll, RetrieveAllOcrBaseNotes, RetrieveAllTranNotes) work fine when run from the Scripting window within Summation but failed to do anything when called externally, even from a .vbs file. The comments for those three have been updated but the actual methods are still available - perhaps there is some environmental component involved and they will work correctly for others. I ran into even stranger problems when there was a .frm file present for the notes database files, though that file won't normally exist unless the notes have been loaded as a database. The .Search method does work though, so the below shows how to essentially get data from all transcript notes into an ADO.NET DataTable:

    sw.Notes.Search("Dep Exists", "Dep");
    int noteCount = sw.Notes.Count;
    string noteReport = noteCount + " transcript notes: \r\n";
    if (noteCount > 0)
        DataTable noteTable = new DataTable("Notes");
        noteTable.Columns.Add("Id", typeof(int));
        noteTable.Columns.Add("Deposition", typeof(string));
        noteTable.Columns.Add("Author", typeof(string));
        noteTable.Columns.Add("Text", typeof(string));

        for (int i = 0; i < noteCount; i++)
            noteTable.Rows.Add(i + 1, sw.Notes.Dep, sw.Notes.Author, sw.Notes.Text);