Example #1
0
void CCellView::HandleDrop(BMessage *inMessage)
{
	long l;
	void * p;
	BPoint dp = inMessage->DropPoint();
	
	fDragIsAcceptable = false;
	
	if (inMessage->FindPointer("container", &p) == B_NO_ERROR)
	{
		key_info ki;
		get_key_info(&ki);
		
		CContainer *srcContainer;
		range srcRange, dstRange;
		CCellView *srcView;
		int action;
		
		srcContainer = (CContainer *)p;
		FailOSErr(inMessage->FindData("range", 'rang', (const void**)&p, &l), errMessageMissing);
		srcRange = *(range *)p;
		FailOSErr(inMessage->FindPointer("cellview", &p), errMessageMissing);
		srcView = (CCellView *)p;
		
		if (srcView != this)
			action = dragCopy;
		else
			action = dragMove;
		
		inMessage->FindBool("dragacopy", &fDragACopy);
		
		if (srcView == this &&
		    (ki.modifiers & B_CONTROL_KEY ||
			fDragACopy))
		{
			BPopUpMenu popup("dragpopup", false);
			popup.SetFont(be_plain_font);
			popup.AddItem(new BMenuItem(GetMessage(msgLinkHere), NULL));
			popup.AddItem(new BMenuItem(GetMessage(msgMoveHere), NULL));
			popup.AddItem(new BMenuItem(GetMessage(msgCopyHere), NULL));
			popup.AddSeparatorItem();
			popup.AddItem(new BMenuItem(GetMessage(msgCancel), NULL));
			
			BMenuItem *item = popup.Go(dp, false, true);
			int result = item ? popup.IndexOf(item) : -1;
			switch (result)
			{
				case 0: action = dragLink; break;
				case 1: action = dragMove; break;
				case 2: action = dragCopy; break;
				default:
					ClearAnts();
					fCurCell = fSelection.TopLeft();
					return;
			}
		}
	
		dstRange = srcRange;
		dstRange.OffsetBy(fCurCell.h - dstRange.left,
			fCurCell.v - dstRange.top);
		
		((CCellWindow *)Window())->
			RegisterCommand(new CDragCommand(this, srcContainer,
				fContainer, &srcRange, &dstRange, action));
	}
	else if (inMessage->FindData("text/plain", B_MIME_DATA, (const void **)&p, &l) == B_NO_ERROR)
	{
		cell dc;
		
		ConvertFromScreen(&dp);
		GetCellHitBy(dp, dc);
		
		BMemoryIO buf(p, l);
		CContainer *srcContainer = new CContainer;
		range srcRange, dstRange;
		
		CTextConverter conv(buf, srcContainer);
		conv.ConvertFromText(srcRange);
		
		dstRange = srcRange;
		dstRange.OffsetBy(dc.h - srcRange.left, dc.v - srcRange.top);
		
		((CCellWindow *)Window())->
			RegisterCommand(new CDragCommand(this, srcContainer,
				fContainer, &srcRange, &dstRange, dragMove));

		srcContainer->Release();
	}
	else
	{
		beep();
		ClearAnts();
		fCurCell = fSelection.TopLeft();
	}
} /* CCellView::HandleDrop */