// CClassifierTreeView.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "ClassifierTreeView.h"
#include "ClassifierTableItemsView.h"
#include "SelectClassifierItemDlg.h"
#include "PictureView.h"
#include "dictionary.h"

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

/////////////////////////////////////////////////////////////////////////////
// CClassifierTreeView
CString CClassifierTreeView::m_LastClassifierElement=_T("");

IMPLEMENT_DYNCREATE(CClassifierTreeView, CaplTreeView)

CaplStrStrMap CClassifierTreeView::st_mapLastLevels;

CClassifierTreeView::CClassifierTreeView()
{
	m_api = NULL;
	m_pTableView = NULL;
	m_pPictureView = NULL;
	m_pClassifDlg = NULL;
}

CClassifierTreeView::~CClassifierTreeView()
{
	while(m_ItemsArray.GetSize()>0)
		delete m_ItemsArray[0];
}


BEGIN_MESSAGE_MAP(CClassifierTreeView, CaplTreeView)
	//{{AFX_MSG_MAP(CClassifierTreeView)
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnItemSelChange)
	ON_UPDATE_COMMAND_UI(ID_ADD_CLASSIFIER_SYSTEM, OnUpdateAddClassifierSystem)
	ON_COMMAND(ID_ADD_CLASSIFIER_SYSTEM, OnAddClassifierSystem)
	ON_COMMAND(ID_ADD_CLASSIFIER_ELEMENT, OnAddClassifierLevel)
	ON_UPDATE_COMMAND_UI(ID_ADD_CLASSIFIER_ELEMENT, OnUpdateAddClassifierLevel)
	ON_COMMAND(ID_DB_CONNECT, OnDbConnect)
	ON_COMMAND(ID_DELETE_ELEMENT, OnDeleteElement)
	ON_UPDATE_COMMAND_UI(ID_DELETE_ELEMENT, OnUpdateDeleteElement)
	ON_COMMAND(ID_EDIT_ELEMENT, OnEditElement)
	ON_UPDATE_COMMAND_UI(ID_EDIT_ELEMENT, OnUpdateEditElement)
	ON_COMMAND(ID_REFRESH, OnRefresh)
	ON_WM_LBUTTONDBLCLK()
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONDOWN()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClassifierTree drawing

void CClassifierTreeView::OnDraw(CDC* pDC)
{
}

/////////////////////////////////////////////////////////////////////////////
// CClassifierTreeView diagnostics

#ifdef _DEBUG
void CClassifierTreeView::AssertValid() const
{
	CaplTreeView::AssertValid();
}

void CClassifierTreeView::Dump(CDumpContext& dc) const
{
	CaplTreeView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CClassifierTreeView message handlers

void CClassifierTreeView::OnInitialUpdate() 
{
	CaplTreeView::OnInitialUpdate();

	if(m_api==NULL) return;

	GetTreeCtrl().SetImageList(aplGetInstImageList(), TVSIL_NORMAL);
	long lStyles=::GetWindowLong(GetTreeCtrl().m_hWnd,GWL_STYLE);
	lStyles|=LVS_SINGLESEL|LVS_SHOWSELALWAYS;
	lStyles^=TVS_EDITLABELS;
	::SetWindowLong(GetTreeCtrl().m_hWnd,GWL_STYLE,lStyles);

	LoadData();

	if(m_pTableView)
	{
		if(m_pTableView->m_Mode&APL_CLASSIFIER_EDITOR || m_pTableView->m_Mode&APL_CLASSIFIER_EXE_EDITOR)
		{
			m_OleDropTarget.Revoke();
			m_OleDropTarget.Register(this);
		}
	}
}

void CClassifierTreeView::LoadData()
{
	if(!m_api->m_data.IsDictLoad()) return;

	SetRedraw(FALSE);

	CClassifierTableItemsView* pView = m_pTableView;
	m_pTableView = NULL;

	while(m_ItemsArray.GetSize()>0)
		delete m_ItemsArray[0];
	
	if(!m_api->m_bLoadedOrgstruct) m_api->m_appr_mgr.LoadOrgStruct();
	m_api->m_form_mgr.LoadData();
	m_api->m_charact_mgr.LoadDictionary();

	if(m_BaseSystems.Size==0)
	{
		m_api->m_classifier_mgr.LoadSubClassifierSystems(NULL, m_BaseSystems);
	}
	m_api->m_classifier_mgr.LoadExtentInfo(m_BaseSystems);

	int i;

	CClassifierTreeItem *Item=NULL;
	for(i=0; i<m_BaseSystems.GetSize(); i++)
	{
		if(m_BaseSystems[i]==NULL) continue;
		if(m_BaseSystems[i]->GetType()==NULL) continue;
		if(m_BaseSystems[i]->GetAccessmode()>aplRO) continue;

		Item = new CClassifierTreeItem(m_api, &m_ItemsArray, this);
		if(!Item->Create(m_BaseSystems[i]))
			delete Item;
		if(m_BaseSystems.GetSize()==1)
			GetTreeCtrl().Expand(Item->m_item, TVE_EXPAND);
	}

	m_pTableView = pView;
	
	CClassifierTreeItem::Sort(&GetTreeCtrl());
	
	RestoreSelectedClassifierItem();
	
	SetRedraw(TRUE);
}

void CClassifierTreeView::OnItemexpanding(NMHDR* pNMHDR, LRESULT *pResult)
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	HTREEITEM cur_item=pNMTreeView->itemNew.hItem;
	if(cur_item==0) return;
	CClassifierTreeItem* item = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(cur_item);
	if(item)
		item->Expand(pNMTreeView->action);
	
	*pResult = 0;
}

