Example #1
0
void
Model::AddToHistory(const char* text)
{
	BList items;
	_LoadHistory(items);

	BString* string = new (nothrow) BString(text);
	if (string == NULL || !items.AddItem(string)) {
		delete string;
		_FreeHistory(items);
		return;
	}

	int32 count = items.CountItems() - 1;
		// don't check last item, since that's the one we just added
	for (int32 t = 0; t < count; ++t) {
		// If the same text is already in the list,
		// then remove it first. Case-sensitive.
		BString* string = static_cast<BString*>(items.ItemAt(t));
		if (*string == text) {
			delete static_cast<BString*>(items.RemoveItem(t));
			break;
		}
	}

	while (items.CountItems() >= HISTORY_LIMIT)
		delete static_cast<BString*>(items.RemoveItem((int32)0));

	_SaveHistory(items);
	_FreeHistory(items);
}
static void
listener_output(syslog_message &message)
{
	// compose the message to be sent to all listeners; just convert
	// the syslog_message into a BMessage
	BMessage output(SYSLOG_MESSAGE);

	output.AddInt32("from", message.from);
	output.AddInt32("when", message.when);
	output.AddString("ident", message.ident);
	output.AddString("message", message.message);
	output.AddInt32("options", message.options);
	output.AddInt32("priority", message.priority);

	sLocker.Lock();

	for (int32 i = sListeners.CountItems(); i-- > 0;) {
		BMessenger *target = (BMessenger *)sListeners.ItemAt(i);

		status_t status = target->SendMessage(&output);
		if (status < B_OK) {
			// remove targets once they can't be reached anymore
			sListeners.RemoveItem(target);
		}
	}

	sLocker.Unlock();
}
Example #3
0
void
TestWindow::AddTest(Test* test)
{
	if (test == NULL || fTests.HasItem(test))
		return;

	if (!fTests.AddItem(test)) {
		delete test;
		return;
	}

	BMessage* message = new BMessage(MSG_SELECT_TEST);
	message->AddInt32("index", fTests.CountItems() - 1);

	BMenuItem* item = new BMenuItem(test->Name(), message);
	if (!fTestSelectionField->Menu()->AddItem(item)) {
		fTests.RemoveItem(fTests.CountItems() - 1);
		delete test;
		delete item;
		return;
	}

	if (fTests.CountItems() == 1)
		SetToTest(0);
}
Example #4
0
void Accounts::Delete()
{
	for (int32 i = gAccounts.CountItems();i-- > 0;)
	{
		Account *account = (Account *)gAccounts.RemoveItem(i);
		delete account;
	}
}
void 
remove_listener(BMessenger *messenger)
{
	if (sLocker.Lock()) {
		sListeners.RemoveItem(messenger);

		sLocker.Unlock();
	}
}
Example #6
0
bool gui_empty_clipboard(void)
{
	current_selection.Truncate(0);
	while (current_selection_textruns.ItemAt(0)) {
		text_run *run = (text_run *)current_selection_textruns.RemoveItem(0L);
		delete run;
	}
	return true;
}
void RemoveAttribute::DoRemoveAttribute(PDocument *doc, BMessage *node, BMessage *valueContainer,BMessage *undoMessage)
{
	node->PrintToStream();
	valueContainer->PrintToStream();
	undoMessage->PrintToStream();
	status_t	err				= B_OK;
	int32 		i				= 0;
	int32		j				= 0;
	BList		*subGroupList	= new BList();
	BMessage	*subGroup		= NULL;
	BMessage	*tmpSubGroup	= new BMessage();
	BList		*changed		= doc->GetChangedNodes();
	//do 
	char		*name			= NULL;
	char		*tmpName		= NULL;
	char		*subGroupName	= NULL;
	type_code	type			= B_ANY_TYPE;
	void*		oldValue		= NULL;
	int32		index			= 0;
	int32		count			= 0;
	ssize_t 	size			= 0;
	err = valueContainer->FindString("name",(const char**)&name);
	err = err | valueContainer->FindInt32("index",(int32 *)&index);
	subGroup = node;
	subGroupList->AddItem(subGroup);
	while (valueContainer->FindString("subgroup",i,(const char**)&subGroupName) == B_OK)
	{	
		subGroup->FindMessage(subGroupName,tmpSubGroup);
		subGroupList->AddItem(tmpSubGroup);
		subGroup	= tmpSubGroup;
		tmpSubGroup	= new BMessage();
		i++;
	}
	delete tmpSubGroup;
#ifdef B_ZETA_VERSION_1_0_0
	while ((subGroup->GetInfo(B_ANY_TYPE, j, (const char **)&tmpName, &type, &count) == B_OK) && ((count-1) != index))
#else
	while((subGroup->GetInfo(B_ANY_TYPE, j, (char**)&tmpName, &type, &count) == B_OK) && ((count-1) != index))
#endif
		j++;
	subGroup->FindData(name,type,count-1,(const void **)&oldValue,&size);

	undoMessage->AddData("deletedAttribut",type,oldValue,size);
	undoMessage->AddString("deletedName",name);
	undoMessage->AddInt32("deletedType",type);
	subGroup->RemoveData(name,index);
	for (i=subGroupList->CountItems()-1;i>0;i--)
	{
		tmpSubGroup = (BMessage *)subGroupList->ItemAt(i-1);
		valueContainer->FindString("subgroup",i-1,(const char**)&subGroupName);
		if (tmpSubGroup)
			tmpSubGroup->ReplaceMessage(subGroupName,(BMessage *)subGroupList->ItemAt(i));
		delete subGroupList->RemoveItem(i);
	}
	changed->AddItem(node);
	
}
Example #8
0
// Function taken from Haiku ShowImage,
// function originally written by Michael Pfeiffer
bool
SlideShowSaver::FindNextImage(entry_ref *in_current, entry_ref *out_image, bool next, bool rewind)
{
//	ASSERT(next || !rewind);
	BEntry curImage(in_current);
	entry_ref entry, *ref;
	BDirectory parent;
	BList entries;
	bool found = false;
	int32 cur;

	if (curImage.GetParent(&parent) != B_OK)
		return false;

	while (parent.GetNextRef(&entry) == B_OK) {
		if (entry != *in_current) {
			entries.AddItem(new entry_ref(entry));
		} else {
			// insert current ref, so we can find it easily after sorting
			entries.AddItem(in_current);
		}
	}

	entries.SortItems(CompareEntries);

	cur = entries.IndexOf(in_current);
//	ASSERT(cur >= 0);

	// remove it so FreeEntries() does not delete it
	entries.RemoveItem(in_current);

	if (next) {
		// find the next image in the list
		if (rewind) cur = 0; // start with first
		for (; (ref = (entry_ref*)entries.ItemAt(cur)) != NULL; cur ++) {
			if (IsImage(ref)) {
				found = true;
				*out_image = (const entry_ref)*ref;
				break;
			}
		}
	} else {
		// find the previous image in the list
		cur --;
		for (; cur >= 0; cur --) {
			ref = (entry_ref*)entries.ItemAt(cur);
			if (IsImage(ref)) {
				found = true;
				*out_image = (const entry_ref)*ref;
				break;
			}
		}
	}

	FreeEntries(&entries);
	return found;
}
/*
	void GetAppList(const char *signature, BList *teamIDList) const
	@case 3			teamIDList is not NULL and not empty, signature is not
					NULL and app(s) with this signature is (are) running
	@results		Should append the team IDs of all running apps with the
					supplied signature to teamIDList.
*/
void GetAppListTester::GetAppListTestB3()
{
	const char *signature = "application/x-vnd.obos-app-run-testapp1";
	// create a list with some dummy entries
	BList list;
	list.AddItem((void*)-7);
	list.AddItem((void*)-42);
	// get a list of running applications for reference
	BRoster roster;
	BList list1(list);
	roster.GetAppList(signature, &list1);
	check_list(list1, list);
	// run some apps
	AppRunner runner1(true);
	AppRunner runner2(true);
	AppRunner runner3(true);
	CHK(runner1.Run("AppRunTestApp1") == B_OK);
	CHK(runner2.Run("AppRunTestApp2") == B_OK);
	CHK(runner3.Run("BMessengerTestApp1") == B_OK);
	BList expectedApps;
	expectedApps.AddItem((void*)runner1.Team());
	expectedApps.AddItem((void*)runner2.Team());
	// get a new app list and check it
	BList list2(list);
	roster.GetAppList(signature, &list2);
	check_list(list2, list, expectedApps);
	// quit app 1
	runner1.WaitFor(true);
	expectedApps.RemoveItem((void*)runner1.Team());
	BList list3(list);
	roster.GetAppList(signature, &list3);
	check_list(list3, list, expectedApps);
	// quit app 2
	runner2.WaitFor(true);
	expectedApps.RemoveItem((void*)runner2.Team());
	BList list4(list);
	roster.GetAppList(signature, &list4);
	check_list(list4, list, expectedApps);
	// quit app 3
	runner3.WaitFor(true);
	BList list5(list);
	roster.GetAppList(signature, &list5);
	check_list(list5, list, expectedApps);
}
Example #10
0
bool TCueSheetWindow::QuitRequested()
{
	bool retVal = true;
	bool quit       = false;

	// Ask user to save document
	if (fCueSheetView->IsDirty()) {
		long userVal = SaveAlert();

		// Check user response
		switch( userVal)
		{
		// User does not want to save
		case 0:
			fCueSheetView->SetDirty(false);
			retVal = true;
			break;

		// User decided not to quit
		case 1:
			retVal = false;
			break;

		// User wants to save
		case 2:
			retVal = false;
			break;

		default:
			retVal = true;

		}
	}

	// Remove ourself from applications Cue Sheet list if window is closing
	if (retVal) {
		BList* theList = static_cast<MuseumApp*>(be_app)->GetCueSheetList();
		if (theList) {
			theList->RemoveItem(this);

			// If this is the last cue sheet open, tell application to quit
			if (theList->CountItems() == 0) {
				quit = true;
				be_app->PostMessage(B_QUIT_REQUESTED);
			}
		}
	}

	// Now tell app to fix Windows menu to reflect new state
	if (quit == false)
		be_app->PostMessage(FIX_WINDOWS_MENU_MSG);

	// Return user response to application
	return retVal;
}
Example #11
0
File: pmd.cpp Project: histat/dc-nx
// mix audio from any running notes into the output buffer,
// and start any new notes as we run across their sample-positions
static void generate_music(uint8_t *outbuffer, int len)
{
	// account for stereo
	len *= 2;
	
	int outpos = 0;
	while(outpos < len)
	{
		// start any notes that are supposed to begin on this sample
		if (--song.samples_left_in_beat <= 0)
		{
			for(int t=0;t<TOTAL_TRACKS;t++)
				start_notes(&song.track[t], song.beat);
			
			song.beat++;
			song.samples_left_in_beat = song.samples_per_beat;
			
			if (song.beat >= song.loop_end)
				song.beat = song.loop_start;
		}
		
		// mix
		int mix_left = 0;
		int mix_right = 0;
		for(int chan=0;;chan++)
		{
			stRunningNote *snd = (stRunningNote *)running_notes.ItemAt(chan);
			if (!snd) break;
			
			mix_left  += snd->samples[snd->curpos++];
			mix_right += snd->samples[snd->curpos++];
			
			if (snd->curpos >= snd->nsamples*2)
			{
				free_running_note(snd);
				running_notes.RemoveItem(chan);
				chan--;
			}
		}
		
		mix_left /= 3;
		mix_right /= 3;
		
		mix_left = (mix_left / 256) + 128;
		mix_right = (mix_right / 256) + 128;
		
		if (mix_left  < 0) mix_left = 0;
		if (mix_right < 0) mix_right = 0;
		if (mix_left  > 255) mix_left = 255;
		if (mix_right > 255) mix_right = 255;
		
		outbuffer[outpos++] = mix_left;
		outbuffer[outpos++] = mix_right;
	}
}
Example #12
0
void
BOutlineListView::_CullInvisibleItems(BList& list)
{
	int32 index = 0;
	while (index < list.CountItems()) {
		if (reinterpret_cast<BListItem*>(list.ItemAt(index))->IsItemVisible())
			++index;
		else
			list.RemoveItem(index);
	}
}
Example #13
0
void PeepsWindow::DeletePerson(PersonData *data)
{
	if(!data)
		return;
	
	PeepsListItem *previtem=NULL, *nextitem=NULL;
	
	for(int32 i=0; i<data->CountGroups();i++)
	{
		PersonItem *pitem=data->InstanceAt(i);
		GroupItem *gitem=(GroupItem*)fPeopleList->Superitem(pitem);

		if(pitem->IsSelected())
		{
			int32 index=fPeopleList->IndexOf(pitem);
			if(index>1)
			{
				previtem=(PeepsListItem*)fPeopleList->ItemAt(index-1);
//				nextitem=(PeepsListItem*)fPeopleList->ItemAt(index+1);
			}
			else
			{
				// First person in the entire list. Check to see if this is the only item in
				// the group. If it is, then select the next item in the list, if it exists.
				if(fPeopleList->CountItemsUnder(gitem,true)==1)
					nextitem=(PeepsListItem*)fPeopleList->ItemAt(index+1);
				else
					previtem=(PeepsListItem*)fPeopleList->ItemAt(index-1);
			}
		}
		fPeopleList->RemoveItem(pitem);
		data->DestroyInstance(pitem);
		if(fPeopleList->CountItemsUnder(gitem,true)==0)
		{
			fPeopleList->RemoveItem(gitem);
			gGroupData.RemoveGroup(gitem->Name());
		}
	}
	entry_ref personref=data->FileRef();
	BEntry entry(&personref);
	if(previtem)
		fPeopleList->Select(fPeopleList->IndexOf(previtem));
	else
	if(nextitem)
		fPeopleList->Select(fPeopleList->IndexOf(nextitem));
	else
		fPeopleList->Select(0L);
#ifndef DATA_READ_ONLY
	TrashFile(&entry);
#endif

	gPeopleData.RemoveItem(data);
	delete data;
}
void RemoveAttribute::AddAttribute(PDocument *doc, BMessage *node, BMessage *valueContainer,BMessage *undoMessage)
{
	node->PrintToStream();
	valueContainer->PrintToStream();
	undoMessage->PrintToStream();
	int32 		i				= 0;
	status_t	err				= B_OK;
	BList		*subGroupList	= new BList();
	BMessage	*subGroup		= NULL;
	BMessage	*tmpSubGroup	= new BMessage();
	BList		*changed		= doc->GetChangedNodes();
	//do 
	char		*name			= NULL;
	char		*subGroupName	= NULL;
	type_code	type			= B_ANY_TYPE;
	ssize_t		size			= 0;
	
	//undo
	char		*compareName	= NULL;
	void*		newValue		= NULL;
	int32		lastIndex		= -1;
	int32		count			= 0;
	int32		index			= 0;
	type_code	typeFound		= B_ANY_TYPE;

	err = undoMessage->FindString("deletedName",(const char**)&name);
	err = err | undoMessage->FindInt32("deletedType",(int32 *)&type);
	err = undoMessage->FindData("deletedAttribut", type,(const void **)&newValue, &size);
	
	subGroup = node;
	subGroupList->AddItem(subGroup);
	while (valueContainer->FindString("subgroup",i,(const char**)&subGroupName) == B_OK)
	{	
		subGroup->FindMessage(subGroupName,tmpSubGroup);
		subGroupList->AddItem(tmpSubGroup);
		subGroup	= tmpSubGroup;
		tmpSubGroup	= new BMessage();
		i++;
	}
	delete tmpSubGroup;
	subGroup->AddData(name,type,newValue,size);
	for (i=subGroupList->CountItems()-1;i>0;i--)
	{
		tmpSubGroup = (BMessage *)subGroupList->ItemAt(i-1);
		valueContainer->FindString("subgroup",i-1,(const char**)&subGroupName);
		if (tmpSubGroup)
			tmpSubGroup->ReplaceMessage(subGroupName,(BMessage *)subGroupList->ItemAt(i));
		delete subGroupList->RemoveItem(i);
	}
	changed->AddItem(node);
}
Example #15
0
void
AboutView::PickRandomHaiku()
{
	BPath path;
	if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) != B_OK)
		path = "/system/data";
	path.Append("fortunes");
	path.Append("Haiku");

	BFile fortunes(path.Path(), B_READ_ONLY);
	struct stat st;
	if (fortunes.InitCheck() < B_OK)
		return;
	if (fortunes.GetStat(&st) < B_OK)
		return;

	char* buff = (char*)malloc((size_t)st.st_size + 1);
	if (!buff)
		return;
	buff[(size_t)st.st_size] = '\0';
	BList haikuList;
	if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) {
		char* p = buff;
		while (p && *p) {
			char* e = strchr(p, '%');
			BString* s = new BString(p, e ? (e - p) : -1);
			haikuList.AddItem(s);
			p = e;
			if (p && (*p == '%'))
				p++;
			if (p && (*p == '\n'))
				p++;
		}
	}
	free(buff);
	if (haikuList.CountItems() < 1)
		return;

	BString* s = (BString*)haikuList.ItemAt(rand() % haikuList.CountItems());
	BFont font(be_bold_font);
	font.SetSize(be_bold_font->Size());
	font.SetFace(B_BOLD_FACE | B_ITALIC_FACE);
	fCreditsView->SelectAll();
	fCreditsView->Delete();
	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kDarkGrey);
	fCreditsView->Insert(s->String());
	fCreditsView->Insert("\n");
	while ((s = (BString*)haikuList.RemoveItem((int32)0))) {
		delete s;
	}
}
Example #16
0
void
AboutView::PickRandomHaiku()
{
	BFile fortunes(
#ifdef __HAIKU__
		"/etc/fortunes/Haiku",
#else
		"data/etc/fortunes/Haiku",
#endif
		B_READ_ONLY);
	struct stat st;
	if (fortunes.InitCheck() < B_OK)
		return;
	if (fortunes.GetStat(&st) < B_OK)
		return;
	char* buff = (char*)malloc((size_t)st.st_size + 1);
	if (!buff)
		return;
	buff[(size_t)st.st_size] = '\0';
	BList haikuList;
	if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) {
		char* p = buff;
		while (p && *p) {
			char* e = strchr(p, '%');
			BString* s = new BString(p, e ? (e - p) : -1);
			haikuList.AddItem(s);
			p = e;
			if (p && (*p == '%'))
				p++;
			if (p && (*p == '\n'))
				p++;
		}
	}
	free(buff);
	if (haikuList.CountItems() < 1)
		return;
	BString* s = (BString*)haikuList.ItemAt(rand() % haikuList.CountItems());
	BFont font(be_bold_font);
	font.SetSize(be_bold_font->Size());
	font.SetFace(B_BOLD_FACE | B_ITALIC_FACE);
	fCreditsView->SelectAll();
	fCreditsView->Delete();
	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kDarkGrey);
	fCreditsView->Insert(s->String());
	fCreditsView->Insert("\n");
	while ((s = (BString*)haikuList.RemoveItem((int32)0))) {
		delete s;
	}
}
Example #17
0
void gui_start_selection(struct gui_window *g)
{
	current_selection.Truncate(0);
	while (current_selection_textruns.ItemAt(0)) {
		text_run *run = (text_run *)current_selection_textruns.RemoveItem(0L);
		delete run;
	}

	if (!g->view->LockLooper())
		return;

	g->view->MakeFocus();

	g->view->UnlockLooper();
}
Example #18
0
//! newExtensionsList contains all the entries (char*) which are to be added.
status_t
merge_extensions(BMimeType& type, const BList& newExtensionsList,
	const char* removeExtension)
{
	BMessage extensions;
	status_t status = type.GetFileExtensions(&extensions);
	if (status < B_OK)
		return status;

	// replace the entry, and remove any equivalent entries
	BList mergedList;
	mergedList.AddList(&newExtensionsList);
	int32 originalCount = mergedList.CountItems();

	const char* extension;
	for (int32 i = 0; extensions.FindString("extensions", i,
			&extension) == B_OK; i++) {

		for (int32 j = originalCount; j-- > 0;) {
			if (!strcmp((const char*)mergedList.ItemAt(j), extension)) {
				// Do not add this old item again, since it's already
				// there.
				mergedList.RemoveItem(j);
				originalCount--;
			}
		}

		// The item will be added behind "originalCount", so we cannot
		// remove it accidentally in the next iterations, it's is added
		// for good.
		if (removeExtension == NULL || strcmp(removeExtension, extension))
			mergedList.AddItem((void *)extension);
	}

	mergedList.SortItems(compare_extensions);

	// Copy them to a new message (their memory is still part of the
	// original BMessage)
	BMessage newExtensions;
	for (int32 i = 0; i < mergedList.CountItems(); i++) {
		newExtensions.AddString("extensions",
			(const char*)mergedList.ItemAt(i));
	}

	return type.SetFileExtensions(&newExtensions);
}
Example #19
0
// ObjectChanged
void
DragSortableListView::ObjectChanged(const Observable* object)
{
	if (object != fSelection || fModifyingSelection || fSyncingToSelection)
		return;

//printf("%s - syncing start\n", Name());
	fSyncingToSelection = true;

	// try to sync to Selection
	BList selectedItems;

	int32 count = fSelection->CountSelected();
	for (int32 i = 0; i < count; i++) {
		int32 index = IndexOfSelectable(fSelection->SelectableAtFast(i));
		if (index >= 0) {
			BListItem* item = ItemAt(index);
			if (item && !selectedItems.HasItem((void*)item))
				selectedItems.AddItem((void*)item);
		}
	}

	count = selectedItems.CountItems();
	if (count == 0) {
		if (CurrentSelection(0) >= 0)
			DeselectAll();
	} else {
		count = CountItems();
		for (int32 i = 0; i < count; i++) {
			BListItem* item = ItemAt(i);
			bool selected = selectedItems.RemoveItem((void*)item);
			if (item->IsSelected() != selected) {
				Select(i, true);
			}
		}
	}

	fSyncingToSelection = false;
//printf("%s - done\n", Name());
}
Example #20
0
/***********************************************************
 * InitGUI
 ***********************************************************/
