vymmodel.cpp
author insilmaril
Wed, 30 Jul 2008 14:42:03 +0000
branchrelease-1-12-maintained
changeset 43 cf274b28e5fe
parent 40 394b2f297e1d
child 57 d045ba89798e
permissions -rw-r--r--
Fixed animation timer, which didn't stop once activated
insilmaril@40
     1
#include <QApplication>
insilmaril@40
     2
#include <typeinfo>
insilmaril@40
     3
insilmaril@40
     4
#include "geometry.h"		// for addBBox
insilmaril@40
     5
#include "vymmodel.h"
insilmaril@40
     6
insilmaril@40
     7
insilmaril@40
     8
extern Settings settings;
insilmaril@40
     9
insilmaril@40
    10
VymModel::VymModel() 
insilmaril@40
    11
{
insilmaril@40
    12
//    cout << "Const VymModel\n";
insilmaril@40
    13
}
insilmaril@40
    14
insilmaril@40
    15
insilmaril@40
    16
VymModel::~VymModel() 
insilmaril@40
    17
{
insilmaril@40
    18
//    cout << "Destr VymModel\n";
insilmaril@40
    19
}	
insilmaril@40
    20
insilmaril@40
    21
void VymModel::clear() 
insilmaril@40
    22
{
insilmaril@40
    23
	while (!mapCenters.isEmpty())
insilmaril@40
    24
		delete mapCenters.takeFirst();
insilmaril@40
    25
}
insilmaril@40
    26
insilmaril@40
    27
void VymModel::init () 
insilmaril@40
    28
{
insilmaril@40
    29
	addMapCenter();
insilmaril@40
    30
insilmaril@40
    31
	// animations
insilmaril@40
    32
	animationUse=settings.readBoolEntry("/animation/use",false);
insilmaril@40
    33
	animationTicks=settings.readNumEntry("/animation/ticks",10);
insilmaril@40
    34
	animationInterval=settings.readNumEntry("/animation/interval",50);
insilmaril@40
    35
	animObjList.clear();
insilmaril@40
    36
	animationTimer=new QTimer (this);
insilmaril@40
    37
	connect(animationTimer, SIGNAL(timeout()), this, SLOT(animate()));
insilmaril@40
    38
insilmaril@40
    39
}
insilmaril@40
    40
insilmaril@40
    41
void VymModel::setMapEditor(MapEditor *me)
insilmaril@40
    42
{
insilmaril@40
    43
	mapEditor=me;
insilmaril@40
    44
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
    45
		mapCenters.at(i)->setMapEditor(mapEditor);
insilmaril@40
    46
}
insilmaril@40
    47
insilmaril@40
    48
MapEditor* VymModel::getMapEditor()
insilmaril@40
    49
{
insilmaril@40
    50
	return mapEditor;
insilmaril@40
    51
}
insilmaril@40
    52
insilmaril@40
    53
void VymModel::setVersion (const QString &s)
insilmaril@40
    54
{
insilmaril@40
    55
	version=s;
insilmaril@40
    56
}
insilmaril@40
    57
insilmaril@40
    58
void VymModel::setAuthor (const QString &s)
insilmaril@40
    59
{
insilmaril@40
    60
	author=s;
insilmaril@40
    61
}
insilmaril@40
    62
insilmaril@40
    63
QString VymModel::getAuthor()
insilmaril@40
    64
{
insilmaril@40
    65
	return author;
insilmaril@40
    66
}
insilmaril@40
    67
insilmaril@40
    68
void VymModel::setComment (const QString &s)
insilmaril@40
    69
{
insilmaril@40
    70
	comment=s;
insilmaril@40
    71
}
insilmaril@40
    72
insilmaril@40
    73
QString VymModel::getComment ()
insilmaril@40
    74
{
insilmaril@40
    75
	return comment;
insilmaril@40
    76
}
insilmaril@40
    77
insilmaril@40
    78
QString VymModel::getDate ()
insilmaril@40
    79
{
insilmaril@40
    80
	return QDate::currentDate().toString ("yyyy-MM-dd");
insilmaril@40
    81
}
insilmaril@40
    82
insilmaril@40
    83