void CClassifierTreeView::OnItemSelChange(NMHDR* pNMHDR, LRESULT* pResult)
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	HTREEITEM cur_item=pNMTreeView->itemNew.hItem;
	if(!m_api->m_data.IsDictLoad()) return;
	if(cur_item==0) return;
	CClassifierTreeItem* item = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(cur_item);
	if(item==0) return;
	if(item->m_inst==NULL) return;
	Update(item->m_inst);
}

void CClassifierTreeView::OnUpdateAddClassifierSystem(CCmdUI* pCmdUI) 
{
	if(m_api==NULL)
	{
		pCmdUI->Enable(FALSE);
		return;
	}
	else if(!m_api->m_data.IsDictLoad())
	{
		pCmdUI->Enable(FALSE);
		return;
	}

	HTREEITEM item = GetTreeCtrl().GetSelectedItem();
	CaplInstance* parent = NULL;
	CClassifierTreeItem* ParentTreeItem = NULL;
	if(item!=NULL)
	{
		ParentTreeItem = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(item);
		if(ParentTreeItem->m_inst!=0)
		{
			if(ParentTreeItem->m_inst->GetType()==0) pCmdUI->Enable(TRUE);
			else
			{
				if(!m_api->m_data.IsKindOf(ParentTreeItem->m_inst, m_api->m_classifier_mgr.e_apl_classifier_system))
					pCmdUI->Enable(FALSE);
				else
					pCmdUI->Enable(TRUE);
			}
		}
	}
	else
		pCmdUI->Enable();
}

void CClassifierTreeView::OnAddClassifierSystem() 
{
	if(m_api==NULL || !m_api->m_data.IsConnected()) return;
	HTREEITEM item = GetTreeCtrl().GetSelectedItem();
	CaplInstance* parent = NULL;
	CClassifierTreeItem* ParentTreeItem = NULL;
	if(item!=NULL)
	{
		ParentTreeItem = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(item);
		if(ParentTreeItem)
		{
			if(!m_api->m_data.IsKindOf(ParentTreeItem->m_inst, m_api->m_classifier_mgr.e_apl_classifier_system))
			{
				AfxMessageBox( APL_T("Нельзя добавлять справочник в элемент структуры!"), MB_ICONINFORMATION|MB_OK);
				return;
			}
			parent = ParentTreeItem->m_inst;
		}
	}
	if(parent)
	{
		if(parent->GetAccessmode()>aplRW)
		{
			aplErrorMessage(S::NoAccessRight(),parent);
			return;
		}
	}
	CaplInstance* nInst = m_api->m_classifier_mgr.CreateClassifierSystem(parent);
	if(nInst)
	{
		CClassifierTreeItem* TreeItem = new CClassifierTreeItem(m_api, &m_ItemsArray, this);
		if(ParentTreeItem)
		{
			if(!TreeItem->Create(nInst, ParentTreeItem->m_item))
				delete TreeItem;
		}
		else
		{
			if(!TreeItem->Create(nInst))
				delete TreeItem;
		}

	}
}

