// CTableContentElement
// TableContentElement.cpp

#include "StdAfx.h"
#include "reportdict.h"
#include "resource.h"

CTableContentTitle::CTableContentTitle(CaplReportMgr* Mgr)
{
	ASSERT(Mgr);
	m_inst = NULL;
	m_Levels.RemoveAll();
	m_ReportMgr = Mgr;
}

CTableContentTitle::~CTableContentTitle()
{
	for(int i=0; i<m_Levels.GetSize();i++)
		delete m_Levels[i];
	m_Levels.RemoveAll();
}

void CTableContentTitle::Update(bool bSet /* = true */)
{
	if(bSet)
	{
		if(m_inst==0)
			m_inst = m_ReportMgr->m_data->CreateInstance(m_ReportMgr->e_apl_table_content_title);
		aplExtent ext;
		for(int i=0; i<m_Levels.GetSize();i++)
		{
			m_Levels[i]->Update(bSet);
			ext.Add(m_Levels[i]->m_inst);
		}
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_tct_levels, ext);
	}
	else
	{
		ASSERT(m_inst);
		aplExtent ext;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tct_levels, ext);
		for(int i=0; i<ext.GetSize();i++)
		{
			CTableContentTitleLevel* level = new CTableContentTitleLevel(m_ReportMgr);
			level->m_inst = ext[i];
			level->Update(bSet);
			m_Levels.Add(level);
		}
	}
}

CTableContentTitleLevel::CTableContentTitleLevel(CaplReportMgr* Mgr)
{
	ASSERT(Mgr);
	m_ReportMgr = Mgr;
	m_inst = NULL;
	m_ParaDelta = 5;//5 мм
	m_Font.lfOutPrecision = OUT_DEFAULT_PRECIS;
	m_Font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	m_Font.lfQuality = DEFAULT_QUALITY;
	m_Font.lfPitchAndFamily = DEFAULT_PITCH;
	m_Font.lfWidth = 0;
	m_Font.lfOrientation = 0;
	m_Font.lfStrikeOut = 0;
	m_Font.lfItalic = 255;
	m_Font.lfUnderline = 0;
	m_Font.lfEscapement = 0;
	m_Font.lfHeight = 120;
	m_Font.lfWeight = FW_NORMAL;
	m_Font.lfCharSet = RUSSIAN_CHARSET;
	_strcpy(m_Font.lfFaceName,_T("Arial"));
}

CTableContentTitleLevel::~CTableContentTitleLevel()
{
}

void CTableContentTitleLevel::Update(bool bSet /* = true */)
{
	if(bSet)
	{
		if(m_inst==0)
			m_inst = m_ReportMgr->m_data->CreateInstance(m_ReportMgr->e_apl_table_content_title_level);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_tctl_paradelta, m_ParaDelta);
		CaplInstance* font;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tctl_font, font);
		if(font==NULL)
			font = m_ReportMgr->m_data->CreateInstance(m_ReportMgr->e_font);
		m_ReportMgr->SetFontValue(font, m_Font);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_tctl_font, font);
	}
	else
	{
		ASSERT(m_inst);
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tctl_paradelta, m_ParaDelta);
		CaplInstance* font;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tctl_font, font);
		m_ReportMgr->GetFontValue(font, m_Font);
	}
}

CTableContentElement::CTableContentElement(CaplReportMgr* dict):CReportElement(dict, E_TABLE_CONTENT_TITLE)
{
	m_TableContentTitle = new CTableContentTitle(dict);
	m_PageWidth = 30;
	m_TextWidth = 100;
	m_iHeight = 60;

	m_lfTitleFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
	m_lfTitleFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	m_lfTitleFont.lfQuality = DEFAULT_QUALITY;
	m_lfTitleFont.lfPitchAndFamily = DEFAULT_PITCH;
	m_lfTitleFont.lfWidth = 0;
	m_lfTitleFont.lfOrientation = 0;
	m_lfTitleFont.lfStrikeOut = 0;
	m_lfTitleFont.lfItalic = 255;
	m_lfTitleFont.lfUnderline = 0;
	m_lfTitleFont.lfEscapement = 0;
	m_lfTitleFont.lfHeight = 160;
	m_lfTitleFont.lfWeight = FW_NORMAL;
	m_lfTitleFont.lfCharSet = RUSSIAN_CHARSET;
	_strcpy(m_lfTitleFont.lfFaceName,_T("Arial"));

	m_sTitle = APL_T("Содержание");
	
	m_name = APL_T("Содержание");

	m_CloneSheet = NULL;
}