void VymModel::setScene (QGraphicsScene *s)
insilmaril@40
    84
{
insilmaril@40
    85
	mapScene=s;
insilmaril@40
    86
    init();	// Here we have a mapScene set, 
insilmaril@40
    87
			// which is (still) needed to create MapCenters
insilmaril@40
    88
}
insilmaril@40
    89
insilmaril@40
    90
QGraphicsScene* VymModel::getScene ()
insilmaril@40
    91
{
insilmaril@40
    92
	return mapScene;
insilmaril@40
    93
}
insilmaril@40
    94
insilmaril@40
    95
MapCenterObj* VymModel::addMapCenter()
insilmaril@40
    96
{
insilmaril@40
    97
	return addMapCenter (QPointF(0,0));
insilmaril@40
    98
}
insilmaril@40
    99
insilmaril@40
   100
MapCenterObj* VymModel::addMapCenter(QPointF absPos)
insilmaril@40
   101
{
insilmaril@40
   102
	MapCenterObj *mapCenter = new MapCenterObj(mapScene);
insilmaril@40
   103
	mapCenter->move (absPos);
insilmaril@40
   104
    mapCenter->setVisibility (true);
insilmaril@40
   105
	mapCenter->setHeading (QApplication::translate("Heading of mapcenter in new map", "New map"));
insilmaril@40
   106
	mapCenter->setMapEditor(mapEditor);		//FIXME needed to get defLinkStyle, mapLinkColorHint ... for later added objects
insilmaril@40
   107
	mapCenters.append(mapCenter);
insilmaril@40
   108
	return mapCenter;
insilmaril@40
   109
}
insilmaril@40
   110
insilmaril@40
   111
MapCenterObj *VymModel::removeMapCenter(MapCenterObj* mco)
insilmaril@40
   112
{
insilmaril@40
   113
	int i=mapCenters.indexOf (mco);
insilmaril@40
   114
	if (i>=0)
insilmaril@40
   115
	{
insilmaril@40
   116
		mapCenters.removeAt (i);
insilmaril@40
   117
		delete (mco);
insilmaril@40
   118
		if (i>0) return mapCenters.at(i-1);	// Return previous MCO
insilmaril@40
   119
	}
insilmaril@40
   120
	return NULL;
insilmaril@40
   121
}
insilmaril@40
   122
insilmaril@40
   123
BranchObj* VymModel::first()
insilmaril@40
   124
{
insilmaril@40
   125
	if (mapCenters.count()>0) 
insilmaril@40
   126
		return mapCenters.first();
insilmaril@40
   127
	else	
insilmaril@40
   128
		return NULL;
insilmaril@40
   129
}
insilmaril@40
   130
	
insilmaril@40
   131
BranchObj* VymModel::next(BranchObj *bo_start)
insilmaril@40
   132
{
insilmaril@40
   133
	BranchObj *rbo;
insilmaril@40
   134
	BranchObj *bo=bo_start;
insilmaril@40
   135
	if (bo)
insilmaril@40
   136
	{
insilmaril@40
   137
		// Try to find next branch in current MapCenter
insilmaril@40
   138
		rbo=bo->next();
insilmaril@40
   139
		if (rbo) return rbo;
insilmaril@40
   140
insilmaril@40
   141
		// Try to find MapCenter of bo
insilmaril@40
   142
		while (bo->getDepth()>0) bo=(BranchObj*)bo->getParObj();
insilmaril@40
   143
insilmaril@40
   144
		// Try to find next MapCenter
insilmaril@40
   145
		int i=mapCenters.indexOf ((MapCenterObj*)bo);
insilmaril@40
   146
		if (i+2 > mapCenters.count() || i<0) return NULL;
insilmaril@40
   147
		if (mapCenters.at(i+1)!=bo_start)
insilmaril@40
   148
			return mapCenters.at(i+1);
insilmaril@40
   149
	} 
insilmaril@40
   150
	return NULL;
insilmaril@40
   151
}
insilmaril@40
   152
insilmaril@40
   153
LinkableMapObj* VymModel::findMapObj(QPointF p, LinkableMapObj *excludeLMO)
insilmaril@40
   154
{
insilmaril@40
   155
	LinkableMapObj *lmo;
insilmaril@40
   156
insilmaril@40
   157
	for (int i=0;i<mapCenters.count(); i++)
insilmaril@40
   158
	{
insilmaril@40
   159
		lmo=mapCenters.at(i)->findMapObj (p,excludeLMO);
insilmaril@40
   160
		if (lmo) return lmo;
insilmaril@40
   161
	}
insilmaril@40
   162
	return NULL;
insilmaril@40
   163
}
insilmaril@40
   164