void
HAddressView::InitGUI()
{
	float divider = StringWidth(_("Subject:")) + 20;
	divider = max_c(divider , StringWidth(_("From:"))+20);
	divider = max_c(divider , StringWidth(_("To:"))+20);
	divider = max_c(divider , StringWidth(_("Bcc:"))+20);
	
	BRect rect = Bounds();
	rect.top += 5;
	rect.left += 20 + divider;
	rect.right = Bounds().right - 5;
	rect.bottom = rect.top + 25;
	
	BTextControl *ctrl;
	ResourceUtils rutils;
	const char* name[] = {"to","subject","from","cc","bcc"};
	
	for(int32 i = 0;i < 5;i++)
	{
		ctrl = new BTextControl(BRect(rect.left,rect.top
								,(i == 1)?rect.right+divider:rect.right
								,rect.bottom)
								,name[i],"","",NULL
								,B_FOLLOW_LEFT_RIGHT|B_FOLLOW_TOP,B_WILL_DRAW|B_NAVIGABLE);
		
		if(i == 1)
		{
			ctrl->SetLabel(_("Subject:"));
			ctrl->SetDivider(divider);
			ctrl->MoveBy(-divider,0);
		}else{
			ctrl->SetDivider(0);
		}
		BMessage *msg = new BMessage(M_MODIFIED);
		msg->AddPointer("pointer",ctrl);
		ctrl->SetModificationMessage(msg);
		ctrl->SetEnabled(!fReadOnly);
		AddChild(ctrl);
	
		rect.OffsetBy(0,25);
		switch(i)
		{
		case 0:
			fTo = ctrl;
			break;
		case 1:
			fSubject = ctrl;
			break;
		case 2:
			fFrom = ctrl;
			fFrom->SetEnabled(false);
			fFrom->SetFlags(fFrom->Flags() & ~B_NAVIGABLE);
			break;
		case 3:
			fCc = ctrl;
			break;
		case 4:
			fBcc = ctrl;
			break;
		}
	}
	//
	BRect menuRect= Bounds();
	menuRect.top += 5;
	menuRect.left += 22;
	menuRect.bottom = menuRect.top + 25;
	menuRect.right = menuRect.left + 16;
	
	BMenu *toMenu = new BMenu(_("To:"));
	BMenu *ccMenu = new BMenu(_("Cc:"));
	BMenu *bccMenu = new BMenu(_("Bcc:"));
	BQuery query;
	BVolume volume;
	BVolumeRoster().GetBootVolume(&volume);
	query.SetVolume(&volume);
	query.SetPredicate("((META:email=*)&&(BEOS:TYPE=application/x-person))");

	if(!fReadOnly && query.Fetch() == B_OK)
	{
		BString addr[4],name,group,nick;
		entry_ref ref;
		BList peopleList;
	
	
		while(query.GetNextRef(&ref) == B_OK)
		{
			BNode node(&ref);
			if(node.InitCheck() != B_OK)
				continue;
			
			ReadNodeAttrString(&node,"META:name",&name);		
			ReadNodeAttrString(&node,"META:email",&addr[0]);
			ReadNodeAttrString(&node,"META:email2",&addr[1]);
			ReadNodeAttrString(&node,"META:email3",&addr[2]);
			ReadNodeAttrString(&node,"META:email4",&addr[3]);
			ReadNodeAttrString(&node,"META:group",&group);
			ReadNodeAttrString(&node,"META:nickname",&nick);
			
			for(int32 i = 0;i < 4;i++)
			{
				if(addr[i].Length() > 0)
				{
					if(nick.Length() > 0)
					{
						nick += " <";
						nick += addr[i];
						nick += ">";
						fAddrList.AddItem(strdup(nick.String()));
					}
					fAddrList.AddItem(strdup(addr[i].String()));
					
					BString title = name;
					title << " <" << addr[i] << ">";
				
					AddPersonToList(peopleList,title.String(),group.String());
				}
			}
		}
		
		// Sort people data
		peopleList.SortItems(HAddressView::SortPeople);
		// Build menus
		BTextControl *control[3] = {fTo,fCc,fBcc};
		BMenu *menus[3] = {toMenu,ccMenu,bccMenu};
		int32 count = peopleList.CountItems();
		PersonData *data;
		bool needSeparator = false;
		bool hasSeparator = false;
		for(int32 k = 0;k < 3;k++)
		{
			for(int32 i = 0;i < count;i++)
			{
				BMessage *msg = new BMessage(M_ADDR_MSG);
				msg->AddPointer("pointer",control[k]);
				data =  (PersonData*)peopleList.ItemAt(i);
				msg->AddString("email",data->email);
				if(needSeparator && !hasSeparator && strlen(data->group) == 0)
				{
					menus[k]->AddSeparatorItem();
					hasSeparator = true;
				}else
					needSeparator = true;
				AddPerson(menus[k],data->email,data->group,msg,0,0);
			}
			hasSeparator = false;
			needSeparator = false;
		}
		// free all data
		while(count > 0)
		{
			data =  (PersonData*)peopleList.RemoveItem(--count);
			free(data->email);
			free(data->group);
			delete data;
		}
	}
	BMenuField *field = new BMenuField(menuRect,"ToMenu","",toMenu,
							B_FOLLOW_TOP|B_FOLLOW_LEFT,B_WILL_DRAW);
	field->SetDivider(0);
	field->SetEnabled(!fReadOnly);
	AddChild(field);
	
	rect = menuRect;
	rect.OffsetBy(0,28);
	rect.left = Bounds().left + 5;
	rect.right = rect.left + 16;
	rect.top += 26;
	rect.bottom = rect.top + 16;
	ArrowButton *arrow = new ArrowButton(rect,"addr_arrow"
										,new BMessage(M_EXPAND_ADDRESS));
	AddChild(arrow);
	//==================== From menu
	BMenu *fromMenu = new BMenu(_("From:"));
	BPath path;
	::find_directory(B_USER_SETTINGS_DIRECTORY,&path);
	path.Append(APP_NAME);
	path.Append("Accounts");
	BDirectory dir(path.Path());
	BEntry entry;
	status_t err = B_OK;
	int32 account_count = 0;
	while(err == B_OK)
	{
		if((err = dir.GetNextEntry(&entry)) == B_OK && !entry.IsDirectory())
		{
			char name[B_FILE_NAME_LENGTH+1];
			entry.GetName(name);
			BMessage *msg = new BMessage(M_ACCOUNT_CHANGE);
			msg->AddString("name",name);
			BMenuItem *item = new BMenuItem(name,msg);
			fromMenu->AddItem(item);
			item->SetTarget(this,Window());
			account_count++;
		}
	}
	if(account_count != 0)
	{
		int32 smtp_account;
		((HApp*)be_app)->Prefs()->GetData("smtp_account",&smtp_account);
		BMenuItem *item(NULL);
		if(account_count > smtp_account)
			item = fromMenu->ItemAt(smtp_account);
		if(!item)
			item = fromMenu->ItemAt(0);
		if(item)
		{
			ChangeAccount(item->Label());
			item->SetMarked(true);
		}
	}else{
		(new BAlert("",_("Could not find mail accounts"),_("OK"),NULL,NULL,B_WIDTH_AS_USUAL,B_INFO_ALERT))->Go();
		Window()->PostMessage(B_QUIT_REQUESTED);
	}
	fromMenu->SetRadioMode(true);
	
	menuRect.OffsetBy(0,25*2);
	field = new BMenuField(menuRect,"FromMenu","",fromMenu,
							B_FOLLOW_TOP|B_FOLLOW_LEFT,B_WILL_DRAW);
	field->SetDivider(0);
	
	AddChild(field);
	//=================== CC menu
	menuRect.OffsetBy(0,25);
	field = new BMenuField(menuRect,"CcMenu","",ccMenu,
							B_FOLLOW_TOP|B_FOLLOW_LEFT,B_WILL_DRAW);
	field->SetDivider(0);
	field->SetEnabled(!fReadOnly);
	AddChild(field);

	//=================== BCC menu	
	menuRect.OffsetBy(0,25);
	field = new BMenuField(menuRect,"BccMenu","",bccMenu,
							B_FOLLOW_TOP|B_FOLLOW_LEFT,B_WILL_DRAW);
	field->SetDivider(0);
	field->SetEnabled(!fReadOnly);
	AddChild(field);
	

}
Example #21
0
File: pmd.cpp Project: histat/dc-nx
static void dump_running_notes(void)
{
	while(running_notes.CountItems())
		free_running_note((stRunningNote *)running_notes.RemoveItem(0));
}
Example #22
0
// returns true if score is destined for greatness
bool Hall::JudgeScore(unsigned long gametime, unsigned long game, int tiles)
{
bool Yes = false;

BList *L;
	
	switch(tiles)
	{
	case 14 * 6: L = List1; break;
	case 18 * 8: L = List2; break;
	case 24 * 12: L = List3; break;
	case 28 * 16: L = List4; break;
	case 32 * 20: L = List5; break;
	default: L = NULL;
	}

	if (!L)
	{
		//printf("No game size!\n");
		return false;
	}

	HSList *h = new HSList();
		

	h->SetGameID(game);
	h->SetGameTime(gametime);
	h->SetNumberTiles(tiles);
	h->SetTimeOfGame(time(NULL));
			

	h->SetName(NULL);

	/* Add the new item
	 */
	L->AddItem(h); 

	L->SortItems(cmpFunc);


	/*
	 * Limit entries to 5
	 */
	if (L->CountItems() > 5)
	{
		HSList *hs;
		hs = (HSList *)L->RemoveItem(5);
		delete hs;
	}

	if (L->HasItem(h))
	{
	AskName *Ask = new AskName();
	char *name;

		name = Ask->Go();
		Ask->Lock();
		Ask->Quit();
		be_app->SetCursor(B_HAND_CURSOR);
		h->SetName(name);
		free(name);
		_changed = true;
		Yes = true;
	}

	return Yes;
}
Example #23
0
status_t
CDDBDaemon::_Lookup(const dev_t device)
{
	scsi_toc_toc* toc = (scsi_toc_toc*)malloc(kMaxTocSize);
	if (toc == NULL)
		return B_NO_MEMORY;

	uint32 cddbId;
	if (!_CanLookup(device, &cddbId, toc)) {
		free(toc);
		printf("Skipping device with id %ld.\n", device);
		return B_BAD_TYPE;
	}
		
	printf("Looking up CD with CDDB Id %08lx.\n", cddbId);

	CDDBServer cddb_server("freedb.freedb.org:80");

	status_t result;

	BList queryResponse;
	if ((result = cddb_server.Query(cddbId, toc, &queryResponse)) != B_OK) {
		printf("Error when querying CD.\n");
		free(toc);
		return result;
	}
			
	free(toc);

	QueryResponseData* diskData = _SelectResult(&queryResponse);
	if (diskData == NULL) {
		printf("Could not find any CD entries in query response.\n");
		return B_BAD_INDEX;
	}

	ReadResponseData readResponse;
	if ((result = cddb_server.Read(diskData, &readResponse)) != B_OK) {
		return result;
	}
	
	if (_WriteCDData(device, diskData, &readResponse) == B_OK) {
		printf("CD data saved.\n");
	} else {
		printf("Error writting CD data.\n" );
	}

	// Delete itens in the query response BList;
	int32 count = queryResponse.CountItems();
	for (int32 i = 0; i < count; ++i) {
		delete (QueryResponseData*)queryResponse.RemoveItem(0L);
	}
						
	queryResponse.MakeEmpty();

	// Delete itens in the track data BList in the read response data;
	count = readResponse.tracks.CountItems();
	for (int32 i = 0; i < count; ++i) {
		delete (TrackData*)readResponse.tracks.RemoveItem(0L);
	}
						
	readResponse.tracks.MakeEmpty();
							
	return B_OK;
}
void
PairsView::_ReadRandomIcons()
{
	// TODO: maybe read the icons only once at startup

	// clean out any previous icons
	for (int i = 0; i < fCardBitmaps.CountItems(); i++)
		delete ((BBitmap*)fCardBitmaps.ItemAt(i));

	fCardBitmaps.MakeEmpty();

	BDirectory appsDirectory;
	BDirectory prefsDirectory;

	BPath path;
	if (find_directory(B_BEOS_APPS_DIRECTORY, &path) == B_OK)
		appsDirectory.SetTo(path.Path());
	if (find_directory(B_BEOS_PREFERENCES_DIRECTORY, &path) == B_OK)
		prefsDirectory.SetTo(path.Path());

	// read vector icons from apps and prefs folder and put them
	// into a BList as BBitmaps
	BList bitmaps;

	BEntry entry;
	while (appsDirectory.GetNextEntry(&entry) == B_OK
		|| prefsDirectory.GetNextEntry(&entry) == B_OK) {

		BNode node(&entry);
		BNodeInfo nodeInfo(&node);

		if (nodeInfo.InitCheck() < B_OK)
			continue;

		uint8* data;
		size_t size;
		type_code type;

		if (nodeInfo.GetIcon(&data, &size, &type) < B_OK)
			continue;

		if (type != B_VECTOR_ICON_TYPE) {
			delete[] data;
			continue;
		}

		BBitmap* bitmap = new BBitmap(
			BRect(0, 0, kBitmapSize - 1, kBitmapSize - 1), 0, B_RGBA32);
		if (BIconUtils::GetVectorIcon(data, size, bitmap) < B_OK) {
			delete[] data;
			delete bitmap;
			continue;
		}

		delete[] data;

		if (_HasBitmap(bitmaps, bitmap) || !bitmaps.AddItem(bitmap))
			delete bitmap;
		else if (bitmaps.CountItems() >= 128) {
			// this is enough to choose from, stop eating memory...
			break;
		}
	}

	// pick random bitmaps from the ones we got in the list
	srand((unsigned)time(0));

	for (int i = 0; i < fNumOfCards / 2; i++) {
		int32 index = rand() % bitmaps.CountItems();
		BBitmap* bitmap = ((BBitmap*)bitmaps.RemoveItem(index));
		if (bitmap == NULL) {
			char buffer[512];
			snprintf(buffer, sizeof(buffer), B_TRANSLATE("Pairs did not find "
				"enough vector icons in the system; it needs at least %d."),
				fNumOfCards / 2);
			BString msgStr(buffer);
			msgStr << "\n";
			BAlert* alert = new BAlert("Fatal", msgStr.String(),
				B_TRANSLATE("OK"), 	NULL, NULL, B_WIDTH_FROM_WIDEST,
				B_STOP_ALERT);
			alert->SetShortcut(0, B_ESCAPE);
			alert->Go();
			exit(1);
		}
		fCardBitmaps.AddItem(bitmap);
	}

	// delete the remaining bitmaps from the list
	while (BBitmap* bitmap = (BBitmap*)bitmaps.RemoveItem(0L))
		delete bitmap;
}
Example #25
0
	void Pop() 
	{
		fNestedBoxes.RemoveItem((int32)fNestedBoxes.CountItems()-1);
	}
