Скачиваний:
8
Добавлен:
01.05.2014
Размер:
32 Кб
Скачать
// OLEAppView.cpp : implementation of the COLEAppView class
//

#include "stdafx.h"
#include "OLEApp.h"

#include "OLEAppDoc.h"
#include "CntrItem.h"
#include "OLEAppView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// COLEAppView

IMPLEMENT_DYNCREATE(COLEAppView, CScrollView)

BEGIN_MESSAGE_MAP(COLEAppView, CScrollView)
	//{{AFX_MSG_MAP(COLEAppView)
	ON_WM_DESTROY()
	ON_WM_SETFOCUS()
	ON_WM_SIZE()
	ON_COMMAND(ID_OLE_INSERT_NEW, OnInsertObject)
	ON_COMMAND(ID_CANCEL_EDIT_CNTR, OnCancelEditCntr)
	ON_COMMAND(ID_CANCEL_EDIT_SRVR, OnCancelEditSrvr)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_SETCURSOR()
	ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
	ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditClear)
	ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
	ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
	ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_COMMAND(ID_MOVE, OnMove)
	ON_COMMAND(ID_SENDTOBACK, OnSendtoback)
	ON_COMMAND(ID_DELETE, OnDelete)
	ON_COMMAND(ID_VIEW_SCALE, OnViewScale)
	ON_COMMAND(ID_SET_COLOR_BLACK, OnSetColorBlack)
	ON_COMMAND(ID_SET_COLOR_BLUE, OnSetColorBlue)
	ON_COMMAND(ID_SET_COLOR_GREEN, OnSetColorGreen)
	ON_COMMAND(ID_FIND, OnFind)
	ON_COMMAND(ID_FREE_VIEW, OnFreeView)
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_DELETEBYKEY, OnDeleteByKey)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COLEAppView construction/destruction

COLEAppView::COLEAppView()
{
	m_pSelection = NULL;
	// TODO: add construction code here
    m_FirstPoint = CPoint(0,0);         // Set 1st recorded point to 0,0
    m_SecondPoint = CPoint(0,0);        // Set 2nd recorded point to 0,0
	m_ThirdPoint = CPoint(0,0);         // Set 2nd recorded point to 0,0
    m_pTempElement = 0;                 // Set temporary element pointer to 0
    m_pSelected = 0;                    // No element selected initially
	m_kSelected = "";                   // And no key
    m_MoveMode = FALSE;                 // Set move mode off
    m_CursorPos = CPoint(0,0);          // Initialize as zero
    m_FirstPos = CPoint(0,0);           // Initialize as zero
    m_Scale = 1;                        // Set scale to 1:1
    SetScrollSizes(MM_TEXT, CSize(0,0));// Set arbitrary scrollers
    m_triangleState = 0;                
    m_text = "";
	m_counter = 0;
}

COLEAppView::~COLEAppView()
{
}

BOOL COLEAppView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// COLEAppView drawing

void COLEAppView::OnDraw(CDC* pDC)
{
	COLEAppDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// draw the OLE items from the list
	POSITION pos = pDoc->GetStartPosition();
	while (pos != NULL)
	{
		// draw the item
		COLEAppCntrItem* pItem = (COLEAppCntrItem*)pDoc->GetNextItem(pos);

		pItem->Draw(pDC, pItem->m_rect);

		// draw the tracker over the item
		CRectTracker tracker;
		SetupTracker(pItem, &tracker);
		tracker.Draw(pDC);
	}

   Hash<stringKey, CElement*>::iterator it = pDoc->getHashStart();
   Hash<stringKey, CElement*>::iterator end = pDoc->getHashEnd();
   while(it != end){
	  pair<stringKey, CElement*> he = it++;

	  CElement* pElement = he.second;
	  string keyText = (m_MoveMode)? "": he.first.getKey(); // if if drag object - don't show it's key

      if(pDC->RectVisible(pElement->GetBoundRect()))
         pElement->Draw(pDC, m_pSelected, keyText);  // ...draw it
   }
}

void COLEAppView::OnInitialUpdate()
{
	ResetScrollSizes();               // Set up the scrollbars
	CView::OnInitialUpdate();
	// TODO: remove this code when final selection model code is written
	m_pSelection = NULL;    // initialize selection

}