CTableContentElement::~CTableContentElement()
{
	delete m_TableContentTitle;
}

BOOL CTableContentElement::Draw(CDC* pDC, double scale, int draw_mode, UINT flag /* = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT */)
{
	CReportElement::Draw(pDC, scale, draw_mode, flag);
	if(draw_mode==0)//Значит это режим редактирования
	{
		CRect rect;
		CFont font, *old;
		GetRect(rect, scale, pDC->IsPrinting());

		CPen m_obj_pen, *old_pen;
		m_obj_pen.CreatePen(PS_SOLID | PS_GEOMETRIC, (int)((double)m_line_width*scale), OBJ_COLOR);
		old_pen = pDC->SelectObject(&m_obj_pen);

		DrawRect(pDC, rect);
		if(m_select && !pDC->IsPrinting() && flag&DRAW_SEL) 
			DrawSelPoints(pDC, scale); // отрисовка рамки выделения

		font.CreatePointFontIndirect(&m_lfTitleFont, pDC);
		old = pDC->SelectObject(&font);
		DrawText(pDC, rect, m_sTitle, scale);
		pDC->SelectObject(old_pen);
		pDC->SelectObject(old);
		font.DeleteObject();
	}
	return TRUE;
}

int CTableContentElement::GetMemSize()
{
	return CReportElement::GetMemSize();
}

void CTableContentElement::CopyToMem(BYTE* pByte, int &ind)
{
	m_type = E_RECT;
	CReportElement::CopyToMem(pByte, ind);
	m_type = E_TABLE_CONTENT_TITLE;
}

bool CTableContentElement::LoadDataFromMem(BYTE *pByte, int &ind)
{
	return CReportElement::LoadDataFromMem(pByte, ind);
}

CReportElement* CTableContentElement::CreateClon()
{
	CTableContentElement *tce(NULL);
	try
	{
		tce = new CTableContentElement(m_ReportMgr);
		tce->m_size = m_size;
		tce->m_org_pt = m_org_pt;
		tce->m_name = m_name;
		tce->m_type = m_type;
		tce->m_fixed = m_fixed;
		tce->m_line_width = m_line_width;
		tce->m_color = m_color;
		for(int i=0; i<m_TableContentTitle->m_Levels.GetSize(); i++)
		{
			CTableContentTitleLevel* level = new CTableContentTitleLevel(m_ReportMgr);
			level->m_Font = m_TableContentTitle->m_Levels[i]->m_Font;
			level->m_ParaDelta = m_TableContentTitle->m_Levels[i]->m_ParaDelta;
			tce->m_TableContentTitle->m_Levels.Add(level);
		}
		tce->m_sTitle = m_sTitle;
		tce->m_lfTitleFont = m_lfTitleFont;
	}
	catch (...)
	{
		if(tce)
			delete tce;
	}
	return tce;
}

