{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)
}
}
}
}