/***************************************************************************
 *   Copyright (C) 2011 by Jeremy Burton   *
 *   jburton@39net-w04   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <stdio.h>

#include <QFontDatabase>
#include <QFileDialog>
#include <QDomDocument>
#include <QTextStream>
#include <QMessageBox>
#include <QColorDialog>
#include <QToolBar>

#include "textitem.h"
#include "textitem2.h"
#include "polygonitem.h"
#include "ellipseitem.h"
#include "boxitem.h"
#include "shapeitem.h"
#include "circtext.h"

const CVersion
    CCirctext::version = CVersion(0,11,12,"");

static const QString
	COLOR_STYLE("QWidget { background-color : %1;}");

CCirctext::CCirctext()
{
  //itemsCb_block = false;

  setWindowIcon(QIcon(":/images/128/chalk_board.png"));

  mainWidget = new Ui::MainWindow();
  mainWidget->setupUi(this);

/*
  QFontDatabase database;
  QStringList fonts = database.families();
  for (int i=0;i<fonts.count(); i++)
    mainWidget->fontfamilyCb->addItem(fonts.at(i));
*/
  QComboBox *cb = mainWidget->fontweightCb;
  cb->addItem("Light",QFont::Light);
  cb->addItem("Normal",QFont::Normal);
  cb->addItem("DemiBold",QFont::DemiBold);
  cb->addItem("Bold",QFont::Bold);
  cb->addItem("Black",QFont::Black);

  mainWidget->centreProp->setMinimum(-100.0);
  mainWidget->centreProp->setMaximum(100.0);
  mainWidget->radiusProp->setMinimum(0.5);
  mainWidget->radiusProp->setMaximum(200.0);
  mainWidget->sizeProp->setMinimum(1.0);
  mainWidget->sizeProp->setMaximum(400.0);
  mainWidget->offsetProp->setMinimum(-200.0);
  mainWidget->offsetProp->setMaximum(200.0);

  //Base Items
  connect(mainWidget->centreProp, SIGNAL(valueChanged(double,double)), this, SLOT(Slot_centrePropChange(double,double)));
  connect(mainWidget->strokeChk, SIGNAL(toggled(bool)), this, SLOT(Slot_strokeChkToggle(bool)));
  connect(mainWidget->strokewidthSpin, SIGNAL(valueChanged(double)), this, SLOT(Slot_strokewidthSpinChange(double)));
  connect(mainWidget->strokeColorBtn, SIGNAL(clicked()), this, SLOT(Slot_strokeColorBtnClick()));
  connect(mainWidget->angleSpin, SIGNAL(valueChanged(double)), this, SLOT(Slot_angleSpinChange(double)));
  connect(mainWidget->fillChk, SIGNAL(toggled(bool)), this, SLOT(Slot_fillChkToggle(bool)));
  connect(mainWidget->fillColorBtn, SIGNAL(clicked()), this, SLOT(Slot_fillColorBtnClick()));
  connect(mainWidget->centrelockChk, SIGNAL(toggled(bool)), this, SLOT(Slot_centrelockChkToggle(bool)));
  connect(mainWidget->sizelockChk, SIGNAL(toggled(bool)), this, SLOT(Slot_sizelockChkToggle(bool)));
  connect(mainWidget->anglelockChk, SIGNAL(toggled(bool)), this, SLOT(Slot_anglelockChkToggle(bool)));

  //Polar
  connect(mainWidget->radiusProp, SIGNAL(valueChanged(double,double)), this, SLOT(Slot_radiusPropChange(double,double)));
  connect(mainWidget->circularChk, SIGNAL(toggled(bool)), this, SLOT(Slot_circularChkToggle(bool)));

  //Text
  connect(mainWidget->spacingSpin, SIGNAL(valueChanged(double)), this, SLOT(Slot_spacingSpinChange(double)));
  connect(mainWidget->fontheightSpin, SIGNAL(valueChanged(double)), this, SLOT(Slot_fontheightSpinChange(double)));
  connect(mainWidget->txtEdit, SIGNAL(textChanged(const QString &)), this, SLOT(Slot_txtEditChange(const QString &)));
  connect(mainWidget->reverseChk, SIGNAL(toggled(bool)), this, SLOT(Slot_reverseChkToggle(bool)));
  connect(mainWidget->smallcapsChk, SIGNAL(toggled(bool)), this, SLOT(Slot_smallcapsChkToggle(bool)));
  connect(mainWidget->drawpathChk, SIGNAL(toggled(bool)), this, SLOT(Slot_drawpathChkToggle(bool)));
  connect(mainWidget->fontfamilyCb, SIGNAL(currentIndexChanged(int)), this, SLOT(Slot_fontfamilyCbChange(int)));
  connect(mainWidget->fontweightCb, SIGNAL(currentIndexChanged(int)), this, SLOT(Slot_fontweightCbChange(int)));
  connect(mainWidget->fontstretchSpin, SIGNAL(valueChanged(int)), this, SLOT(Slot_fontstretchSpinChange(int)));
  connect(mainWidget->refcharEdit, SIGNAL(textChanged(const QString &)), this, SLOT(Slot_refcharEditChange(const QString &)));
  connect(mainWidget->anchorangleSpin, SIGNAL(valueChanged(double)), this, SLOT(Slot_anchorangleSpinChange(double)));
  connect(mainWidget->justifyCb, SIGNAL(currentIndexChanged(int)), this, SLOT(Slot_justifyCbChange(int)));

  //Text2

  //Box
  connect(mainWidget->sizeProp, SIGNAL(valueChanged(double,double)), this, SLOT(Slot_sizePropChange(double,double)));
  connect(mainWidget->constrainpropChk, SIGNAL(toggled(bool)), this, SLOT(Slot_constrainpropChkToggle(bool)));
  connect(mainWidget->squareChk, SIGNAL(toggled(bool)), this, SLOT(Slot_squareChkToggle(bool)));

  //Polygon
  connect(mainWidget->pointsSpin, SIGNAL(valueChanged(int)), this, SLOT(Slot_pointsSpinChange(int)));
  connect(mainWidget->incrementSpin, SIGNAL(valueChanged(int)), this, SLOT(Slot_incrementSpinChange(int)));

  //Radial
  connect(mainWidget->radius3Spin, SIGNAL(valueChanged(double)), this, SLOT(Slot_radius3SpinChange(double)));

  //Shape
  connect(mainWidget->offsetProp, SIGNAL(valueChanged(double,double)), this, SLOT(Slot_offsetPropChange(double,double)));
  connect(mainWidget->scaleSpin, SIGNAL(valueChanged(double)), this, SLOT(Slot_scaleSpinChange(double)));
  connect(mainWidget->pointsEdit, SIGNAL(textChanged()), this, SLOT(Slot_pointsEditChange()));
  connect(mainWidget->nameEdt, SIGNAL(textChanged(const QString &)), this, SLOT(Slot_nameEdtChange(const QString &)));

  connect(mainWidget->actionNew, SIGNAL(triggered()), this, SLOT(Slot_new()));
  connect(mainWidget->actionLoad, SIGNAL(triggered()), this, SLOT(Slot_load()));
  connect(mainWidget->actionSave, SIGNAL(triggered()), this, SLOT(Slot_save()));
  connect(mainWidget->actionSaveAs, SIGNAL(triggered()), this, SLOT(Slot_saveas()));
  connect(mainWidget->actionExportPDF, SIGNAL(triggered()), this, SLOT(Slot_exportPDF()));
  connect(mainWidget->actionExit, SIGNAL(triggered()), this, SLOT(close()));

  //Item List Action / Add buttons
  //connect(mainWidget->itemAddText1Btn, SIGNAL(clicked()), this, SLOT(Slot_itemAdd_Text1()));
  //connect(mainWidget->itemAddText2Btn, SIGNAL(clicked()), this, SLOT(Slot_itemAdd_Text2()));
  //connect(mainWidget->itemAddBoxBtn, SIGNAL(clicked()), this, SLOT(Slot_itemAdd_Box()));
  //connect(mainWidget->itemAddCircleBtn, SIGNAL(clicked()), this, SLOT(Slot_itemAdd_Circle()));
  //connect(mainWidget->itemAddEllipseBtn, SIGNAL(clicked()), this, SLOT(Slot_itemAdd_Ellipse()));
  //connect(mainWidget->itemAddPolygonBtn, SIGNAL(clicked()), this, SLOT(Slot_itemAdd_Polygon()));
  //connect(mainWidget->itemAddRadialBtn, SIGNAL(clicked()), this, SLOT(Slot_itemAdd_Radial()));
  //connect(mainWidget->itemAddShapeBtn, SIGNAL(clicked()), this, SLOT(Slot_itemAdd_Shape()));
  connect(mainWidget->itemCopyBtn, SIGNAL(clicked()), this, SLOT(Slot_itemCopyBtnClick()));
  connect(mainWidget->itemDelBtn, SIGNAL(clicked()), this, SLOT(Slot_itemDelBtnClick()));
  connect(mainWidget->upBtn, SIGNAL(clicked()), this, SLOT(Slot_upBtnClick()));
  connect(mainWidget->downBtn, SIGNAL(clicked()), this, SLOT(Slot_downBtnClick()));

  //connect(mainWidget->itemsCb, SIGNAL(currentIndexChanged(int)), this, SLOT(Slot_itemsCbChange(int)));
  connect(mainWidget->itemsLst, SIGNAL(currentRowChanged(int)), this, SLOT(Slot_itemSelect(int)));

  connect(mainWidget->zoomSlide, SIGNAL(valueChanged(int)), this, SLOT(zoomChangeSlot(int)));

  connect(mainWidget->canvas, SIGNAL(itemChange(int)), this, SLOT(Slot_itemChange(int)));
  connect(mainWidget->canvas, SIGNAL(canvasChange()), this, SLOT(Slot_canvasChange()));
  //connect(mainWidget->itemsWgt, SIGNAL(itemSelect(int)), this, SLOT(Slot_itemSelect(int)));

  connect(mainWidget->actionPreview, SIGNAL(triggered()), this, SLOT(Slot_actionPreviewTrigger()));

  connect(mainWidget->actionAbout, SIGNAL(triggered()), this, SLOT(Slot_about()));
  connect(mainWidget->actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));

  connect(mainWidget->actionTest, SIGNAL(triggered()), this, SLOT(Slot_actionTestTrigger()));

