Monday, November 08, 2010 at 12:05 AM.

on openBuddies (flopenwindow = true, flbringtofront = false) {
		<<3/13/02; 8:35:01 AM by DW
	local (adrdata = radio.outliner.init ()); //set up
	local (flnewoutline = adrdata^.stats.flNewBuddyOutline);
	local (adroutline = @adrdata^.buddies);
	local (existingBuddies = {});
	bundle { //fill existingBuddies
		local (outlinecopy = adroutline^, oldtarget = target.set (@outlinecopy), atts);
		op.firstsummit ();
		loop {
			op.attributes.getAll (@atts);
			if defined (atts.type) {
				if atts.type == {
					existingBuddies = existingBuddies + {atts.url}}};
			if not op.go (down, 1) {
		target.set (oldtarget)};
	local (newBuddies = {});
	bundle { //fill newBuddies
		local (adrsub);
		for adrsub in @adrdata^.subscriptions {
			if not (existingBuddies contains nameof (adrsub^)) {
				newBuddies = newBuddies + {nameof (adrsub^)}}}};
	bundle { //add new buddies to the outline
		local (oldtarget = target.set (adroutline));
		local (oldcursor = op.getCursor ());
		local (olddisplay = op.getDisplay ());
		op.setDisplay (false);
		op.go (left, infinity); op.go (down, infinity);
		local (flsetlinetext);
		bundle { //set flsetlinetext
			local (atts);
			new (tabletype, @atts);
			op.attributes.getAll (@atts);
			flsetlinetext = sizeof (atts) == 0};
		local (adrsub, url, atts);
		new (tabletype, @atts);
		for url in newBuddies {
			adrsub = @adrdata^.subscriptions.[url];
			if flsetlinetext {
				op.setlinetext (adrsub^.author);
				flsetlinetext = false}
			else {
				op.insert (adrsub^.author, down)};
			atts.type =;
			atts.url = url;
			atts.bold = false;
			op.attributes.addgroup (@atts)};
		op.setCursor (oldcursor);
		op.setDisplay (olddisplay);
		target.set (oldtarget)};
	if flopenwindow {
		if (not window.isopen (adroutline)) or flbringtofront {
			edit (adroutline, windowTitle:"Buddies", flReadOnly:true, adrButtonTable:@radio.outliner.buttons.buddyWindow)}};
	<<bundle //orig code
		<<local (adroutline = @adrworkgroup^.outline, flnewoutline = false)
		<<if not defined (adroutline^)
			<<new (outlinetype, adroutline)
			<<flnewoutline = true
		<<local (existingBuddies = {})
		<<bundle //fill existingBuddies
			<<local (outlinecopy = adroutline^, oldtarget = target.set (@outlinecopy), atts)
			<<op.firstsummit ()
				<<op.attributes.getAll (@atts)
				<<if defined (atts.type)
					<<if atts.type == "instantOutlinerMember"
						<<existingBuddies = existingBuddies + {atts.usernum}
				<<if not op.go (down, 1)
			<<target.set (oldtarget)
		<<local (newUsers = {})
		<<bundle //fill newUsers
			<<for adruser in @adrworkgroup^.users
				<<if not (existingBuddies contains nameof (adruser^))
					<<newUsers = newUsers + {nameof (adruser^)}
		<<bundle //add new users to the outline
			<<local (oldtarget = target.set (adroutline))
			<<local (oldcursor = op.getCursor ())
			<<local (olddisplay = op.getDisplay ())
			<<op.setDisplay (false)
			<<op.go (left, infinity); op.go (down, infinity)
			<<local (flsetlinetext)
			<<bundle //set flsetlinetext
				<<local (atts)
				<<new (tabletype, @atts)
				<<op.attributes.getAll (@atts)
				<<flsetlinetext = sizeof (atts) == 0
			<<local (adruser, atts)
			<<new (tabletype, @atts)
			<<for usernum in newUsers
				<<adruser = @adrworkgroup^.users.[usernum]
				<<if flsetlinetext
					<<op.setlinetext (adruser^.name)
					<<flsetlinetext = false
					<<op.insert (adruser^.name, down)
				<<atts.type = "instantOutlinerMember"
				<<atts.usernum = number (nameof (adruser^))
				<<atts.workgroupname = nameof (adrworkgroup^)
				<<atts.bold = false
				<<op.attributes.addgroup (@atts)
			<<if flnewoutline
				<<op.firstsummit (); op.deleteline ()
				<<op.setCursor (oldcursor)
			<<op.setDisplay (olddisplay)
			<<target.set (oldtarget)
		<<if flopenwindow
			<<edit (adroutline, windowTitle:nameof (adrworkgroup^), flReadOnly:true, adrButtonTable:@instantOutlinerSuite.buttons.workgroupWindow)
		<<return (adroutline)
bundle { //test code
	openBuddies ()}

This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.