text: //////////////////////////////////////////////////////////////////////////
  //
  // pgAdmin III - PostgreSQL Tools
  //
  // Portions Copyright (C) 1998 - 2011, Julian Smart
  // Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team
  // This software is released under the PostgreSQL Licence
  //
  // divided.cpp - wxDividedShape class
  //
  //////////////////////////////////////////////////////////////////////////
  
  #include "pgAdmin3.h"
  
  #include "ogl/ogl.h"
  
  static wxChar *
  oglCopystring (const wxChar *s)
  {
  	if (s == NULL) s = wxEmptyString;
  	size_t len = wxStrlen (s) + 1;
  
  	wxChar *news = new wxChar[len];
  	memcpy (news, s, len * sizeof(wxChar));    // Should be the fastest
  
  	return news;
  }
  
  class wxDividedShapeControlPoint: public wxControlPoint
  {
  	DECLARE_DYNAMIC_CLASS(wxDividedShapeControlPoint)
  private:
  	int regionId;
  public:
  	wxDividedShapeControlPoint()
  	{
  		regionId = 0;
  	}
  	wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object, int region,
  	                           double size, double the_xoffset, double the_yoffset, int the_type);
  	~wxDividedShapeControlPoint();
  
  	void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0);
  	void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0);
  	void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0);
  };
  
  IMPLEMENT_DYNAMIC_CLASS(wxDividedShapeControlPoint, wxControlPoint)
  
  /*
   * Divided object
   *
   */
  
  IMPLEMENT_DYNAMIC_CLASS(wxDividedShape, wxRectangleShape)
  
  wxDividedShape::wxDividedShape(double w, double h): wxRectangleShape(w, h)
  {
  	ClearRegions();
  }
  
  wxDividedShape::~wxDividedShape()
  {
  }
  
  void wxDividedShape::OnDraw(wxDC &dc)
  {
  	wxRectangleShape::OnDraw(dc);
  }
  
  void wxDividedShape::OnDrawContents(wxDC &dc)
  {
  	double defaultProportion = (double)(GetRegions().GetCount() > 0 ? (1.0 / ((double)(GetRegions().GetCount()))) : 0.0);
  	double currentY = (double)(m_ypos - (m_height / 2.0));
  	double maxY = (double)(m_ypos + (m_height / 2.0));
  
  	double leftX = (double)(m_xpos - (m_width / 2.0));
  	double rightX = (double)(m_xpos + (m_width / 2.0));
  
  	if (m_pen) dc.SetPen(* m_pen);
  
  	if (m_textColour.IsOk()) dc.SetTextForeground(m_textColour);
  
  #ifdef __WXMSW__
  	// For efficiency, don't do this under X - doesn't make
  	// any visible difference for our purposes.
  	if (m_brush)
  		dc.SetTextBackground(m_brush->GetColour());
  #endif
  	/*
  	  if (!formatted)
  	  {
  	    FormatRegionText();
  	    formatted = TRUE;
  	  }
  	*/
  	if (GetDisableLabel()) return;
  
  	double xMargin = 2;
  	double yMargin = 2;
  	dc.SetBackgroundMode(wxTRANSPARENT);
  
  	wxNode *node = GetRegions().GetFirst();
  	while (node)
  	{
  		wxShapeRegion *region = (wxShapeRegion *)node->GetData();
  		dc.SetFont(* region->GetFont());
  		dc.SetTextForeground(region->GetActualColourObject());
  
  		double proportion =
  		    region->m_regionProportionY < 0.0 ? defaultProportion : region->m_regionProportionY;
  
  		double y = currentY + m_height * proportion;
  		double actualY = maxY < y ? maxY : y;
  
  		double centreX = m_xpos;
  		double centreY = (double)(currentY + (actualY - currentY) / 2.0);
  
  		oglDrawFormattedText(dc, &region->m_formattedText,
  		                     (double)(centreX), (double)(centreY), (double)(m_width - 2 * xMargin), (double)(actualY - currentY - 2 * yMargin),
  		                     region->m_formatMode);
  		if ((y <= maxY) && (node->GetNext()))
  		{
  			wxPen *regionPen = region->GetActualPen();
  			if (regionPen)
  			{
  				dc.SetPen(* regionPen);
  				dc.DrawLine(WXROUND(leftX), WXROUND(y), WXROUND(rightX), WXROUND(y));
  			}
  		}
  
  		currentY = actualY;
  
  		node = node->GetNext();
  	}
  }
  
  void wxDividedShape::SetSize(double w, double h, bool WXUNUSED(recursive))
  {
  	SetAttachmentSize(w, h);
  	m_width = w;
  	m_height = h;
  	SetRegionSizes();
  }
  
  void wxDividedShape::SetRegionSizes()
  {
  	if (GetRegions().GetCount() == 0)
  		return;
  
  	double defaultProportion = (double)(GetRegions().GetCount() > 0 ? (1.0 / ((double)(GetRegions().GetCount()))) : 0.0);
  	double currentY = (double)(m_ypos - (m_height / 2.0));
  	double maxY = (double)(m_ypos + (m_height / 2.0));
  
  //  double leftX = (double)(m_xpos - (m_width / 2.0));
  //  double rightX = (double)(m_xpos + (m_width / 2.0));
  
  	wxNode *node = GetRegions().GetFirst();
  	while (node)
  	{
  		wxShapeRegion *region = (wxShapeRegion *)node->GetData();
  		double proportion =
  		    region->m_regionProportionY <= 0.0 ? defaultProportion : region->m_regionProportionY;
  
  		double sizeY = (double)proportion * m_height;
  		double y = currentY + sizeY;
  		double actualY = maxY < y ? maxY : y;
  
  		double centreY = (double)(currentY + (actualY - currentY) / 2.0);
  
  		region->SetSize(m_width, sizeY);
  		region->SetPosition(0.0, (double)(centreY - m_ypos));
  		currentY = actualY;
  		node = node->GetNext();
  	}
  }
  
  // Attachment points correspond to regions in the divided box
  bool wxDividedShape::GetAttachmentPosition(int attachment, double *x, double *y, int nth, int no_arcs,
          wxLineShape *line)
  {
  	int totalNumberAttachments = (GetRegions().GetCount() * 2) + 2;
  	if ((GetAttachmentMode() == ATTACHMENT_MODE_NONE) || (attachment >= totalNumberAttachments))
  	{
  		return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs);
  	}
  
  	int n = GetRegions().GetCount();
  	bool isEnd = (line && line->IsEnd(this));
  
  	double left = (double)(m_xpos - m_width / 2.0);
  	double right = (double)(m_xpos + m_width / 2.0);
  	double top = (double)(m_ypos - m_height / 2.0);
  	double bottom = (double)(m_ypos + m_height / 2.0);
  
  	// Zero is top, n+1 is bottom.
  	if (attachment == 0)
  	{
  		*y = top;
  		if (m_spaceAttachments)
  		{
  			if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE))
  			{
  				// Align line according to the next handle along
  				wxRealPoint *point = line->GetNextControlPoint(this);
  				if (point->x < left)
  					*x = left;
  				else if (point->x > right)
  					*x = right;
  				else
  					*x = point->x;
  			}
  			else
  				*x = left + (nth + 1) * m_width / (no_arcs + 1);
  		}
  		else
  			*x = m_xpos;
  	}
  	else if (attachment == (n + 1))
  	{
  		*y = bottom;
  		if (m_spaceAttachments)
  		{
  			if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE))
  			{
  				// Align line according to the next handle along
  				wxRealPoint *point = line->GetNextControlPoint(this);
  				if (point->x < left)
  					*x = left;
  				else if (point->x > right)
  					*x = right;
  				else
  					*x = point->x;
  			}
  			else
  				*x = left + (nth + 1) * m_width / (no_arcs + 1);
  		}
  		else
  			*x = m_xpos;
  	}
  	// Left or right.
  	else
  	{
  		bool isLeft = !(attachment < (n + 1));
  		int i = (isLeft) ? (totalNumberAttachments - attachment - 1) : (attachment - 1);
  		wxNode *node = GetRegions().Item(i);
  		if (node)
  		{
  			wxShapeRegion *region = (wxShapeRegion *)node->GetData();
  
  			if (isLeft)
  				*x = left;
  			else
  				*x = right;
  
  			// Calculate top and bottom of region
  			top = (double)((m_ypos + region->m_y) - (region->m_height / 2.0));
  			bottom = (double)((m_ypos + region->m_y) + (region->m_height / 2.0));
  
  			// Assuming we can trust the absolute size and
  			// position of these regions...
  			if (m_spaceAttachments)
  			{
  				if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE))
  				{
  					// Align line according to the next handle along
  					wxRealPoint *point = line->GetNextControlPoint(this);
  					if (point->y < bottom)
  						*y = bottom;
  					else if (point->y > top)
  						*y = top;
  					else
  						*y = point->y;
  				}
  				else
  //          *y = (double)(((m_ypos + region->m_y) - (region->m_height/2.0)) + (nth + 1)*region->m_height/(no_arcs+1));
  					*y = (double)(top + (nth + 1) * region->m_height / (no_arcs + 1));
  			}
  			else
  				*y = (double)(m_ypos + region->m_y);
  		}
  		else
  		{
  			*x = m_xpos;
  			*y = m_ypos;
  			return FALSE;
  		}
  	}
  	return TRUE;
  }
  
  int wxDividedShape::GetNumberOfAttachments() const
  {
  	// There are two attachments for each region (left and right),
  	// plus one on the top and one on the bottom.
  	int n = (GetRegions().GetCount() * 2) + 2;
  
  	int maxN = n - 1;
  	wxNode *node = m_attachmentPoints.GetFirst();
  	while (node)
  	{
  		wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData();
  		if (point->m_id > maxN)
  			maxN = point->m_id;
  		node = node->GetNext();
  	}
  	return maxN + 1;
  }
  
  bool wxDividedShape::AttachmentIsValid(int attachment) const
  {
  	int totalNumberAttachments = (GetRegions().GetCount() * 2) + 2;
  	if (attachment >= totalNumberAttachments)
  	{
  		return wxShape::AttachmentIsValid(attachment);
  	}
  	else if (attachment >= 0)
  		return TRUE;
  	else
  		return FALSE;
  }
  
  void wxDividedShape::Copy(wxShape &copy)
  {
  	wxRectangleShape::Copy(copy);
  }
  
  // Region operations
  
  void wxDividedShape::MakeControlPoints()
  {
  	wxRectangleShape::MakeControlPoints();
  
  	MakeMandatoryControlPoints();
  }
  
  void wxDividedShape::MakeMandatoryControlPoints()
  {
  	double currentY = (double)(GetY() - (m_height / 2.0));
  	double maxY = (double)(GetY() + (m_height / 2.0));
  
  	wxNode *node = GetRegions().GetFirst();
  	int i = 0;
  	while (node)
  	{
  		wxShapeRegion *region = (wxShapeRegion *)node->GetData();
  
  		double proportion = region->m_regionProportionY;
  
  		double y = currentY + m_height * proportion;
  		double actualY = (double)(maxY < y ? maxY : y);
  
  		if (node->GetNext())
  		{
  			wxDividedShapeControlPoint *controlPoint =
  			    new wxDividedShapeControlPoint(m_canvas, this, i, CONTROL_POINT_SIZE, 0.0, (double)(actualY - GetY()), 0);
  			m_canvas->AddShape(controlPoint);
  			m_controlPoints.Append(controlPoint);
  		}
  		currentY = actualY;
  		i ++;
  		node = node->GetNext();
  	}
  }
  
  void wxDividedShape::ResetControlPoints()
  {
  	// May only have the region handles, (n - 1) of them.
  	if (m_controlPoints.GetCount() > (GetRegions().GetCount() - 1))
  		wxRectangleShape::ResetControlPoints();
  
  	ResetMandatoryControlPoints();
  }
  
  void wxDividedShape::ResetMandatoryControlPoints()
  {
  	double currentY = (double)(GetY() - (m_height / 2.0));
  	double maxY = (double)(GetY() + (m_height / 2.0));
  
  	wxNode *node = m_controlPoints.GetFirst();
  	int i = 0;
  	while (node)
  	{
  		wxControlPoint *controlPoint = (wxControlPoint *)node->GetData();
  		if (controlPoint->IsKindOf(CLASSINFO(wxDividedShapeControlPoint)))
  		{
  			wxNode *node1 = GetRegions().Item(i);
  			wxShapeRegion *region = (wxShapeRegion *)node1->GetData();
  
  			double proportion = region->m_regionProportionY;
  
  			double y = currentY + m_height * proportion;
  			double actualY = (double)(maxY < y ? maxY : y);
  
  			controlPoint->m_xoffset = 0.0;
  			controlPoint->m_yoffset = (double)(actualY - GetY());
  			currentY = actualY;
  			i ++;
  		}
  		node = node->GetNext();
  	}
  }
  
  #if wxUSE_PROLOGIO
  void wxDividedShape::WriteAttributes(wxExpr *clause)
  {
  	wxRectangleShape::WriteAttributes(clause);
  }
  
  void wxDividedShape::ReadAttributes(wxExpr *clause)
  {
  	wxRectangleShape::ReadAttributes(clause);
  }
  #endif
  
  /*
   * Edit the division colour/style
   *
   */
  
  void wxDividedShape::EditRegions()
  {
  	wxMessageBox(wxT("EditRegions() is unimplemented."), wxT("OGL"), wxOK);
  
  	// TODO
  #if 0
  	if (GetRegions().GetCount() < 2)
  		return;
  
  	wxBeginBusyCursor();
  
  	GraphicsForm *form = new GraphicsForm("Divided nodes");
  	// Need an array to store all the style strings,
  	// since they need to be converted to integers
  	char **styleStrings = new char *[GetRegions().GetCount()];
  	for (int j = 0; j < GetRegions().GetCount(); j++)
  		styleStrings[j] = NULL;
  
  	int i = 0;
  	wxNode *node = GetRegions().GetFirst();
  	while (node && node->GetNext())
  	{
  		wxShapeRegion *region = (wxShapeRegion *)node->GetData();
  		char buf[50];
  		sprintf(buf, "Region %d", (i + 1));
  		form->Add(wxMakeFormMessage(buf));
  		form->Add(wxMakeFormNewLine());
  
  		form->Add(wxMakeFormString("Colour", &region->penColour, wxFORM_CHOICE,
  		                           new wxList(wxMakeConstraintStrings(
  		                                   "Invisible"        ,
  		                                   "BLACK"            ,
  		                                   "BLUE"             ,
  		                                   "BROWN"            ,
  		                                   "CORAL"            ,
  		                                   "CYAN"             ,
  		                                   "DARK GREY"        ,
  		                                   "DARK GREEN"       ,
  		                                   "DIM GREY"         ,
  		                                   "GREY"             ,
  		                                   "GREEN"            ,
  		                                   "LIGHT BLUE"       ,
  		                                   "LIGHT GREY"       ,
  		                                   "MAGENTA"          ,
  		                                   "MAROON"           ,
  		                                   "NAVY"             ,
  		                                   "ORANGE"           ,
  		                                   "PURPLE"           ,
  		                                   "RED"              ,
  		                                   "TURQUOISE"        ,
  		                                   "VIOLET"           ,
  		                                   "WHITE"            ,
  		                                   "YELLOW"           ,
  		                                   NULL),
  		                                      NULL), NULL, wxVERTICAL, 150));
  
  		char *styleString = NULL;
  		switch (region->penStyle)
  		{
  			case wxSHORT_DASH:
  				styleString = "Short Dash";
  				break;
  			case wxLONG_DASH:
  				styleString = "Long Dash";
  				break;
  			case wxDOT:
  				styleString = "Dot";
  				break;
  			case wxDOT_DASH:
  				styleString = "Dot Dash";
  				break;
  			case wxSOLID:
  			default:
  				styleString = "Solid";
  				break;
  		}
  		styleStrings[i] = oglCopystring(styleString);
  		form->Add(wxMakeFormString("Style", &(styleStrings[i]), wxFORM_CHOICE,
  		                           new wxList(wxMakeConstraintStrings(
  		                                   "Solid"            ,
  		                                   "Short Dash"       ,
  		                                   "Long Dash"        ,
  		                                   "Dot"              ,
  		                                   "Dot Dash"         ,
  		                                   NULL),
  		                                      NULL), NULL, wxVERTICAL, 100));
  		node = node->GetNext();
  		i ++;
  		if (node && node->GetNext())
  			form->Add(wxMakeFormNewLine());
  	}
  	wxDialogBox *dialog = new wxDialogBox(m_canvas->GetParent(), "Divided object properties", 10, 10, 500, 500);
  	if (GraphicsLabelFont)
  		dialog->SetLabelFont(GraphicsLabelFont);
  	if (GraphicsButtonFont)
  		dialog->SetButtonFont(GraphicsButtonFont);
  	form->AssociatePanel(dialog);
  	form->dialog = dialog;
  
  	dialog->Fit();
  	dialog->Centre(wxBOTH);
  
  	wxEndBusyCursor();
  
  	dialog->Show(TRUE);
  
  	node = GetRegions().GetFirst();
  	i = 0;
  	while (node)
  	{
  		wxShapeRegion *region = (wxShapeRegion *)node->GetData();
  
  		if (styleStrings[i])
  		{
  			if (strcmp(styleStrings[i], "Solid") == 0)
  				region->penStyle = wxSOLID;
  			else if (strcmp(styleStrings[i], "Dot") == 0)
  				region->penStyle = wxDOT;
  			else if (strcmp(styleStrings[i], "Short Dash") == 0)
  				region->penStyle = wxSHORT_DASH;
  			else if (strcmp(styleStrings[i], "Long Dash") == 0)
  				region->penStyle = wxLONG_DASH;
  			else if (strcmp(styleStrings[i], "Dot Dash") == 0)
  				region->penStyle = wxDOT_DASH;
  			delete[] styleStrings[i];
  		}
  		region->m_actualPenObject = NULL;
  		node = node->GetNext();
  		i ++;
  	}
  	delete[] styleStrings;
  	Draw(dc);
  #endif
  }
  
  void wxDividedShape::OnRightClick(double x, double y, int keys, int attachment)
  {
  	if (keys & KEY_CTRL)
  	{
  		EditRegions();
  	}
  	else
  	{
  		wxRectangleShape::OnRightClick(x, y, keys, attachment);
  	}
  }
  
  wxDividedShapeControlPoint::wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object,
          int region, double size, double the_m_xoffset, double the_m_yoffset, int the_type):
  	wxControlPoint(the_canvas, object, size, the_m_xoffset, the_m_yoffset, the_type)
  {
  	regionId = region;
  }
  
  wxDividedShapeControlPoint::~wxDividedShapeControlPoint()
  {
  }
  
  // Implement resizing of divided object division
  void wxDividedShapeControlPoint::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment))
  {
  	wxClientDC dc(GetCanvas());
  	GetCanvas()->PrepareDC(dc);
  
  	dc.SetLogicalFunction(OGLRBLF);
  #if wxCHECK_VERSION(3, 0, 0)
  	wxPen dottedPen(wxColour(0, 0, 0), 1, wxPENSTYLE_DOT);
  #else
  	wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
  #endif
  	dc.SetPen(dottedPen);
  	dc.SetBrush((* wxTRANSPARENT_BRUSH));
  
  	wxDividedShape *dividedObject = (wxDividedShape *)m_shape;
  	double x1 = (double)(dividedObject->GetX() - (dividedObject->GetWidth() / 2.0));
  	double y1 = y;
  	double x2 = (double)(dividedObject->GetX() + (dividedObject->GetWidth() / 2.0));
  	double y2 = y;
  	dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y2));
  }
  
  void wxDividedShapeControlPoint::OnBeginDragLeft(double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment))
  {
  	wxClientDC dc(GetCanvas());
  	GetCanvas()->PrepareDC(dc);
  
  	wxDividedShape *dividedObject = (wxDividedShape *)m_shape;
  	dc.SetLogicalFunction(OGLRBLF);
  #if wxCHECK_VERSION(3, 0, 0)
  	wxPen dottedPen(wxColour(0, 0, 0), 1, wxPENSTYLE_DOT);
  #else
  	wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
  #endif
  	dc.SetPen(dottedPen);
  	dc.SetBrush((* wxTRANSPARENT_BRUSH));
  
  	double x1 = (double)(dividedObject->GetX() - (dividedObject->GetWidth() / 2.0));
  	double y1 = y;
  	double x2 = (double)(dividedObject->GetX() + (dividedObject->GetWidth() / 2.0));
  	double y2 = y;
  	dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y2));
  	m_canvas->CaptureMouse();
  }
  
  void wxDividedShapeControlPoint::OnEndDragLeft(double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment))
  {
  	wxClientDC dc(GetCanvas());
  	GetCanvas()->PrepareDC(dc);
  
  	wxDividedShape *dividedObject = (wxDividedShape *)m_shape;
  	wxNode *node = dividedObject->GetRegions().Item(regionId);
  	if (!node)
  		return;
  
  	wxShapeRegion *thisRegion = (wxShapeRegion *)node->GetData();
  	wxShapeRegion *nextRegion = NULL; // Region below this one
  
  	dc.SetLogicalFunction(wxCOPY);
  
  	m_canvas->ReleaseMouse();
  
  	// Find the old top and bottom of this region,
  	// and calculate the new proportion for this region
  	// if legal.
  
  	double currentY = (double)(dividedObject->GetY() - (dividedObject->GetHeight() / 2.0));
  	double maxY = (double)(dividedObject->GetY() + (dividedObject->GetHeight() / 2.0));
  
  	// Save values
  	double thisRegionTop = 0.0;
  #if 0
  	// this variable is not readed later
  	double thisRegionBottom = 0.0;
  #endif
  	double nextRegionBottom = 0.0;
  
  	node = dividedObject->GetRegions().GetFirst();
  	while (node)
  	{
  		wxShapeRegion *region = (wxShapeRegion *)node->GetData();
  
  		double proportion = region->m_regionProportionY;
  		double yy = currentY + (dividedObject->GetHeight() * proportion);
  		double actualY = (double)(maxY < yy ? maxY : yy);
  
  		if (region == thisRegion)
  		{
  			thisRegionTop = currentY;
  #if 0
  			// no need for assignment if value is not used later
  			thisRegionBottom = actualY;
  #endif
  			if (node->GetNext())
  				nextRegion = (wxShapeRegion *)node->GetNext()->GetData();
  		}
  		if (region == nextRegion)
  		{
  			nextRegionBottom = actualY;
  		}
  
  		currentY = actualY;
  		node = node->GetNext();
  	}
  	if (!nextRegion)
  		return;
  
  	// Check that we haven't gone above this region or below
  	// next region.
  	if ((y <= thisRegionTop) || (y >= nextRegionBottom))
  		return;
  
  	// dividedObject->EraseLinks(dc);
  
  	// Now calculate the new proportions of this region and the next region.
  	double thisProportion = (double)((y - thisRegionTop) / dividedObject->GetHeight());
  	double nextProportion = (double)((nextRegionBottom - y) / dividedObject->GetHeight());
  	thisRegion->SetProportions(0.0, thisProportion);
  	nextRegion->SetProportions(0.0, nextProportion);
  	m_yoffset = (double)(y - dividedObject->GetY());
  
  	// Now reformat text
  	int i = 0;
  	node = dividedObject->GetRegions().GetFirst();
  	while (node)
  	{
  		wxShapeRegion *region = (wxShapeRegion *)node->GetData();
  		if (!region->GetText().IsEmpty())
  		{
  			wxChar *s = oglCopystring(region->GetText());
  			dividedObject->FormatText(dc, s, i);
  			delete[] s;
  		}
  		node = node->GetNext();
  		i++;
  	}
  	dividedObject->SetRegionSizes();
  	dividedObject->GetEventHandler()->OnMoveLinks();
  
  	if (GetCanvas())
  		GetCanvas()->Refresh();
  }
  
  