Email Selected Objects

This script allows you to send selected objects or the current view by email. The view is included in the email body as an HTML table.

See also Export View to HTML.

The following options allow you to send the current object, selected objects or the current view.

emailRequirements(current Module, SELECTION)

emailRequirements(current Module, OBJECT)

emailRequirements(current Module, VIEW)

The following code should be saved in a file and #included before calling one of the above options.

//  Email selected objects or view

/*
	02-MAR-2011		Tony Goodman	Initial Version
*/

pragma runLim, 0

int VIEW      = 0
int OBJECT    = 1
int SELECTION = 2

Buffer tb2 = create

/*************************************
	makeEmail
*************************************/
void makeEmail(string subject, Buffer htmlBuffer)
{
	string      res        = null
	OleAutoObj  objOutlook = null
	OleAutoObj  objItem    = null
	OleAutoArgs args       = create

	objOutlook = oleCreateAutoObject("Outlook.Application")

	if (null objOutlook)
	{
		return
	}

    	clear args

	if (!null objItem)
	{
		oleCloseAutoObject(objItem)
	}

    	put(args, 0)

    	res = oleMethod(objOutlook, "CreateItem", args, objItem)

    	if (null objItem)
	{
		ack "Failed to create item"
		return
    	}

   	res = olePut(objItem,"HTMLBody", stringOf(htmlBuffer))

    	res = olePut(objItem, "Subject", subject)

    	res = oleMethod(objItem, "Display")

	if (!null objOutlook)
	{
		oleCloseAutoObject(objOutlook)
	}

}

/*************************************
	escapeQuotes
*************************************/
void escapeQuotes(Buffer buf, Buffer &bTemp) {
	int i = 0

	setempty(bTemp)

	for (i = 0; i < length(buf); i++)
	{
		if (buf[i] == '"')
		{
			bTemp += '"' ""
		}

		bTemp += buf[i] ""
	}
}

/*************************************
	escapeBrackets
*************************************/
void escapeBrackets(string s, Buffer &bTemp) {
	int i = 0

	setempty(bTemp)

	for (i = 0; i < length(s); i++)
	{
		if (s[i] == '<')
		{
			bTemp += "&lt;"
		}
		else if (s[i] == '>')
		{
			bTemp += "&gt;"
		}
		else
		{
			bTemp += s[i] ""
		}
	}
}

/*************************************
	convertRichText
*************************************/
void convertRichText(Buffer& b, string s, int& len, int max)
{
	RichTextParagraph rp = null
    RichText rt = null
    bool     limitText = false
	int ind = 0
	int i = 0

    if (!null len && !null max)
        limitText = true
    else
        limitText = false

    if (limitText && len >= max)
        return

    setempty b

	for rp in s do
	{
		ind = rp.indentLevel

		for (i = 0; i < ind; i += 360)
		{
				b += "<ul>"
		}

		if (rp.isBullet)
		{
			b += "<li>"
		}

    for rt in rp do {
        if (limitText && len >= max)
            break
        setempty tb2
        tb2 += rt.text
        if (limitText)
           // truncateBuffer(tb2, len, max)
        safeHTMLBuffer(tb2, true, true)

        if (rt.bold)
            b += "<b>"
        if (rt.underline)
            b += "<u>"
        if (rt.italic)
            b += "<i>"
        if (rt.strikethru)
            b += "<s>"
        if (rt.superscript)
            b += "<sup>"
        if (rt.subscript)
            b += "<sub>"
        if (rt.charset == charsetSymbol)
            b += "<font face=\"Symbol\">"

        b += tb2

        if (rt.charset == charsetSymbol)
            b += "</font>"
        if (rt.subscript)
            b += "</sub>"
        if (rt.superscript)
            b += "</sup>"
        if (rt.strikethru)
            b += "</s>"
        if (rt.italic)
            b += "</i>"
        if (rt.underline)
            b += "</u>"
        if (rt.bold)
            b += "</b>"

		if (rt.newline)
            b += "<br>"
    }

	if (rp.isBullet)
	{
		b += "</li>"
	}

	for (i = 0; i < ind; i += 360)
	{
			b += "</ul>"
	}
}

}