/////////////////////////////////////////////////////////////////////////////
// COLEAppView printing

BOOL COLEAppView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void COLEAppView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void COLEAppView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

void COLEAppView::OnDestroy()
{
	// Deactivate the item on destruction; this is important
	// when a splitter view is being used.
   CView::OnDestroy();
   COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
   if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
   {
      pActiveItem->Deactivate();
      ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
   }
}


/////////////////////////////////////////////////////////////////////////////
// OLE Client support and commands

BOOL COLEAppView::IsSelected(const CObject* pDocItem) const
{
	// The implementation below is adequate if your selection consists of
	//  only COLEAppCntrItem objects.  To handle different selection
	//  mechanisms, the implementation here should be replaced.

	// TODO: implement this function that tests for a selected OLE client item

	return pDocItem == m_pSelection;
}

void COLEAppView::OnInsertObject()
{
	// Invoke the standard Insert Object dialog box to obtain information
	//  for new COLEAppCntrItem object.
	COleInsertDialog dlg;
	if (dlg.DoModal() != IDOK)
		return;

	BeginWaitCursor();

	COLEAppCntrItem* pItem = NULL;
	TRY
	{
		// Create new item connected to this document.
		COLEAppDoc* pDoc = GetDocument();
		ASSERT_VALID(pDoc);
		pItem = new COLEAppCntrItem(pDoc);
		ASSERT_VALID(pItem);

		// Initialize the item from the dialog data.
		if (!dlg.CreateItem(pItem))
			AfxThrowMemoryException();  // any exception will do
		ASSERT_VALID(pItem);
		pItem->UpdateLink();
		pItem->UpdateFromServerExtent();
		
		// If item created from class list (not from file) then launch
		//  the server to edit the item.
        if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
			pItem->DoVerb(OLEIVERB_SHOW, this);

		ASSERT_VALID(pItem);

		SetSelection(pItem);
		pItem->InvalidateItem();
	}
	CATCH(CException, e)
	{
		if (pItem != NULL)
		{
			ASSERT_VALID(pItem);
			pItem->Delete();
		}
		AfxMessageBox(IDP_FAILED_TO_CREATE);
	}
	END_CATCH

	EndWaitCursor();
	GetDocument()->NotifyChanged();
}

// The following command handler provides the standard keyboard
//  user interface to cancel an in-place editing session.  Here,
//  the container (not the server) causes the deactivation.
void COLEAppView::OnCancelEditCntr()
{
	// Close any in-place active item on this view.
	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL)
	{
		pActiveItem->Close();
	}
	ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
	GetDocument()->NotifyChanged();
}

// Special handling of OnSetFocus and OnSize are required for a container
//  when an object is being edited in-place.
void COLEAppView::OnSetFocus(CWnd* pOldWnd)
{
	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL &&
		pActiveItem->GetItemState() == COleClientItem::activeUIState)
	{
		// need to set focus to this item if it is in the same view
		CWnd* pWnd = pActiveItem->GetInPlaceWindow();
		if (pWnd != NULL)
		{
			pWnd->SetFocus();   // don't call the base class
			return;
		}
	}

	CView::OnSetFocus(pOldWnd);
}

void COLEAppView::OnSize(UINT nType, int cx, int cy)
{
	ResetScrollSizes();
	CView::OnSize(nType, cx, cy);
	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL)
		pActiveItem->SetItemRects();
}

/////////////////////////////////////////////////////////////////////////////
// OLE Server support

// The following command handler provides the standard keyboard
//  user interface to cancel an in-place editing session.  Here,
//  the server (not the container) causes the deactivation.
void COLEAppView::OnCancelEditSrvr()
{
	GetDocument()->OnDeactivateUI(FALSE);
	GetDocument()->NotifyChanged();
}

COLEAppCntrItem* COLEAppView::HitTestItems(CPoint point)
{
	COLEAppDoc* pDoc = GetDocument();
	COLEAppCntrItem* pItemHit = NULL;
	POSITION pos = pDoc->GetStartPosition();
	while (pos != NULL)
	{
		COLEAppCntrItem* pItem = (COLEAppCntrItem*)pDoc->GetNextItem(pos);
		if (pItem->m_rect.PtInRect(point))
			pItemHit = pItem;
	}
	return pItemHit;    // return top item at point
}


