Add Annotations Button

    {info} For two connected tables on a many:many relationship, create a button which allows notations to be associated with the selected record. The many:many relationship means a single record can have many notations, or a single notation can have many records.

    This script is part of a system set up in the Markush demo data set in order to add annotations to inventions. This allows the notes on the inventions to be viewed per invention, or the see all the inventions linked to a single annotation. This particular script is a button to be placed on the Inventions form. The Inventions table has a many:many relationship with the Notes table based on ID. This allows the Notes table to be a child table to the Inventions table.

    The script works by building an array of existing notations and putting them in a combo box, or offering a text box to input a new notation. New notations are inserted into the Notes table, and the ID returned. Existing notations are already associated with their ID. The script then makes a relationship between the two IDs. On the Inventions form itself, you can select an invention and see all the notations. If you have also turned the Notes table into a dataTree by putting Inventions as an edge, you can then set up a form which allows you to select notations, and see all associated Inventions. The dataTree structure dictates how the data can be viewed. This system can be used to add notations to any type of information based on the row's ID.

    
    /** Add annotations to an Invention button, from the Invention form
    *
    * @author Erin Bolstad (ebolstad@chemaxon.com)
    * Dec 2011
    */
    
    import com.im.df.api.dml.*
    import com.im.commons.progress.*
    import groovy.swing.SwingBuilder
    import com.im.df.api.util.DIFUtilities
    import java.awt.*
    import org.openide.NotifyDescriptor
    import org.openide.DialogDisplayer
    
    evaluate = { widget ->
    
        def rs = widget.form.resultSet
        def dataTree = rs.dataTree
        def ety = dataTree.rootVertex.entity
        def parentVS = rs.rootVertexState
        def schema = ety.schema
    
        def VMNSvertex = dataTree.rootVertex.edges.find { it.destination.entity.name == 'VMNS' }
        def inventionVertex = VMNSvertex.destination.edges.find { it.destination.entity.name == 'Inventions' }
        def invenV = inventionVertex.getDestination()
        def invenVS = rs.getVertexState(invenV)
        def invenIds = invenVS.selectedRowsIds
        def invenFirstId = invenIds.get(0)
    
        def noteEdge = inventionVertex.destination.edges.find { it.destination.entity.name == 'Notes' }
        def noteEntity = noteEdge.destination.entity
        def noteEdp = noteEntity.schema.dataProvider.getEntityDataProvider(noteEntity)
        def noteRS = noteEntity.schema.dataProvider.getDefaultResultSet(dataTree, true, DFEnvironmentRO.DEV_NULL)
        def noteVS = noteRS.getVertexState(noteEdge.destination)
    
        noteEdp.lockable.withLock('Notating') { envRW ->
    
            def noteIDs = noteEdp.queryForIds(DFTermExpression.ALL_DATA, null, envRW)
            def noteData = noteVS.getData(noteIDs, envRW)
            def noteFld = noteEntity.fields.items.find { it.name == 'NOTE' }
            def noteUserFld = noteEntity.fields.items.find { it.name == 'User' }
            def noteDateFld = noteEntity.fields.items.find { it.name == 'Date Added' }
    
            noteRef = [:]
            noteList = ["-"]
    
            noteData.each { id, noteMap ->
                notetation = noteData[id][noteFld.id]
                noteRef.putAt(id, notetation)
                noteList << notetation
            }
            def noteSel = new SwingBuilder()
    
            noteSel.setVariable('properties',[:])
    
            def vars = noteSel.variables
    
            def frame = noteSel.dialog(title:'Notations', modal:true) {
                panel () {
                    gridBagLayout()
                    label(text:"Enter a new notation:", constraints:gbc(
                            gridx:0,
                            gridy:0,
                            insets:[10,10,10,5]))
                    textField(id:'newName', constraints:gbc(
                            gridx:1,
                            gridy:0,
                            fill:GridBagConstraints.HORIZONTAL,
                            insets:[10,10,10,10]))
                    label(text:" Or, select an existing notation from the list", constraints:gbc(
                            gridy:1,
                            gridwidth:2,
                            insets:[10,50,5,50]))
                    comboBox(id:'notetations', items:noteList, constraints:gbc(
                            gridy:2,
                            gridwidth:2,
                            insets:[5,10,10,10]))
                    button(id:'ok', label: "OK", constraints:gbc(
                            gridx:0,
                            gridy:3,
                            anchor:LINE_END,
                            insets:[10,0,10,0]),
                            actionPerformed: {
                                vars.buttonResults = 'ok'
                                dispose()})
                    button(id:'cancel', label: "Cancel", constraints:gbc(
                            gridx:1,
                            gridy:3,
                            anchor:LINE_START,
                            insets:[10,0,10,0]),
                            actionPerformed: {
                                vars.buttonResults = 'quit'
                                dispose()})
                }
            }
    
            frame.pack()
            frame.setLocationRelativeTo(null)
            frame.show()
    
            def chosenAction = vars.buttonResults
    
            if (chosenAction == 'quit') {
                return
            }
    
            if (chosenAction == 'ok') {
                newNotetation = vars.newName.text
                selNotetation = vars.notetations.selectedItem
            }
    
            rel = DIFUtilities.findUsagesInRelationships(noteEntity)
            firstRel = rel.get(0)
    
            //Get current invention ID - make relationship with only that one.
    
            def userName = schema.getUsername()
            def timeStamp = new Date()
    
            if (selNotetation == "-") {
    
                // See if Notation already exists, throw warning message
    
                def newNoteIDs = noteEdp.queryForIds(DFTermExpression.ALL_DATA, null, envRW)
                def newNoteData = noteVS.getData(newNoteIDs, envRW)
    
                newNoteRef = [:]
                newNoteList = ["-"]
    
                if (!newNoteData.isEmpty()) {
                    newNoteData.each { id, noteMap ->
                        notetation = newNoteData[id][noteFld.id]
                        newNoteRef.putAt(id, notetation)
                        newNoteList << notetation
                    }
                }
    
                if (newNoteList.contains(newNotetation)) {
                    def message1 = "$newNotetation already exists!\nCheck the drop down box"
                    NotifyDescriptor w = new NotifyDescriptor.Message(message1)
                    DialogDisplayer.getDefault().notify(w)
                    return
    
                }else{
                    vals =[(noteFld.id):newNotetation]
                    vals.putAt(noteUserFld.id, userName)
                    vals.putAt(noteDateFld.id, timeStamp)
                    noteEdp.insert(vals, null, envRW)
                    def insNoteIDs = noteEdp.queryForIds(DFTermExpression.ALL_DATA, null, envRW)
                    def insNoteData = noteVS.getData(insNoteIDs, envRW)
                    newNoteRef = [:]
    
                    insNoteData.each { id, noteMap ->
                        notetation = insNoteData[id][noteFld.id]
                        newNoteRef.putAt(id, notetation)
                    }
                    newLastKey = newNoteRef.max{ it.key }
                    newIdx = newLastKey.key
                    def x = ("$newIdx" as String) as Integer
                    def y = ("$invenFirstId" as String) as Object
    
                    DIFUtilities.connectRelationalData(firstRel.forward, y, x, envRW)
    
                    def message = "Please Note:\nTo see this new Note in the Notation View,\nyou will first need to select 'Show All' in Query mode."
                    NotifyDescriptor d = new NotifyDescriptor.Message(message)
                    DialogDisplayer.getDefault().notify(d)
                }
            }
    
            if (selNotetation != "-") {
                def selKeySet = noteRef.find { id, notet -> notet == selNotetation}
                def selNoteID = selKeySet.key
    
                // Get the note IDs for the invention in question
                def checkIDs = noteVS.getIdsForParentId(invenFirstId, DFEnvironmentRO.DEV_NULL)
    
                if (checkIDs.contains(selNoteID)) {
                    def message2 = "$selNotetation already assigned to Invention $invenFirstId!"
                    NotifyDescriptor q = new NotifyDescriptor.Message(message2)
                    DialogDisplayer.getDefault().notify(q)
                    return
                } else {
                    def x = ("$selNoteID" as String) as Integer
                    def y = ("$invenFirstId" as String) as Object
                    DIFUtilities.connectRelationalData(firstRel.forward, y, x, envRW)
                }
            }
        }
    
    }