void CTableContentElement::Update(bool set /* = true */)
{
	if(set)//Запись (создание)
	{
		if(m_inst==0)
			m_inst = m_ReportMgr->m_data->CreateInstance(m_ReportMgr->e_apl_table_content_element);
		m_TableContentTitle->Update(set);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_tce_tct, m_TableContentTitle->m_inst);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_tce_pWidth, m_PageWidth);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_tce_title, m_sTitle);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_tce_pTWidth, m_TextWidth);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_tce_height, m_iHeight);

		CaplInstance* font = NULL;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tce_font, font);
		if(font==NULL)
			font = m_ReportMgr->m_data->CreateInstance(m_ReportMgr->e_font);
		m_ReportMgr->SetFontValue(font, m_lfTitleFont);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_tce_font, font);
		
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_textcolor, (int)m_color);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_backgroundcolor, (int)m_background_color);

		m_ReportMgr->PutPoint(m_inst,m_ReportMgr->a_elem_org_pt,m_org_pt);
		m_ReportMgr->PutPoint(m_inst,m_ReportMgr->a_elem_size,m_size);
	}
	else
	{
		delete m_TableContentTitle;
		m_TableContentTitle = new CTableContentTitle(m_ReportMgr);			
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tce_tct, m_TableContentTitle->m_inst);
		m_TableContentTitle->Update(set);
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tce_pWidth, m_PageWidth);
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tce_title, m_sTitle);
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tce_pTWidth, m_TextWidth);
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tce_height, m_iHeight);

		CaplInstance* font = NULL;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tce_font, font);
		m_lfTitleFont = m_ReportMgr->GetFontValue(font);

		int tmp_color;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_textcolor, tmp_color);
		m_color = (COLORREF)tmp_color;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_backgroundcolor, tmp_color);
		m_background_color= (COLORREF)tmp_color;

		m_ReportMgr->GetPoint(m_inst,m_ReportMgr->a_elem_org_pt,m_org_pt);
		m_ReportMgr->GetPoint(m_inst,m_ReportMgr->a_elem_size,m_size);
	}
}

CPageReferenceElement::CPageReferenceElement(CaplReportMgr* dict):CRectReportElement(dict)
{
	m_type = E_REFERENCE_ELEMENT;
	m_Sheet = NULL;

	m_name = APL_T("Ссылка на страницу");
}

CPageReferenceElement::~CPageReferenceElement()
{
}

void CPageReferenceElement::Update(bool set/* =true */)
{
	if(set)
	{
		if(m_inst==NULL)
			m_inst = m_ReportMgr->m_data->CreateInstance(m_ReportMgr->e_apl_reference_element);
		CRectReportElement::Update(set);
		CaplInstance* inst = NULL;
		if(m_Sheet)
			inst = m_Sheet->m_inst;
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_apl_ref_elem_element, inst);
	}
	else
	{
		CaplInstance* inst = NULL;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_ref_elem_element, inst);
		if(inst)
		{
			int cnt = m_ReportMgr->m_sheets.GetSize();
			for(int i=0; i<cnt; i++)
				if(m_ReportMgr->m_sheets[i]->m_inst==inst)
				{
					m_Sheet = m_ReportMgr->m_sheets[i];
					break;
				}
		}
		CRectReportElement::Update(set);
		if(m_Sheet==NULL)
			m_ReportMgr->m_UpdateReference.Add(this);
	}
}

BOOL CPageReferenceElement::Draw(CDC* pDC, double scale, int draw_mode, UINT flag /* = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT */)
{
	if(m_Sheet)
	{
		if(draw_mode>0)
		{
			CString buf = m_Sheet->m_name;
			buf.TrimLeft(APL_T("Лист"));
			m_value.SetText(APL_T("Лист ") + buf);
		}
		else
			m_value.SetText(m_Sheet->m_name);
	}
	CRectReportElement::Draw(pDC, scale, draw_mode, flag);
	return TRUE;
}

CReportElement* CPageReferenceElement::CreateClon()
{
	CPageReferenceElement* elem = new CPageReferenceElement(m_ReportMgr);
	elem->m_Sheet = m_Sheet;
	elem->m_org_pt = m_org_pt;
	elem->m_name = m_name;
	elem->m_size = m_size;
	elem->m_type = m_type;
	elem->m_fixed = m_fixed;
	elem->m_line_width = m_line_width;
	elem->m_value = m_value;
	elem->m_color = m_color;
	return elem;
}