Example #26
0
_EXPORT ssize_t utf8_to_rfc2047 (char **bufp, ssize_t length, uint32 charset, char encoding) {
	struct word {
		BString	originalWord;
		BString	convertedWord;
		bool	needsEncoding;

		// Convert the word from UTF-8 to the desired character set.  The
		// converted version also includes the escape codes to return to ASCII
		// mode, if relevant.  Also note if it uses unprintable characters,
		// which means it will need that special encoding treatment later.
		void ConvertWordToCharset (uint32 charset) {
			int32 state = 0;
			int32 originalLength = originalWord.Length();
			int32 convertedLength = originalLength * 5 + 1;
			char *convertedBuffer = convertedWord.LockBuffer (convertedLength);
			mail_convert_from_utf8 (charset, originalWord.String(),
				&originalLength, convertedBuffer, &convertedLength, &state);
			for (int i = 0; i < convertedLength; i++) {
				if ((convertedBuffer[i] & (1 << 7)) ||
					(convertedBuffer[i] >= 0 && convertedBuffer[i] < 32)) {
					needsEncoding = true;
					break;
				}
			}
			convertedWord.UnlockBuffer (convertedLength);
		};
	};
	struct word *currentWord;
	BList words;

	// Break the header into words.  White space characters (including tabs and
	// newlines) separate the words.  Each word includes any space before it as
	// part of the word.  Actually, quotes and other special characters
	// (",()<>@) are treated as separate words of their own so that they don't
	// get encoded (because MIME headers get the quotes parsed before character
	// set unconversion is done).  The reader is supposed to ignore all white
	// space between encoded words, which can be inserted so that older mail
	// parsers don't have overly long line length problems.

	const char *source = *bufp;
	const char *bufEnd = *bufp + length;
	const char *specialChars = "\"()<>@,";

	while (source < bufEnd) {
		currentWord = new struct word;
		currentWord->needsEncoding = false;

		int wordEnd = 0;

		// Include leading spaces as part of the word.
		while (source + wordEnd < bufEnd && isspace (source[wordEnd]))
			wordEnd++;

		if (source + wordEnd < bufEnd &&
			strchr (specialChars, source[wordEnd]) != NULL) {
			// Got a quote mark or other special character, which is treated as
			// a word in itself since it shouldn't be encoded, which would hide
			// it from the mail system.
			wordEnd++;
		} else {
			// Find the end of the word.  Leave wordEnd pointing just after the
			// last character in the word.
			while (source + wordEnd < bufEnd) {
				if (isspace(source[wordEnd]) ||
					strchr (specialChars, source[wordEnd]) != NULL)
					break;
				if (wordEnd > 51 /* Makes Base64 ISO-2022-JP "word" a multiple of 4 bytes */ &&
					0xC0 == (0xC0 & (unsigned int) source[wordEnd])) {
					// No English words are that long (46 is the longest),
					// break up what is likely Asian text (which has no spaces)
					// at the start of the next non-ASCII UTF-8 character (high
					// two bits are both ones).  Note that two encoded words in
					// a row get joined together, even if there is a space
					// between them in the final output text, according to the
					// standard.  Next word will also be conveniently get
					// encoded due to the 0xC0 test.
					currentWord->needsEncoding = true;
					break;
				}
				wordEnd++;
			}
		}
		currentWord->originalWord.SetTo (source, wordEnd);
		currentWord->ConvertWordToCharset (charset);
		words.AddItem(currentWord);
		source += wordEnd;
	}

	// Combine adjacent words which contain unprintable text so that the
	// overhead of switching back and forth between regular text and specially
	// encoded text is reduced.  However, the combined word must be shorter
	// than the maximum of 75 bytes, including character set specification and
	// all those delimiters (worst case 22 bytes of overhead).

	struct word *run;

	for (int32 i = 0; (currentWord = (struct word *) words.ItemAt (i)) != NULL; i++) {
		if (!currentWord->needsEncoding)
			continue; // No need to combine unencoded words.
		for (int32 g = i+1; (run = (struct word *) words.ItemAt (g)) != NULL; g++) {
			if (!run->needsEncoding)
				break; // Don't want to combine encoded and unencoded words.
			if ((currentWord->convertedWord.Length() + run->convertedWord.Length() <= 53)) {
				currentWord->originalWord.Append (run->originalWord);
				currentWord->ConvertWordToCharset (charset);
				words.RemoveItem(g);
				delete run;
				g--;
			} else // Can't merge this word, result would be too long.
				break;
		}
	}

	// Combine the encoded and unencoded words into one line, doing the
	// quoted-printable or base64 encoding.  Insert an extra space between
	// words which are both encoded to make word wrapping easier, since there
	// is normally none, and you're allowed to insert space (the receiver
	// throws it away if it is between encoded words).

	BString rfc2047;
	bool	previousWordNeededEncoding = false;

	const char *charset_dec = "none-bug";
	for (int32 i = 0; mail_charsets[i].charset != NULL; i++) {
		if (mail_charsets[i].flavor == charset) {
			charset_dec = mail_charsets[i].charset;
			break;
		}
	}

	while ((currentWord = (struct word *)words.RemoveItem(0L)) != NULL) {
		if ((encoding != quoted_printable && encoding != base64) ||
		!currentWord->needsEncoding) {
			rfc2047.Append (currentWord->convertedWord);
		} else {
			// This word needs encoding.  Try to insert a space between it and
			// the previous word.
			if (previousWordNeededEncoding)
				rfc2047 << ' '; // Can insert as many spaces as you want between encoded words.
			else {
				// Previous word is not encoded, spaces are significant.  Try
				// to move a space from the start of this word to be outside of
				// the encoded text, so that there is a bit of space between
				// this word and the previous one to enhance word wrapping
				// chances later on.
				if (currentWord->originalWord.Length() > 1 &&
					isspace (currentWord->originalWord[0])) {
					rfc2047 << currentWord->originalWord[0];
					currentWord->originalWord.Remove (0 /* offset */, 1 /* length */);
					currentWord->ConvertWordToCharset (charset);
				}
			}

			char *encoded = NULL;
			ssize_t encoded_len = 0;
			int32 convertedLength = currentWord->convertedWord.Length ();
			const char *convertedBuffer = currentWord->convertedWord.String ();

			switch (encoding) {
				case quoted_printable:
					encoded = (char *) malloc (convertedLength * 3);
					encoded_len = encode_qp (encoded, convertedBuffer, convertedLength, true /* headerMode */);
					break;
				case base64:
					encoded = (char *) malloc (convertedLength * 2);
					encoded_len = encode_base64 (encoded, convertedBuffer, convertedLength, true /* headerMode */);
					break;
				default: // Unknown encoding type, shouldn't happen.
					encoded = (char *) convertedBuffer;
					encoded_len = convertedLength;
					break;
			}

			rfc2047 << "=?" << charset_dec << '?' << encoding << '?';
			rfc2047.Append (encoded, encoded_len);
			rfc2047 << "?=";

			if (encoding == quoted_printable || encoding == base64)
				free(encoded);
		}
		previousWordNeededEncoding = currentWord->needsEncoding;
		delete currentWord;
	}

	free(*bufp);

	ssize_t finalLength = rfc2047.Length ();
	*bufp = (char *) (malloc (finalLength + 1));
	memcpy (*bufp, rfc2047.String(), finalLength);
	(*bufp)[finalLength] = 0;

	return finalLength;
}
Example #27
0
BEmailMessage *
BEmailMessage::ReplyMessage(mail_reply_to_mode replyTo, bool accountFromMail,
	const char *quoteStyle)
{
	BEmailMessage *reply = new BEmailMessage;

	// Set ReplyTo:

	if (replyTo == B_MAIL_REPLY_TO_ALL) {
		reply->SetTo(From());

		BList list;
		get_address_list(list, CC(), extract_address);
		get_address_list(list, To(), extract_address);

		// Filter out the sender
		BMailAccounts accounts;
		BMailAccountSettings* account = accounts.AccountByID(Account());
		BString sender;
		if (account)
			sender = account->ReturnAddress();
		extract_address(sender);

		BString cc;

		for (int32 i = list.CountItems(); i-- > 0;) {
			char *address = (char *)list.RemoveItem((int32)0);

			// add everything which is not the sender and not already in the list
			if (sender.ICompare(address) && cc.FindFirst(address) < 0) {
				if (cc.Length() > 0)
					cc << ", ";

				cc << address;
			}

			free(address);
		}

		if (cc.Length() > 0)
			reply->SetCC(cc.String());
	} else if (replyTo == B_MAIL_REPLY_TO_SENDER || ReplyTo() == NULL)
		reply->SetTo(From());
	else
		reply->SetTo(ReplyTo());

	// Set special "In-Reply-To:" header (used for threading)
	const char *messageID = _body ? _body->HeaderField("Message-Id") : NULL;
	if (messageID != NULL)
		reply->SetHeaderField("In-Reply-To", messageID);

	// quote body text
	reply->SetBodyTextTo(BodyText());
	if (quoteStyle)
		reply->Body()->Quote(quoteStyle);

	// Set the subject (and add a "Re:" if needed)
	BString string = Subject();
	if (string.ICompare("re:", 3) != 0)
		string.Prepend("Re: ");
	reply->SetSubject(string.String());

	// set the matching outbound chain
	if (accountFromMail)
		reply->SendViaAccountFrom(this);

	return reply;
}
Example #28
0
// RemoveModule
bool
ModuleList::RemoveModule(Module *module)
{
	return (module && fModules.RemoveItem(module));
}
BMessage* Delete::Do(PDocument *doc, BMessage *settings)
{
/*	BMessage	*node				= new BMessage();
	BMessage	*commandMessage		= PCommand::Do(doc,settings);
	BList		*parentGroupList	= NULL;
	BMessage	*connection			= new BMessage();
	int32		i					= 0;
	while (settings->FindPointer("node",i,(void **)&node))
	{
		if (settings->FindPointer("parentGroupList",i,(void **)&parentGroupList))
			parentGroupList->RemoveItem(node);
		else
			(doc->GetAllNodes())->RemoveItem(node);
		i++;
	}
	i = 0;
	while (settings->FindPointer("connection",i,(void **)&connection))
	{
		i++;
		(doc->GetAllConnections())->RemoveItem(connection);
	}
	return commandMessage;*/
	//**Todo
	BMessage		*undoMessage		= new BMessage();
	BList			*selected			= doc->GetSelected();
	BList			*connections		= doc->GetAllConnections();
	BList			*allNodes			= doc->GetAllNodes();
	BList			*changed			= doc->GetChangedNodes();
	BMessage		*node				= NULL;
	BMessage		*connection			= NULL;
	BList			*outgoing			= NULL;
	BList			*incoming			= NULL;
	int32			i					= 0;
	while (	(node = (BMessage *)selected->RemoveItem(i)) != NULL)
	{
		allNodes->RemoveItem(node);
		connections->RemoveItem(node);
		changed->AddItem(node);
		undoMessage->AddPointer("node",node);
		if (node->FindPointer("Node::outgoing",(void **)&outgoing) == B_OK)
		{
			for (int32 i=0;i<outgoing->CountItems();i++)
			{
				connection= (BMessage *)outgoing->ItemAt(i);
				connections->RemoveItem(connection);
//				trash->AddItem(connection);
				changed->AddItem(connection);
				undoMessage->AddPointer("node",connection);
			}
		}
		if (node->FindPointer("Node::incoming",(void **)&incoming) == B_OK)
		{
			for (int32 i=0;i<incoming->CountItems();i++)
			{
				connection= (BMessage *)incoming->ItemAt(i);
				connections->RemoveItem(connection);
//				trash->AddItem(connection);
				changed->AddItem(connection);
				undoMessage->AddPointer("node",connection);
			}
		}
	}
	doc->SetModified();
	settings->RemoveName("Delete::Undo");
	settings->AddMessage("Delete::Undo",undoMessage);
	settings = PCommand::Do(doc,settings);
	return settings;
}
Example #30
0
status_t
BEmailMessage::RenderToRFC822(BPositionIO *file)
{
	if (_body == NULL)
		return B_MAIL_INVALID_MAIL;

	// Do real rendering

	if (From() == NULL) {
		// set the "From:" string
		SendViaAccount(_account_id);
	}

	BList recipientList;
	get_address_list(recipientList, To(), extract_address);
	get_address_list(recipientList, CC(), extract_address);
	get_address_list(recipientList, _bcc, extract_address);

	BString recipients;
	for (int32 i = recipientList.CountItems(); i-- > 0;) {
		char *address = (char *)recipientList.RemoveItem((int32)0);

		recipients << '<' << address << '>';
		if (i)
			recipients << ',';

		free(address);
	}

	// add the date field
	int32 creationTime = time(NULL);
	{
		char date[128];
		struct tm tm;
		localtime_r(&creationTime, &tm);

		size_t length = strftime(date, sizeof(date),
			"%a, %d %b %Y %H:%M:%S", &tm);

		// GMT offsets are full hours, yes, but you never know :-)
		snprintf(date + length, sizeof(date) - length, " %+03d%02d",
			tm.tm_gmtoff / 3600, (tm.tm_gmtoff / 60) % 60);

		SetHeaderField("Date", date);
	}

	// add a message-id

	// empirical evidence indicates message id must be enclosed in
	// angle brackets and there must be an "at" symbol in it
	BString messageID;
	messageID << "<";
	messageID << system_time();
	messageID << "-BeMail@";

	char host[255];
	if (gethostname(host, sizeof(host)) < 0 || !host[0])
		strcpy(host, "zoidberg");

	messageID << host;
	messageID << ">";

	SetHeaderField("Message-Id", messageID.String());

	status_t err = BMailComponent::RenderToRFC822(file);
	if (err < B_OK)
		return err;

	file->Seek(-2, SEEK_CUR);
		// Remove division between headers

	err = _body->RenderToRFC822(file);
	if (err < B_OK)
		return err;

	// Set the message file's attributes.  Do this after the rest of the file
	// is filled in, in case the daemon attempts to send it before it is ready
	// (since the daemon may send it when it sees the status attribute getting
	// set to "Pending").

	if (BFile *attributed = dynamic_cast <BFile *>(file)) {
		BNodeInfo(attributed).SetType(B_MAIL_TYPE);

		attributed->WriteAttrString(B_MAIL_ATTR_RECIPIENTS,&recipients);

		BString attr;

		attr = To();
		attributed->WriteAttrString(B_MAIL_ATTR_TO,&attr);
		attr = CC();
		attributed->WriteAttrString(B_MAIL_ATTR_CC,&attr);
		attr = Subject();
		attributed->WriteAttrString(B_MAIL_ATTR_SUBJECT,&attr);
		attr = ReplyTo();
		attributed->WriteAttrString(B_MAIL_ATTR_REPLY,&attr);
		attr = From();
		attributed->WriteAttrString(B_MAIL_ATTR_FROM,&attr);
		if (Priority() != 3 /* Normal is 3 */) {
			sprintf (attr.LockBuffer (40), "%d", Priority());
			attr.UnlockBuffer(-1);
			attributed->WriteAttrString(B_MAIL_ATTR_PRIORITY,&attr);
		}
		attr = "Pending";
		attributed->WriteAttrString(B_MAIL_ATTR_STATUS, &attr);
		attr = "1.0";
		attributed->WriteAttrString(B_MAIL_ATTR_MIME, &attr);

		attributed->WriteAttr(B_MAIL_ATTR_ACCOUNT, B_INT32_TYPE, 0,
			&_account_id, sizeof(int32));

		attributed->WriteAttr(B_MAIL_ATTR_WHEN, B_TIME_TYPE, 0, &creationTime,
			sizeof(int32));
		int32 flags = B_MAIL_PENDING | B_MAIL_SAVE;
		attributed->WriteAttr(B_MAIL_ATTR_FLAGS, B_INT32_TYPE, 0, &flags,
			sizeof(int32));

		attributed->WriteAttr(B_MAIL_ATTR_ACCOUNT_ID, B_INT32_TYPE, 0,
			&_account_id, sizeof(int32));
	}

	return B_OK;
}