void COLEAppView::OnLButtonDown(UINT nFlags, CPoint point) {

	COLEAppCntrItem* pItemHit = HitTestItems(point);
	SetSelection(pItemHit);

	if (pItemHit != NULL)
	{
		CRectTracker tracker;
		SetupTracker(pItemHit, &tracker);

		UpdateWindow();
		if (tracker.Track(this, point))
		{
			pItemHit->InvalidateItem();
			pItemHit->m_rect = tracker.m_rect;
			pItemHit->InvalidateItem();
			GetDocument()->SetModifiedFlag();
		}
	}
	else {

		CClientDC aDC(this);                // Create a device context
		OnPrepareDC(&aDC);                  // Get origin adjusted
		aDC.DPtoLP(&point);                 // convert point to Logical

		if(nFlags & MK_CONTROL) {
			this->OnMove();
		}
		else {
			// Get a pointer to the document for this view
			COLEAppDoc* pDoc = GetDocument();
			ASSERT_VALID(pDoc);                  // Verify the pointer is good

			if (pDoc->GetElementType() == TEXT){
				
				if (inputDialog.DoModal()==IDOK){
					if (inputDialog.m_textBox.IsEmpty())
						AfxMessageBox("Text should be at least 1 character long");
					else{
						m_FirstPoint = point;               // Record the cursor position
						m_text = inputDialog.m_textBox;
						inputDialog.m_textBox = "";
						// Define a Device Context object for the view
						CClientDC aDC(this);
						aDC.SetROP2(R2_NOTXORPEN);  // Set the drawing mode
						draw(aDC);
						stopDrawing();
					}
				}
			}
			else if (m_triangleState == 0){
				m_triangleState = 1;
				m_text = "";
				m_FirstPoint = point;               // Record the cursor position
				SetCapture();                       // Capture subsequent mouse messages
			}
			else if (m_triangleState == 2){
				bool cancel = false;

				if(this == GetCapture())	// Stop capturing mouse messages
					ReleaseCapture();        

				if (pDoc->GetElementType() == TEXTINTRIANGLE ){
					if (inputDialog.DoModal()==IDOK){
						if (inputDialog.m_textBox.IsEmpty())
							AfxMessageBox("Text should be at least 1 character long");
						else{
							m_text = inputDialog.m_textBox;
							inputDialog.m_textBox = "";
							draw(aDC);
						}
					}
					else{
						cancel = true;
					}
				}
				stopDrawing(cancel);
				m_triangleState = 0;
			}
			else{
				m_FirstPoint = point;               // Record the cursor position
				SetCapture();                       // Capture subsequent mouse messages
			}
		}
	}
	//CView::OnLButtonDown(nFlags, point);
}

void COLEAppView::OnLButtonUp(UINT nFlags, CPoint point) {
	GetDocument()->NotifyChanged();
	if(m_MoveMode){
		if(this == GetCapture())
			ReleaseCapture();        // Stop capturing mouse messages

		// In moving mode, so drop the element
		m_MoveMode = FALSE;                 // Kill move mode
		GetDocument()->UpdateAllViews(0);   // Redraw all the views
		//m_pSelected = 0;                    // De-select the element
		GetDocument()->NotifyChanged();
	}
	else {  
		if (GetDocument()->GetElementType() != TRIANGLE && GetDocument()->GetElementType() != TEXTINTRIANGLE){
			stopDrawing();
		}
		else if (m_triangleState == 1){
			m_triangleState = 2;
			if(this == GetCapture())
				ReleaseCapture();        // Stop capturing mouse messages
			SetCapture();                // Capture subsequent mouse messages
		}
	}
}