void CClassifierTreeView::OnAddClassifierLevel() 
{
	if(m_api==NULL || !m_api->m_data.IsConnected()) return;
	HTREEITEM item = GetTreeCtrl().GetSelectedItem();
	CaplInstance* parent = NULL;
	CaplInstance* system = NULL;
	CClassifierTreeItem* ParentTreeItem = NULL;
	if(item!=NULL)
	{
		ParentTreeItem = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(item);
		if(ParentTreeItem)
			parent = ParentTreeItem->m_inst;
	}
	if(m_api->m_data.IsKindOf(parent, m_api->m_classifier_mgr.e_apl_classifier_level))
		m_api->m_data.GetAttr(parent, m_api->m_classifier_mgr.a_apl_classifier_level_system, system);
	else
	{
		system = parent;
		parent = NULL;
	}
	if(system==NULL)
		return;
	if(parent)
	{
		if(parent->GetAccessmode()>aplRW)
		{
			aplErrorMessage(S::NoAccessRight(),parent);
			return;
		}
	}
	CaplInstance* nInst = m_api->m_classifier_mgr.CreateClassifierLevel(system, parent);
	if(nInst)
	{
		CClassifierTreeItem* TreeItem = new CClassifierTreeItem(m_api, &m_ItemsArray, this);
		if(ParentTreeItem)
		{
			if(!TreeItem->Create(nInst, ParentTreeItem->m_item))
				delete TreeItem;
			TreeItem->Expand(TVE_EXPAND);
			GetTreeCtrl().Expand(TreeItem->m_item, TVE_EXPAND);
		}
		else
		{
			if(!TreeItem->Create(nInst))
				delete TreeItem;
		}
		
	}
}

void CClassifierTreeView::OnUpdateAddClassifierLevel(CCmdUI* pCmdUI) 
{
	if(m_api==NULL)
	{
		pCmdUI->Enable(FALSE);
		return;
	}
	else if(!m_api->m_data.IsDictLoad())
	{
		pCmdUI->Enable(FALSE);
		return;
	}
	
	HTREEITEM item = GetTreeCtrl().GetSelectedItem();
	CaplInstance* parent = NULL;
	CClassifierTreeItem* ParentTreeItem = NULL;
	pCmdUI->Enable(item!=NULL);
}

void CClassifierTreeView::OnDbConnect() 
{
	if(m_api->m_data.IsConnected())
	{
		if(AfxMessageBox( APL_T("Соединение с БД установлено. Разорвать текущее соединение?"), MB_ICONQUESTION|MB_YESNO)!=IDYES)
			return;
	}
	while(m_ItemsArray.GetSize()>0)
		delete m_ItemsArray[0];
	
	m_BaseSystems.Clear();
	m_api->Disconnect();
	m_api->Connect();

	LoadData();
}

void CClassifierTreeView::OnDeleteElement() 
{
	if(m_api==NULL) return;
	if(!m_api->m_data.IsConnected()) return;
	
	HTREEITEM item = GetTreeCtrl().GetSelectedItem();
	CaplInstance* parent = NULL;
	CClassifierTreeItem* ParentTreeItem = NULL;
	if(item!=NULL)
	{
		ParentTreeItem = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(item);
		if(ParentTreeItem)
			parent = ParentTreeItem->m_inst;
	}
	else 
		return;

	if(AfxMessageBox( APL_T("Вы действительно желаете удалить выделенный элемент?"), MB_YESNO|MB_ICONQUESTION)!=IDYES) return;
	
	if(parent->GetAccessmode()==aplOWN)
	{
		if(m_api->m_classifier_mgr.DeleteClassifierItem(parent))
			delete ParentTreeItem;
	}
	else
		aplErrorMessage(S::NoAccessRight(),parent);
}

void CClassifierTreeView::OnUpdateDeleteElement(CCmdUI* pCmdUI) 
{
	if(m_api==NULL)
	{
		pCmdUI->Enable(FALSE);
		return;
	}
	else if(!m_api->m_data.IsDictLoad())
	{
		pCmdUI->Enable(FALSE);
		return;
	}
	
	HTREEITEM item = GetTreeCtrl().GetSelectedItem();
	CaplInstance* parent = NULL;
	CClassifierTreeItem* ParentTreeItem = NULL;
	pCmdUI->Enable(item!=NULL);
}