insilmaril@40
   165
LinkableMapObj* VymModel::findObjBySelect(const QString &s)
insilmaril@40
   166
{
insilmaril@40
   167
	LinkableMapObj *lmo;
insilmaril@40
   168
	if (!s.isEmpty() )
insilmaril@40
   169
	{
insilmaril@40
   170
		QString part;
insilmaril@40
   171
		QString typ;
insilmaril@40
   172
		QString num;
insilmaril@40
   173
		part=s.section(",",0,0);
insilmaril@40
   174
		typ=part.left (2);
insilmaril@40
   175
		num=part.right(part.length() - 3);
insilmaril@40
   176
		if (typ=="mc" && num.toInt()>=0 && num.toInt() <mapCenters.count() )
insilmaril@40
   177
			return mapCenters.at(num.toInt() );
insilmaril@40
   178
	}		
insilmaril@40
   179
insilmaril@40
   180
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   181
	{
insilmaril@40
   182
		lmo=mapCenters.at(i)->findObjBySelect(s);
insilmaril@40
   183
		if (lmo) return lmo;
insilmaril@40
   184
	}	
insilmaril@40
   185
	return NULL;
insilmaril@40
   186
}
insilmaril@40
   187
insilmaril@40
   188
LinkableMapObj* VymModel::findID (const QString &s)
insilmaril@40
   189
{
insilmaril@40
   190
	LinkableMapObj *lmo;
insilmaril@40
   191
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   192
	{
insilmaril@40
   193
		lmo=mapCenters.at(i)->findID (s);
insilmaril@40
   194
		if (lmo) return lmo;
insilmaril@40
   195
	}	
insilmaril@40
   196
	return NULL;
insilmaril@40
   197
}
insilmaril@40
   198
insilmaril@40
   199
QString VymModel::saveToDir (const QString &tmpdir,const QString &prefix, int verbose, const QPointF &offset)
insilmaril@40
   200
{
insilmaril@40
   201
    QString s;
insilmaril@40
   202
insilmaril@40
   203
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   204
		s+=mapCenters.at(i)->saveToDir (tmpdir,prefix,verbose,offset);
insilmaril@40
   205
    return s;
insilmaril@40
   206
}
insilmaril@40
   207
insilmaril@40
   208
insilmaril@40
   209
//////////////////////////////////////////////
insilmaril@40
   210
// View related
insilmaril@40
   211
//////////////////////////////////////////////
insilmaril@40
   212
insilmaril@40
   213
void VymModel::updateRelPositions()
insilmaril@40
   214
{
insilmaril@40
   215
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   216
		mapCenters.at(i)->updateRelPositions();
insilmaril@40
   217
}
insilmaril@40
   218
insilmaril@40
   219
void VymModel::reposition()
insilmaril@40
   220
{
insilmaril@40
   221
	for (int i=0;i<mapCenters.count(); i++)
insilmaril@40
   222
		mapCenters.at(i)->reposition();	//	for positioning heading
insilmaril@40
   223
}
insilmaril@40
   224
insilmaril@40
   225