void COLEAppView::stopDrawing(bool cancel){
	if(this == GetCapture())
		ReleaseCapture();        // Stop capturing mouse messages

	//if there is an element, add it to the document
	if(m_pTempElement){ 
		if (!cancel){
			// add key
			string key = "";
			if (keyInputDialog.DoModal()==IDOK){
				if (keyInputDialog.m_textBox.IsEmpty())
					AfxMessageBox("Text should be at least 1 character long");
				else{
					key = keyInputDialog.m_textBox;
					keyInputDialog.m_textBox = "";
				}
			}
			if (key != ""){
				// put element with given key in hash
				bool res = GetDocument()->AddElement(m_pTempElement, key);
				if (!res)
					AfxMessageBox("Element w/ given key is already in hash.");			}
		}
		//AfxMessageBox("alarm!");
		//GetDocument()->UpdateAllViews(0,0,m_pTempElement);  // Tell all the views
		GetDocument()->UpdateAllViews(0);   // Redraw all the views
		m_pTempElement = 0;      // Reset the element pointer

		GetDocument()->NotifyChanged();
	}
}

void COLEAppView::draw(CClientDC& aDC){
	if(m_pTempElement)
	{
		aDC.SetROP2(R2_NOTXORPEN);      // Set drawing mode

		// Redraw the old element so it disappears from the view
		m_pTempElement->Draw(&aDC);

		delete m_pTempElement;        // Delete the old element
		m_pTempElement = 0;           // Reset the pointer to 0
	}

	// Create a temporary element of the type and color that
	// is recorded in the document object, and draw it
	m_pTempElement = CreateElement();  // Create a new element
	m_pTempElement->Draw(&aDC);        // Draw the element
}

void COLEAppView::OnMouseMove(UINT nFlags, CPoint point) {
	// Define a Device Context object for the view
	CClientDC aDC(this);
	OnPrepareDC(&aDC);            // Get origin adjusted

	// If we are in move mode, move the selected element and return
	if(nFlags == (MK_LBUTTON | MK_CONTROL)) {
		m_MoveMode = TRUE;
		aDC.DPtoLP(&point);        // Convert to logical coordinatess
		MoveElement(aDC, point);   // Move the element
		return;
	}   

	if((nFlags & MK_LBUTTON) && (this == GetCapture()) && (m_triangleState != 2)) {
		aDC.DPtoLP(&point);        // convert point to Logical
		m_SecondPoint = point;     // Save the current cursor position

		draw(aDC);
	}
	else if((m_triangleState == 2) && (this == GetCapture())) {
		aDC.DPtoLP(&point);        // convert point to Logical

		m_text = "";
		// Save the current cursor position
		m_ThirdPoint = point; 
		draw(aDC);
	}
	else {/* if (nFlags & MK_CONTROL)*/       // We are not drawing an element...
		// ...so do highlighting
		CRect aRect;
		pair<stringKey, CElement*> pSelection = SelectElement(point);
		CElement* pCurrentSelection = pSelection.second;
		string pCurrentKey = pSelection.first.getKey();

		if(pCurrentSelection!=m_pSelected) {
			if(m_pSelected) {             // Old elemented selected?
										   // Yes, so draw it unselected
				aRect = m_pSelected->GetBoundRect(); // Get bounding rectangle
				aDC.LPtoDP(aRect);                   // Conv to device coords
				aRect.NormalizeRect();               // Normalize
				InvalidateRect(aRect, FALSE);        // Invalidate area
			}

			m_pSelected = pCurrentSelection;        // Save elem under cursor
			m_kSelected = pCurrentKey;

			if(m_pSelected) {                        // Is there one?
			                                       // Yes, so get it redrawn
				aRect = m_pSelected->GetBoundRect(); // Get bounding rectangle
				aDC.LPtoDP(aRect);                   // Conv to device coords
				aRect.NormalizeRect();               // Normalize
				InvalidateRect(aRect, FALSE);        // Invalidate area
			}
			// if it's text then invalidate rect
			if (GetDocument()->GetElementType() == TEXT)
				GetDocument()->UpdateAllViews(0,0,m_pSelected);  // Tell all views
		}
	}
}