/*************************************
	emitHeader
*************************************/
void emitHeader(Buffer htmlBuffer)
{
	htmlBuffer += "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
	htmlBuffer += "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
	htmlBuffer += "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
	htmlBuffer += "<head>\n"

	htmlBuffer += "<style>\n"

	htmlBuffer += ".myCell {\n"
	htmlBuffer += "margin: 0px;\n"
	htmlBuffer += "padding: 5px;\n"
	htmlBuffer += "vertical-align: top;\n"
	htmlBuffer += "font: 11px Arial, sans-serif;\n"
	htmlBuffer += "border: 1px solid #CCCCCC;\n"
	htmlBuffer += "}\n"

	htmlBuffer += ".myTable {\n"
	htmlBuffer += "margin: 0px;\n"
	htmlBuffer += "padding: 0px;\n"
	htmlBuffer += "vertical-align: top;\n"
	htmlBuffer += "}\n"

	htmlBuffer += ".myAnchor {\n"
	htmlBuffer += "text-decoration: none;\n"
	htmlBuffer += "font: 11px Arial, sans-serif;\n"
	htmlBuffer += "color: #000000;\n"
	htmlBuffer += "}\n"

	htmlBuffer += ".myAnchorBold {\n"
	htmlBuffer += "text-decoration: none;\n"
	htmlBuffer += "font: bold 11px Arial, sans-serif, bold;\n"
	htmlBuffer += "color: #000000;\n"
	htmlBuffer += "}\n"

	htmlBuffer += "</style>\n"
	htmlBuffer += "</head>\n"
	htmlBuffer += "<body>\n"
}

/*************************************
	emitFooter
*************************************/
void emitFooter(Buffer htmlBuffer)
{
	htmlBuffer += "</body>\n"
	htmlBuffer += "</html>\n"
	htmlBuffer += "\n"
}

/*************************************
	emitTableObject
*************************************/
void emitTableObject(Object oTable, int scope, Buffer htmlBuffer)
{
	Buffer tempBuf = create
	string s = ""
	Object oRow = null
	Object oCell = null
	bool 	tableCellsAreVisible = false
	bool tableCellsAreSelected = false

	if (isVisible(oTable))
	{
		if (scope == SELECTION)
		{
			if (!isSelected(oTable))
			{
				return
			}
		}

		htmlBuffer += "<tr><td class=\"myCell\"/><td class=\"myCell\"/><a class=\"myText\">>> Table</a></td></tr>\n"
		return
	}

	for oRow in oTable do
	{
		for oCell in oRow do
		{
			if (isVisible(oCell))
			{
				tableCellsAreVisible = true

				if (isSelected(oCell))
				{
					tableCellsAreSelected = true
				}
			}
		}
	}

	if (!tableCellsAreVisible) return

	if (scope == SELECTION && !tableCellsAreSelected)
	{
		return
	}

	htmlBuffer += "<tr>\n"

	htmlBuffer += "<td class=\"myCell\"/>\n"

	htmlBuffer += "<td class=\"myCell\">\n"

	htmlBuffer += "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n"

	for oRow in oTable do
	{
		htmlBuffer += "<tr>\n"

		for oCell in oRow do
		{
			if (!isVisible(oCell))
			{
				continue
			}

			htmlBuffer += "<td class=\"myCell\">\n"
			htmlBuffer += "<a class=\"myText\"> "
			convertRichText(tempBuf, richText(oCell."Object Text"), i, null)
			htmlBuffer += tempBuf
			htmlBuffer += "</a>\n"
			htmlBuffer += "</td>\n"
		}

		htmlBuffer += "</tr>\n"
	}

	htmlBuffer += "</table>"

	htmlBuffer += "</td>\n"

	htmlBuffer += "</tr>\n"

	delete(tempBuf)
	tempBuf = null
}