bool CTableContentElement::GenContent()
{
	m_CloneSheet = m_ReportMgr->CloneSheet(m_owner_sheet, -2);
	int y = 0;
	if(!m_sTitle.IsEmpty())
	{
		CRect rect;
		GetRect(rect, 1, 1);
		//проверка поместиться ли это в доступную область.
		CDC* pDC = AfxGetMainWnd()->GetDC();
		int mm = pDC->SetMapMode(MM_LOMETRIC);
		int width = rect.Width()-60;
		CStringArray strs;
		int cnt = CTextValue::BreakString(&strs, int(width)-m_line_width, pDC, m_sTitle);

		int texth = pDC->GetTextExtent(m_sTitle).cy;
		texth = int(double(texth)*2);
		for(int i=0; i<cnt; i++)
		{
			CRectReportElement* nElem = new CRectReportElement(m_ReportMgr);
			nElem->m_org_pt.x = m_org_pt.x;
			nElem->m_org_pt.y = m_org_pt.y;
			nElem->m_size.cx = m_size.cx;
			nElem->m_size.cy = -texth;
			nElem->m_line_width = 0;
			nElem->m_value.m_align = AT_CENTER|AT_VCENTER;
			nElem->m_value.SetText(strs[i]);
			nElem->m_value.m_font = m_lfTitleFont;
			m_owner_sheet->Add(nElem);
			y+=texth;
		}
		pDC->SetMapMode(mm);
		AfxGetMainWnd()->ReleaseDC(pDC);
	}
	CTableContentElement* elem = this;
	int cnt = m_ReportMgr->m_TableContents.GetSize();
	for(int i=0; i<cnt; i++)
	{
		if(!AddRow(m_ReportMgr->m_TableContents[i], &elem, y, 0, 0))
		{
			delete m_CloneSheet;
			return false;
		}
	}
	if(cnt==0)
	{
		delete m_CloneSheet;
		return false;
	}
	CTableContent* TableContent;
	if(!m_sTitle.IsEmpty())
	{
		TableContent = new CTableContent(m_ReportMgr);
		TableContent->m_Title = m_sTitle;
		m_ReportMgr->m_TableContents.Add(TableContent);
		TableContent->AddSheet(m_owner_sheet);
	}
	
	delete m_CloneSheet;
	return true;
}