void CClassifierTreeView::OnEditElement() 
{
	if(m_api==NULL) return;
	if(!m_api->m_data.IsConnected()) return;
	
	HTREEITEM item = GetTreeCtrl().GetSelectedItem();
	CaplInstance* parent = NULL;
	CClassifierTreeItem* ParentTreeItem = NULL;
	if(item!=NULL)
	{
		ParentTreeItem = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(item);
		if(ParentTreeItem)
			parent = ParentTreeItem->m_inst;
	}
	else 
		return;

	m_api->m_classifier_mgr.ShowClassifierProperties(parent);
	ParentTreeItem->Refresh();
	Update(parent);
}

void CClassifierTreeView::OnUpdateEditElement(CCmdUI* pCmdUI) 
{
	if(m_api==NULL)
	{
		pCmdUI->Enable(FALSE);
		return;
	}
	else if(!m_api->m_data.IsDictLoad())
	{
		pCmdUI->Enable(FALSE);
		return;
	}
	
	HTREEITEM item = GetTreeCtrl().GetSelectedItem();
	CaplInstance* parent = NULL;
	CClassifierTreeItem* ParentTreeItem = NULL;
	pCmdUI->Enable(item!=NULL);
}

void CClassifierTreeView::OnRefresh() 
{
	if(m_pTableView)
		m_pTableView->UpdateTable(NULL);
	if(m_pPictureView)
		m_pPictureView->UpdatePicture(NULL, m_api);
	LoadData();
}

bool CClassifierTreeView::Update(CaplInstance *inst)
{
	BeginWaitCursor();
	bool bRes = true;
	if(m_pPictureView)
	{
		if(::IsWindow(m_pPictureView->m_hWnd))
		{
			if(m_pPictureView->IsKindOf(RUNTIME_CLASS(CPictureView)))
				bRes &= m_pPictureView->UpdatePicture(inst, m_api);
		}
	}
	else
		bRes = false;
	if(m_pTableView)
	{
		if(::IsWindow(m_pTableView->m_hWnd))
		{
			if(m_pTableView->IsKindOf(RUNTIME_CLASS(CClassifierTableItemsView)))
				bRes &= m_pTableView->UpdateTable(inst);
		}
	}
	else
		bRes = false;
	if(m_pClassifDlg)
		m_pClassifDlg->CheckFillFindButtons(inst);
	EndWaitCursor();
	return bRes;
}

void CClassifierTreeView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	UINT flags = 0;
	HTREEITEM ht = GetTreeCtrl().HitTest(point, &flags);
	if(ht!=0 && flags&TVHT_ONITEM)
	{
		CaplInstance* Inst = NULL;
		CClassifierTreeItem* ParentTreeItem = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(ht);
		if(ParentTreeItem)
		{
			Inst = ParentTreeItem->m_inst;
			if(Inst)
			{
				m_api->m_classifier_mgr.ShowClassifierProperties(Inst);
				ParentTreeItem->Refresh();
				Update(Inst);
			}
		}
		return;
	}
	
	CaplTreeView::OnLButtonDblClk(nFlags, point);
}