/*************************************
	emitView
*************************************/
string emitView(Module m, int scope, Buffer htmlBuffer)
{
	string res          = ""
	Object o            = null
	Object currObj      = null
	Column c            = null
	real   w            = 0.0
	real   myWidth = 0.0
	Buffer tempBuf = create
	int i = 0

	emitHeader(htmlBuffer)

	currObj = current Object

	htmlBuffer += "<table class=\"myTable\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n"

	// header row
	htmlBuffer += "<tr>\n"
	htmlBuffer += "<td class=\"myCell\">\n"

	htmlBuffer += "<b>Exported from DOORS:</b> " stringOf(dateOf intOf today) "<br>"

	htmlBuffer += "<b>Module:</b> " fullName(m) " [version " version(m) "]<br>"

	if (scope == VIEW)
	{
		htmlBuffer += "<b>View:</b> " currentView(m) "<br>"
	}
	else if (scope == SELECTION)
	{
		htmlBuffer += "<b>View:</b> " currentView(m) " <b>(Selected Objects Only)</b><br>"
	}
	else if (scope == OBJECT)
	{
		htmlBuffer += "<b>View:</b> " currentView(m) " <b>(Single Object Only)</b><br>"
	}

	htmlBuffer += "</td>\n"
	htmlBuffer += "</tr>\n"
	htmlBuffer += "</table>\n"

	htmlBuffer += "<table class=\"myTable\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n"

	for c in m do
	{
		w += realOf(width(c))
	}

	// table header
	htmlBuffer += "<tr>\n"
	for c in m do
	{
		myWidth = (realOf(width(c)) / w) * 100.0
		htmlBuffer += "<th width=\"" (int intOf(myWidth)) "%\" class=\"myCell\"><b>" title(c) "</b></th>\n"
	}
	htmlBuffer += "</tr>\n"

	// standard DOORS module - just export all objects in order.
	for o in document m do
	{
		//print identifier(o) "\n"

		if (table(o))
		{
			emitTableObject(o, scope, htmlBuffer)
		}
		else
		{
			if (!isVisible(o))
			{
				continue
			}

			if (scope == SELECTION)
			{
				if (!(isSelected(o) || o == currObj))
				{
					continue
				}
			}

			// new row in the table for each object in the current entity
			htmlBuffer += "<tr>\n"

			for c in m do
			{
				if (main(c))
				{
					if (o."Object Heading" "" != "")
					{
						htmlBuffer += "<td class=\"myCell\"><b>" number(o) " "
						convertRichText(tempBuf, o."Object Heading" "", i, null)
						htmlBuffer += tempBuf
						htmlBuffer += "</b></td>\n"
					}
					else if (o."Object Text" "" != "")
					{
						htmlBuffer += "<td class=\"myCell\">"
						convertRichText(tempBuf, richText(o."Object Text"), i, null)
						htmlBuffer += tempBuf
						htmlBuffer += "</td>\n"
					}
					else
					{
						htmlBuffer += "<td class=\"myCell\"><br></td>\n"
					}
				}
				else
				{
					if (text(c, o) == "")
					{
						htmlBuffer += "<td class=\"myCell\"><br></td>\n"
					}
					else
					{
						htmlBuffer += "<td class=\"myCell\">"
						convertRichText(tempBuf, richText(c, o), i, null)
						htmlBuffer += tempBuf
						htmlBuffer += " </td>\n"
					}
				}
			}

			// end of row for the current object
			htmlBuffer += "</tr>\n"
		}
	}

	htmlBuffer += "</table>\n"

	emitFooter(htmlBuffer)

	return(res)
}

/*************************************
	emailRequirements (no dialog)
*************************************/
void emailRequirements(Module m, int scope)
{
	string res = ""

	if (null m)
	{
		return
	}

	if (scope == SELECTION)
	{
		if (null current Object)
		{
			return
		}
	}

	Buffer htmlBuffer = create

	res = emitView(m, scope, htmlBuffer)

	if (res != "")
	{
		warningBox("ERROR: " res "")
		return
	}

	makeEmail(fullName(m), htmlBuffer)

	delete(htmlBuffer)
}

//emailRequirements(current Module, SELECTION)
//emailRequirements(current Module, OBJECT)
//emailRequirements(current Module, VIEW)