bool CTableContentElement::AddRow(CTableContent *tc, CTableContentElement **elem, int &y, int Paragraph, int level)
{
	//[Колесников А.С.] 27.01.2011
	//вместо цикла вставил условие - при генерации отчета в элементе содержание выводились все уровни, а не те, которые были определены
	if (level >= m_TableContentTitle->m_Levels.GetSize())
		return true;
//  	while(level >= m_TableContentTitle->m_Levels.GetSize())
//  		m_TableContentTitle->AddLevel();
	
	
	CTableContentTitleLevel* pLev = m_TableContentTitle->m_Levels[level];
	CRect rect;
	(*elem)->GetRect(rect, 1, 1);
	rect.NormalizeRect();
	//проверка поместиться ли это в доступную область.
	CDC* pDC = AfxGetMainWnd()->GetDC();
	int mm = pDC->SetMapMode(MM_LOMETRIC);
	int width = (int) m_TextWidth;
	if(width) width-=60;
	else width = rect.Width()-Paragraph-int(pLev->m_ParaDelta*10)-60;
	
	CStringArray strs;
//	int cnt = CTextValue::BreakString(&strs, int(width)-m_line_width, pDC, tc->m_Title);
	int cnt = CTextValue::BreakString(&strs, int(width), pDC, tc->m_Title);
	int texth = m_iHeight;
	int h = (cnt + 1) * m_iHeight;
	if (!m_iHeight)
	{
		texth = pDC->GetTextExtent(tc->m_Title).cy;
		texth = int(double(texth) * 2);
		h = int(2 * double(cnt) * double(texth));
	}
	else
	{

	}

	pDC->SetMapMode(mm);
	AfxGetMainWnd()->ReleaseDC(pDC);


	CReportSheet* CurSheet = (*elem)->m_owner_sheet;
	if(rect.Height()<y+h)
	{
		//Значит не помещается и нужно менять страницу.
		int ind = m_ReportMgr->FindSheetInd((*elem)->m_owner_sheet);
		CReportSheet* nSheet = m_ReportMgr->CloneSheet(m_CloneSheet, ind+1);
		if(nSheet==NULL)
		{
			AfxMessageBox(APL_T("Ошибка при дублировании страницы!"));
			return false;
		}
		nSheet->LoadElementsFromFile();
		*elem = NULL;
		for(int i=0; i<nSheet->m_els.GetSize(); i++)
		{
			if(nSheet->m_els[i]->GetType()==E_TABLE_CONTENT_TITLE)
				*elem = (CTableContentElement*)nSheet->m_els[i];
		}
		if(*elem==NULL)
		{
			AfxMessageBox(APL_T("Ошибка при дублировании страницы!")); 
			return false;
		}
		y = 0;
		(*elem)->GetRect(rect, 1, 1); 
		rect.NormalizeRect();
		if(rect.Height()<y+h)
		{
			AfxMessageBox(APL_T("Не корректный шаблон. В элемент содержания не помещается ни одна строка."));
			return false;
		}
		CurSheet = nSheet;
	}
	//Непосредственно добавление строки.
	Paragraph+=int(pLev->m_ParaDelta*10);
	if(Paragraph>0 && !tc->m_Title.IsEmpty())
	{
		CRectReportElement *nElem;
		for(int i=0; i<cnt; i++)
		{
			nElem = new CRectReportElement(m_ReportMgr);
			nElem->m_org_pt.x = (*elem)->m_org_pt.x-10;
			nElem->m_org_pt.y = rect.bottom-y-texth;
			nElem->m_size.cx = Paragraph-15;
			nElem->m_size.cy = texth;
			nElem->m_line_width = 0;
			nElem->m_value.m_align = AT_LEFT| AT_BOTTOM;
			CurSheet->Add(nElem);
			nElem = new CRectReportElement(m_ReportMgr);
			nElem->m_org_pt.x = (*elem)->m_org_pt.x+Paragraph-10;
			nElem->m_org_pt.y = rect.bottom-y-texth;
			nElem->m_size.cx = rect.Width()-Paragraph-int(m_PageWidth*10);
			nElem->m_size.cy = texth;
			nElem->m_value.SetText(strs[i]);
			nElem->m_line_width = 0;
			nElem->m_value.m_font = pLev->m_Font;
			nElem->m_value.m_align = AT_LEFT| AT_BOTTOM;
			CurSheet->Add(nElem);
			CPageReferenceElement *nPRElem = new CPageReferenceElement(m_ReportMgr);
			nPRElem->m_org_pt.x = (*elem)->m_org_pt.x + (*elem)->m_size.cx - int(m_PageWidth*10)-nElem->m_size.cx-10;
			nPRElem->m_org_pt.y = rect.bottom-y-texth;
			nPRElem->m_size.cx = int(m_PageWidth*10)-50+nElem->m_size.cx;
			nPRElem->m_size.cy = texth;
			nPRElem->m_line_width = 0;
			nPRElem->m_value.m_font = pLev->m_Font;
			nPRElem->m_value.m_align = AT_RIGHT| AT_BOTTOM;
			if(i==0 && tc->m_sheets.GetSize()>0)
				nPRElem->m_Sheet = tc->m_sheets[0];
			CurSheet->Add(nPRElem);
			y+=texth;
			nElem->m_size = nPRElem->m_size;
			nElem->m_org_pt = nPRElem->m_org_pt;
		}
	}
	for(int i=0; i<tc->m_Childs.GetSize();i++)
	{
		if(!AddRow(tc->m_Childs[i], elem, y, Paragraph, level+1))
			return false;
	}
	return true;
}

void CTableContentElement::Delete()
{
	if(m_inst==NULL) return;
	CaplInstance* font;
	m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_apl_tce_font, font);
	if(font)
		m_ReportMgr->m_data->DeleteInstance(font);
	CaplInstance* inst;
	//Удаление точек
	m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_org_pt, inst);
	if(inst)
		m_ReportMgr->m_data->DeleteInstance(inst);
	m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_size, inst);
	if(inst)
		m_ReportMgr->m_data->DeleteInstance(inst);
}


void CTableContentTitle::DelLevel(int Level)
{
	if(Level<0 || Level>=m_Levels.GetSize()) return;
	delete m_Levels[Level];
	m_Levels.RemoveAt(Level);
}