QPolygonF VymModel::shape(BranchObj *bo)
insilmaril@40
   226
{
insilmaril@40
   227
	// Creating (arbitrary) shapes
insilmaril@40
   228
insilmaril@40
   229
	QPolygonF p;
insilmaril@40
   230
	QRectF rb=bo->getBBox();
insilmaril@40
   231
	if (bo->getDepth()==0)
insilmaril@40
   232
	{
insilmaril@40
   233
		// Just take BBox of this mapCenter
insilmaril@40
   234
		p<<rb.topLeft()<<rb.topRight()<<rb.bottomRight()<<rb.bottomLeft();
insilmaril@40
   235
		return p;
insilmaril@40
   236
	}
insilmaril@40
   237
insilmaril@40
   238
	// Take union of BBox and TotalBBox 
insilmaril@40
   239
insilmaril@40
   240
	QRectF ra=bo->getTotalBBox();
insilmaril@40
   241
	if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
insilmaril@40
   242
		p   <<ra.bottomLeft()
insilmaril@40
   243
			<<ra.topLeft()
insilmaril@40
   244
			<<QPointF (rb.topLeft().x(), ra.topLeft().y() )
insilmaril@40
   245
			<<rb.topRight()
insilmaril@40
   246
			<<rb.bottomRight()
insilmaril@40
   247
			<<QPointF (rb.bottomLeft().x(), ra.bottomLeft().y() ) ;
insilmaril@40
   248
	else		
insilmaril@40
   249
		p   <<ra.bottomRight()
insilmaril@40
   250
			<<ra.topRight()
insilmaril@40
   251
			<<QPointF (rb.topRight().x(), ra.topRight().y() )
insilmaril@40
   252
			<<rb.topLeft()
insilmaril@40
   253
			<<rb.bottomLeft()
insilmaril@40
   254
			<<QPointF (rb.bottomRight().x(), ra.bottomRight().y() ) ;
insilmaril@40
   255
	return p;		
insilmaril@40
   256
insilmaril@40
   257
}
insilmaril@40
   258
insilmaril@40
   259
void VymModel::moveAway(LinkableMapObj *lmo)
insilmaril@40
   260
{
insilmaril@40
   261
	// Autolayout:
insilmaril@40
   262
	//
insilmaril@40
   263
	// Move all branches and MapCenters away from lmo 
insilmaril@40
   264
	// to avoid collisions 
insilmaril@40
   265
insilmaril@40
   266
	QPolygonF pA;
insilmaril@40
   267
	QPolygonF pB;
insilmaril@40
   268
insilmaril@40
   269
	BranchObj *boA=(BranchObj*)lmo;
insilmaril@40
   270
	BranchObj *boB;
insilmaril@40
   271
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   272
	{
insilmaril@40
   273
		boB=mapCenters.at(i);
insilmaril@40
   274
		pA=shape (boA);
insilmaril@40
   275
		pB=shape (boB);
insilmaril@40
   276
		PolygonCollisionResult r = PolygonCollision(pA, pB, QPoint(0,0));
insilmaril@40
   277
		cout <<"------->"
insilmaril@40
   278
			<<"="<<r.intersect
insilmaril@40
   279
			<<"  ("<<qPrintable(boA->getHeading() )<<")"
insilmaril@40
   280
			<<"  with ("<< qPrintable (boB->getHeading() )
insilmaril@40
   281
			<<")  willIntersect"
insilmaril@40
   282
			<<r.willIntersect 
insilmaril@40
   283
			<<"  minT="<<r.minTranslation<<endl<<endl;
insilmaril@40
   284
	}
insilmaril@40
   285
}
insilmaril@40
   286
insilmaril@40
   287
void VymModel::animate()
insilmaril@40
   288
{
insilmaril@40
   289
	animationTimer->stop();
insilmaril@40
   290
	BranchObj *bo;
insilmaril@40
   291
	int i=0;
insilmaril@40
   292
	while (i<animObjList.size() )
insilmaril@40
   293
	{
insilmaril@40
   294
		bo=(BranchObj*)animObjList.at(i);
insilmaril@40
   295
		if (!bo->animate())
insilmaril@40
   296
		{
insilmaril@40
   297
			if (i>=0) animObjList.removeAt(i);
insilmaril@40
   298
			i--;
insilmaril@40
   299
		}
insilmaril@40
   300
		bo->reposition();
insilmaril@40
   301
		i++;
insilmaril@40
   302
	} 
insilmaril@40
   303
	mapEditor->updateSelection();
insilmaril@40
   304
	mapScene->update();
insilmaril@43
   305
	if (!animObjList.isEmpty() ) animationTimer->start();
insilmaril@40
   306
}
insilmaril@40
   307
insilmaril@40
   308
insilmaril@40
   309
void VymModel::startAnimation(const QPointF &start, const QPointF &dest)
insilmaril@40
   310
{
insilmaril@40
   311
	BranchObj *bo=getSelectedBranch();
insilmaril@40
   312
	if (bo && bo->getDepth()>0) 
insilmaril@40
   313
	{
insilmaril@40
   314
		AnimPoint ap;
insilmaril@40
   315
		ap.setStart (start);
insilmaril@40
   316
		ap.setDest  (dest);
insilmaril@40
   317
		ap.setTicks (animationTicks);
insilmaril@40
   318
		ap.setAnimated (true);
insilmaril@40
   319
		bo->setAnimation (ap);
insilmaril@40
   320
		animObjList.append( bo );
insilmaril@40
   321
		animationTimer->setSingleShot (true);
insilmaril@40
   322
		animationTimer->start(animationInterval);
insilmaril@40
   323
	}
insilmaril@40
   324
}
insilmaril@40
   325