void CClassifierTreeView::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	if(!m_api->m_data.IsConnected()) return;

	HTREEITEM ht = NULL;
	if(point != CPoint(-1, -1))
	{
		ScreenToClient(&point);
		UINT flags = TVHT_ONITEM;
		ht = GetTreeCtrl().HitTest(point, &flags);
		if(ht && flags&TVHT_ONITEM)
		{
			GetTreeCtrl().SelectItem(ht);
			GetTreeCtrl().SelectDropTarget(ht);
		}
		else
			ht = NULL;
	}
	else
	{
		ht = GetTreeCtrl().GetSelectedItem();
		if(ht)
		{
			CRect rect;
			GetTreeCtrl().GetItemRect(ht, rect, TRUE);
			point = CPoint(rect.left+10, rect.bottom-2);
		}
	}
	ClientToScreen(&point);

	CaplMenu menu;
	CMenu* pPopup;
	VERIFY(menu.LoadMenu(IDR_CLASSIFIER_CONTEXT_MENU));
	menu.Install(this);
	pPopup = menu.GetSubMenu(0);
	ASSERT(pPopup);

	if(ht==NULL)
	{
		pPopup->EnableMenuItem(ID_EDIT_ELEMENT, MF_GRAYED|MF_BYCOMMAND);
		pPopup->EnableMenuItem(ID_DELETE_ELEMENT, MF_GRAYED|MF_BYCOMMAND);
	}
	else
	{
		CaplInstance* Inst = NULL;
		CClassifierTreeItem* ParentTreeItem = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(ht);
		if(ParentTreeItem)
		{
			Inst = ParentTreeItem->m_inst;
			if(Inst)
			{
				if(m_api->m_data.IsKindOf(Inst, m_api->m_classifier_mgr.e_apl_classifier_level))
					pPopup->EnableMenuItem(ID_ADD_CLASSIFIER_SYSTEM, MF_GRAYED|MF_BYCOMMAND);
				else
					pPopup->ModifyMenu(ID_ADD_CLASSIFIER_SYSTEM, MF_STRING|MF_BYCOMMAND, ID_ADD_CLASSIFIER_SYSTEM,  APL_T("Добавить вложенный справочник..."));

				if(Inst->GetAccessmode()>aplRW){
					pPopup->EnableMenuItem(ID_ADD_CLASSIFIER_SYSTEM, MF_GRAYED|MF_BYCOMMAND);
					pPopup->EnableMenuItem(ID_ADD_CLASSIFIER_ELEMENT, MF_GRAYED|MF_BYCOMMAND);
					pPopup->EnableMenuItem(ID_DELETE_ELEMENT, MF_GRAYED|MF_BYCOMMAND);
				}
			}
		}
	}
	
	BOOL cmd = pPopup->TrackPopupMenu(TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
	if(cmd)
	{
		if(cmd==ID_ADD_CLASSIFIER_SYSTEM && ht==NULL)
		{
			CaplInstance* nInst = m_api->m_classifier_mgr.CreateClassifierSystem(NULL);
			if(nInst)
			{
				CClassifierTreeItem* TreeItem = new CClassifierTreeItem(m_api, &m_ItemsArray, this);
				if(!TreeItem->Create(nInst))
					delete TreeItem;
			}
		}
		else
			SendMessage(WM_COMMAND, cmd);
	}
}

void CClassifierTreeView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	if(m_api)
	{
		ClientToScreen(&point);
		OnContextMenu(this, point);
	}
	
	CaplTreeView::OnRButtonDown(nFlags, point);
}

bool CClassifierTreeView::RestoreSelectedClassifierItem()
{
	CWinApp *app = AfxGetApp();
	bool bFound;
	CaplInstance* inst;
	HTREEITEM item;
	int ind = -1, id, i;
	CString buf, tmp,tmp1;


	if(st_sTitle!=_T("")) buf=st_mapLastLevels.Get(st_sTitle);
	//if(buf==_T(""))	buf = m_LastClassifierElement;
	if(buf==_T("")) return true;


	//Разбираем строчку и формируем дерево
	SetRedraw(FALSE);
	while(!buf.IsEmpty())
	{
		ind = buf.ReverseFind(_T(':'));
		if(ind<0) {tmp=buf; buf=_T("");}
		else
		{
			tmp=buf.Right(buf.GetLength()-ind-1);
			if(ind==0) buf=_T("");
			else
			{
				tmp1=buf.Left(ind);
				buf=tmp1;
			}
		}
		id = _atoi(tmp);
		inst = m_api->m_data.GetInstById(id);
		if(inst!=0)
		{
			//Раскручивание дерева
			bFound = false;
			for(i=0; i<m_ItemsArray.GetSize(); i++)
			{
				if(m_ItemsArray.GetAt(i)->m_inst==inst)
				{
					m_ItemsArray.GetAt(i)->Expand(TVE_EXPAND);
					item = m_ItemsArray.GetAt(i)->m_item;
					GetTreeCtrl().Expand(item, TVE_EXPAND);
					if(buf.IsEmpty())
					{
						GetTreeCtrl().EnsureVisible(item);
						GetTreeCtrl().SelectItem(item);
						if(m_pTableView)
							m_pTableView->UpdateTable(inst);
					}
					bFound = true;
					break;
				}
			}
		}
	}
	SetRedraw();

	return true;
}