void CTableContentTitle::DelLevel(CTableContentTitleLevel *level)
{
	int cnt = m_Levels.GetSize();
	for(int i=0; i<cnt; i++)
	{
		if(level==m_Levels[i])
		{
			delete level;
			m_Levels.RemoveAt(i);
			return;
		}
	}
}

void CTableContentTitle::Delete()
{
	CaplInstance* font;
	for(int i=0; i<m_Levels.GetSize(); i++)
	{
		font = NULL;
		if(!m_Levels[i]->m_inst) continue;
		m_ReportMgr->m_data->GetAttr(m_Levels[i]->m_inst, m_ReportMgr->a_apl_tctl_font, font);
		if(font)
			m_ReportMgr->m_data->DeleteInstance(font);
		m_ReportMgr->m_data->DeleteInstance(m_Levels[i]->m_inst);
	}
	m_ReportMgr->m_data->DeleteInstance(m_inst);
}

CTableContentTitleLevel* CTableContentTitle::AddLevel()
{
	CTableContentTitleLevel* level = new CTableContentTitleLevel(m_ReportMgr);
	m_Levels.Add(level);
	return level;
}

void CTableContentElement::DrawText(CDC *pDC, CRect r, CString str, double scale)
{
	if(pDC==NULL) return;
	int bkMode = pDC->SetBkMode(TRANSPARENT);
	CSize sz;
	CSize size;
	r.NormalizeRect();

	CRect TmpRect = r;
	TmpRect.DeflateRect(CSize((int)(-9.0*scale),(int)(-9.0*scale)));
	
	str.Replace(_T("\n"), _T(""));
	str.Replace(_T("\r"), _T(""));
	
	CRgn rgn1, rgn2;
	HRGN OldRgn = CreateRectRgn(0,0,1,1);
	int res = GetClipRgn(pDC->m_hDC, OldRgn);
	ASSERT(res>-1);
	CRect RgnRect = TmpRect;
	ConvertLOMETRICtoTEXT(pDC, RgnRect);
	rgn1.CreateRectRgnIndirect(RgnRect);
	if(res==1)
	{
		rgn2.Attach(OldRgn);
		rgn1.CombineRgn(&rgn1, &rgn2, RGN_AND);
		rgn2.Detach();
	}
	int Result = pDC->SelectClipRgn(&rgn1);
	pDC->SetMapMode(MM_LOMETRIC);
	CPoint pt = CPoint(r.left,r.bottom);//Спецефика LOMETRIC;

	size = pDC->GetTextExtent(str);
	pt.y = (r.bottom + r.top)/2+size.cy/2;
	
	int cx, cy;
	cy = size.cy;
	cx = size.cx;

	pt.x = r.Width()/2-cx/2+r.left;

	pDC->TextOut(pt.x, pt.y, str);

	rgn1.DeleteObject();
	rgn1.Attach(OldRgn);
	if(res==1)
		pDC->SelectClipRgn(&rgn1);
	else
		pDC->SelectClipRgn(NULL);
	rgn1.DeleteObject();
	pDC->SetBkMode(bkMode);
}

int CTableContentElement::ShowContextMenu(CPoint pt, CWnd * wnd, int mode)
{
	if(wnd == NULL) return false;
	
	HINSTANCE hInst = AfxGetResourceHandle();
	AfxSetResourceHandle(dllInst);
	wnd->ClientToScreen(&pt);
	
	CMenu menu;
	CMenu *pPopup;
	menu.LoadMenu(IDR_CONTEXT_MENU);
	pPopup = menu.GetSubMenu(5);
	
	if(m_fixed && mode==0)
		pPopup->ModifyMenu(ID_FIXED,MF_BYCOMMAND|MF_STRING, ID_FIXED,APL_T("Раcфиксировать"));
	
	BOOL res = pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD,pt.x, pt.y, wnd);
	
	AfxSetResourceHandle(hInst);
	if(res == 0) return false;
	
	switch(res)
	{
	case ID_FIXED :
		if(m_fixed>0) m_fixed = 0;
		else m_fixed = 1;
		break;
	case ID_ALIGN :
		Align();
		break;
	default : 
		return ExecuteCmd(res);
	}
	return 0;
}