insilmaril@40
   326
void VymModel::stopAnimation(MapObj *mo)
insilmaril@40
   327
{
insilmaril@40
   328
	int i=animObjList.indexOf(mo);
insilmaril@40
   329
    if (i>=0)
insilmaril@40
   330
		animObjList.removeAt (i);
insilmaril@40
   331
}
insilmaril@40
   332
insilmaril@40
   333
//////////////////////////////////////////////
insilmaril@40
   334
// Selection related
insilmaril@40
   335
//////////////////////////////////////////////
insilmaril@40
   336
insilmaril@40
   337
insilmaril@40
   338
// Only as long as we dont have Model/View yet
insilmaril@40
   339
LinkableMapObj* VymModel::getSelection()
insilmaril@40
   340
{
insilmaril@40
   341
	return mapEditor->getSelection();
insilmaril@40
   342
}
insilmaril@40
   343
BranchObj* VymModel::getSelectedBranch()
insilmaril@40
   344
{
insilmaril@40
   345
	return mapEditor->getSelectedBranch();
insilmaril@40
   346
}
insilmaril@40
   347
insilmaril@40
   348
insilmaril@40
   349
bool VymModel::select (const QString &s)
insilmaril@40
   350
{
insilmaril@40
   351
	return mapEditor->select (s);
insilmaril@40
   352
}
insilmaril@40
   353
insilmaril@40
   354
QString VymModel::getSelectString (LinkableMapObj *lmo)
insilmaril@40
   355
{
insilmaril@40
   356
	QString s;
insilmaril@40
   357
	if (!lmo) return s;
insilmaril@40
   358
	if (typeid(*lmo)==typeid(BranchObj) ||
insilmaril@40
   359
		typeid(*lmo)==typeid(MapCenterObj) )
insilmaril@40
   360
	{	
insilmaril@40
   361
		LinkableMapObj *par=lmo->getParObj();
insilmaril@40
   362
		if (par)
insilmaril@40
   363
		{
insilmaril@40
   364
			if (lmo->getDepth() ==1)
insilmaril@40
   365
				// Mainbranch, return 
insilmaril@40
   366
				s= "bo:" + QString("%1").arg(((BranchObj*)lmo)->getNum());
insilmaril@40
   367
			else	
insilmaril@40
   368
				// Branch, call myself recursively
insilmaril@40
   369
				s= getSelectString(par) + ",bo:" + QString("%1").arg(((BranchObj*)lmo)->getNum());
insilmaril@40
   370
		} else
insilmaril@40
   371
		{
insilmaril@40
   372
			// MapCenter
insilmaril@40
   373
			int i=mapCenters.indexOf ((MapCenterObj*)lmo);
insilmaril@40
   374
			if (i>=0) s=QString("mc:%1").arg(i);
insilmaril@40
   375
		}	
insilmaril@40
   376
	}	
insilmaril@40
   377
	return s;
insilmaril@40
   378
insilmaril@40
   379
}
insilmaril@40
   380
insilmaril@40
   381
	
insilmaril@40
   382
void VymModel::setHideTmp (HideTmpMode mode)
insilmaril@40
   383
{
insilmaril@40
   384
	for (int i=0;i<mapCenters.count(); i++)
insilmaril@40
   385
		mapCenters.at(i)->setHideTmp (mode);	
insilmaril@40
   386
}
insilmaril@40
   387
insilmaril@40
   388
QRectF VymModel::getTotalBBox()
insilmaril@40
   389
{
insilmaril@40
   390
	QRectF r;
insilmaril@40
   391
	for (int i=0;i<mapCenters.count(); i++)
insilmaril@40
   392
		r=addBBox (mapCenters.at(i)->getTotalBBox(), r);
insilmaril@40
   393
	return r;	
insilmaril@40
   394
}
insilmaril@40
   395