mainWidget->statusbar->addPermanentWidget(mainWidget->zoomLbl);
mainWidget->statusbar->addPermanentWidget(mainWidget->zoomSlide);

//TODO: clean this up, it's all legacy now
  mainWidget->basePropPage->setVisible(false);
  mainWidget->polarPropPage->setVisible(false);
  mainWidget->textPropPage->setVisible(false);
  mainWidget->boxPropPage->setVisible(false);
  mainWidget->polygonPropPage->setVisible(false);
  mainWidget->radialPropPage->setVisible(false);

  create_menus();
  create_toolbars();

  itemsLst_populate();

  mainWidget->canvas->auto_zoom_req = true;

  QSettings settings("JBS", "Circ Text");
  restoreGeometry(settings.value("geometry").toByteArray());
  restoreState(settings.value("windowState").toByteArray());

  //mainWidget->itemsWgt->setItems(&mainWidget->canvas->items);
  //mainWidget->itemsWgt->setMouseTracking(true);
}

CCirctext::~CCirctext()
{
}

void CCirctext::closeEvent(QCloseEvent *event)
{
  if (save_check())
  {
     QSettings settings("JBS", "Circ Text");
     settings.setValue("geometry", saveGeometry());
     settings.setValue("windowState", saveState());
     QMainWindow::closeEvent(event);
  }
  else
    event->ignore();
}

void CCirctext::create_menus()
{
/*
  QMenu *menu;
  QAction *act;
  QActionGroup *actgroup;

  menu = mainWidget->menuView->addMenu("Grid");
  actgroup = new QActionGroup(menu);
  act = new QAction("Off", this);
  act->setCheckable(true);
  act->setData(0);
  menu->addAction(act);
  actgroup->addAction(act);
  act = new QAction("Cartesian", this);
  act->setCheckable(true);
  act->setChecked(true);
  act->setData(1);
  menu->addAction(act);
  actgroup->addAction(act);
  act = new QAction("Polar", this);
  act->setCheckable(true);
  act->setData(2);
  menu->addAction(act);
  actgroup->addAction(act);

  connect(menu, SIGNAL(triggered(QAction *)), this, SLOT(Slot_gridMenuTrigger(QAction *)));
*/
  mainWidget->gridOffAct->setData(0);
  mainWidget->gridCartesianAct->setData(1);
  mainWidget->gridPolarAct->setData(2);

  QActionGroup *actgroup = new QActionGroup(mainWidget->menuGrid);
  actgroup->addAction(mainWidget->gridOffAct);
  actgroup->addAction(mainWidget->gridCartesianAct);
  actgroup->addAction(mainWidget->gridPolarAct);

  connect(mainWidget->menuGrid, SIGNAL(triggered(QAction *)), this, SLOT(Slot_gridMenuTrigger(QAction *)));
}

