|
For a project, I had to provide a way for users to select certain images to delete out of an XPage. Displaying and giving a checkbox to delete was easy - but then I had to actually delete the images. There could be any number of attachments (all images, so I don't need to worry about type), and the user should be able to delete any of the images.
Here is where my problem came up. I could delete the embedded objects from the NotesDocument no problem - but this left "ghosts" in the rich text field. The deleted image still had an icon in the RTField, but with 0 bytes. Since the next step in the process is in classic Notes, the user there would see attachment icons that would not launch/contain anything. So I needed to get them out.
So I need to delete from the Rich Text field. But of course there could be mutliple copies of this field in the document. So if I want to delete something in the third RT Field, I have to delete the two before it, then delete - but if I save then, I have deleted the 2 fields that might have something I need to keep. So I created an agent for those documents flagged (and in my "Delete Images" view). As I check each attachment, I move it to a temporary document if it's to be kept. When I've deleted all the RTFields, I copy it back over from my temporary document (if there are any - it will fail if there is nothing there) and save it. So it also "cleans up" the document a bit, and no "ghosts".
Cheers,
Brian
Option Public
Option Declare
Sub Initialize
Dim s As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim rtItem As Variant
Dim getIndex As Variant
Dim item As NotesItem
Dim tempDoc As NotesDocument
Dim tempRTField As NotesRichTextItem
Dim agent As NotesAgent
Dim view As NotesView
Const LOG_VERBOSE = True
If LOG_VERBOSE Then Dim agentLog As New NotesLog (s.CurrentDatabase.Title & " - " & s.CurrentAgent.Name )
If LOG_VERBOSE Then Call agentLog.OpenNotesLog ( "", "AgentLog.nsf" )
If LOG_VERBOSE Then Call agentLog.LogAction ("Agent Started" )
On Error GoTo ErrorHandler
Set db = s.Currentdatabase
Set view = db.getview("Delete Images")
view.Autoupdate = False
Set doc = view.Getfirstdocument()
Do While Not doc Is Nothing
'Set agent = s.Currentagent
'Set doc = db.Getdocumentbyid(agent.Parameterdocid)
If LOG_VERBOSE Then Call agentLog.LogAction("DocID: " + doc.Noteid)
Set tempDoc = db.Createdocument()
Call tempDoc.Replaceitemvalue("Form", "RTfieldHolder")
Set tempRTField = tempDoc.Createrichtextitem("body")
If doc.Hasitem("delImage") Then
Set item = doc.getFirstItem("delImage")
If LOG_VERBOSE Then Call agentLog.Logaction("I have the item " + doc.delImage(0))
ForAll x In item.Values
If LOG_VERBOSE Then Call agentLog.Logaction(x)
End ForAll
ForAll x In doc.Items
If UCase(x.Name) = "BODY" Then
Set rtItem = doc.Getfirstitem("Body")
If rtItem.Type = RICHTEXT Then
ForAll o In rtitem.EmbeddedObjects
If ( o.Type = EMBED_ATTACHMENT ) Then
Print("checking on (" & o.Name & ")")
'see if it's one we need to delete
getIndex = ArrayGetIndex(item.Values, o.Name, 5)
If Not(IsNull(getIndex)) Then
'Delete it
Print("deleting (" & o.Name & ")")
Call o.Remove
Else
Print("Keeping " & o.Name)
End If
End If
End ForAll
End If
If LOG_VERBOSE Then Call agentLog.Logaction("temp body size: " & tempRTField.Valuelength)
If tempRTField.valueLength < 2 Then
'do not add, nothing of any significant size
Else
Call tempRTField.Appendrtitem(rtItem)
End If
Call x.Remove
End If
End ForAll
Call doc.Removeitem("delImage")
'Copy the items back to the original document
Dim newItem As NotesItem
Set newItem = tempRTField.CopyItemToDocument(doc, "body")
'only copy over if there is something significant
'Save the original doc, but not the temp doc
Call doc.Save(True, False)
If LOG_VERBOSE Then Call agentLog.Logaction("just saved doc")
Else
If LOG_VERBOSE Then Call agentLog.Logaction("no delImages recorded")
End If
Set doc = view.Getnextdocument(doc)
Loop
view.Autoupdate = true
GoTo TheEnd
ErrorHandler:
If LOG_VERBOSE Then Call agentLog.LogError ( Err, "Line " & Erl & ": " & Error$ )
Resume TheEnd
TheEnd:
If LOG_VERBOSE Then Call agentLog.LogAction ( "Agent Finished" )
If LOG_VERBOSE Then Call agentLog.Close
End Sub
|
| |
Add a Comment
More Actions
Comments (2)
1 Theo Heselmans commented Jan 14 2013 Permalink 0
Very nice solution, thanks for sharing.
Could you elaborate a bit more on how you got those ghost attachments in the first place? I have those sometimes too, but don't know what part of my code causes them.
2 Brian M Moore commented Jan 14 2013 Permalink 0
@Theo - I'm not sure, it happens if you remove the attachment via a NotesEmbeddedObject from a NotesDocument, the "ghost" (an icon in front of file of 0 bytes) will show in the RichTextField. If you remove it from the RichTextField, no "ghost".
I would surmise this is because the file isn't really in the RT Field, but in a $FILE field. Removing from the NotesDocument removes the $FILE, but doesn't touch the part of the Rich Text field that points to that $FILE, so that the attachment could be accessed from the RT Field.
Cheers,
Brian |