void CClassifierTreeView::OnDestroy() 
{
	//m_LastClassifierElement=_T("");
	
	if(m_api==NULL) {CaplTreeView::OnDestroy();return;}
	if(!m_api->m_data.IsDictLoad()) {CaplTreeView::OnDestroy();return;}

	HTREEITEM item = GetTreeCtrl().GetSelectedItem();
	if(item==NULL) return;
	CClassifierTreeItem* pItem = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(item);

	if(pItem==NULL) return;

	CString buf, res;
	CaplInstance *parent = pItem->m_inst;
	while(1)
	{
		if(0==parent) break;
		if(res!=_T("")) res+=_T(':');
		buf.Format(_T("%d"), parent->GetId());
		res+=buf;
		if(m_api->m_data.IsKindOf(parent,m_api->m_classifier_mgr.e_apl_classifier_level))
		{
			CaplInstance *par1;
			m_api->m_data.GetAttr(parent, m_api->m_classifier_mgr.a_apl_classifier_level_parent, par1);
			if(0!=par1) parent=par1;
			else m_api->m_data.GetAttr(parent, m_api->m_classifier_mgr.a_apl_classifier_level_system, parent);
		}
		else if(m_api->m_data.IsKindOf(parent,m_api->m_classifier_mgr.e_apl_classifier_system))
		{
			m_api->m_data.GetAttr(parent, m_api->m_classifier_mgr.a_apl_classifier_system_parent, parent);
		}
		else break;
	}
	m_LastClassifierElement = res;

	if(st_sTitle!=_T("")) st_mapLastLevels.Add(st_sTitle,res);

	CaplTreeView::OnDestroy();
}

BOOL CClassifierTreeView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) 
{
	if(m_pTableView==NULL) return FALSE;
	if(!(m_pTableView->m_Mode&APL_CLASSIFIER_EDITOR || m_pTableView->m_Mode&APL_CLASSIFIER_EXE_EDITOR)) return FALSE;

	HTREEITEM ht=GetTreeCtrl().HitTest(point);
	if(ht)
	{
		CClassifierTreeItem* pItem = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(ht);
		if(pItem)
		{
			GetTreeCtrl().SelectItem(ht);
			GetTreeCtrl().SelectDropTarget(ht);
			Update(pItem->m_inst);
			m_pTableView->Paste(pDataObject);
		}
	}
	return FALSE;
}

DROPEFFECT CClassifierTreeView::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) 
{
	if(m_pTableView==NULL) return DROPEFFECT_NONE;
	if(!(m_pTableView->m_Mode&APL_CLASSIFIER_EDITOR || m_pTableView->m_Mode&APL_CLASSIFIER_EXE_EDITOR)) return DROPEFFECT_NONE;
	
	return DROPEFFECT_LINK|DROPEFFECT_COPY;
}

void CClassifierTreeView::OnDragLeave() 
{
	if(m_pTableView==NULL) return;
	if(!(m_pTableView->m_Mode&APL_CLASSIFIER_EDITOR || m_pTableView->m_Mode&APL_CLASSIFIER_EXE_EDITOR)) return;
	
	CaplTreeView::OnDragLeave();
}

DROPEFFECT CClassifierTreeView::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) 
{
	if(m_pTableView==NULL) return DROPEFFECT_NONE;
	if(!(m_pTableView->m_Mode&APL_CLASSIFIER_EDITOR || m_pTableView->m_Mode&APL_CLASSIFIER_EXE_EDITOR)) return DROPEFFECT_NONE;

	// Сделать активным
	CMDIChildWnd *act_frm=((CMDIFrameWnd*)AfxGetMainWnd())->MDIGetActive();
	CWnd *my_frm=this->GetParentFrame();
	if(my_frm==NULL) return DROPEFFECT_NONE;
	my_frm = my_frm->GetParentFrame();
	if(my_frm!=act_frm) ((CMDIFrameWnd*)AfxGetMainWnd())->MDIActivate(my_frm);
	
	HTREEITEM ht = GetTreeCtrl().HitTest(point);
	if(ht!=0)GetTreeCtrl().SelectDropTarget(ht);

	return DROPEFFECT_LINK|DROPEFFECT_COPY;
}

CaplInstance *CClassifierTreeView::GetSelectedInstance()
{
	HTREEITEM hitem = GetTreeCtrl().GetSelectedItem();
	if(0==hitem) return 0;
	CClassifierTreeItem* item = (CClassifierTreeItem*)GetTreeCtrl().GetItemData(hitem);
	if(item==0) return 0;
	return item->m_inst;
}