void CCirctext::create_toolbars()
{
  QAction *act;

  QToolBar *view = addToolBar("View");

  view->addAction(mainWidget->actionPreview);


  QToolBar *additems = addToolBar("Add Items");

  act = new QAction(QIcon(":/images/24/text.png"), "Add &Text1", this);
  act->setStatusTip("New circular text item");
  additems->addAction(act);
  connect(act, SIGNAL(triggered()), this, SLOT(Slot_itemAdd_Text1()));

  act = new QAction(QIcon(":/images/24/text.png"), "Add &Text2", this);
  act->setStatusTip("New elliptical text item");
  additems->addAction(act);
  connect(act, SIGNAL(triggered()), this, SLOT(Slot_itemAdd_Text2()));

  act = new QAction(QIcon(":/images/24/box.png"), "Add &Box", this);
  act->setStatusTip("New box item");
  additems->addAction(act);
  connect(act, SIGNAL(triggered()), this, SLOT(Slot_itemAdd_Box()));

  act = new QAction(QIcon(":/images/24/circle.png"), "Add &Circle", this);
  act->setStatusTip("New circle item");
  additems->addAction(act);
  connect(act, SIGNAL(triggered()), this, SLOT(Slot_itemAdd_Ellipse()));

  act = new QAction(QIcon(":/images/24/ellipse.png"), "Add &Ellipse", this);
  act->setStatusTip("New ellipse item");
  additems->addAction(act);
  connect(act, SIGNAL(triggered()), this, SLOT(Slot_itemAdd_Ellipse()));

  act = new QAction(QIcon(":/images/24/polygon.png"), "Add &Polygon", this);
  act->setStatusTip("New polygon item");
  additems->addAction(act);
  connect(act, SIGNAL(triggered()), this, SLOT(Slot_itemAdd_Polygon()));

  act = new QAction(QIcon(":/images/24/radial.png"), "Add &Radial", this);
  act->setStatusTip("New radial item");
  additems->addAction(act);
  connect(act, SIGNAL(triggered()), this, SLOT(Slot_itemAdd_Radial()));

  act = new QAction(QIcon(":/images/24/shape.png"), "Add &Shape", this);
  act->setStatusTip("New shape item");
  additems->addAction(act);
  connect(act, SIGNAL(triggered()), this, SLOT(Slot_itemAdd_Shape()));
}

baseitem *CCirctext::curitem()
{
  return mainWidget->canvas->items[mainWidget->canvas->curitem];
}

void CCirctext::itemsLst_populate()
{
  baseitem *item;
/*
  QLabel *stackitem;
  QBoxLayout *stack = mainWidget->stackLayout;
  //QObjectList list = stack->children();
  while (stack->count()>1)
    delete stack->takeAt(0);
  mainWidget->itemsWgt->update();
*/
  //mainWidget->itemsWgt->setVisible(false);

  mainWidget->itemsLst->blockSignals(true);
  //itemsCb_block = true;
  //mainWidget->itemsCb->clear();
  mainWidget->itemsLst->clear();
QBrush boxbrush(Qt::SolidPattern),textbrush(Qt::SolidPattern);
  for (int i=0;i<mainWidget->canvas->items.count();i++)
{
    item = mainWidget->canvas->items[i];
    //mainWidget->itemsCb->addItem(item->describe());
QListWidgetItem *lstitem = new QListWidgetItem(item->describe(),mainWidget->itemsLst);
//lstitem->setBackground(QBrush(Qt::darkBlue));
//lstitem->setForeground(QBrush(Qt::white));
//mainWidget->itemsLst->addItem(lstitem);
    switch (item->getType())
    {
      case baseitem::textitem1_type:	boxbrush.setColor(Qt::darkBlue); textbrush.setColor(Qt::white); break;
      case baseitem::textitem2_type:	boxbrush.setColor(Qt::blue); textbrush.setColor(Qt::white); break;
      case baseitem::boxitem_type:	boxbrush.setColor(Qt::red); textbrush.setColor(Qt::black); break;
      case baseitem::polygonitem_type:	boxbrush.setColor(Qt::green); textbrush.setColor(Qt::black); break;
      case baseitem::radialitem_type:	boxbrush.setColor(Qt::cyan); textbrush.setColor(Qt::black); break;
      case baseitem::ellipseitem_type:	boxbrush.setColor(Qt::magenta); textbrush.setColor(Qt::black); break;
      case baseitem::shapeitem_type:	boxbrush.setColor(Qt::darkGray); textbrush.setColor(Qt::white); break;
    }
lstitem->setBackground(boxbrush);
lstitem->setForeground(textbrush);
/*
    stackitem = new QLabel;
    stackitem->setMinimumSize(24,24);
    switch (item->getType())
    {
      case baseitem::textitem_type:
	stackitem->setPixmap(QPixmap(":images/24/text.png"));
	break;
      case baseitem::circleitem_type:
	stackitem->setPixmap(QPixmap(":images/24/circle.png"));
	break;
      case baseitem::boxitem_type:
	stackitem->setPixmap(QPixmap(":images/24/box.png"));
	break;
      case baseitem::polygonitem_type:
	stackitem->setPixmap(QPixmap(":images/24/polygon.png"));
	break;
      case baseitem::radialitem_type:
	stackitem->setPixmap(QPixmap(":images/24/radial.png"));
	break;
    }
    stack->insertWidget(0,stackitem);
*/}
  //mainWidget->itemsCb->setCurrentIndex(-1);
  mainWidget->itemsLst->setCurrentRow(-1);
  mainWidget->itemsLst->blockSignals(false);
//itemsCb_block = false;
  //mainWidget->itemsCb->setCurrentIndex(mainWidget->canvas->curitem);
  mainWidget->itemsLst->setCurrentRow(mainWidget->canvas->curitem);
}

void CCirctext::Slot_about()
{
  QMessageBox::about(this, "About Circ Text",
	QString("Circ Text - a design program for creating artworks based on circular or elliptical.<br><br>"
	"Version %1.%2.%3 %4<br><br>"
	"&copy; 2011-2013 Jeremy Burton.").arg(version.major).arg(version.minor).arg(version.build).arg(version.subversion));
}

void CCirctext::Slot_zoomChange(int v)
{
  mainWidget->canvas->setZoom((double)v/10.0);
  mainWidget->zoomLbl->setText(QString().sprintf("x%.1f",mainWidget->canvas->getZoom()));
  //mainWidget->canvas->update();
}