CElement* COLEAppView::CreateElement() {
	// Get a pointer to the document for this view
	COLEAppDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);                  // Verify the pointer is good

	// Now select the element using the type stored in the document
	switch(pDoc->GetElementType())
	{     
		case LINE:                  
			return new Line(m_FirstPoint, m_SecondPoint, pDoc->GetElementColor());

		case TRIANGLE: 
			if (m_triangleState == 1)
				return new Line(m_FirstPoint, m_SecondPoint, pDoc->GetElementColor());
			else if (m_triangleState == 2)
				return new Triangle(m_FirstPoint, m_SecondPoint, m_ThirdPoint, pDoc->GetElementColor());

		case TEXT:
			return new Text(m_text, m_FirstPoint, pDoc->GetElementColor());

		case TEXTINTRIANGLE: 
			if (m_triangleState == 1)
				return new Line(m_FirstPoint, m_SecondPoint, pDoc->GetElementColor());
			else if (m_triangleState == 2)
				return new TextInTriangle(m_FirstPoint, m_SecondPoint, m_ThirdPoint, m_text, pDoc->GetElementColor());

		default:
			//	Something's gone wrong
			AfxMessageBox("Bad Element code", MB_OK);
			AfxAbort();
			return NULL;
	}
}

// Find the element at the cursor
pair<stringKey, CElement*> COLEAppView::SelectElement(CPoint aPoint) {
	// Convert parameter aPoint to logical coordinates
	CClientDC aDC(this);
	OnPrepareDC(&aDC);
	aDC.DPtoLP(&aPoint);

	COLEAppDoc* pDoc=GetDocument();      // Get a pointer to the document
	CElement* pElement = 0;                // Store an element pointer
	CRect aRect(0,0,0,0);                  // Store a rectangle

	Hash<stringKey, CElement*>::iterator it = pDoc->getHashStart();
	Hash<stringKey, CElement*>::iterator end = pDoc->getHashEnd();

	while(it != end){
		pair<stringKey, CElement*> he = it++;

		pElement = he.second;
		aRect = pElement->GetBoundRect();

		// Select the first element that appears under the cursor
		if(aRect.PtInRect(aPoint))
		return he;
	}

	return pair<stringKey, CElement*>(stringKey(),0);                              // No element found
}

void COLEAppView::MoveElement(CClientDC& aDC, CPoint& point) {
	CSize Distance = point - m_CursorPos;   // Get move distance
	m_CursorPos = point;          // Set current point as 1st for next time

	// If there is an element, selected, move it
	if(m_pSelected)	{
		//if current element is text -> invaldate it's encloding rectangle
		//(GetDocument()->GetElementType() == TEXT)

		CRect     aRect = m_pSelected->GetBoundRect(); // Get bounding rectangle
		aDC.LPtoDP(aRect);                   // Conv to device coords
		aRect.NormalizeRect();               // Normalize
		InvalidateRect(aRect);        // Invalidate area

		CRect     aRect1 = m_pSelected->getKeyRectangle(); // Get bounding rectangle
		aDC.LPtoDP(aRect1);                   // Conv to device coords
		aRect1.NormalizeRect();               // Normalize
		InvalidateRect(aRect1);        // Invalidate area

		aDC.SetROP2(R2_NOTXORPEN);
		m_pSelected->Draw(&aDC,m_pSelected); // Draw the element to erase it
		m_pSelected->Move(Distance);         // Now move the element
		m_pSelected->Draw(&aDC,m_pSelected); // Draw the moved element
	}
}

void COLEAppView::OnRButtonDown(UINT nFlags, CPoint point) {
	if(m_MoveMode) {
		// In moving mode, so drop element back in original position
		CClientDC aDC(this);
		OnPrepareDC(&aDC);                  // Get origin adjusted
		MoveElement(aDC, m_FirstPos);       // Move element to orig position
		m_MoveMode = FALSE;                 // Kill move mode
		m_pSelected = 0;                    // De-select element
		GetDocument()->UpdateAllViews(0);   // Redraw all the views
		return;                             // We are done
	}
}