void CCirctext::Slot_spacingSpinChange(double v)
{
  textitem *item = (textitem *)curitem();
  item->spacing = v;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

#ifdef OLD
void CCirctext::Slot_radius1SpinChange(double v)
{
  polaritem *item = (polaritem *)curitem();
  item->radius1 = v;
  if (item->circular /*&& item->radius1 != item->radius2*/)
    mainWidget->radius2Spin->setValue(item->radius1);
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_radius2SpinChange(double v)
{
  if (mainWidget->canvas->curitem<0)
    return;

  polaritem *item = (textitem *)curitem();
  item->radius2 = v;
  if (item->circular /*&& item->radius1 != item->radius2*/)
    mainWidget->radius1Spin->setValue(item->radius2);
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}
#endif

void CCirctext::Slot_radiusPropChange(double vx,double vy)
{
  if (mainWidget->canvas->curitem<0)
    return;

  polaritem *item = (textitem *)curitem();
  item->radius1 = vx;
  item->radius2 = vy;
//  if (item->circular /*&& item->radius1 != item->radius2*/)
//    mainWidget->radius1Spin->setValue(item->radius2);
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->itemsLst->currentItem()->setText(item->describe());
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_radius3SpinChange(double v)
{
  radialitem *item = (radialitem *)curitem();
  item->radius3 = v;
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_fontheightSpinChange(double v)
{
  textitem *item = (textitem *)curitem();
  item->fontheight = v;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_angleSpinChange(double v)
{
  baseitem *item = (baseitem *)curitem();
  item->angle = v;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_anchorangleSpinChange(double v)
{
  textitem *item = (textitem *)curitem();
  item->anchorangle = v;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_txtEditChange(const QString &t)
{
  textitem *item = (textitem *)curitem();
  item->str = t;
  //mainWidget->itemsCb->setItemText(mainWidget->canvas->curitem,item->describe());
  mainWidget->itemsLst->currentItem()->setText(item->describe());
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_reverseChkToggle(bool checked)
{
  textitem *item = (textitem *)curitem();
  item->forward = !checked;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_smallcapsChkToggle(bool checked)
{
  textitem *item = (textitem *)curitem();
  item->smallcaps = checked;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_drawpathChkToggle(bool checked)
{
  textitem *item = (textitem *)curitem();
  item->drawpath = checked;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}
/*
void CCirctext::Slot_widthSpinChange(double v)
{
  boxitem *item = (boxitem *)curitem();
  item->width = v;
  if (item->square && item->width != item->height)
    mainWidget->heightSpin->setValue(item->width);
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->canvas->update();
}

void CCirctext::Slot_heightSpinChange(double v)
{
  boxitem *item = (boxitem *)curitem();
  item->height = v;
  if (item->square && item->width != item->height)
     mainWidget->widthSpin->setValue(item->height);
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->canvas->update();
}
*/
void CCirctext::Slot_sizePropChange(double vx,double vy)
{
  boxitem *item = (boxitem *)curitem();
  item->width = vx;
  item->height = vy;
//  if (item->square && item->width != item->height)
//     mainWidget->widthSpin->setValue(item->height);
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->itemsLst->currentItem()->setText(item->describe());
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_constrainpropChkToggle(bool checked)
{
  boxitem *item = (boxitem *)curitem();
  item->constrainprop = checked;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_circularChkToggle(bool checked)
{
  polaritem *item = (polaritem *)curitem();
  item->circular = checked;
  mainWidget->radiusProp->setLocked(checked);
  //mainWidget->radius2Spin->setEnabled(!checked);
  if (item->circular)
  {
    item->radius1 = item->radius2 = std::max(item->radius1,item->radius2);
    Slot_itemChange(mainWidget->canvas->curitem);
    //mainWidget->radius1Spin->setValue(item->radius1);
    //mainWidget->radius2Spin->setValue(item->radius2);
  }
  mainWidget->itemsLst->currentItem()->setText(item->describe());
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_squareChkToggle(bool checked)
{
  boxitem *item = (boxitem *)curitem();
  item->square = checked;
  mainWidget->sizeProp->setLocked(checked);
  if (item->square)
  {
    item->width = item->height = std::max(item->width,item->height);
    Slot_itemChange(mainWidget->canvas->curitem);
    //mainWidget->widthSpin->setValue(item->width);
    //mainWidget->heightSpin->setValue(item->height);
  }
  mainWidget->itemsLst->currentItem()->setText(item->describe());
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

/*
void CCirctext::Slot_offsetxSpinChange(double v)
{
  shapeitem *item = (shapeitem *)curitem();
  item->offset.setX(v);
  item->update();
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->canvas->update();
}

void CCirctext::Slot_offsetySpinChange(double v)
{
  shapeitem *item = (shapeitem *)curitem();
  item->offset.setY(v);
  item->update();
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->canvas->update();
}
*/

void CCirctext::Slot_offsetPropChange(double vx,double vy)
{
  shapeitem *item = (shapeitem *)curitem();
  item->offset.setX(vx);
  item->offset.setY(vy);
  item->update();
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_scaleSpinChange(double v)
{
  shapeitem *item = (shapeitem *)curitem();
  item->scale = v;
  item->update();
  mainWidget->canvas->auto_zoom_req = true;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_pointsEditChange()
{
  double x,y;
  shapeitem *item = (shapeitem *)curitem();
  QStringList sl = mainWidget->pointsEdit->toPlainText().split("\n");
  item->points.clear();
  for (int i=0;i<sl.size();i++)
  {
    if (sscanf(sl[i].toAscii().data(),"%lf,%lf",&x,&y) == 2)
      item->points << QPointF(x,y);
  }
  item->update();
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_nameEdtChange(const QString &t)
{
  shapeitem *item = (shapeitem *)curitem();
  item->name = t;
  //mainWidget->itemsCb->setItemText(mainWidget->canvas->curitem,item->describe());
  mainWidget->itemsLst->currentItem()->setText(item->describe());
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_strokewidthSpinChange(double v)
{
  baseitem *item = (baseitem *)curitem();
  item->strokewidth = v;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

/*
void CCirctext::Slot_centrexSpinChange(double v)
{
  baseitem *item = (baseitem *)curitem();
  item->centre.setX(v);
  mainWidget->canvas->update();
}

void CCirctext::Slot_centreySpinChange(double v)
{
  baseitem *item = (baseitem *)curitem();
  item->centre.setY(v);
  mainWidget->canvas->update();
}
*/

void CCirctext::Slot_centrePropChange(double vx,double vy)
{
  baseitem *item = curitem();
  item->centre.setX(vx);
  item->centre.setY(vy);
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_strokeChkToggle(bool checked)
{
  baseitem *item = (baseitem *)curitem();
  item->stroke = checked;
//printf("item: %d stroke=%d\n",mainWidget->canvas->curitem,checked);
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_strokeColorBtnClick()
{

//printf("Slot_colorBtnTrigger\n");
  baseitem *item = (baseitem *)curitem();
  QColor color = QColorDialog::getColor(item->strokecolor, this, "Item Colour");
  if (color.isValid())
  {
    item->strokecolor = color;
    mainWidget->strokeColorLED->setStyleSheet(COLOR_STYLE.arg(color.name()));
    mainWidget->canvas->modified = true;
  }
//printf(" color=%lu\n",color.value());
}

void CCirctext::Slot_fillChkToggle(bool checked)
{
  baseitem *item = curitem();
  item->fill = checked;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_fillColorBtnClick()
{
  baseitem *item = (baseitem *)curitem();
  QColor color = QColorDialog::getColor(item->fillcolor, this, "Fill Colour");
  if (color.isValid())
  {
    item->fillcolor = color;
    mainWidget->fillColorLED->setStyleSheet(COLOR_STYLE.arg(color.name()));
    mainWidget->canvas->modified = true;
  }
}

void CCirctext::Slot_centrelockChkToggle(bool checked)
{
  baseitem *item = curitem();
  item->centrelock = checked;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_sizelockChkToggle(bool checked)
{
  baseitem *item = curitem();
  item->sizelock = checked;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_anglelockChkToggle(bool checked)
{
  baseitem *item = curitem();
  item->anglelock = checked;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_pointsSpinChange(int v)
{
  polygonitem *item = (polygonitem *)curitem();
  item->points = v;
  mainWidget->itemsLst->currentItem()->setText(item->describe());
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_incrementSpinChange(int v)
{
  polygonitem *item = (polygonitem *)curitem();
  item->increment = v;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::props_clear()
{
  for (int i=mainWidget->propsLayout->rowCount();i>=0;i--)
  {
    QLayoutItem *item;
    for (int j=0;j<2;j++)
    {
      item = mainWidget->propsLayout->itemAtPosition(i,j);
      if (item)
      {
	item->widget()->setVisible(false);
	mainWidget->propsLayout->removeItem(item);
      }
    }
  }
}

void CCirctext::props_add(struct CCirctext::prop_s *props)
{
  int r;

  for (int i=0;props[i].widget;i++)
  {
    r = mainWidget->propsLayout->rowCount();
    if (props[i].label)
    {
      mainWidget->propsLayout->addWidget(props[i].label,r,0);
      props[i].label->setVisible(true);
      mainWidget->propsLayout->addWidget(props[i].widget,r,1,Qt::AlignLeft);
    }
    else
      mainWidget->propsLayout->addWidget(props[i].widget,r,0,1,2,Qt::AlignLeft);
    props[i].widget->setVisible(true);
    props[i].widget->setEnabled(true);
    props[i].widget->blockSignals(false);
  }
}

void CCirctext::props_block(struct CCirctext::prop_s *props)
{
  for (int i=0;props[i].widget;i++)
    props[i].widget->blockSignals(true);
}

void CCirctext::Slot_itemSelect(int index)
{
  static prop_s
    base_props[] = {
	{new QLabel("Centre (mm)"),	mainWidget->centreProp},
	{new QLabel("Rotation"),	mainWidget->angleSpin},
	//{new QLabel("Stroke width"),	mainWidget->strokewidthSpin},
	{new QLabel("Line"),		mainWidget->strokeProp},
	{new QLabel("Fill"),		mainWidget->fillProp},
	{0,				mainWidget->centrelockChk},
	{0,				mainWidget->sizelockChk},
	{0,				mainWidget->anglelockChk},
	{0,0}
    },
    text_props[] = {
	{new QLabel("Font"),		mainWidget->fontfamilyCb},
	{new QLabel("Weight"),		mainWidget->fontweightCb},
	{new QLabel("Spacing"),		mainWidget->spacingSpin},
	{new QLabel("Stretch"),		mainWidget->fontstretchSpin},
	{new QLabel("Text Height"),	mainWidget->fontheightSpin},
	{new QLabel("Anchor angle"),	mainWidget->anchorangleSpin},
	{new QLabel("Text"),		mainWidget->txtEdit},
	{new QLabel("Height basis"),	mainWidget->refcharEdit},
	{new QLabel("Justify"),		mainWidget->justifyCb},
	{0,				mainWidget->reverseChk},
	{0,				mainWidget->smallcapsChk},
	{0,				mainWidget->drawpathChk},
	{0,0}
    },
/*
    text2_props[] = {
	{new QLabel("Radius (y)"),	mainWidget->radius2Spin},
	{0,0}
    },
*/
    box_props[] = {
	{new QLabel("Size (mm)"),	mainWidget->sizeProp},
	{0,				mainWidget->squareChk},
	//{0,				mainWidget->constrainpropChk},
	{0,0}
    },
    polar_props[] = {
	{new QLabel("Radius (mm)"),	mainWidget->radiusProp},
	{0,				mainWidget->circularChk},
	{0,0}
    },
    polygon_props[] = {
	{new QLabel("Ponts"),		mainWidget->pointsSpin},
	{new QLabel("Increment"),	mainWidget->incrementSpin},
	{0,0}
    },
    radial_props[] = {
	{new QLabel("Inner radius"),	mainWidget->radius3Spin},
	{0,0}
    },
    shape_props[] = {
	{new QLabel("Name"),		mainWidget->nameEdt},
	{new QLabel("Offset (mm)"),	mainWidget->offsetProp},
	{new QLabel("Scale"),		mainWidget->scaleSpin},
	{new QLabel("Ponts"),		mainWidget->pointsEdit},
	{0,0}
    };

  bool
    modified_state;

  //if (itemsCb_block)
  //  return;

  CCanvas *canvas = mainWidget->canvas;
  modified_state = canvas->modified;
  canvas->curitem = index;

  //Clear the properties grid
  props_clear();

  if (index<0)
  {
    canvas->update();
    return;
  }

  baseitem::EItemType itemtype = canvas->items[index]->getType();

  baseitem *item = canvas->items[index];

  props_block(base_props);
  mainWidget->centreProp->setValue(item->centre.x(),item->centre.y());
  mainWidget->angleSpin->setValue(item->angle);
  mainWidget->strokewidthSpin->setValue(item->strokewidth);
  mainWidget->strokeChk->setChecked(item->stroke);
  mainWidget->strokeColorLED->setStyleSheet(COLOR_STYLE.arg(item->strokecolor.name()));
  mainWidget->fillChk->setChecked(item->fill);
  mainWidget->fillColorLED->setStyleSheet(COLOR_STYLE.arg(item->fillcolor.name()));
  mainWidget->centrelockChk->setChecked(item->centrelock);
  mainWidget->sizelockChk->setChecked(item->sizelock);
  mainWidget->anglelockChk->setChecked(item->anglelock);
  props_add(base_props);

  switch (itemtype)
  {
    case baseitem::textitem1_type:
    {
	textitem *item = (textitem *)canvas->items[index];
	props_block(polar_props);
	mainWidget->radiusProp->setValue(item->radius1,item->radius2);
	mainWidget->radiusProp->setLocked(item->circular);
	mainWidget->circularChk->setChecked(item->circular);
        props_add(polar_props);
	props_block(text_props);
	mainWidget->anchorangleSpin->setValue(item->anchorangle);
	mainWidget->spacingSpin->setValue(item->spacing);
	mainWidget->fontheightSpin->setValue(item->fontheight);
	mainWidget->txtEdit->setText(item->str);
	mainWidget->reverseChk->setCheckState(item->forward?Qt::Unchecked:Qt::Checked);
	mainWidget->smallcapsChk->setCheckState(item->smallcaps?Qt::Checked:Qt::Unchecked);
	mainWidget->drawpathChk->setCheckState(item->drawpath?Qt::Checked:Qt::Unchecked);
	mainWidget->fontfamilyCb->setCurrentIndex(mainWidget->fontfamilyCb->findText(item->fontfamily));
	mainWidget->fontweightCb->setCurrentIndex(mainWidget->fontweightCb->findData(item->fontweight));
	mainWidget->fontstretchSpin->setValue(item->fontstretch);
	mainWidget->refcharEdit->setText(item->refchar);
	mainWidget->justifyCb->setCurrentIndex(item->justify);
	props_add(text_props);

	mainWidget->circularChk->setEnabled(false);
	break;
    }

    case baseitem::textitem2_type:
    {
	textitem2 *item = (textitem2 *)canvas->items[index];
	props_block(polar_props);
	mainWidget->radiusProp->setValue(item->radius1,item->radius2);
	mainWidget->radiusProp->setLocked(item->circular);
	//mainWidget->radius1Spin->setValue(item->radius1);
	//mainWidget->radius2Spin->setValue(item->radius2);
	mainWidget->circularChk->setChecked(item->circular);
        props_add(polar_props);
	props_block(text_props);
	mainWidget->anchorangleSpin->setValue(item->anchorangle);
	mainWidget->spacingSpin->setValue(item->spacing);
	mainWidget->fontheightSpin->setValue(item->fontheight);
	mainWidget->txtEdit->setText(item->str);
	mainWidget->reverseChk->setCheckState(item->forward?Qt::Unchecked:Qt::Checked);
	mainWidget->smallcapsChk->setCheckState(item->smallcaps?Qt::Checked:Qt::Unchecked);
	mainWidget->drawpathChk->setCheckState(item->drawpath?Qt::Checked:Qt::Unchecked);
	mainWidget->fontfamilyCb->setCurrentIndex(mainWidget->fontfamilyCb->findText(item->fontfamily));
	mainWidget->fontweightCb->setCurrentIndex(mainWidget->fontweightCb->findData(item->fontweight));
	mainWidget->fontstretchSpin->setValue(item->fontstretch);
	mainWidget->refcharEdit->setText(item->refchar);
	mainWidget->justifyCb->setCurrentIndex(item->justify);
	props_add(text_props);

	mainWidget->justifyCb->setEnabled(false);
	break;
    }

    case baseitem::boxitem_type:
    {
	props_block(box_props);
	boxitem *item = (boxitem *)canvas->items[index];
	//mainWidget->boxPropPage->setVisible(true);
	//mainWidget->widthSpin->setValue(item->width);
	//mainWidget->heightSpin->setValue(item->height);
	mainWidget->sizeProp->setValue(item->width,item->height);
	mainWidget->squareChk->setChecked(item->square);
	mainWidget->constrainpropChk->setChecked(item->constrainprop);
	props_add(box_props);
	break;
    }

//     case baseitem::circleitem_type:
//     {
// 	circleitem *item = (circleitem *)canvas->items[index];
// 	props_add(polar_props);
// 	mainWidget->radius1Spin->setValue(item->radius1);
// 	mainWidget->circularChk->setChecked(item->circular); mainWidget->circularChk->setEnabled(false);
// 	break;
//     }

    case baseitem::ellipseitem_type:
    {
	ellipseitem *item = (ellipseitem *)canvas->items[index];
	props_block(polar_props);
	mainWidget->radiusProp->setValue(item->radius1,item->radius2);
	mainWidget->radiusProp->setLocked(item->circular);
	mainWidget->circularChk->setChecked(item->circular);
	props_add(polar_props);
	break;
    }

    case baseitem::polygonitem_type:
    {
	polygonitem *item = (polygonitem *)canvas->items[index];
	props_block(polar_props);
	mainWidget->radiusProp->setValue(item->radius1,item->radius2);
	//mainWidget->radius1Spin->setValue(item->radius1);
	mainWidget->circularChk->setChecked(item->circular);
	props_add(polar_props);
	props_block(polygon_props);
	mainWidget->pointsSpin->setValue(item->points);
	mainWidget->incrementSpin->setValue(item->increment);
	props_add(polygon_props);

	mainWidget->circularChk->setEnabled(false);
	break;
    }

    case baseitem::radialitem_type:
    {
	radialitem *item = (radialitem *)canvas->items[index];
	props_block(polar_props);
	mainWidget->radiusProp->setValue(item->radius1,item->radius2);
	//mainWidget->radius1Spin->setValue(item->radius1);
	mainWidget->circularChk->setChecked(item->circular);
	props_add(polar_props);
	props_block(radial_props);
	mainWidget->radius3Spin->setValue(item->radius3);
	props_add(radial_props);

	mainWidget->circularChk->setEnabled(false);
	break;
    }

    case baseitem::shapeitem_type:
    {
	shapeitem *item = (shapeitem *)canvas->items[index];
	props_block(shape_props);

	mainWidget->nameEdt->setText(item->name);
	mainWidget->offsetProp->setValue(item->offset.x(),item->offset.y());
	//mainWidget->offsetProp->xSpin->setValue(item->offset.x());
	//mainWidget->offsetProp->ySpin->setValue(item->offset.y());
	mainWidget->scaleSpin->setValue(item->scale);

	QString s;
	for (int i=0; i<item->points.size(); i++)
	  s += QString::number(item->points[i].x()) +","+ QString::number(item->points[i].y()) + "\n";
	
	mainWidget->pointsEdit->setPlainText(s);
	props_add(shape_props);
	break;
    }
  }

  mainWidget->upBtn->setEnabled(index>0);
  mainWidget->downBtn->setEnabled(index<(canvas->items.count()-1));

  canvas->update();
  canvas->modified = modified_state;
}

void CCirctext::Slot_itemChange(int index)
{
  CCanvas *canvas = mainWidget->canvas;

  canvas->modified = true;

  if (canvas->curitem == index)
  {
    baseitem *item = (baseitem *)canvas->items[index];
    mainWidget->centreProp->setValue(item->centre.x(),item->centre.y());
    mainWidget->angleSpin->setValue(item->angle);

    switch (canvas->items[index]->getType())
    {
      case baseitem::textitem2_type:
      {
	//textitem2 *item = (textitem2 *)canvas->items[index];
	//mainWidget->radius2Spin->setValue(item->radius2);
	//DROP THROUGH
      }

      case baseitem::textitem1_type:
      {
	textitem *item = (textitem *)canvas->items[index];
	mainWidget->radiusProp->setValue(item->radius1,item->radius2);
	//mainWidget->radius1Spin->setValue(item->radius1);
	mainWidget->fontheightSpin->setValue(item->fontheight);
	mainWidget->anchorangleSpin->setValue(item->anchorangle);
	break;
      }

      case baseitem::boxitem_type:
      {
	boxitem *item = (boxitem *)canvas->items[index];
	//mainWidget->widthSpin->setValue(item->width);
	//mainWidget->heightSpin->setValue(item->height);
	mainWidget->sizeProp->setValue(item->width,item->height);
	break;
      }

//       case baseitem::circleitem_type:
//       {
// 	circleitem *item = (circleitem *)canvas->items[index];
// 	mainWidget->radius1Spin->setValue(item->radius1);
// 	break;
//       }

      case baseitem::ellipseitem_type:
      {
	ellipseitem *item = (ellipseitem *)canvas->items[index];
	mainWidget->radiusProp->setValue(item->radius1,item->radius2);
	//mainWidget->radius1Spin->setValue(item->radius1);
	//mainWidget->radius2Spin->setValue(item->radius2);
	break;
      }

      case baseitem::polygonitem_type:
      {
	polygonitem *item = (polygonitem *)canvas->items[index];
	mainWidget->radiusProp->setValue(item->radius1,item->radius2);
	//mainWidget->radius1Spin->setValue(item->radius1);
	break;
      }

      case baseitem::radialitem_type:
      {
	radialitem *item = (radialitem *)canvas->items[index];
	mainWidget->radiusProp->setValue(item->radius1,item->radius2);
	//mainWidget->radius1Spin->setValue(item->radius1);
	mainWidget->radius3Spin->setValue(item->radius3);
	mainWidget->angleSpin->setValue(item->angle);
	//mainWidget->radiusSpin->setValue(item->radius);
	break;
      }

      case baseitem::shapeitem_type:
      {
	shapeitem *item = (shapeitem *)canvas->items[index];
	mainWidget->offsetProp->setValue(item->offset.x(),item->offset.y());
	//mainWidget->offsetProp->xSpin->setValue(item->offset.x());
	//mainWidget->offsetProp->ySpin->setValue(item->offset.y());
	item->update();
	break;
      }
    }
  }
}

void CCirctext::Slot_canvasChange()
{
  mainWidget->zoomSlide->setValue(mainWidget->canvas->getZoom()*10.0);
}

void CCirctext::Slot_exportPDF()
{
  QString fileName = QFileDialog::getSaveFileName(this,"Output PDF",".","PDF Files (*.pdf);;All Files (*)");
  if (fileName.isEmpty())
    return;

  mainWidget->canvas->output(fileName);
}

void CCirctext::itemAdd(baseitem *item)
{
  mainWidget->canvas->items.prepend(item);
  //mainWidget->itemsCb->insertItem(0,item->describe());
  //mainWidget->itemsCb->setCurrentIndex(0);
  mainWidget->itemsLst->insertItem(0,item->describe());
  mainWidget->itemsLst->setCurrentRow(0);
  //mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
  //mainWidget->itemsWgt->update();
}

void CCirctext::Slot_itemAdd_Text1()
{
  itemAdd(new textitem1(QString("Item %1").arg(mainWidget->canvas->items.count())));
}

void CCirctext::Slot_itemAdd_Text2()
{
  itemAdd(new textitem2(QString("Item %1").arg(mainWidget->canvas->items.count())));
}

void CCirctext::Slot_itemAdd_Box()
{
  itemAdd(new boxitem);
}

void CCirctext::Slot_itemAdd_Circle()
{
  ellipseitem *item = new ellipseitem;
  item->circular = true;
  itemAdd(item);
}

void CCirctext::Slot_itemAdd_Ellipse()
{
  itemAdd(new ellipseitem);
}

void CCirctext::Slot_itemAdd_Polygon()
{
  itemAdd(new polygonitem);
}

void CCirctext::Slot_itemAdd_Radial()
{
  itemAdd(new radialitem);
}

void CCirctext::Slot_itemAdd_Shape()
{
  shapeitem *shape = new shapeitem;
  shape->offset.setX(0.0);
  shape->offset.setY(27.0);
  shape->points.append(QPointF(-2.8,-.15));
  shape->points.append(QPointF(-2.8,.15));
  shape->points.append(QPointF(-0.2,.15));
  shape->points.append(QPointF(-0.2,1.0));
  shape->points.append(QPointF(2.8,0.0));
  shape->points.append(QPointF(-0.2,-1.0));
  shape->points.append(QPointF(-0.2,-.15));
  shape->update();

  itemAdd(shape);
}

void CCirctext::Slot_itemCopyBtnClick()
{
  if (mainWidget->canvas->curitem < 0)
    return;

  baseitem *item = curitem()->dup();
  mainWidget->canvas->items.prepend(item);
  //mainWidget->itemsCb->insertItem(0,item->describe());
  //mainWidget->itemsCb->setCurrentIndex(0);
  mainWidget->itemsLst->insertItem(0,item->describe());
  mainWidget->itemsLst->setCurrentRow(0);
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_itemDelBtnClick()
{
  if (mainWidget->canvas->curitem < 0)
    return;

  mainWidget->canvas->items.removeAt(mainWidget->canvas->curitem);
  mainWidget->canvas->auto_zoom_req = true;
  //mainWidget->itemsCb->removeItem(mainWidget->canvas->curitem);
  mainWidget->itemsLst->blockSignals(true);
  QListWidgetItem *item = mainWidget->itemsLst->takeItem(mainWidget->canvas->curitem);
  delete item;
  Slot_itemSelect(mainWidget->itemsLst->currentRow());
  mainWidget->itemsLst->blockSignals(false);
  mainWidget->canvas->modified = true;
  //if (mainWidget->canvas->curitem >= mainWidget->canvas->items.count())
  //  mainWidget->canvas->curitem = mainWidget->canvas->items.count()-1;
  //mainWidget->itemsWgt->update();
}

void CCirctext::Slot_upBtnClick()
{
  int index = mainWidget->canvas->curitem;

  if (index<=0 || index>(mainWidget->canvas->items.count()-1))
    return;

  mainWidget->canvas->items.move(index,index-1);
  mainWidget->canvas->curitem = index-1;
  mainWidget->canvas->modified = true;
  itemsLst_populate();
  //mainWidget->itemsWgt->update();
}

void CCirctext::Slot_downBtnClick()
{
  int index = mainWidget->canvas->curitem;

  if (index<0 || index>=(mainWidget->canvas->items.count()-1))
    return;

  mainWidget->canvas->items.move(index,index+1);
  mainWidget->canvas->curitem = index+1;
  mainWidget->canvas->modified = true;
  itemsLst_populate();
  //mainWidget->itemsWgt->update();
}

void CCirctext::Slot_fontfamilyCbChange(int index)
{
  textitem *item = (textitem *)curitem();
  item->fontfamily = mainWidget->fontfamilyCb->itemText(index);
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_fontweightCbChange(int index)
{
  textitem *item = (textitem *)curitem();
  item->fontweight = mainWidget->fontweightCb->itemData(index).toInt();
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_fontstretchSpinChange(int v)
{
  textitem *item = (textitem *)curitem();
  item->fontstretch = v;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_refcharEditChange(const QString &t)
{
  if (t.count() < 1) return;
  textitem *item = (textitem *)curitem();
//printf("refchar=%c\n",mainWidget->canvas->items[mainWidget->canvas->curitem]->refchar[0].toAscii());
  item->refchar = t;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_justifyCbChange(int index)
{
  textitem *item = (textitem *)curitem();
  item->justify = (textitem::ETextJustify)index;
  mainWidget->canvas->update();
  mainWidget->canvas->modified = true;
}

void CCirctext::Slot_actionPreviewTrigger()
{
  mainWidget->canvas->preview = mainWidget->actionPreview->isChecked();
  mainWidget->canvas->update();
}

void CCirctext::Slot_actionTestTrigger()
{
  shapeitem *shape = new shapeitem;
  //QPointF sctr(0.0,-27.0);
  QPointF sctr(0.0,0.0);
  shape->offset.setX(0.0);
  shape->offset.setY(27.0);
  shape->points.append(QPointF(-2.8,-.15)+sctr);
  shape->points.append(QPointF(-2.8,.15)+sctr);
  shape->points.append(QPointF(-0.2,.15)+sctr);
  shape->points.append(QPointF(-0.2,1.0)+sctr);
  shape->points.append(QPointF(2.8,0.0)+sctr);
  shape->points.append(QPointF(-0.2,-1.0)+sctr);
  shape->points.append(QPointF(-0.2,-.15)+sctr);
  shape->update();
  mainWidget->canvas->items.prepend(shape);
  mainWidget->canvas->curitem = 0;

  itemsLst_populate();
  mainWidget->canvas->modified = true;
/*
  QFont font = QFont("Arial", 20);
  QFontMetrics *fontmetrics = new QFontMetrics(font);
  QRect rect;
  const char *s = "abcdefg";

  for (int i=0; s[i]; i++)
  {
    rect = fontmetrics->boundingRect(QChar(s[i]));
    printf("Test: %c - (%d,%d) (%d,%d)\n",s[i],rect.x(),rect.y(),rect.width(),rect.height());
  }
*/
}

void CCirctext::Slot_gridMenuTrigger(QAction *act)
{
  act->setChecked(true);
  mainWidget->canvas->setGridType(act->data().toInt());
  mainWidget->canvas->update();
}

void CCirctext::save(const QString &filename)
{
  QDomDocument doc( "CircTextML" );
  QDomElement root = doc.createElement( "circtext" );
  doc.appendChild( root );

  mainWidget->canvas->toDom(doc,root);

  QFile file(filename);
  if( !file.open( QIODevice::WriteOnly ) )
    return;

  QTextStream ts( &file );
  ts.setCodec("UTF-8");  //If we always save as UTF-8 unicode filenames should work. Othewise on windows it saves in some other encoding.
  ts << doc.toString();

  mainWidget->canvas->filename = filename;
  mainWidget->canvas->modified = false;
}

void CCirctext::Slot_save()
{
  if (mainWidget->canvas->filename.isEmpty())
    Slot_saveas();
  else
    save(mainWidget->canvas->filename);
}

void CCirctext::Slot_saveas()
{
  QString fileName = QFileDialog::getSaveFileName(this,"Save Design As",".","Circ Text Files (*.circtext)");
  if (fileName.isEmpty())
    return;

  fileName.replace('\\','/');

  QFileInfo fi(fileName);
  //QDir::setCurrent(Config::dir_layout = fi.dir().path());
  if (fi.completeSuffix().isEmpty())
    fileName += ".circtext";

  save(fileName);
}

int CCirctext::save_check()
{
  if (mainWidget->canvas->modified)
  {
    int ret = QMessageBox::warning(this, "Circ Text",
                        "The design has been modified.\n"
                        "Do you want to save your changes?",
                        QMessageBox::Yes | QMessageBox::Default,
                        QMessageBox::No,
                        QMessageBox::Cancel | QMessageBox::Escape);
    if (ret == QMessageBox::Yes)
      Slot_save();
    else
    if (ret == QMessageBox::Cancel)
      return false;
  }
  return true;
}

void CCirctext::Slot_new()
{
  if (save_check())
  {
    mainWidget->canvas->clear();
    //mainWidget->itemsCb->clear();
    mainWidget->itemsLst->clear();
    //mainWidget->itemsCb->curitem = -1;
    //props_clear();
    mainWidget->canvas->modified = false;
  }
}

void CCirctext::load()
{
  QString fileName = QFileDialog::getOpenFileName(this,"Load Design",".","Circ Text Files (*.circtext)");
  if (fileName.isEmpty())
    return;

  QDomDocument doc( "CircTextML" );
  QFile file(fileName);
  if (!file.open(QIODevice::ReadOnly))
  {
    QMessageBox::warning(this, "Circ Text",
                              QString("Cannot read file %1:\n%2.")
                              .arg(fileName)
                              .arg(file.errorString()));
    return;
  }
  if (!doc.setContent(&file)) 
  {
    file.close();
    return;
  }
  file.close();

  if (!fromDom(doc))
    return;

  if (mainWidget->canvas->items.size()>0)
    mainWidget->canvas->curitem = 0;
  itemsLst_populate();

//setCurrentFile(fileName);
  mainWidget->canvas->filename = fileName;
  mainWidget->canvas->modified = false;

  return;
}

void CCirctext::Slot_load()
{
  if (save_check())
    load();
}

bool CCirctext::fromDom(QDomDocument &doc)
{
  QDomElement root = doc.documentElement();
  if (root.tagName() != "circtext")
  {
    QMessageBox::warning(this, "Circ Text",
                              "Cannot load file\nThis is not an circtext file.");
    return false;
  }

  QDomNode n = root.firstChild();
  while(!n.isNull()) 
  {
    QDomElement e = n.toElement(); // try to convert the node to an element.
    if(!e.isNull()) 
    {
      if (e.tagName() == "canvas")
	mainWidget->canvas->fromDom(doc,e);
    }
    n = n.nextSibling();
  }

  return true;
}