void COLEAppView::OnRButtonUp(UINT nFlags, CPoint point) {
	// Create the cursor menu
	CMenu aMenu;
	aMenu.LoadMenu(IDR_CURSOR_MENU);    // Load the cursor menu
	ClientToScreen(&point);             // Convert to screen coordinates

	// Display the pop-up at the cursor position
	if(m_pSelected) {
		// Check color menu items
		COLORREF Color = m_pSelected->getColor();
		aMenu.CheckMenuItem(ID_SET_COLOR_BLACK, (BLACK==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_SET_COLOR_GREEN, (GREEN==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_SET_COLOR_BLUE, (BLUE==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);

		aMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
	}
	else {
		// Check color menu items
		COLORREF Color = GetDocument()->GetElementColor();
		aMenu.CheckMenuItem(ID_COLOR_BLACK, (BLACK==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_COLOR_GREEN, (GREEN==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_COLOR_BLUE, (BLUE==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);

		// Check element menu items
		WORD ElementType = GetDocument()->GetElementType();
		aMenu.CheckMenuItem(ID_ELEMENT_LINE, (LINE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_ELEMENT_TRIANGLE, (TRIANGLE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_ELEMENT_TEXT, (TEXT==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_ELEMENT_TEXTINTRIANGLE, (TEXTINTRIANGLE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);

		// Display the context pop-up
		aMenu.GetSubMenu(1)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
	}
}

void COLEAppView::SetSelection(COLEAppCntrItem* pItem)
{
	// close in-place active item
	if (pItem == NULL || m_pSelection != pItem)
	{
		COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
		if (pActiveItem != NULL && pActiveItem != pItem)
			pActiveItem->Close();
	}
	// update view to new selection
	if (m_pSelection != pItem)
	{
		if (m_pSelection != NULL)
			OnUpdate(NULL, HINT_UPDATE_ITEM, m_pSelection);

		m_pSelection = pItem;
		if (m_pSelection != NULL)
			OnUpdate(NULL, HINT_UPDATE_ITEM, m_pSelection);
	}
}

void COLEAppView::SetupTracker(COLEAppCntrItem* pItem, CRectTracker* pTracker)
{
	pTracker->m_rect = pItem->m_rect;

	if (pItem == m_pSelection)
		pTracker->m_nStyle |= CRectTracker::resizeInside;

	if (pItem->GetType() == OT_LINK)
		pTracker->m_nStyle |= CRectTracker::dottedLine;
	else
		pTracker->m_nStyle |= CRectTracker::solidLine;

	if (pItem->GetItemState() == COleClientItem::openState ||
		pItem->GetItemState() == COleClientItem::activeUIState)
	{
		pTracker->m_nStyle |= CRectTracker::hatchInside;
}
}


/////////////////////////////////////////////////////////////////////////////
// COLEAppView diagnostics

#ifdef _DEBUG
void COLEAppView::AssertValid() const
{
	CView::AssertValid();
}

void COLEAppView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

COLEAppDoc* COLEAppView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COLEAppDoc)));
	return (COLEAppDoc*)m_pDocument;
}
#endif //_DEBUG

void COLEAppView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	OnLButtonDown(nFlags, point);

	if (m_pSelection != NULL)
	{
		m_pSelection->DoVerb(GetKeyState(VK_CONTROL) < 0 ?
			OLEIVERB_OPEN : OLEIVERB_PRIMARY, this);
	}

	CView::OnLButtonDblClk(nFlags, point);
}

void COLEAppView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) {
	
	CScrollView::OnPrepareDC(pDC, pInfo);
/*	COLEAppDoc* pDoc = GetDocument();
	pDC->SetMapMode(MM_ANISOTROPIC);           // Set the map mode
	CSize DocSize = pDoc->GetDocSize();        // Get the document size

	// y extent must be negative because we want MM_LOENGLISH
	DocSize.cy = -DocSize.cy;                  // Change sign of y
	pDC->SetWindowExt(DocSize);                // Now set the window extent

	// Get the number of pixels per inch in x and y
	int xLogPixels = pDC->GetDeviceCaps(LOGPIXELSX);
	int yLogPixels = pDC->GetDeviceCaps(LOGPIXELSY);

	// Calculate the viewport extent in x and y
	long xExtent = (long)DocSize.cx*m_Scale*xLogPixels/100L;
	long yExtent = (long)DocSize.cy*m_Scale*yLogPixels/100L;

	pDC->SetViewportExt((int)xExtent, (int)-yExtent); // Set viewport extent
*/
}

BOOL COLEAppView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	if (pWnd == this && m_pSelection != NULL)
	{
		// give the tracker for the selection a chance
		CRectTracker tracker;
		SetupTracker(m_pSelection, &tracker);
		if (tracker.SetCursor(this, nHitTest))
			return TRUE;
	}

	return CView::OnSetCursor(pWnd, nHitTest, message);
}

void COLEAppView::OnEditClear()
{
	if (m_pSelection != NULL)
	{
		m_pSelection->Delete();
		m_pSelection = NULL;
		GetDocument()->UpdateAllViews(NULL);
	}
}

void COLEAppView::OnUpdateEditClear(CCmdUI* pCmdUI)
{
	pCmdUI->Enable(m_pSelection != NULL);

}
void COLEAppView::OnEditCopy()
{
	if (m_pSelection != NULL)
		m_pSelection->CopyToClipboard();
}

void COLEAppView::OnUpdateEditCopy(CCmdUI* pCmdUI)
{
	pCmdUI->Enable(m_pSelection != NULL);
}

void COLEAppView::OnEditPaste()
{
	COLEAppCntrItem* pItem = NULL;

	TRY
	{
		// Create new item connected to this document.
		COLEAppDoc* pDoc = GetDocument();
		ASSERT_VALID(pDoc);
		pItem = new COLEAppCntrItem(pDoc);
		ASSERT_VALID(pItem);

		// Initialize the item from clipboard data
		if (!pItem->CreateFromClipboard())
			AfxThrowMemoryException();  // any exception will do
		ASSERT_VALID(pItem);

		// update the size before displaying
		pItem->UpdateFromServerExtent();

		// set selection to newly pasted item
		SetSelection(pItem);
		pItem->InvalidateItem();
	}
	CATCH(CException, e)
	{
		if (pItem != NULL)
		{
			ASSERT_VALID(pItem);
			pItem->Delete();
		}
		AfxMessageBox(IDP_FAILED_TO_CREATE);
	}
	END_CATCH

	GetDocument()->NotifyChanged();
}
void COLEAppView::OnUpdate(CView* /* pSender */, LPARAM lHint, CObject* pHint)
{
/*	switch (lHint)
	{
	case HINT_UPDATE_WINDOW:    // invalidate entire window
		Invalidate();
		return;
		break;
	case HINT_UPDATE_ITEM:      // invalidate single item
		{
			CRectTracker tracker;
			SetupTracker((COLEAppCntrItem*)pHint, &tracker);
			CRect rect;
			tracker.GetTrueRect(rect);
			InvalidateRect(rect);
			return;
		}
		break;
	}

	if(pHint) {
		CClientDC aDC(this);            // Create a device context
		OnPrepareDC(&aDC);              // Get origin adjusted

		// Get the enclosing rectangle and convert to client coordinates
		CRect aRect=((CElement*)pHint)->GetBoundRect();
		aDC.LPtoDP(aRect);
		aRect.NormalizeRect();
		InvalidateRect(aRect);          // Get the area redrawn
	}
	else
		InvalidateRect(0);
*/
	Invalidate();
	GetDocument()->NotifyChanged();
}


void COLEAppView::OnMove() {
	CClientDC aDC(this);
	OnPrepareDC(&aDC);              // Set up the device context
	GetCursorPos(&m_CursorPos);     // Get cursor position in screen coords
	ScreenToClient(&m_CursorPos);   // Convert to client coords
	aDC.DPtoLP(&m_CursorPos);       // Convert to logical
	m_FirstPos = m_CursorPos;       // Remember first position
	m_MoveMode = TRUE;              // Start move mode	
}

void COLEAppView::OnSendtoback() 
{
	GetDocument()->SendToBack(m_pSelected);  // Move element in list	
}

void COLEAppView::OnDelete() {
	if(m_pSelected) {
		deleteElement(m_kSelected);
	}	
}

void COLEAppView::deleteElement(string key) {
		COLEAppDoc* pDoc = GetDocument();	// Get the document pointer
		pDoc->DeleteElement(key);			// Delete the element
		pDoc->UpdateAllViews(0);			// Redraw all the views
		m_pSelected = 0;					// Reset selected element ptr
		GetDocument()->NotifyChanged();
}

void COLEAppView::OnViewScale() {
/*	CScaleDialog aDlg;            // Create a dialog object
	aDlg.m_Scale = m_Scale;       // Pass the view scale to the dialog

	if(aDlg.DoModal() == IDOK) {
		m_Scale = aDlg.m_Scale;    // Get the new scale

		// Get the frame window for this view
		CChildFrame* viewFrame = (CChildFrame*)GetParentFrame();

		// Build the message string
		CString StatusMsg("View Scale:");
		StatusMsg += (char)('0' + m_Scale);

		// Write the string to the status bar
		viewFrame->m_StatusBar.GetStatusBarCtrl().SetText(StatusMsg, 0, 0);
		ResetScrollSizes();        // Adjust scrolling to the new scale
		InvalidateRect(0);         // Invalidate the whole window
	}
*/
}

void COLEAppView::ResetScrollSizes() {
   CClientDC aDC(this);
   OnPrepareDC(&aDC);                            // Set up the device context
   CSize DocSize = GetDocument()->GetDocSize();  // Get the document size
   aDC.LPtoDP(&DocSize);                         // Get the size in pixels
   SetScrollSizes(MM_TEXT, DocSize);             // Set up the scrollbars
}

void COLEAppView::setColor(COLORREF aColor) {
	if(m_pSelected)
	{
		COLEAppDoc* pDoc = GetDocument();  // Get the document pointer
		m_pSelected->setColor(aColor);
		pDoc->UpdateAllViews(0);             // Redraw all the views
		//m_pSelected = 0;                     // Reset selected element ptr
	}
}

void COLEAppView::OnSetColorBlack() {
	setColor(BLACK);
}

void COLEAppView::OnSetColorBlue() {
	setColor(BLUE);
}

void COLEAppView::OnSetColorGreen() {
	setColor(GREEN);
}

void COLEAppView::OnFind() {
	string key = "";
	if (keyInputDialog.DoModal()==IDOK){
		if (keyInputDialog.m_textBox.IsEmpty())
			AfxMessageBox("Text should be at least 1 character long");
		else{
			key = keyInputDialog.m_textBox;
			keyInputDialog.m_textBox = "";
		}
	}

	if (key == "")
		return;

	COLEAppDoc* pDoc = GetDocument();  // Get the document pointer
	Hash<stringKey, CElement*>::iterator it = pDoc->findElement(key);
	Hash<stringKey, CElement*>::iterator end = pDoc->getHashEnd();

	if (it != end){
		m_pSelected = (*it).second;
		pDoc->UpdateAllViews(0);
	}
	else{
		AfxMessageBox("Element was not found!", MB_OK);
	}
}

void COLEAppView::OnFreeView() {
	// TODO: Add your command handler code here
	
}

void COLEAppView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
	COLEAppDoc* pDoc = GetDocument();  // Get the document pointer

	if (nChar == VK_RIGHT){
		Hash<stringKey, CElement*>::iterator& it = pDoc->getHashIterator();
		Hash<stringKey, CElement*>::iterator end = pDoc->getHashEnd();

		try{
			it++;
			m_pSelected = (*it).second;
			m_kSelected = (*it).first.getKey();
			pDoc->UpdateAllViews(0);
		}catch(Hash<stringKey, CElement*>::HashException e){
			AfxMessageBox(string("Hash exception thrown: " + e.what()).c_str(), MB_OK);
			it--;
		}
	}

	else if (nChar == VK_LEFT){
		Hash<stringKey, CElement*>::iterator& it = pDoc->getHashIterator();
		Hash<stringKey, CElement*>::iterator begin = pDoc->getHashStart();

		try{
			it--;
			m_pSelected = (*it).second;
			m_kSelected = (*it).first.getKey();
			pDoc->UpdateAllViews(0);
		}catch(Hash<stringKey, CElement*>::HashException e){
			AfxMessageBox(string("Hash exception thrown: " + e.what()).c_str(), MB_OK);
			it++;
		}
	}

	else if (nChar == VK_DELETE){
		if (m_pSelected){
			string key = m_kSelected;
			if (AfxMessageBox("Are you sure you want to delete this element?", MB_YESNO) == IDYES){
				deleteElement(key);
			}
		}
	}

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void COLEAppView::OnDeleteByKey() 
{
	string key = "";
	if (keyInputDialog.DoModal()==IDOK){
		if (keyInputDialog.m_textBox.IsEmpty())
			AfxMessageBox("Text should be at least 1 character long");
		else{
			key = keyInputDialog.m_textBox;
			keyInputDialog.m_textBox = "";
		}
	}

	if (key == "")
		return;

	deleteElement(key);
}
Соседние файлы в папке OLEApp